qt 无边框窗体的拖动和改变大小

参考:https://www.cnblogs.com/xufeiyang/p/3313104.html

这个类是关于无边框窗体的拖动和改变大小的。如果是QWidget,请将继承类改为QWidget,并将源文件的QDialog用QWidget替换。

我曾想将这个类作为中间类,让窗口类继承此类,这样如果有多个无边框窗口,就不用每个窗口都作重复改变了,但是没有成功。由于时间关系,没再做深入研究。以后有时间再说吧。

头文件:

 1 #ifndef CustomFrameLessWidget_H
 2 #define CustomFrameLessWidget_H
 3 
 4 #include <QRect>
 5 #include <QDialog>
 6 #include <QWidget>
 7 #include <QMouseEvent>
 8 
 9 #define PADDING 2
10 enum Direction { UP=0, DOWN=1, LEFT, RIGHT, LEFTTOP, LEFTBOTTOM, RIGHTBOTTOM, RIGHTTOP, NONE };
11 
12 class CustomFrameLessWidget : public QDialog
13 {
14     Q_OBJECT
15 public:
16     CustomFrameLessWidget(QWidget* parent = NULL);
17     void region(const QPoint &cursorGlobalPoint);
18 protected:
19     void mouseReleaseEvent(QMouseEvent *event);
20     void mouseMoveEvent(QMouseEvent *event);
21     void mousePressEvent(QMouseEvent *event);
22 public:
23     bool isLeftPressDown;  // 判断左键是否按下
24     QPoint dragPosition;   // 窗口移动拖动时需要记住的点
25     Direction dir;        // 窗口大小改变时,记录改变方向
26 
27 };
28 
29 #endif // CustomFrameLessWidget_H

