Qt-无边框窗口实现拖动和改变大小(Qt::FramelessWindowHint)
相关资料:
https://blog.csdn.net/dragoo1/article/details/121163236 原文
代码实例:
.pro
1 QT += core gui 2 3 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 4 5 CONFIG += c++11 6 7 # The following define makes your compiler emit warnings if you use 8 # any Qt feature that has been marked deprecated (the exact warnings 9 # depend on your compiler). Please consult the documentation of the 10 # deprecated API in order to know how to port your code away from it. 11 DEFINES += QT_DEPRECATED_WARNINGS 12 13 # You can also make your code fail to compile if it uses deprecated APIs. 14 # In order to do so, uncomment the following line. 15 # You can also select to disable deprecated APIs only up to a certain version of Qt. 16 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 17 18 SOURCES += \ 19 main.cpp \ 20 mainwindow.cpp 21 22 HEADERS += \ 23 mainwindow.h 24 25 FORMS += \ 26 mainwindow.ui 27 28 # Default rules for deployment. 29 qnx: target.path = /tmp/$${TARGET}/bin 30 else: unix:!android: target.path = /opt/$${TARGET}/bin 31 !isEmpty(target.path): INSTALLS += target
main.cpp
1 #include "mainwindow.h" 2 3 #include <QApplication> 4 5 int main(int argc, char *argv[]) 6 { 7 QApplication a(argc, argv); 8 MainWindow w; 9 w.show(); 10 return a.exec(); 11 }
mainwindow.h
1 #ifndef MAINWINDOW_H 2 #define MAINWINDOW_H 3 4 #include <QMainWindow> 5 6 #include <QtGui> 7 8 9 #define EDGE_MARGIN 8 10 11 QT_BEGIN_NAMESPACE 12 namespace Ui { class MainWindow; } 13 QT_END_NAMESPACE 14 15 class MainWindow : public QMainWindow 16 { 17 Q_OBJECT 18 19 public: 20 explicit MainWindow(QWidget *parent = 0); 21 protected: 22 virtual void mouseMoveEvent(QMouseEvent * event); 23 virtual void mousePressEvent(QMouseEvent * event); 24 virtual void mouseReleaseEvent(QMouseEvent * event); 25 virtual void enterEvent(QEvent * event); 26 virtual void leaveEvent(QEvent * event); 27 private: 28 QPoint dragPosition; //鼠标拖动的位置 29 enum {nodir, 30 top = 0x01, 31 bottom = 0x02, 32 left = 0x04, 33 right = 0x08, 34 topLeft = 0x01 | 0x04, 35 topRight = 0x01 | 0x08, 36 bottomLeft = 0x02 | 0x04, 37 bottomRight = 0x02 | 0x08 38 } resizeDir; //更改尺寸的方向 39 40 private: 41 void testEdge(QMouseEvent *event); //检测鼠标是否接近窗口边缘 42 43 44 private: 45 Ui::MainWindow *ui; 46 }; 47 #endif // MAINWINDOW_H
mainwindow.cpp
1 #include "mainwindow.h" 2 #include "ui_mainwindow.h" 3 4 5 #define min(a,b) ((a)<(b)? (a) :(b)) 6 #define max(a,b) ((a)>(b)? (a) :(b)) 7 8 9 MainWindow::MainWindow(QWidget *parent) 10 : QMainWindow(parent) 11 , ui(new Ui::MainWindow) 12 { 13 resizeDir = nodir; //初始化检测方向为无 14 setWindowFlags(Qt::FramelessWindowHint); //设置无边框 15 setMouseTracking(true); //开启鼠标追踪 16 setMinimumSize(90, 200); 17 } 18 19 void MainWindow::mousePressEvent(QMouseEvent * event) 20 { 21 if (event->button() == Qt::LeftButton) //每当按下鼠标左键就记录一下位置 22 { 23 dragPosition = event->globalPos() - frameGeometry().topLeft(); //获得鼠标按键位置相对窗口左上面的位置 24 } 25 } 26 27 void MainWindow::testEdge(QMouseEvent *event) 28 { 29 int diffLeft = event->globalPos().x() - frameGeometry().left(); //计算鼠标距离窗口上下左右有多少距离 30 int diffRight = event->globalPos().x() - frameGeometry().right(); 31 int diffTop = event->globalPos().y() - frameGeometry().top(); 32 int diffBottom = event->globalPos().y() - frameGeometry().bottom(); 33 34 Qt::CursorShape cursorShape; 35 36 if(diffTop < EDGE_MARGIN && diffTop>=0){ //根据 边缘距离 分类改变尺寸的方向 37 if(diffLeft < EDGE_MARGIN && diffLeft>=0){ 38 resizeDir = topLeft; 39 cursorShape = Qt::SizeFDiagCursor; 40 } 41 else if(diffRight > -EDGE_MARGIN && diffRight<=0){ 42 resizeDir = topRight; 43 cursorShape = Qt::SizeBDiagCursor; 44 } 45 else{ 46 resizeDir = top; 47 cursorShape = Qt::SizeVerCursor; 48 } 49 } 50 else if(abs(diffBottom) < EDGE_MARGIN && diffBottom<=0){ 51 if(diffLeft < EDGE_MARGIN && diffLeft>=0){ 52 resizeDir = bottomLeft; 53 cursorShape = Qt::SizeBDiagCursor; 54 } 55 else if(diffRight > -EDGE_MARGIN && diffRight<=0){ 56 resizeDir = bottomRight; 57 cursorShape = Qt::SizeFDiagCursor; 58 } 59 else{ 60 resizeDir = bottom; 61 cursorShape = Qt::SizeVerCursor; 62 } 63 } 64 else if(abs(diffLeft) < EDGE_MARGIN){ 65 resizeDir = left; 66 cursorShape = Qt::SizeHorCursor; 67 } 68 else if(abs(diffRight) < EDGE_MARGIN){ 69 resizeDir = right; 70 cursorShape = Qt::SizeHorCursor; 71 } 72 else{ 73 resizeDir = nodir; 74 cursorShape = Qt::ArrowCursor; 75 } 76 77 QApplication::setOverrideCursor(cursorShape); 78 } 79 80 void MainWindow::mouseMoveEvent(QMouseEvent * event) 81 { 82 if (event->buttons() & Qt::LeftButton){ //如果左键是按下的 83 if(resizeDir == nodir){ //如果鼠标不是放在边缘那么说明这是在拖动窗口 84 move(event->globalPos() - dragPosition); 85 } 86 else{ 87 int ptop,pbottom,pleft,pright; //窗口上下左右的值 88 ptop = frameGeometry().top(); 89 pbottom = frameGeometry().bottom(); 90 pleft = frameGeometry().left(); 91 pright = frameGeometry().right(); 92 if(resizeDir & top){ //检测更改尺寸方向中包含的上下左右分量 93 if(height() == minimumHeight()){ 94 ptop = min(event->globalY(),ptop); 95 } 96 else if(height() == maximumHeight()){ 97 ptop = max(event->globalY(),ptop); 98 } 99 else{ 100 ptop = event->globalY(); 101 } 102 } 103 else if(resizeDir & bottom){ 104 if(height() == minimumHeight()){ 105 pbottom = max(event->globalY(),ptop); 106 } 107 else if(height() == maximumHeight()){ 108 pbottom = min(event->globalY(),ptop); 109 } 110 else{ 111 pbottom = event->globalY(); 112 } 113 } 114 115 if(resizeDir & left){ //检测左右分量 116 if(width() == minimumWidth()){ 117 pleft = min(event->globalX(),pleft); 118 } 119 else if(width() == maximumWidth()){ 120 pleft = max(event->globalX(),pleft); 121 } 122 else{ 123 pleft = event->globalX(); 124 } 125 } 126 else if(resizeDir & right){ 127 if(width() == minimumWidth()){ 128 pright = max(event->globalX(),pright); 129 } 130 else if(width() == maximumWidth()){ 131 pright = min(event->globalX(),pright); 132 } 133 else{ 134 pright = event->globalX(); 135 } 136 } 137 setGeometry(QRect(QPoint(pleft,ptop),QPoint(pright,pbottom))); 138 } 139 } 140 else testEdge(event); //当不拖动窗口、不改变窗口大小尺寸的时候 检测鼠标边缘 141 } 142 void MainWindow::mouseReleaseEvent(QMouseEvent *event) 143 { 144 if(resizeDir != nodir){ //还原鼠标样式 145 testEdge(event); 146 } 147 } 148 149 void MainWindow::enterEvent(QEvent * event) 150 { 151 QWidget::enterEvent(event); 152 } 153 154 void MainWindow::leaveEvent(QEvent * event) 155 { 156 QApplication::setOverrideCursor(Qt::IBeamCursor); 157 QWidget::leaveEvent(event); 158 }
mainwindow.ui
1 <?xml version="1.0" encoding="UTF-8"?> 2 <ui version="4.0"> 3 <class>MainWindow</class> 4 <widget class="QMainWindow" name="MainWindow"> 5 <property name="geometry"> 6 <rect> 7 <x>0</x> 8 <y>0</y> 9 <width>800</width> 10 <height>600</height> 11 </rect> 12 </property> 13 <property name="windowTitle"> 14 <string>MainWindow</string> 15 </property> 16 <widget class="QWidget" name="centralwidget"/> 17 <widget class="QMenuBar" name="menubar"> 18 <property name="geometry"> 19 <rect> 20 <x>0</x> 21 <y>0</y> 22 <width>800</width> 23 <height>22</height> 24 </rect> 25 </property> 26 </widget> 27 <widget class="QStatusBar" name="statusbar"/> 28 </widget> 29 <resources/> 30 <connections/> 31 </ui>
作者:疯狂Delphi
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
欢迎关注我,一起进步!扫描下方二维码即可加我