将窗口中的小窗口按住拖动,使其在该窗口中移动。
效果图如下:
鼠标左键按住上图中的彩色窗口,就可以在窗口的客户区中来回拖动窗口。
项目的文件结构如下:
创建基于QWidget的应用程序,main.cpp的程序没有做任何的改变,主要的实现的代码如下:
dialog.h
#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }
QT_END_NAMESPACEclass Dialog : public QDialog
{Q_OBJECTpublic:Dialog(QWidget *parent = nullptr);~Dialog();void getDragAreaRect();//获取窗口可拖动的区域大小,客户端的区域void getMousePressRect();//获取鼠标按下的窗口的区域widget
protected:void mousePressEvent(QMouseEvent *event);void mouseMoveEvent(QMouseEvent *event);void mouseReleaseEvent(QMouseEvent *event);
private:Ui::Dialog *ui;bool m_isPress;//是否按下鼠标QPoint m_startPos;//鼠标按下时的点QPoint m_topleftPos;//被拖动窗口左上角的点QPoint m_offsetPos;//窗口左上角于鼠标点击点的差值QRect m_dragArea;//可进行拖动的区域QRect m_pressArea;//被拖动的窗口的可点击区域
};#endif // DIALOG_H
dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
#include <QMouseEvent>
#include <QDebug>Dialog::Dialog(QWidget *parent): QDialog(parent), ui(new Ui::Dialog),m_isPress(false)
{ui->setupUi(this);getDragAreaRect();getMousePressRect();
}Dialog::~Dialog()
{delete ui;
}void Dialog::getDragAreaRect()
{m_dragArea = this->geometry();//客户区大小
}void Dialog::getMousePressRect()
{m_pressArea = ui->widget->rect();
}void Dialog::mousePressEvent(QMouseEvent *event)
{bool isContain = m_pressArea.contains(event->pos());
// qDebug()<<"isContain:"<<isContain<<"m_pressArea:"<<m_pressArea;if(event->button() & Qt::MouseButton::LeftButton && isContain){
// qDebug()<<"鼠标按下";m_isPress = true;m_startPos = event->pos();m_topleftPos = ui->widget->frameGeometry().topLeft();m_offsetPos = m_startPos - m_topleftPos;}QWidget::mousePressEvent(event);
}void Dialog::mouseMoveEvent(QMouseEvent *event)
{if(m_isPress && m_dragArea.contains(event->pos()))//鼠标按下的点在整个可拖动区域内拖动{QPoint currPos = event->pos();int x = currPos.x() - m_offsetPos.x();int y = currPos.y() - m_offsetPos.y();int borderWid = m_dragArea.width() - m_pressArea.width();int borderHei = m_dragArea.height() - m_pressArea.height();if(x < 0){x = 0;}if(y < 0){y = 0;}if(x > borderWid){x = borderWid;}if(y > borderHei){y = borderHei;}ui->widget->move(x,y);}QWidget::mouseMoveEvent(event);
}void Dialog::mouseReleaseEvent(QMouseEvent *event)
{m_isPress = false;//更新被移动的窗口的位置,保证被点击的点在窗口内m_pressArea.setLeft(ui->widget->geometry().x());m_pressArea.setTop(ui->widget->geometry().y());m_pressArea.setRight(m_pressArea.left() + ui->widget->width());m_pressArea.setBottom(m_pressArea.top() + ui->widget->height());
// qDebug()<<"m_pressArea:"<<m_pressArea;QWidget::mouseReleaseEvent(event);
}
ui文件只是向其中拖入了一个widget,并设置了其样式,其它没有做改变。