ToB企服应用市场:ToB评测及商务社交产业平台
标题:
实现qt 窗口无边框拖拽
[打印本页]
作者:
李优秀
时间:
2024-11-10 13:16
标题:
实现qt 窗口无边框拖拽
无边框拖拽是参考
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()
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4