使用C++与Qt6,在windows上打造MacOS风格桌面应用窗口

在桌面应用、嵌入式系统等开发领域中,C++与Qt6的组合一直是开发者的优选方案之一。二者结合不仅能发挥C++的性能优势,还能借助Qt6的框架能力大幅度提升开发效率,尤其在跨平台场景下优势显著。

一、准备开发环境

**开发工具:**Visual Studio 2022

**开发环境:**Qt6.9

二、创建新项目

1.在Visual Studio中创建新项目,选择Qt Widgets Application

2.输入项目名后点击创建

3.弹出Qt的引导界面,点击下一步,选择开发版本以及所需的库,默认的Qt Core,QtGui,QtWidgets即可完成项目创建

三、设计用户界面

MacOS桌面应用窗口的显著特征是整体窗口为圆角,顶部标签栏为毛玻璃且窗口名在标签栏中心位置,关闭、最小化、缩放按钮则在标签栏的最左侧,且为红黄绿三种颜色。

四、编写代码

创建两个文件:macwindow.cpp,macwindow.h

macwindow.h

cpp 复制代码
#pragma once
#include <QMainWindow>
#include <QWidget>
#include <QGraphicsEffect>

class MacWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MacWindow(QWidget *parent = nullptr);

protected:
    void paintEvent(QPaintEvent *event) override;
    void mousePressEvent(QMouseEvent *event) override;
    void mouseMoveEvent(QMouseEvent *event) override;

private:
    QPoint m_dragPosition;
};

macwindow.cpp

cpp 复制代码
#include "stdafx.h"
#include "macwindow.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>
#include <QPainter>
#include <QLabel>

MacWindow::MacWindow(QWidget *parent) : 
    QMainWindow(parent),
    m_dragPosition(0, 0) 
{
    setWindowFlags(Qt::FramelessWindowHint);
    setAttribute(Qt::WA_TranslucentBackground);
    setFixedSize(800, 600);

    QWidget *mainWidget = new QWidget(this);
    mainWidget->setObjectName("mainWidget");
    mainWidget->setStyleSheet("QWidget#mainWidget{background:white;border-radius:6px;}");

    QVBoxLayout *mainLayout = new QVBoxLayout(mainWidget);
    mainLayout->setContentsMargins(0, 0, 0, 0);
    mainLayout->setSpacing(0);

    QWidget *titleBar = new QWidget(mainWidget);
    titleBar->setFixedHeight(30);
    titleBar->setStyleSheet("background:#f0f0f0;border-top-left-radius:6px;border-top-right-radius:6px;");

    QHBoxLayout *titleLayout = new QHBoxLayout(titleBar);
    titleLayout->setContentsMargins(12, 0, 12, 0);
    titleLayout->setSpacing(8);

    QWidget *btnGroup = new QWidget(titleBar);
    QHBoxLayout *btnLayout = new QHBoxLayout(btnGroup);
    btnLayout->setSpacing(8);
    btnLayout->setContentsMargins(0, 0, 0, 0);

    QPushButton *closeBtn = new QPushButton(btnGroup);
    closeBtn->setFixedSize(12, 12);
    closeBtn->setStyleSheet("background:#ff5f56;border-radius:6px;border:none;");
    connect(closeBtn, &QPushButton::clicked, this, &QMainWindow::close);

    QPushButton *minimizeBtn = new QPushButton(btnGroup);
    minimizeBtn->setFixedSize(12, 12);
    minimizeBtn->setStyleSheet("background:#ffbd2e;border-radius:6px;border:none;");
    connect(minimizeBtn, &QPushButton::clicked, this, &QMainWindow::showMinimized);

    QPushButton *maximizeBtn = new QPushButton(btnGroup);
    maximizeBtn->setFixedSize(12, 12);
    maximizeBtn->setStyleSheet("background:#27c93f;border-radius:6px;border:none;");
    connect(maximizeBtn, &QPushButton::clicked, this, [this](){ 
        isMaximized() ? showNormal() : showMaximized(); 
    });

    btnLayout->addWidget(closeBtn);
    btnLayout->addWidget(minimizeBtn);
    btnLayout->addWidget(maximizeBtn);

    QLabel *titleLabel = new QLabel("1", titleBar);
    titleLabel->setAlignment(Qt::AlignCenter);
    titleLabel->setStyleSheet("color:#555555;font:12px 'Microsoft YaHei';");

    QWidget *spacer = new QWidget(titleBar);
    spacer->setFixedSize(btnGroup->sizeHint());

    titleLayout->addWidget(btnGroup);
    titleLayout->addWidget(titleLabel, 1);
    titleLayout->addWidget(spacer);

    QWidget *contentWidget = new QWidget(mainWidget);
    contentWidget->setStyleSheet("background:white;border-bottom-left-radius:6px;border-bottom-right-radius:6px;");

    mainLayout->addWidget(titleBar);
    mainLayout->addWidget(contentWidget, 1);
    setCentralWidget(mainWidget);
}

void MacWindow::paintEvent(QPaintEvent *event) {
    Q_UNUSED(event);
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setPen(Qt::NoPen);
    painter.setBrush(QColor(240, 240, 240));
    painter.drawRoundedRect(rect(), 6, 6);
}

void MacWindow::mousePressEvent(QMouseEvent *event) {
    if (event->button() == Qt::LeftButton) {
        m_dragPosition = event->globalPosition().toPoint() - this->frameGeometry().topLeft();
        event->accept();
    }
}

void MacWindow::mouseMoveEvent(QMouseEvent *event) {
    if (event->buttons() & Qt::LeftButton) {
        move(event->globalPosition().toPoint() - m_dragPosition);
        event->accept();
    }
}

main.cpp

cpp 复制代码
#include "stdafx.h"
#include "macwindow.h"
#include <QApplication>

int main(int argc, char* argv[]) {
    QApplication app(argc, argv);
    MacWindow window;
    window.setWindowTitle("1");
    window.show();
    return app.exec();
}

stdafx.h

cpp 复制代码
#pragma once
#pragma execution_character_set("utf-8")
#pragma warning(disable : 4828)

#include <QtWidgets/QMainWindow>
#include <QtGui/QPainter>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QLabel>
#include <QtGui/QMouseEvent>
#include <QtWidgets/QHBoxLayout>

五、项目源码地址

链接:https://pan.baidu.com/s/1DX7CtIM55nG_uIj_5iXBzA?pwd=ud41