Qt QMainWindow 自定义标题栏

MainWindow.h

cpp 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QMouseEvent>
#include <QPushButton>
#include <QLabel>
#include <QWidget>

class MainWindow : public QMainWindow {
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

protected:
    void mousePressEvent(QMouseEvent *event) override;
    void mouseMoveEvent(QMouseEvent *event) override;
    void mouseReleaseEvent(QMouseEvent *event) override;
private slots:
    void onMinimizeClicked();
    void onMaximizeClicked();
    void onCloseClicked();

private:
    void setupUI();
    void setStyles();

    QWidget *titleBar;  // 自定义标题栏
    QLabel *titleLabel;
    QLabel *titleIconLabel;
    QPushButton *minButton;
    QPushButton *maxButton;
    QPushButton *closeButton;
    QPoint lastMousePosition;
    bool isMaximized = false;
    bool mousePressed = false;
};

#endif // MAINWINDOW_H

MainWindow.cpp

cpp 复制代码
#include "QtWin.h"
#include <QVBoxLayout>
#define  BTN_WIDTH 40
#define  BTN_HEIGHT 40
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
    setWindowFlags(Qt::FramelessWindowHint); // 去掉系统标题栏
    setMinimumSize(800, 500);

    setupUI();
    setStyles();
}

MainWindow::~MainWindow() {}

void MainWindow::setupUI() {
    titleBar = new QWidget(this);
    titleBar->setFixedHeight(BTN_HEIGHT);

    titleIconLabel = new QLabel( this);
    titleIconLabel->setFixedSize(QSize(30, 30));
    QIcon icon(":/res/title_icon.png");
    titleIconLabel->setPixmap(icon.pixmap(QSize(30, 30)));

    titleLabel = new QLabel("My Application", this);
    titleLabel->setStyleSheet("font-size: 16px; color: white;");

    minButton = new QPushButton( this);
    minButton->setToolTip("最小化");
    minButton->setFixedSize(QSize(BTN_WIDTH, BTN_HEIGHT));
    minButton->setObjectName("btnMin");



    maxButton = new QPushButton( this);
    maxButton->setToolTip("最大化");
    maxButton->setFixedSize(QSize(BTN_WIDTH, BTN_HEIGHT));
    maxButton->setObjectName("btnMax");

    closeButton = new QPushButton(this);
    closeButton->setToolTip("关闭");
    closeButton->setFixedSize(QSize(BTN_WIDTH, BTN_HEIGHT));
    closeButton->setObjectName("btnClose");

    // **标题栏布局**
    QHBoxLayout *titleLayout = new QHBoxLayout(titleBar);
    titleLayout->addWidget(titleIconLabel);
    titleLayout->addSpacing(10);
    titleLayout->addWidget(titleLabel);
    titleLayout->addStretch();
    titleLayout->addWidget(minButton);
    titleLayout->addWidget(maxButton);
    titleLayout->addWidget(closeButton);
    titleLayout->setContentsMargins(5, 0, 0, 0);
    titleBar->setLayout(titleLayout);

    // **主窗口内容**
    QWidget *centralWidget = new QWidget(this);
    centralWidget->setStyleSheet("background-color: #F5F5F5;"); // 内容区域背景色

    // **主布局,确保 `titleBar` 在最上方**
    QVBoxLayout *mainLayout = new QVBoxLayout();
    mainLayout->setContentsMargins(0, 0, 0, 0);  // 确保不被遮挡
    mainLayout->setSpacing(0);  // 避免 titleBar 和内容区之间有间距
    mainLayout->addWidget(titleBar);
    mainLayout->addWidget(centralWidget);

    // **设置 `centralWidget`**
    QWidget *mainContainer = new QWidget(this);
    mainContainer->setLayout(mainLayout);
    setCentralWidget(mainContainer);

    // **按钮功能**
    connect(minButton, &QPushButton::clicked, this, &MainWindow::onMinimizeClicked);
    connect(maxButton, &QPushButton::clicked, this, &MainWindow::onMaximizeClicked);
    connect(closeButton, &QPushButton::clicked, this, &MainWindow::onCloseClicked);
}

