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 }