之前的一版存在 bug. 如果将鼠标放移动到界面内某个可点击的 widget 上 (如: QPushButton) 上, 按住鼠标左键不放, 界面可能会出现界面非预期移动的问题.
那是因为当鼠标移动到可点击的 widget(如: QPushButton)上时, mousePressEvent 这个信号被可点击的 widget 拦截了, 所以包含这个 widget 的界面的 mousePressEvent(QMouseEvent *event)不会被触发.
所以 m_last_mouse_position 记录的还是上次鼠标点击左键时的位置. 去 qt 论坛咨询了一下官方人员, 他们给出的建议是限定一下可拖动的区域. 具体代码如下.
- #ifndef CUSTOMIZE_QWIDGET_H
- #define CUSTOMIZE_QWIDGET_H
- #include <QDialog>
- #include <QMouseEvent>
- class CustomizeQWidget : public QDialog
- {
- Q_OBJECT
- public:
- explicit CustomizeQWidget(QWidget *parent = 0);
- ~CustomizeQWidget();
- public slots:
- void on_button_close_clicked();
- //void on_button_minimize_cliked();
- private:
- void paintEvent(QPaintEvent *);
- void mousePressEvent(QMouseEvent *event);
- void mouseMoveEvent(QMouseEvent *event);
- void mouseReleaseEvent(QMouseEvent *event);
- virtual bool VaildArea(QMouseEvent * event);
- private:
- QPoint m_last_mouse_position;
- bool m_move_widget_flag;
- };
- #endif // CUSTOMIZE_QWIDGET_H
- #include "customize_ui/customize_qwidget.h"
- #include <QStyleOption>
- #include <QPainter>
- #include <QBrush>
- CustomizeQWidget::CustomizeQWidget(QWidget *parent):
- QDialog(parent),
- m_move_widget_flag(false)
- {
- this->setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::Dialog);
- }
- CustomizeQWidget::~CustomizeQWidget()
- {
- }
- void CustomizeQWidget::paintEvent(QPaintEvent *)
- {
- QStyleOption opt;
- opt.init(this);
- QPainter p(this);
- style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
- }
- void CustomizeQWidget::mousePressEvent(QMouseEvent *event)
- {
- if(event->button() == Qt::LeftButton && VaildArea(event))
- {
- m_last_mouse_position = event->globalPos();
- m_move_widget_flag = true;
- }
- }
- void CustomizeQWidget::mouseMoveEvent(QMouseEvent *event)
- {
- if (!event->buttons().testFlag(Qt::LeftButton) || !m_move_widget_flag)
- return;
- const QPoint position = pos() + event->globalPos() - m_last_mouse_position; //the position of mainfrmae + (current_mouse_position - last_mouse_position)
- move(position.x(), position.y());
- m_last_mouse_position = event->globalPos();
- }
- void CustomizeQWidget::mouseReleaseEvent(QMouseEvent *event)
- {
- if(event->button() == Qt::LeftButton)
- {
- m_move_widget_flag = false;
- }
- }
- void CustomizeQWidget::on_button_close_clicked()
- {
- this->close();
- }
- bool CustomizeQWidget::VaildArea(QMouseEvent *event)
- {
- Q_UNUSED(event);
- return true;
- }
实现类中重写 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.
还有哪块写的不明白的, 可以留言给我.
来源: http://www.bubuko.com/infodetail-3340158.html