void MainWindow::setStyles() {
    setStyleSheet(R"(
        QWidget {
            background-color: #2E3A46;
        }
        QLabel {
            font-weight: bold;
        }
    )");


    minButton->setStyleSheet(R"(
QPushButton {
    border: none;
    background: transparent;
    border-image: url(:/res/btn_min.png) 0 80 0 0;
    min-width: 40px;
    min-height: 40px;
}

QPushButton:hover {
     border-image: url(:/res/btn_min.png) 0 40 0 40;
}

QPushButton:pressed {
    border-image: url(:/res/btn_min.png) 0 80 0 40;
}

)");


    closeButton->setStyleSheet(R"(
    QPushButton {
        border: none;
        border-image: url(:/res/btn_close.png) 0 80 0 0;
    }
    QPushButton:hover {
        border-image: url(:/res/btn_close.png) 0 40 0 40 ;
    }
    QPushButton:pressed {
        border-image: url(:/res/btn_close.png) 0 80 0 40;
    }
)");

    maxButton->setStyleSheet(R"(
    QPushButton {
        border: none;
        border-image: url(:/res/btn_max.png) 0 80 0 0;
    }
    QPushButton:hover {
        border-image: url(:/res/btn_max.png) 0 40 0 40 ;
    }
    QPushButton:pressed {
        border-image: url(:/res/btn_max.png) 0 80 0 40;
    }
)");
}

// **最小化窗口**
void MainWindow::onMinimizeClicked() {
    showMinimized();
}

// **最大化/还原**
void MainWindow::onMaximizeClicked() {
    if (isMaximized) {
        showNormal();
        isMaximized = false;
    }
    else {
        showMaximized();
        isMaximized = true;
    }
}

// **关闭窗口**
void MainWindow::onCloseClicked() {
    close();
}

// **窗口拖动**
void MainWindow::mousePressEvent(QMouseEvent *event) {
    if (event->button() == Qt::LeftButton && titleBar->geometry().contains(event->pos())) {
        lastMousePosition = event->globalPos() - frameGeometry().topLeft();
        mousePressed = true;
event->accept();
    }
}

void MainWindow::mouseMoveEvent(QMouseEvent *event) {
    if (event->buttons() & Qt::LeftButton && mousePressed ) {
        move(event->globalPos() - lastMousePosition);
        event->accept();
    }
}
void MainWindow::mouseReleaseEvent(QMouseEvent *event) {
    Q_UNUSED(event)
        mousePressed = false;
}

main.cpp

cpp 复制代码
#include "MainWindow.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

下载:qtQMainWindow自定义标题栏资源-CSDN文库

相关推荐
charlie1145141914 小时前
逐步理解Qt信号与槽机制
数据库·qt
yaso_zhang9 小时前
当生产了~/qt-arm/bin/qmake,可以单独编译其他-源码的某个模块,如下,编译/qtmultimedia
qt
code bean10 小时前
【Qt/C++】深入理解 Lambda 表达式与 `mutable` 关键字的使用
开发语言·c++·qt
爱看书的小沐1 天前
【小沐学GIS】基于C++绘制二维瓦片地图2D Map(QT、OpenGL、GIS)
c++·qt·gis·opengl·glfw·glut·二维地图
炬火初现1 天前
Qt 的原理及使用(1)——qt的背景及安装
开发语言·qt
weixin_1101 天前
Qt 无边框窗口,支持贴边分屏
c++·qt
gaoenyang7605251 天前
QT Creator配置Kit
开发语言·qt
3D打印-HUSTAIBO1 天前
QT中connect高级链接——指针、lambda、宏
qt
刘梓谦1 天前
Qt获取CPU使用率及内存占用大小
开发语言·c++·qt
追烽少年x2 天前
Qt中在子线程中刷新UI的方法
qt