之前的一版存在bug。如果将鼠标放移动到界面内某个可点击的widget上(如:QPushButton)上,按住鼠标左键不放,界面可能会出现界面非预期移动的问题。
那是因为当鼠标移动到可点击的widget(如:QPushButton)上时,mousePressEvent这个信号被可点击的widget拦截了,所以包含这个widget的界面的mousePressEvent(QMouseEvent *event)不会被触发。
所以m_last_mouse_position记录的还是上次鼠标点击左键时的位置。去qt论坛咨询了一下官方人员,他们给出的建议是限定一下可拖动的区域。具体代码如下。
1 #ifndef CUSTOMIZE_QWIDGET_H 2 #define CUSTOMIZE_QWIDGET_H 3 #include <QDialog> 4 #include <QMouseEvent> 5 6 class CustomizeQWidget : public QDialog 7 { 8 Q_OBJECT 9 public: 10 explicit CustomizeQWidget(QWidget *parent = 0); 11 ~CustomizeQWidget(); 12 public slots: 13 void on_button_close_clicked(); 14 //void on_button_minimize_cliked(); 15 private: 16 void paintEvent(QPaintEvent *); 17 void mousePressEvent(QMouseEvent *event); 18 void mouseMoveEvent(QMouseEvent *event); 19 void mouseReleaseEvent(QMouseEvent *event); 20 virtual bool VaildArea(QMouseEvent * event); 21 private: 22 QPoint m_last_mouse_position; 23 24 bool m_move_widget_flag; 25 }; 26 #endif // CUSTOMIZE_QWIDGET_H
1 #include "customize_ui/customize_qwidget.h" 2 #include <QStyleOption> 3 #include <QPainter> 4 #include <QBrush> 5 6 CustomizeQWidget::CustomizeQWidget(QWidget *parent): 7 QDialog(parent), 8 m_move_widget_flag(false) 9 { 10 this->setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::Dialog); 11 } 12 13 CustomizeQWidget::~CustomizeQWidget() 14 { 15 } 16 17 void CustomizeQWidget::paintEvent(QPaintEvent *) 18 { 19 QStyleOption opt; 20 opt.init(this); 21 QPainter p(this); 22 style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); 23 } 24 25 void CustomizeQWidget::mousePressEvent(QMouseEvent *event) 26 { 27 if(event->button() == Qt::LeftButton && VaildArea(event)) 28 { 29 m_last_mouse_position = event->globalPos(); 30 m_move_widget_flag = true; 31 } 32 } 33 34 void CustomizeQWidget::mouseMoveEvent(QMouseEvent *event) 35 { 36 if (!event->buttons().testFlag(Qt::LeftButton) || !m_move_widget_flag) 37 return; 38 const QPoint position = pos() + event->globalPos() - m_last_mouse_position; //the position of mainfrmae + (current_mouse_position - last_mouse_position) 39 move(position.x(), position.y()); 40 m_last_mouse_position = event->globalPos(); 41 } 42 43 void CustomizeQWidget::mouseReleaseEvent(QMouseEvent *event) 44 { 45 if(event->button() == Qt::LeftButton) 46 { 47 m_move_widget_flag = false; 48 } 49 } 50 void CustomizeQWidget::on_button_close_clicked() 51 { 52 this->close(); 53 } 54 55 bool CustomizeQWidget::VaildArea(QMouseEvent *event) 56 { 57 Q_UNUSED(event); 58 return true; 59 }
实现类中重写 VaildArea 方法。实现的是鼠标左键记录的有效位置。
例如:
bool MyDialog::VaildArea(QMouseEvent * event) { if((event->globalX() > this->pos().x() && event->globalX() < this->pos().x() + 345 && event->globalY() > this->pos().y() && event->globalY() < this->pos().y() + 25) || (event->globalX() > this->pos().x() && event->globalX() < this->pos().x() + 370 && event->globalY() >= this->pos().y() + 25 && event->globalY() < this->pos().y() + 50)) return true; return false; }
event->globalX() > this->pos().x() && event->globalX() < this->pos().x() + 345 && event->globalY() > this->pos().y() && event->globalY() < this->pos().y() + 25)
这句话实现的是鼠标在上边那个红框点击左键有效。
(event->globalX() > this->pos().x() && event->globalX() < this->pos().x() + 370 && event->globalY() >= this->pos().y() + 25 && event->globalY() < this->pos().y() + 50)
这句话实现的是鼠标在上边那个红框点击左键有效。
这个界面宽370,关闭按钮25×25。
还有哪块写的不明白的,可以留言给我。
原文:https://www.cnblogs.com/devil-shadow/p/12070322.html