实现qt 窗口无边框拖拽

打印 上一主题 下一主题

主题 549|帖子 549|积分 1647

无边框拖拽是参考Qt实战6.万能的无边框窗口(FramelessWindow) - Qt小罗 - 博客园的文章,对其代码进行修改而来。
本篇一共会提供本人写的无边框的代码以及Qt实战6.万能的无边框窗口(FramelessWindow) - Qt小罗 - 博客园里面的完整代码供各人参考.
代码利用的话,我是直接让widget继承于framlessWidget,下图是效果图

参考的代码就不表明了,只表明一点我写的

相比较,我将m_movePoint酿成是m_pressPoint隔断鼠标的相对坐标;然后让m_bIsResizing的值由m_direction来判定是否要拉伸窗口,同时添加了一个透明的带边框的窗体border(TransparentBorder不是qt库的)来实现预览移动而拉伸的状态,因为我将qt小罗的及时修改边框的位置和大小改成延时,以是必要有个能预览的边框来观看。
至于函数

由鼠标按下和松开来调用其他函数,例如鼠标按下要对一些变量进行重新设置制止前次操作的影响、判定是否要拉伸窗口和让border绑定父窗口显示出border。其他函数必要自己查看
代码存放:
haoyouxiaoju/qt_widget: 存放qt 写过的widget
本人的代码
  1. //framelessWidget.h
  2. #pragma once
  3. #include <QWidget>
  4. class TransparentBorder;
  5. class FramelessWidget : public QWidget
  6. {
  7.         Q_OBJECT
  8. public:
  9.                 enum Direction {//鼠标处于哪个边界
  10.                 BOTTOMRIGHT,
  11.                 TOPRIGHT,
  12.                 TOPLEFT,
  13.                 BOTTOMLEFT,
  14.                 RIGHT,
  15.                 DOWN,
  16.                 LEFT,
  17.                 UP,
  18.                 NONE
  19.         };
  20.         enum {//距离边界多少时改变鼠标样式
  21.                 MARGIN_MIN_SIZE = 0,
  22.                 MARGIN_MAX_SIZE = 4
  23.         };
  24. public:
  25.         FramelessWidget(QWidget* parent = nullptr);
  26.         ~FramelessWidget();
  27.        
  28.        
  29.         void setBorderColor(const QColor& color);
  30. protected:
  31.         bool event(QEvent* event) override;
  32.         void leaveEvent(QEvent* event) override;
  33.         void mousePressEvent(QMouseEvent* event) override;
  34.         void mouseMoveEvent(QMouseEvent* event) override;
  35.         void mouseReleaseEvent(QMouseEvent* event) override;
  36.         //修改鼠标样式,且是否处于边界
  37.         void updateRegion(QMouseEvent* event);
  38.         //修改大小和位置,即geometry
  39.         void resizeRegion(int marginTop, int marginBottom, int marginLeft, int marginRight);
  40.         void createShadow();
  41.         void maximizeWidget();
  42.         void restoreWidget();
  43.     void paintEvent(QPaintEvent* event) override;
  44. private:
  45.         bool m_bIsPressed;                //是否鼠标按下
  46.         bool m_bIsResizing;                //是否要拉伸
  47.         bool m_bIsDoublePressed;//没用到
  48.         QPoint m_pressPoint;        //鼠标按下时的坐标
  49.         QPoint m_pressPoint_initial;//没用到
  50.         QPoint m_movePoint;                //鼠标移动了的相对坐标
  51.         Direction m_direction;        //鼠标的状态即在哪个边界
  52.         QRect rect;                                //用于存放geometry
  53.         TransparentBorder* border;
  54. };
  55. class TransparentBorder :public  QWidget {
  56. public:
  57.         TransparentBorder();
  58.         ~TransparentBorder();
  59.         void resizeBorder(const QPoint& movePoint,FramelessWidget::Direction direction);
  60.         void moveBorder(const QPoint& movePoint);
  61.         void setParentRect(const QRect& rect);
  62.         void setBorderColor(const QColor& color);
  63. protected:
  64.         void paintEvent(QPaintEvent* event) override;
  65.        
  66. private:
  67.         QPoint marginOrigin;
  68.         QRect parentRect;
  69.         QColor borderColor;
  70. };
复制代码
[code]//framelessWidget.cpp#include "framelesswidget.h"#include #include #include #include #include #include #include #include #include #include "model/data.h"FramelessWidget::FramelessWidget(QWidget* parent)        : QWidget(parent), m_bIsPressed(false), m_bIsResizing(false), m_bIsDoublePressed(false),        m_direction(NONE){        setWindowFlags(Qt::FramelessWindowHint);    //隐蔽标题栏(无边框)        setAttribute(Qt::WA_StyledBackground);      //启用样式配景绘制        //setAttribute(Qt::WA_TranslucentBackground); //配景透明        setAttribute(Qt::WA_Hover);        setAttribute(Qt::WA_StaticContents);        this->setMinimumSize(50, 50);                border = new TransparentBorder();//并没有让border挂在this下面,以是得析构时得delete        border->hide();}FramelessWidget::~FramelessWidget(){        delete border;}bool FramelessWidget::event(QEvent* event){        ///        // 使得移除窗口仍能进行鼠标移动的事件        ///        if (event->type() == QEvent::HoverMove) {                QHoverEvent* hoverEvent = static_cast(event);                QMouseEvent mouseEvent(QEvent::MouseMove, hoverEvent->pos(),                        Qt::NoButton, Qt::NoButton, Qt::NoModifier);                mouseMoveEvent(&mouseEvent);                //LOG() button() == Qt:eftButton) {                m_bIsPressed = true;                m_pressPoint = event->globalPos();//鼠标按下的绝对坐标                m_movePoint = QPoint(0, 0);//使得前次移动的相对坐标清零        }        //*        //如果m_direction不为NoNE 即 鼠标在窗口边界 那么就是要进行窗口拉伸        //*        if (m_direction != NONE) {                m_bIsResizing = true;        }        //由于利用的是 额外创建一个boder边框使得能够预览窗口的位置        // 以是得让boder知道要绑定谁,且知道他的geometry        border->setParentRect(geometry());        border->show();//显示边框}void FramelessWidget::mouseMoveEvent(QMouseEvent* event){        QWidget::mouseMoveEvent(event);        m_movePoint = event->globalPos() - m_pressPoint;        //LOG()

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

李优秀

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表