1.在窗口显示之前,设置WindowFlags为FramelessWindowHint,以产生一个没有边界的窗口
例如
Widget::Widget(QWidget *parent) : QWidget(parent, Qt::FramelessWindowHint), //在此设置WindowFlags ui(new Ui::Widget){ ui->setupUi(this); //setWindowFlags(Qt::FramelessWindowHint); 或在构造函数体中设置}
2.在设计器中,拖一个Widget到窗口上。为方便描述,我命名此Widget为titleBarWidget
将titleBarWidget的minimumSize->height改为30,以固定标题栏高度
更改titleBarWidget的样式表为background-color: #12B7F5;
再拖一个Vertical Spacer到窗口上,并设置窗口为竖直布局
为去除标题栏边距,将layoutLeftMargin、layoutTopMargin和layoutRightMargin都设置为0
效果如图
3.为了能拖动标题栏移动窗口,我们定义一个类,如下
TitleBarWidget.h
#ifndef TITLEBARWIDGET_H#define TITLEBARWIDGET_H#includeclass TitleBarWidget : public QWidget{ Q_OBJECTpublic: explicit TitleBarWidget(QWidget *parent = nullptr);protected: virtual void mousePressEvent(QMouseEvent *event); virtual void mouseMoveEvent(QMouseEvent *event);private: int differenceX, differenceY;};#endif // TITLEBARWIDGET_H
TitleBarWidget.cpp
#include "TitleBarWidget.h"#includeTitleBarWidget::TitleBarWidget(QWidget *parent) : QWidget(parent) { }void TitleBarWidget::mousePressEvent(QMouseEvent *event){ QWidget *parentWidget = static_cast (parent()); differenceX = event->globalX() - parentWidget->x(); differenceY = event->globalY() - parentWidget->y();}void TitleBarWidget::mouseMoveEvent(QMouseEvent *event){ int x = event->globalX() - differenceX; int y = event->globalY() - differenceY; QWidget *parentWidget = static_cast (parent()); parentWidget->move(x, y);}
将titleBarWidget提升为TitleBarWidget,就能实现拖动标题栏移动窗口了
4.然而问题来了,titleBarWidget的样式表失效了
为解决这个问题,需要重写QWidget中的paintEvent,代码如下
void TitleBarWidget::paintEvent(QPaintEvent *event){ Q_UNUSED(event) QStyleOption option; option.init(this); QStylePainter painter(this); painter.drawPrimitive(QStyle::PE_Widget, option);}