系统自带的标题栏很多时候满足不了需求——字体改不了、颜色没法动,跨平台效果也不统一。干脆隐藏掉,自己画一个。
基本思路不复杂:去掉系统边框,在 QDialog 顶部塞一个 QWidget 当作标题栏,里面放图标、标题和最小化/最大化/关闭按钮,再重写鼠标事件让窗口能拖动。
C++ 核心实现
直接看完整代码,后面会拆开讲关键点:
#include <QDialog>
#include <QLabel>
#include <QPushButton>
#include <QHBoxLayout>
#include <QMouseEvent>
#include <QApplication>
class CustomDialog : public QDialog {
Q_OBJECT
public:
explicit CustomDialog(QWidget *parent = nullptr) : QDialog(parent) {
// 隐藏系统标题栏
setWindowFlags(Qt::FramelessWindowHint | windowFlags());
// 创建自定义标题栏
createCustomTitleBar();
// 设置主布局
QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->setContentsMargins(0, 0, 0, 0);
mainLayout->addWidget(titleBar);
// 添加示例内容
QLabel *content = new QLabel(, );
mainLayout->(content);
}
:
QWidget *titleBar;
QPushButton *minimizeButton;
QPushButton *maximizeButton;
QPushButton *closeButton;
QPoint mousePressPosition;
mousePressed;
{
titleBar = ();
QHBoxLayout *layout = (titleBar);
layout->(, , , );
QLabel *titleLabel = (, titleBar);
titleLabel->();
layout->(titleLabel);
minimizeButton = (, titleBar);
minimizeButton->(, );
(minimizeButton, &QPushButton::clicked, , &CustomDialog::showMinimized);
maximizeButton = (, titleBar);
maximizeButton->(, );
(maximizeButton, &QPushButton::clicked, []() { () ? () : (); });
closeButton = (, titleBar);
closeButton->(, );
(closeButton, &QPushButton::clicked, , &CustomDialog::close);
layout->();
layout->(minimizeButton);
layout->(maximizeButton);
layout->(closeButton);
titleBar->(
);
}
:
{
(event->() == Qt::LeftButton && titleBar->().(event->())) {
mousePressPosition = event->().();
mousePressed = ;
}
}
{
(mousePressed) {
(event->().() - mousePressPosition);
}
}
{
(event);
mousePressed = ;
}
};

