无边框拖拽是参考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
本人的代码- //framelessWidget.h
- #pragma once
- #include <QWidget>
- class TransparentBorder;
- class FramelessWidget : public QWidget
- {
- Q_OBJECT
- public:
- enum Direction {//鼠标处于哪个边界
- BOTTOMRIGHT,
- TOPRIGHT,
- TOPLEFT,
- BOTTOMLEFT,
- RIGHT,
- DOWN,
- LEFT,
- UP,
- NONE
- };
- enum {//距离边界多少时改变鼠标样式
- MARGIN_MIN_SIZE = 0,
- MARGIN_MAX_SIZE = 4
- };
- public:
- FramelessWidget(QWidget* parent = nullptr);
- ~FramelessWidget();
-
-
- void setBorderColor(const QColor& color);
- protected:
- bool event(QEvent* event) override;
- void leaveEvent(QEvent* event) override;
- void mousePressEvent(QMouseEvent* event) override;
- void mouseMoveEvent(QMouseEvent* event) override;
- void mouseReleaseEvent(QMouseEvent* event) override;
- //修改鼠标样式,且是否处于边界
- void updateRegion(QMouseEvent* event);
- //修改大小和位置,即geometry
- void resizeRegion(int marginTop, int marginBottom, int marginLeft, int marginRight);
- void createShadow();
- void maximizeWidget();
- void restoreWidget();
- void paintEvent(QPaintEvent* event) override;
- private:
- bool m_bIsPressed; //是否鼠标按下
- bool m_bIsResizing; //是否要拉伸
- bool m_bIsDoublePressed;//没用到
- QPoint m_pressPoint; //鼠标按下时的坐标
- QPoint m_pressPoint_initial;//没用到
- QPoint m_movePoint; //鼠标移动了的相对坐标
- Direction m_direction; //鼠标的状态即在哪个边界
- QRect rect; //用于存放geometry
- TransparentBorder* border;
- };
- class TransparentBorder :public QWidget {
- public:
- TransparentBorder();
- ~TransparentBorder();
- void resizeBorder(const QPoint& movePoint,FramelessWidget::Direction direction);
- void moveBorder(const QPoint& movePoint);
- void setParentRect(const QRect& rect);
- void setBorderColor(const QColor& color);
- protected:
- void paintEvent(QPaintEvent* event) override;
-
- private:
- QPoint marginOrigin;
- QRect parentRect;
- QColor borderColor;
- };
复制代码 [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() |