赞
踩
目录
一般情况下,当去掉窗体标题栏时,按住鼠标左键就无法实现拖动窗体;当去掉窗体标题栏时,窗体四周的边框也去掉了,此时按住鼠标左键拖动窗体四周边沿,无法实现鼠标拖动改变窗体大小。如下为Qt实现去掉窗体标题栏的代码:
-
- setWindowFlag(Qt::FramelessWindowHint); // 去掉标题栏
现在的问题是:
Qt中有个QSizeGrip类,可以很好解决1节提到的问题,关于该类的具体用法,参见Qt Assistant。
下面直接上代码:
.h文件如下:
- #pragma once
-
- #include <QtWidgets/QWidget>
- #include "ui_QtGuiApplication2.h"
-
- class QtGuiApplication2 : public QWidget
- {
- Q_OBJECT
-
- public:
- QtGuiApplication2(QWidget *parent = Q_NULLPTR);
-
- private: // virtual
-
- void mousePressEvent(QMouseEvent* event) override;
-
- void mouseReleaseEvent(QMouseEvent* event) override;
-
- void mouseMoveEvent(QMouseEvent* event) override;
- private:
- Ui::QtGuiApplication2Class ui;
- bool m_bLeftMousePressed{ false }; // 鼠标左键是否被按下
- QPoint m_lastPoint; // 鼠标上次按下的点
- };
.cpp文件如下:
- #include "QtGuiApplication2.h"
- #include<QSizeGrip>
- #include<QVBoxLayout>
- #include<QFrame>
- #include<QStatusBar>
- #include<QMouseEvent>
- QtGuiApplication2::QtGuiApplication2(QWidget *parent)
- : QWidget(parent)
- {
- ui.setupUi(this);
-
- setWindowFlag(Qt::FramelessWindowHint); // 去掉标题栏
-
- QVBoxLayout* pMainWnd = new QVBoxLayout(this);
- setLayout(pMainWnd);
-
- auto pFrame = new QFrame(this);
- pFrame->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
- pMainWnd->addWidget(pFrame);
-
- QHBoxLayout* pBottomLayout = new QHBoxLayout(this);
- pMainWnd->addLayout(pBottomLayout);
-
- // 加一个水平弹簧,为了把后面的QSizeGrip挤到最右边
- auto horizontalSpacer = new QSpacerItem(193, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
- pBottomLayout->addItem(horizontalSpacer);
-
- // 创建QSizeGrip对象,该对象就是用来调整窗体大小的
- auto pSizeGrip = new QSizeGrip(this);
- pSizeGrip->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
- pBottomLayout->addWidget(pSizeGrip); // 将QSizeGrip对象加入窗体右下角
-
- // 也可以加入一个状态栏来实现拖动窗体右下角改变窗体大小
- //auto pStatusBar = new QStatusBar(this);
- //pStatusBar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
- //pBottomLayout->addWidget(pStatusBar);
- }
-
- // 鼠标左键按下,准备移动窗体
- void QtGuiApplication2::mousePressEvent(QMouseEvent* event)
- {
- if (Qt::LeftButton != event->button())
- {
- return;
- }
-
- m_lastPoint = event->globalPos();
- m_bLeftMousePressed = true;
- }
-
- // 移动窗体结束
- void QtGuiApplication2::mouseReleaseEvent(QMouseEvent* event)
- {
- if (Qt::LeftButton != event->button())
- {
- return;
- }
-
- m_bLeftMousePressed = false;
- }
-
- // 开始移动窗体
- void QtGuiApplication2::mouseMoveEvent(QMouseEvent* event)
- {
- auto curMousePt = event->globalPos(); // 注意:这里记录是窗体在屏幕上的坐标位置
- auto offsetPt = curMousePt - m_lastPoint; // 计算和上次移动点的坐标差值
- move(pos() + offsetPt);
- m_lastPoint = curMousePt; // 记录本次窗体所在位置,以便下次计算位置
- }
效果如下:
图1
QSizeGrip对象在窗体中的位置如下:
图2
说明:
从图1可以看到,当按住鼠标左键拖动右下角的QSizeGrip对象以改变窗体大小,此时窗体大小确实改变了,但窗体也随之被移动了,也就是既改变了窗体大小也移动了窗体。原因是QSizeGrip对象必须响应鼠标移动事件才能改变窗体大小,与此同时窗体响应鼠标事件被移动。如何只保证改变窗体大小,而不移动窗体呢?此时必须从QSizeGrip类派生出自己的子类,代码如下:
mySizeGrip.h:
- #pragma once
-
- #include <QSizeGrip>
- namespace Ui { class CMySizeGrip; };
-
- class CMySizeGrip : public QSizeGrip
- {
- Q_OBJECT
-
- public:
- CMySizeGrip(QWidget *parent = Q_NULLPTR);
- ~CMySizeGrip();
- private: // virtual
-
- void mousePressEvent(QMouseEvent* event) override;
-
- void mouseReleaseEvent(QMouseEvent* event) override;
-
- void mouseMoveEvent(QMouseEvent* event) override;
-
- private:
- Ui::CMySizeGrip *ui;
- QPoint m_lastPoint; // 鼠标上次按下的点
- QWidget* m_pParent; // 父窗体,也就是要调节大小的窗体
- };
mySizeGrip.cpp:
- #include "mySizeGrip.h"
- #include "ui_mySizeGrip.h"
- #include<QMouseEvent>
- #include<QApplication>
- CMySizeGrip::CMySizeGrip(QWidget *parent)
- : QSizeGrip(parent)
- {
- m_pParent = parent;
- ui = new Ui::CMySizeGrip();
- ui->setupUi(this);
- }
-
- CMySizeGrip::~CMySizeGrip()
- {
- delete ui;
- }
- void CMySizeGrip::mousePressEvent(QMouseEvent* event)
- {
- if (Qt::LeftButton != event->button())
- {
- return;
- }
-
- m_lastPoint = event->globalPos();
- }
-
- void CMySizeGrip::mouseReleaseEvent(QMouseEvent* event)
- {
-
- }
- void CMySizeGrip::mouseMoveEvent(QMouseEvent* event)
- {
- auto curMousePt = event->globalPos();
- auto offset = curMousePt - m_lastPoint;
- m_lastPoint = curMousePt;
-
- // 调整父窗体大小
- m_pParent->resize(m_pParent->size().width() + offset.x(), m_pParent->size().height() + offset.y());
- }
将前面第29行的:
auto pSizeGrip = new QSizeGrip(this);
改为:
auto pSizeGrip = new CMySizeGrip(this);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。