当前位置:   article > 正文

Qt实现改变无标题栏窗体大小及移动窗体_qt设置窗口无标题栏

qt设置窗口无标题栏

目录

1.问题的提出

2.实现方法

3.存在的问题


1.问题的提出

一般情况下,当去掉窗体标题栏时,按住鼠标左键就无法实现拖动窗体;当去掉窗体标题栏时,窗体四周的边框也去掉了,此时按住鼠标左键拖动窗体四周边沿,无法实现鼠标拖动改变窗体大小。如下为Qt实现去掉窗体标题栏的代码:

  1. setWindowFlag(Qt::FramelessWindowHint); // 去掉标题栏

现在的问题是:

  • 在去掉窗体标题栏的情况下,如何按住鼠标左键,实现鼠标拖动改变窗体大小?
  • 在去掉窗体标题栏的情况下,如何在窗体上按住鼠标左键,实现移动窗体?

2.实现方法

Qt中有个QSizeGrip类,可以很好解决1节提到的问题,关于该类的具体用法,参见Qt Assistant。

下面直接上代码:

.h文件如下:

  1. #pragma once
  2. #include <QtWidgets/QWidget>
  3. #include "ui_QtGuiApplication2.h"
  4. class QtGuiApplication2 : public QWidget
  5. {
  6. Q_OBJECT
  7. public:
  8. QtGuiApplication2(QWidget *parent = Q_NULLPTR);
  9. private: // virtual
  10. void mousePressEvent(QMouseEvent* event) override;
  11. void mouseReleaseEvent(QMouseEvent* event) override;
  12. void mouseMoveEvent(QMouseEvent* event) override;
  13. private:
  14. Ui::QtGuiApplication2Class ui;
  15. bool m_bLeftMousePressed{ false }; // 鼠标左键是否被按下
  16. QPoint m_lastPoint; // 鼠标上次按下的点
  17. };

