文章转自博客园(Qt小罗):Qt实战6.万能的无边框窗口(FramelessWindow) - Qt小罗 - 博客园
1 需求描述
- 实现一个Qt无边框窗口,自定义最大化、最小化、关闭按钮;
- 窗口支持任意拉伸、移动,支持边框阴影;
- 窗口能够集成任意其它窗口到内部形成一个整体。
2 设计思路
最初实现无边框的目标只有一个,即简单好用。所有实现基于Qt本身,现将窗口分为三层,如图:
本文福利,莬费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击莬费领取↓↓
外层和内容层均使用垂直布局,使窗口拉伸时能够自动适应大小。下面对每一层做个简单说明。
2.1 XWidget
作为窗口的最外层,设置为透明,为内层ContentWidget边框设置、阴影显示提供支持。同时根据位置设置光标形状(CursorShape),实现窗口的任意拉伸。
2.2 ContentWidget
作为内容包含层,可设置边框颜色、宽度、圆角、阴影等效果,同时增加最大化、最小化、关闭按钮,以及logo、软件名称显示部件。
2.3 CentralWidget
作为外部嵌入层,XWidget提供一个接口void setCentralWidget(QWidget *widget),将其它窗口集成到ContentWidget内部形成一个整体,这个与QMainWindow类似。
3 代码实现
- 首先,隐藏标题栏、启用样式表,XWidget背景透明,代码如下:
setWindowFlags(Qt::FramelessWindowHint); //隐藏标题栏(无边框)
setAttribute(Qt::WA_StyledBackground); //启用样式背景绘制
setAttribute(Qt::WA_TranslucentBackground); //背景透明
- 为了实现鼠标的位置信息获取不受子控件的影响,启动鼠标悬浮追踪,代码如下:
setAttribute(Qt::WA_Hover);
- 随后便可以在event事件处理函数中获取到悬浮事件,将其转换为鼠标移动事件进行统一处理,代码如下:
bool XWidget::event(QEvent *event)
{
if (event->type() == QEvent::HoverMove) {
QHoverEvent *hoverEvent = static_cast<QHoverEvent *>(event);
QMouseEvent mouseEvent(QEvent::MouseMove, hoverEvent->pos(),
Qt::NoButton, Qt::NoButton, Qt::NoModifier);
mouseMoveEvent(&mouseEvent);
}
return QWidget::event(event);
}
- 进入鼠标移动事件,根据坐标设置鼠标对应的形状,如果鼠标为按下状态且到达X