Qt-Nice-Frameless-Window: 一个跨平台无边框窗口(Frameless Window)解决方案

目录

1.简介

2.安装与集成

3.注意事项


1.简介

Qt-Nice-Frameless-Window 是一个基于 Qt 框架的第三方库,主要用于快速实现跨平台的无边框窗口(Frameless Window),同时解决了原生 Qt 无边框窗口在实际开发中遇到的诸多问题(如窗口拖拽、缩放、标题栏交互、平台兼容性等)。

它的核心功能有:

1.跨平台支持:兼容 Windows、Linux、macOS 三大主流系统,自动适配各平台的窗口行为规范。

2.完整的窗口交互:封装了无边框窗口的基础功能,包括:

  • 窗口拖拽(标题栏区域)
  • 边缘 / 角落缩放
  • 最小化 / 最大化 / 关闭按钮交互
  • 双击标题栏最大化 / 还原

3.视觉增强:支持窗口阴影、半透明效果、自定义标题栏样式,提升界面美观度。

4.轻量易集成:代码结构简洁,无需复杂配置,可快速嵌入现有 Qt 项目。

5.原生体验保留:在 macOS 上保留窗口全屏手势,在 Windows 上支持任务栏预览等原生特性。

与 Qt 原生无边框的对比:

Qt 原生通过 setWindowFlags(Qt::FramelessWindowHint) 可实现无边框,但存在明显缺陷:

  • 需手动实现拖拽、缩放逻辑,且跨平台适配复杂;
  • 窗口阴影、半透明效果需自行处理,不同平台表现不一致;
  • 缺失系统级窗口行为(如 Windows 任务栏右键菜单、macOS 全屏动画)。

而 Qt-Nice-Frameless-Window 封装了这些细节,开发者可专注于业务逻辑而非窗口基础交互。

2.安装与集成

1.获取库

https://github.com/luoyayun361/qt-nice-frameless-window

git地址:https://github.com/luoyayun361/Qt-Nice-Frameless-Window.git

通常可从 GitHub 等代码仓库获取源码(如搜索 Qt-Nice-Frameless-Window),通过 Qt Creator 编译为静态库或动态库,或直接将源码文件加入项目。

2.继承核心窗口类

库中通常提供一个基础窗口类(如 NiceFramelessWindow),通过继承该类实现自定义窗口:

cpp 复制代码
//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include "framelesswindow.h"
#include <QString>

namespace Ui {
class MainWindow;
}

class MainWindow : public CFramelessWindow
{
    Q_OBJECT

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

private slots:
    void on_btnMin_clicked();
    void on_btnMax_clicked();
    void on_btnClose_clicked();
    void on_bthFull_clicked();
    void on_btnIncreaseMargin_clicked();
    void on_btnDecreaseMargin_clicked();
    void on_btnResizeable_clicked();

private:
    QString currentMargins();
private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H
cpp 复制代码
//mainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QRect>

MainWindow::MainWindow(QWidget *parent) :
    CFramelessWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
#ifdef Q_OS_WIN
    //feel free to change this number to see how it works
    setResizeableAreaWidth(8);

    //set titlebar widget, wo we can drag MainWindow by it
    setTitleBar(ui->widgetTitlebar);

    //labelTitleText is a child widget of widgetTitlebar
    //add labelTitleText to ignore list, so we can drag MainWindow by it too
    addIgnoreWidget(ui->labelTitleText);

    //further more, btnMin/btnMax... are child widgets of widgetTitlebar too
    //but we DO NOT want to drag MainWindow by them
#endif

    ui->labelMargins->setText(currentMargins());
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_btnMin_clicked()
{
    showMinimized();
}
void MainWindow::on_btnMax_clicked()
{
    if (isMaximized()) showNormal();
    else showMaximized();
}
void MainWindow::on_btnClose_clicked()
{
    close();
}

void MainWindow::on_bthFull_clicked()
{
    if (isFullScreen()) showNormal();
    else showFullScreen();
}

void MainWindow::on_btnIncreaseMargin_clicked()
{
    QMargins margin = contentsMargins();
    margin += 2;
    setContentsMargins(margin);
    ui->labelMargins->setText(currentMargins());
}

void MainWindow::on_btnDecreaseMargin_clicked()
{
    QMargins margin = contentsMargins();
    margin -= 2;
    setContentsMargins(margin);
    ui->labelMargins->setText(currentMargins());
}

QString MainWindow::currentMargins()
{
    QMargins margins = contentsMargins();
    QRect rect = contentsRect();
    return QString("Current Margins:%1,%2,%3,%4; ContentRect:%5,%6,%7,%8").\
            arg(margins.left()).arg(margins.top()).\
            arg(margins.right()).arg(margins.bottom()).\
            arg(rect.left()).arg(rect.top()).\
            arg(rect.right()).arg(rect.bottom());
}

void MainWindow::on_btnResizeable_clicked()
{
    setResizeable(!isResizeable());
}

3.在 main 函数中使用

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

int main(int argc, char *argv[])
{
    QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

4.展示效果

3.注意事项

  • 不同版本的库 API 可能略有差异,需参考对应仓库的文档;
  • 若需深度定制窗口行为(如自定义缩放区域、修改阴影参数),可通过重写库提供的虚函数实现;
  • 对于高 DPI 屏幕,需确保 Qt 项目已开启高 DPI 支持(QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling))。
相关推荐
汉克老师3 小时前
GESP2026年9月认证C++六级( 第三部分编程题(2、分树规划))精讲
c++·gesp·小学生·学c++编程
学生小羊3 小时前
C++ 初阶 学习博客
c语言·c++·c++与c语言的区别·c++基础学习
江湖人称菠萝包3 小时前
【Qt】《Qt 5.9 C++开发指南》笔记-Chapter8-绘图
笔记·qt·qt5
辛苦才能4 小时前
C++多态原理:虚函数表的内存布局与动态绑定的汇编真相
开发语言·c++
铲灰4 小时前
做个总结而已
开发语言
西西弗Sisyphus4 小时前
Qt 实现一个 水波进度球
c++·qt·c
无忧.芙桃4 小时前
数据结构之排序算法(中):冒泡排序与快速排序,从相邻交换到工程级优化
c语言·c++·排序算法
IvanCodes4 小时前
Python 文件操作(十二):文件与目录的读写
开发语言·python
Hhy_11074 小时前
《C++深度解构04》类和对象(下)——类型转换、static、友元与编译器优化
c语言·c++·学习·类和对象·visual studio
qq_199886874 小时前
第7板块·第1节:通用算子分类与设计模式
c++·人工智能·gpu算力·cuda