源文件:

  1 #include "CustomFrameLessWidget.h"
  2 
  3 CustomFrameLessWidget::CustomFrameLessWidget(QWidget* parent):QDialog(parent)
  4 {
  5     isLeftPressDown = false;
  6     this->dir = NONE;
  7     this->setMinimumHeight(100);
  8     this->setMinimumWidth(150);
  9     this->setWindowFlags(Qt::FramelessWindowHint|Qt::WindowSystemMenuHint); // 设置成无边框对话框
 10     this->setMouseTracking(true);// 追踪鼠标
 11 //    this->setStyleSheet("QDialog{background:url(:/bg_main.png)}"); // 设置样式背景色,可有可无
 12 }
 13 
 14 void CustomFrameLessWidget::region(const QPoint &cursorGlobalPoint)
 15 {
 16     // 获取窗体在屏幕上的位置区域,tl为topleft点,rb为rightbottom点
 17     QRect rect = this->rect();
 18     QPoint tl = mapToGlobal(rect.topLeft());
 19     QPoint rb = mapToGlobal(rect.bottomRight());
 20 
 21     int x = cursorGlobalPoint.x();
 22     int y = cursorGlobalPoint.y();
 23 
 24     if(tl.x() + PADDING >= x && tl.x() <= x && tl.y() + PADDING >= y && tl.y() <= y) {
 25         // 左上角
 26         dir = LEFTTOP;
 27         this->setCursor(QCursor(Qt::SizeFDiagCursor));  // 设置鼠标形状
 28     } else if(x >= rb.x() - PADDING && x <= rb.x() && y >= rb.y() - PADDING && y <= rb.y()) {
 29         // 右下角
 30         dir = RIGHTBOTTOM;
 31         this->setCursor(QCursor(Qt::SizeFDiagCursor));
 32     } else if(x <= tl.x() + PADDING && x >= tl.x() && y >= rb.y() - PADDING && y <= rb.y()) {
 33         //左下角
 34         dir = LEFTBOTTOM;
 35         this->setCursor(QCursor(Qt::SizeBDiagCursor));
 36     } else if(x <= rb.x() && x >= rb.x() - PADDING && y >= tl.y() && y <= tl.y() + PADDING) {
 37         // 右上角
 38         dir = RIGHTTOP;
 39         this->setCursor(QCursor(Qt::SizeBDiagCursor));
 40     } else if(x <= tl.x() + PADDING && x >= tl.x()) {
 41         // 左边
 42         dir = LEFT;
 43         this->setCursor(QCursor(Qt::SizeHorCursor));
 44     } else if( x <= rb.x() && x >= rb.x() - PADDING) {
 45         // 右边
 46         dir = RIGHT;
 47         this->setCursor(QCursor(Qt::SizeHorCursor));
 48     }else if(y >= tl.y() && y <= tl.y() + PADDING){
 49         // 上边
 50         dir = UP;
 51         this->setCursor(QCursor(Qt::SizeVerCursor));
 52     } else if(y <= rb.y() && y >= rb.y() - PADDING) {
 53         // 下边
 54         dir = DOWN;
 55         this->setCursor(QCursor(Qt::SizeVerCursor));
 56     }else {
 57         // 默认
 58         dir = NONE;
 59         this->setCursor(QCursor(Qt::ArrowCursor));
 60     }
 61 }
 62 
 63 void CustomFrameLessWidget::mouseReleaseEvent(QMouseEvent *event)
 64 {
 65     if(event->button() == Qt::LeftButton) {
 66         isLeftPressDown = false;
 67         if(dir != NONE) {
 68             this->releaseMouse();
 69             this->setCursor(QCursor(Qt::ArrowCursor));
 70         }
 71     }
 72 }
 73 
 74 void CustomFrameLessWidget::mousePressEvent(QMouseEvent *event)
 75 {
 76     switch(event->button()) {
 77     case Qt::LeftButton:
 78         isLeftPressDown = true;
 79         if(dir != NONE) {
 80             this->mouseGrabber();
 81         } else {
 82             dragPosition = event->globalPos() - this->frameGeometry().topLeft();
 83         }
 84         break;
 85     case Qt::RightButton:
 86         this->close();
 87         break;
 88     default:
 89         QDialog::mousePressEvent(event);
 90     }
 91 
 92 }
 93 
 94 void CustomFrameLessWidget::mouseMoveEvent(QMouseEvent *event)
 95 {
 96     QPoint gloPoint = event->globalPos();
 97     QRect rect = this->rect();
 98     QPoint tl = mapToGlobal(rect.topLeft());
 99     QPoint rb = mapToGlobal(rect.bottomRight());
100 
101     if(!isLeftPressDown) {
102         this->region(gloPoint);
103     } else {
104 
105         if(dir != NONE) {
106             QRect rMove(tl, rb);
107 
108             switch(dir) {
109             case LEFT:
110                 if(rb.x() - gloPoint.x() <= this->minimumWidth())
111                     rMove.setX(tl.x());
112                 else
113                     rMove.setX(gloPoint.x());
114                 break;
115             case RIGHT:
116                 rMove.setWidth(gloPoint.x() - tl.x());
117                 break;
118             case UP:
119                 if(rb.y() - gloPoint.y() <= this->minimumHeight())
120                     rMove.setY(tl.y());
121                 else
122                     rMove.setY(gloPoint.y());
123                 break;
124             case DOWN:
125                 rMove.setHeight(gloPoint.y() - tl.y());
126                 break;
127             case LEFTTOP:
128                 if(rb.x() - gloPoint.x() <= this->minimumWidth())
129                     rMove.setX(tl.x());
130                 else
131                     rMove.setX(gloPoint.x());
132                 if(rb.y() - gloPoint.y() <= this->minimumHeight())
133                     rMove.setY(tl.y());
134                 else
135                     rMove.setY(gloPoint.y());
136                 break;
137             case RIGHTTOP:
138                 rMove.setWidth(gloPoint.x() - tl.x());
139                 rMove.setY(gloPoint.y());
140                 break;
141             case LEFTBOTTOM:
142                 rMove.setX(gloPoint.x());
143                 rMove.setHeight(gloPoint.y() - tl.y());
144                 break;
145             case RIGHTBOTTOM:
146                 rMove.setWidth(gloPoint.x() - tl.x());
147                 rMove.setHeight(gloPoint.y() - tl.y());
148                 break;
149             default:
150                 break;
151             }
152             this->setGeometry(rMove);
153         } else {
154             move(event->globalPos() - dragPosition);
155             event->accept();
156         }
157     }
158     QDialog::mouseMoveEvent(event);
159 }

 

posted @ 2020-05-07 11:48  阳光下的小土豆  阅读(736)  评论(0编辑  收藏  举报