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
View Code

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 }
View Code

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
View Code

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 }
View Code

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>
View Code

 

 

posted on 2022-07-06 11:58  疯狂delphi  阅读(176)  评论(0编辑  收藏  举报

导航