本文说明如何拖动没有标题栏的窗口,分别处理是否带有子窗口的情况。其中第一部分引用的是其他人的代码。
本节内容引用自:QtWidget: 鼠标拖动窗口(没有标题栏时)
void ShapedClock::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { dragPosition = event->globalPos() - frameGeometry().topLeft(); event->accept(); } } void ShapedClock::mouseMoveEvent(QMouseEvent *event) { if (event->buttons() & Qt::LeftButton) { move(event->globalPos() - dragPosition); event->accept(); } }
const QPoint & QMouseEvent::globalPos () const
Returns the global position of the mouse cursor at the time of the event. This is important on asynchronous window systems like X11. Whenever you move your widgets around in response to mouse events, globalPos() may differ a lot from the current pointer position QCursor::pos(), and from QWidget::mapToGlobal(pos()).
QPoint QWidget::mapToGlobal ( const QPoint & pos ) const
Translates the widget coordinate pos to global screen coordinates. For example, mapToGlobal(QPoint(0,0)) would give the global coordinates of the top-left pixel of the widget.
QPoint QWidget::mapFromGlobal ( const QPoint & pos ) const
Translates the global screen coordinate pos to widget coordinates.
===============================================华丽的分割线===============================================
以上只能用于没有子窗口的Widget,如果有父窗口就会发生父窗口不动,子窗口移动的尴尬情况。
以下代码用于让父窗口移动,FormMainCenter是子窗口,它的父窗口为MainForm:
头文件:
class FormMainCenter : public QWidget { Q_OBJECT public: explicit FormMainCenter(QWidget *parent = 0); ~FormMainCenter(); virtual void mousePressEvent(QMouseEvent *event); virtual void mouseMoveEvent(QMouseEvent *event); private: Ui::FormMainCenter *ui; //记录窗口拖动的位置 QPoint dragPosition; QPoint orignalPositon; }; CPP文件
void FormMainCenter::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { //计算点击的相对位置,确定鼠标是否点这个位置是否可以拖动(这里设定窗口上点击可拖动的范围为700*120)。 QPoint pt = mapFromGlobal(event->globalPos()); if(!(pt.x() < 700 && pt.y() < 120)) { //qDebug() << tr("click ") << pt.x() << "," << pt.y(); orignalPositon.setX(-1); orignalPositon.setY(-1); event->accept(); return; } //使用dragPosition保存开始移动前鼠标点击的位置,用于计算拖动范围。 dragPosition = event->globalPos(); //使用orignalPositon保存开始移动前的主窗口位置 orignalPositon = parentWidget()->pos(); //qDebug() << tr("click ") << dragPosition.x() << "," << dragPosition.y(); //qDebug() << tr("parent pos") << parentWidget()->pos().x() << "," << parentWidget()->pos().y(); event->accept(); } } void FormMainCenter::mouseMoveEvent(QMouseEvent *event) { if (event->buttons() & Qt::LeftButton) { //qDebug() << tr("mouse move pos:") << event->globalPos(); //qDebug() << tr("parent pos:") << parentWidget()->pos(); //qDebug() << tr("delta:") << (event->globalPos() - dragPosition); // 当前鼠标的位置减去开始时保存的位置,就是拖动过程中的偏移量 // 将这个偏移量加上拖动前的父窗口位置,就是父窗口新的位置 if(!(orignalPositon.x() == -1 && orignalPositon.y() == -1)) parentWidget()->move(orignalPositon + (event->globalPos() - dragPosition)); event->accept(); } }