遇到一个奇葩需求,既要我隐藏任务栏和标题栏做全屏,又要我有个标题栏显示信息,那就只能自定义标题栏了。由于这次程序最顶部是一个工具栏,自定义标题栏最大的问题是如何把标题栏加在工具栏的上边,核心问题是如何把工具栏向下移一个标题栏的高度,显示效果如下:

实现代码如下,省却了头文件定义,自己加一下就行
cpp
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->showFullScreen();
this->initGlobalTitleBar();
}
void MainWindow::initGlobalTitleBar()
{
// 1. 创建全局标题栏(主窗口直接子控件,层级最高)
QWidget *globalTitleBar = new QWidget(this);
globalTitleBar->setObjectName("GlobalTitleBar");
globalTitleBar->setFixedHeight(32);
globalTitleBar->setVisible(true);
// 强制置顶(关键:避免被其他控件覆盖)
globalTitleBar->raise();
// 样式:确保能看到,不透明
globalTitleBar->setStyleSheet(R"(
QWidget#GlobalTitleBar {
background-color: #2c3e50;
border-bottom: 2px solid #00BB9E;
}
)");
// 2. 标题栏内容(软件名+关闭按钮)
QLabel *logoLabel = new QLabel(globalTitleBar);
logoLabel->setFixedSize(30, 30);
logoLabel->setScaledContents(false); // 关闭强制拉伸
logoLabel->setAlignment(Qt::AlignCenter); // 图片居中显示
logoLabel->setPixmap(QPixmap(":/icons/edit.png").scaled(28, 28, Qt::KeepAspectRatio, Qt::SmoothTransformation));
QLabel *appNameLabel = new QLabel("你的软件名 v1.0", globalTitleBar);
appNameLabel->setStyleSheet("color: white; font-size:14px; padding-left:15px;");
QPushButton *closeBtn = new QPushButton(globalTitleBar);
closeBtn->setIcon(QIcon(":/icons/exit.png"));
closeBtn->setIconSize(QSize(32, 32));
connect(closeBtn, &QPushButton::clicked, this, [=](){
this->close();
});
// 3. 标题栏布局
QHBoxLayout *titleLayout = new QHBoxLayout(globalTitleBar);
titleLayout->setContentsMargins(5, 0, 5, 0); // 左右加5px边距,避免贴边
titleLayout->setSpacing(0);
titleLayout->addWidget(logoLabel);
titleLayout->addWidget(appNameLabel);
titleLayout->addStretch();
titleLayout->addWidget(m_closeBtn);
// 4. 强制设置标题栏位置(最顶部)
globalTitleBar->setGeometry(0, 0, this->width(), 32);
QToolBar *toolBar = ui->toolBar;
if (toolBar) {
// 关键:给QMainWindow的工具栏区域加顶部边距,让工具栏自动下移
this->setContentsMargins(0, 32, 0, 0); // 顶部边距=标题栏高度(32px)
// 确保工具栏可见(恢复被隐藏的可能)
toolBar->setVisible(true);
toolBar->setEnabled(true);
qDebug() << "工具栏已恢复,可见性:" << toolBar->isVisible();
}
}
// ========== 窗口显示后,确保标题栏置顶 ==========
void MainWindow::showEvent(QShowEvent *event)
{
QMainWindow::showEvent(event);
QWidget *titleBar = this->findChild<QWidget*>("GlobalTitleBar");
if (titleBar) titleBar->raise(); // 防止标题栏被工具栏覆盖
}
void MainWindow::resizeEvent(QResizeEvent *event)
{
QMainWindow::resizeEvent(event);
// 仅更新标题栏宽度,工具栏由Qt自动管理,无需手动调
QWidget *titleBar = this->findChild<QWidget*>("GlobalTitleBar");
if (titleBar) {
titleBar->setGeometry(0, 0, this->width(), 32);
titleBar->raise(); // 始终置顶
}
}