.cpp文件如下:

  1. #include "QtGuiApplication2.h"
  2. #include<QSizeGrip>
  3. #include<QVBoxLayout>
  4. #include<QFrame>
  5. #include<QStatusBar>
  6. #include<QMouseEvent>
  7. QtGuiApplication2::QtGuiApplication2(QWidget *parent)
  8. : QWidget(parent)
  9. {
  10. ui.setupUi(this);
  11. setWindowFlag(Qt::FramelessWindowHint); // 去掉标题栏
  12. QVBoxLayout* pMainWnd = new QVBoxLayout(this);
  13. setLayout(pMainWnd);
  14. auto pFrame = new QFrame(this);
  15. pFrame->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
  16. pMainWnd->addWidget(pFrame);
  17. QHBoxLayout* pBottomLayout = new QHBoxLayout(this);
  18. pMainWnd->addLayout(pBottomLayout);
  19. // 加一个水平弹簧,为了把后面的QSizeGrip挤到最右边
  20. auto horizontalSpacer = new QSpacerItem(193, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
  21. pBottomLayout->addItem(horizontalSpacer);
  22. // 创建QSizeGrip对象,该对象就是用来调整窗体大小的
  23. auto pSizeGrip = new QSizeGrip(this);
  24. pSizeGrip->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
  25. pBottomLayout->addWidget(pSizeGrip); // 将QSizeGrip对象加入窗体右下角
  26. // 也可以加入一个状态栏来实现拖动窗体右下角改变窗体大小
  27. //auto pStatusBar = new QStatusBar(this);
  28. //pStatusBar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
  29. //pBottomLayout->addWidget(pStatusBar);
  30. }
  31. // 鼠标左键按下,准备移动窗体
  32. void QtGuiApplication2::mousePressEvent(QMouseEvent* event)
  33. {
  34. if (Qt::LeftButton != event->button())
  35. {
  36. return;
  37. }
  38. m_lastPoint = event->globalPos();
  39. m_bLeftMousePressed = true;
  40. }
  41. // 移动窗体结束
  42. void QtGuiApplication2::mouseReleaseEvent(QMouseEvent* event)
  43. {
  44. if (Qt::LeftButton != event->button())
  45. {
  46. return;
  47. }
  48. m_bLeftMousePressed = false;
  49. }
  50. // 开始移动窗体
  51. void QtGuiApplication2::mouseMoveEvent(QMouseEvent* event)
  52. {
  53. auto curMousePt = event->globalPos(); // 注意:这里记录是窗体在屏幕上的坐标位置
  54. auto offsetPt = curMousePt - m_lastPoint; // 计算和上次移动点的坐标差值
  55. move(pos() + offsetPt);
  56. m_lastPoint = curMousePt; // 记录本次窗体所在位置,以便下次计算位置
  57. }

效果如下:

图1

QSizeGrip对象在窗体中的位置如下:

图2

说明:

  • Qt中的QDialog和QStatusBar类封装了 QSizeGrip对象,故上面代码也可以插入QStatusBar类到右下角来实现 QSizeGrip对象调整大小功能,即注释掉29~31行代码,取消34~36注释,实现同样功能。
  • Qt中的QDialog和QStatusBar类提供了setSizeGripEnabled(bool)方法用来设置是否启用QSizeGrip对象,默认是启用的,即右下角QSizeGrip对象是可见的。

3.存在的问题

       从图1可以看到,当按住鼠标左键拖动右下角的QSizeGrip对象以改变窗体大小,此时窗体大小确实改变了,但窗体也随之被移动了,也就是既改变了窗体大小也移动了窗体。原因是QSizeGrip对象必须响应鼠标移动事件才能改变窗体大小,与此同时窗体响应鼠标事件被移动。如何只保证改变窗体大小,而不移动窗体呢?此时必须从QSizeGrip类派生出自己的子类,代码如下:

mySizeGrip.h:

  1. #pragma once
  2. #include <QSizeGrip>
  3. namespace Ui { class CMySizeGrip; };
  4. class CMySizeGrip : public QSizeGrip
  5. {
  6. Q_OBJECT
  7. public:
  8. CMySizeGrip(QWidget *parent = Q_NULLPTR);
  9. ~CMySizeGrip();
  10. private: // virtual
  11. void mousePressEvent(QMouseEvent* event) override;
  12. void mouseReleaseEvent(QMouseEvent* event) override;
  13. void mouseMoveEvent(QMouseEvent* event) override;
  14. private:
  15. Ui::CMySizeGrip *ui;
  16. QPoint m_lastPoint; // 鼠标上次按下的点
  17. QWidget* m_pParent; // 父窗体,也就是要调节大小的窗体
  18. };

mySizeGrip.cpp:

  1. #include "mySizeGrip.h"
  2. #include "ui_mySizeGrip.h"
  3. #include<QMouseEvent>
  4. #include<QApplication>
  5. CMySizeGrip::CMySizeGrip(QWidget *parent)
  6. : QSizeGrip(parent)
  7. {
  8. m_pParent = parent;
  9. ui = new Ui::CMySizeGrip();
  10. ui->setupUi(this);
  11. }
  12. CMySizeGrip::~CMySizeGrip()
  13. {
  14. delete ui;
  15. }
  16. void CMySizeGrip::mousePressEvent(QMouseEvent* event)
  17. {
  18. if (Qt::LeftButton != event->button())
  19. {
  20. return;
  21. }
  22. m_lastPoint = event->globalPos();
  23. }
  24. void CMySizeGrip::mouseReleaseEvent(QMouseEvent* event)
  25. {
  26. }
  27. void CMySizeGrip::mouseMoveEvent(QMouseEvent* event)
  28. {
  29. auto curMousePt = event->globalPos();
  30. auto offset = curMousePt - m_lastPoint;
  31. m_lastPoint = curMousePt;
  32. // 调整父窗体大小
  33. m_pParent->resize(m_pParent->size().width() + offset.x(), m_pParent->size().height() + offset.y());
  34. }

将前面第29行的:

auto pSizeGrip = new QSizeGrip(this);

改为:

auto pSizeGrip = new CMySizeGrip(this);

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/136383
推荐阅读
相关标签
  

闽ICP备14008679号