本文最后更新于 2025-02-20,学习久了要注意休息哟

第一章 事件

1.1 事件的概念

众所周知Qt是一个基于C++的框架,主要用来开发带窗口的应用程序(不带窗口的也行,但不是主流)。我们使用的基于窗口的应用程序都是基于事件,其目的主要是用来实现回调(因为只有这样程序的效率才是最高的)。所以在Qt框架内部为我们提供了一些列的事件处理机制,当窗口事件产生之后,事件会经过:事件派发 -> 事件过滤->事件分发->事件处理几个阶段。Qt窗口中对于产生的一系列事件都有默认的处理动作,如果我们有特殊需求就需要在合适的阶段重写事件的处理动作。

事件(event)是由系统或者 Qt 本身在不同的场景下发出的。当用户按下/移动鼠标、敲下键盘,或者是窗口关闭/大小发生变化/隐藏或显示都会发出一个相应的事件。一些事件在对用户操作做出响应时发出,如鼠标/键盘事件等;另一些事件则是由系统自动发出,如计时器事件。

每一个Qt应用程序都对应一个唯一的 QApplication应用程序对象,然后调用这个对象的exec()函数,这样Qt框架内部的事件检测就开始了(程序将进入事件循环来监听应用程序的事件)。

事件派发 -> 内核 向应用程序 发送一个事件信号

事件过滤 -> 对事件 进行过滤 让一些无用事件不进入到应用程序中

事件分发 -> 分发给每个窗口

事件处理 -> 需要对事件处理函数 做 重写

1.2 事件过滤器

1.2.1 什么是事件过滤器

事件过滤器(Event Filter)是 Qt 事件处理机制中的高级功能,允许一个对象拦截并处理其他对象的事件。通过事件过滤器可以实现:

  • 对特定控件的事件进行预处理
  • 集中管理多个对象的同类事件
  • 在不继承类的情况下扩展事件处理能力

1.2.2 事件处理流程

标准事件流程:

事件发生 → 事件接收对象 → event() → 特定事件处理函数(如 mousePressEvent)

带过滤器的流程:

事件发生 → 事件接收对象 → 事件过滤器 → event() → 特定事件处理函数

1.2.2 操作步骤

1、注册过滤器

// 在需要监视的对象上安装过滤器
targetObject->installEventFilter(filterObject);
    //  targetObject 安装者          一般是控件
    //  filterObject 事件接收对象     一般是当前窗口

2、重写 eventFilter 函数

bool FilterObject::eventFilter(QObject* watched, QEvent* event)
{
    // 判定对象
    if(watched == targetObject)
    {
        if (event->type() == QEvent::KeyPress) {
            QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
            if (keyEvent->key() == Qt::Key_Escape) {
                qDebug() << "ESC 键被拦截";
                return true; // 事件已处理
            }
        }
    }

    return QObject::eventFilter(watched, event); // 继续传递事件
}

| 参数 | 说明 |
| :—— | :—————————- |
| watched | 被监视的对象指针 |
| event | 发生的事件对象 |
| 返回值 | true 表示已处理,阻止继续传递 |

1.3 自定义控件

由于 Qt 的 UI 设计器中提供的都是标准控件,自定义控件无法直接拖拽到窗口中,需要以下步骤:

  1. 在项目中新建 一个 .cpp 和 .h 文件 需要继承 QWidget
  2. 在设计器中拖入一个 QWidget 标准控件到窗口中。
  3. 鼠标右键点击该 QWidget,选择 “提升为…”。
  4. 在弹出的对话框中选择提升的类为 MyButton

提升完成后,该控件就变成了自定义的 MyButton 类型。

第二章 鼠标事件

2.1 处理函数

// 当鼠标进入窗口时,触发该事件。该事件仅在进入的瞬间触发一次。
[virtual protected] void QWidget::enterEvent(QEvent *event);

// 当鼠标离开窗口时,触发该事件。该事件仅在离开的瞬间触发一次。
[virtual protected] void QWidget::leaveEvent(QEvent *event);

// 当鼠标左键、右键或中键被按下时,触发该事件。通过参数可判断按下的是哪个键。
[virtual protected] void QWidget::mousePressEvent(QMouseEvent *event);

// 当鼠标左键、右键或中键被释放时,触发该事件。通过参数可判断释放的是哪个键。
[virtual protected] void QWidget::mouseReleaseEvent(QMouseEvent *event);

// 当鼠标移动(包括按住一个或多个鼠标键时移动)时,触发该事件。通过参数可判断在移动过程中哪些键被按下。
[virtual protected] void QWidget::mouseMoveEvent(QMouseEvent *event);

// 当鼠标双击时,触发该事件。通过参数可判断双击使用的是哪个键。
[virtual protected] void QWidget::mouseDoubleClickEvent(QMouseEvent *event);

2.2 QMouseEvent 常用API

1、位置相关

// 获取鼠标事件发生时的位置,相对于事件目标(控件)的位置。
QPoint pos = event->pos();  // 获取鼠标相对于控件的坐标

// 获取鼠标事件发生时的位置,相对于屏幕的全局坐标。
QPoint globalPos = event->globalPos();  // 获取鼠标相对于屏幕的全局坐标

2、按键相关

// 获取鼠标事件发生时,哪个鼠标按钮被按下或释放。返回值是 Qt::MouseButton 枚举值。
Qt::MouseButton button = event->button();  // 获取按下或释放的鼠标按钮

// 获取当前按下的所有鼠标按钮,返回一个 Qt::MouseButtons 枚举值(可能是多个按钮) 移动的时候用 。
Qt::MouseButtons buttons = event->buttons();  // 获取当前按下的鼠标按钮(可能多个)
```c++
Qt::NoButton    // 没有按键按下
Qt::AllButtons  // 所有按键按下
Qt::LeftButton  // 左键
Qt::RightButton // 右键
Qt::MidButton   // 中键

3、修饰键相关

// 获取鼠标事件时修饰键的状态(如 Shift、Ctrl、Alt)。
Qt::KeyboardModifiers modifiers = event->modifiers();  // 获取修饰键的状态

4、鼠标滚轮

// 获取鼠标滚轮的滚动量,返回一个 QPoint,dx 表示水平方向的滚动量,dy 表示垂直方向的滚动量。
QPoint delta = event->angleDelta();  // 获取鼠标滚轮的旋转量

5、鼠标位置变化

// 获取鼠标在上一个事件中的位置。通常用于追踪鼠标移动轨迹。
QPoint lastPos = event->lastPos();  // 获取鼠标上一次事件发生的位置

6、事件类型

// 获取事件的类型,返回值是 QEvent::Type 枚举值(例如:QEvent::MouseButtonPress、QEvent::MouseMove 等)。
QEvent::Type eventType = event->type();  // 获取事件类型

7、事件处理控制

// 标记事件已被处理,停止事件继续传播。
event->accept();  // 事件已处理,停止传播

// 标记事件没有被处理,允许事件继续传播。
event->ignore();  // 允许事件继续传播

1.3 示例程序

  • 通过鼠标 移动一个方块
  • 记录鼠标进入和退出方块的次输

1.1.1 自定义控件

自定义一个标签控件类 LabelX,让它继承自 QLabel,然后重写父类的 enterEvent()leaveEvent()

需要注意的是,我们需要对LabelX 类做一些修改,来到 labelx.h 将父类由 QWidget 修改为 QLabel,如下:

#include <QLabel>

class LabelX : public QLabel
{
        //
};

来到 labelx.cpp 将父类由 QWidget 修改为 QLabel,如下:

#include "labelx.h"

LabelX::LabelX(QWidget* parent) : QLabel{parent}
{
}

LabelX.h 文件

class LabelX : public QLabel
{
protected:
    // 鼠标进入/离开事件
    void enterEvent(QEvent* event);
    void leaveEvent(QEvent* event);
};

LabelX.cpp 文件

// 进入窗口
void LabelX::enterEvent(QEvent* event)
{
    Q_UNUSED(event)         // 消除 为使用变量的警告
    this->setText(QString("enterEvent: %1").arg(cnt++));
}
// 离开窗口
void LabelX::leaveEvent(QEvent* event)
{
    Q_UNUSED(event)
    this->setText("离开窗口");
}

1.1.2 标准控件

如果我们使用标准控件的话,那么就需要使用到事件过滤器

示例程序

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 安装事件过滤器
    ui->label_2->installEventFilter(this);

}

bool Widget::eventFilter(QObject *watched, QEvent *event)
{
    // 判定当前对象
    if(watched == ui->label_2)
    {
        // 判定事件
        if(event->type() == QEvent::Enter)
        {
            ui->label_2->setText("进入");
        }
        if(event->type() == QEvent::Leave)
        {
            ui->label_2->setText("离开");
        }
    }

    return QWidget::eventFilter(watched, event);

}

第三章 键盘事件

3.1 处理函数

键盘事件是用户通过键盘与程序交互的重要方式,主要包括按下和释放事件。

// 当键盘上的按键被按下时,触发该事件。通过参数可判断按下的是哪个键。
[virtual protected] void QWidget::keyPressEvent(QKeyEvent *event);

// 当键盘上的按键被释放时,触发该事件。通过参数可判断释放的是哪个键。
[virtual protected] void QWidget::keyReleaseEvent(QKeyEvent *event);

1、自定义控件
2、标准控件的事件过滤
3、直接用主窗口接受信号 控制 方块

3.2 QKeyEvent 常用API

1、键位相关

// 获取按下或释放的键值。返回一个 Qt::Key 枚举值,表示按下的键。
Qt::Key key = event->key();  // 获取按下或释放的键值

// 获取事件发生时按下的修饰键状态(如 Shift、Ctrl、Alt)。
Qt::KeyboardModifiers modifiers = event->modifiers();  // 获取修饰键的状态

2、键盘输入文本

// 获取键盘事件发生时,按键所对应的文本字符。如果是可打印字符,则返回字符本身。
QString text = event->text();  // 获取按键对应的文本字符(如 'A'、'1')

3、键盘输入码

// 获取按下键的 Unicode 编码(返回按下的键的 Unicode 值)。
ushort unicode = event->unicode();  // 获取键的 Unicode 编码

4、键盘状态

// 判断某个键是否被按下。返回 true 表示该键被按下,false 表示没有按下。
bool isKeyDown = event->isAutoRepeat();  // 判断是否是自动重复的按键事件

5、事件类型

// 获取事件的类型,返回值是 QEvent::Type 枚举值(如:QEvent::KeyPress、QEvent::KeyRelease)。
QEvent::Type eventType = event->type();  // 获取事件类型

6、事件处理控制

// 标记事件已被处理,停止事件继续传播。
event->accept();  // 事件已处理,停止传播

// 标记事件没有被处理,允许事件继续传播。
event->ignore();  // 允许事件继续传播

1.3 示例程序

第四章 定时器事件

定时器事件用于处理定时任务,定时器可以在指定时间间隔后触发某些操作,常用于定时刷新、定时检查等功能。

// 启动一个定时器,定时器在每隔指定毫秒数后触发。
// timerId:定时器的标识符,interval:时间间隔,单位是毫秒。
// void QWidget::startTimer(int interval);  // 启动定时器

4.1 处理函数

// 当定时器触发时,调用该函数。通过 timerId 参数判断哪个定时器触发。
[virtual protected] void QWidget::timerEvent(QTimerEvent *event);

// timerId:触发的定时器标识符。
// 如果有多个定时器,可以通过 timerId 来区分。

4.2 API

// 启动一个定时器,定时器会每隔指定的时间间隔触发一次 timerEvent。
int timerId = startTimer(1000);  // 启动定时器,时间间隔为 1000 毫秒(1秒)

// 停止指定的定时器,释放定时器资源。
killTimer(timerId);  // 停止定时器

// 处理定时器触发的事件。
void timerEvent(QTimerEvent *event) override {
    if (event->timerId() == timerId) {
        // 执行定时任务
    }
}

4.3 示例程序

第五章 拖放事件

5.1 处理函数

事件介绍

// QEvent::DragEnter
// 当拖动文件进入到窗口/控件中时,触发该事件。对应的事件类是 QDragEnterEvent。
QEvent::DragEnter;

// QEvent::DragLeave
// 当拖动文件离开窗口/控件时,触发该事件。对应的事件类是 QDragLeaveEvent。
QEvent::DragLeave;

// QEvent::DragMove
// 当拖动文件在窗口/控件中移动时,触发该事件。对应的事件类是 QDragMoveEvent。
QEvent::DragMove;

// QEvent::Drop
// 当拖动文件在窗口/控件中释放时,触发该事件。对应的事件类是 QDropEvent。
QEvent::Drop;

事件处理函数

// dragEnterEvent(QDragEnterEvent *event)
// 当拖动对象进入控件区域时触发,通常用于判断拖动内容是否有效。
void QWidget::dragEnterEvent(QDragEnterEvent *event);

// dragLeaveEvent(QDragLeaveEvent *event)
// 当拖动对象离开控件区域时触发,通常用于处理离开时的操作。
void QWidget::dragLeaveEvent(QDragLeaveEvent *event);

// dragMoveEvent(QDragMoveEvent *event)
// 当拖动对象在控件区域内移动时触发,用于实时处理拖动中的逻辑。
void QWidget::dragMoveEvent(QDragMoveEvent *event);

// dropEvent(QDropEvent *event)
// 当拖放操作完成,目标控件接受数据时触发。
void QWidget::dropEvent(QDropEvent *event);

5.2 API

5.2.1 QTextEdit

QTextEdit 是一个富文本编辑器控件,支持编辑和显示多种格式的文本(如纯文本和富文本)。

// 设置文本内容
void setPlainText(const QString &text);
// 设置文本框中的纯文本内容(不支持富文本)。

void setHtml(const QString &html);
// 设置文本框中的HTML格式内容。

QString toPlainText() const;
// 获取当前文本框中的纯文本内容。

QString toHtml() const;
// 获取当前文本框中的HTML格式内容。

void append(const QString &text);
// 在文本框内容末尾追加文本。

void setAlignment(Qt::Alignment alignment);
// 设置文本的对齐方式,如左对齐、右对齐或居中。

void setTextColor(const QColor &color);
// 设置文本的颜色。

void setFont(const QFont &font);
// 设置文本的字体。

void setReadOnly(bool readOnly);
// 设置文本框是否为只读模式。

5.2.2 QDragEnterEvent

QDragEnterEvent 是拖动进入控件时触发的事件。用于检测拖动的对象类型和内容。

// 获取拖动数据的 MIME 类型
QMimeData *mimeData() const;
// 获取包含拖动数据的 `QMimeData` 对象。

bool isAccepted() const;
// 返回当前拖动事件是否被接受。

void accept() const;
// 接受当前拖动事件。

void ignore() const;
// 忽略当前拖动事件。

// 检查拖动的数据类型
bool hasUrls() const;
// 判断拖动的数据是否是 URL(通常用于文件拖放)。

bool hasText() const;
// 判断拖动的数据是否是文本。

bool hasImage() const;
// 判断拖动的数据是否是图片。

5.2.3 QDragLeaveEvent

QDragLeaveEvent 是当拖动对象离开控件区域时触发的事件。通常用于取消拖放时的界面反馈(例如,撤销高亮显示等)。

// 获取拖动事件中的 MIME 数据
QMimeData *mimeData() const;
// 获取包含拖动数据的 `QMimeData` 对象。

QPoint pos() const;
// 获取拖动对象离开时的鼠标位置。

void accept() const;
// 接受当前的拖放离开事件,通常表示我们处理了这个事件。

void ignore() const;
// 忽略当前的拖放离开事件,表示不处理这个事件。

5.2.4 QDropEvent

QDropEvent 是拖动操作完成时触发的事件。它处理拖放到控件中的数据。

// 获取拖动事件中的 MIME 数据
QMimeData *mimeData() const;
// 获取包含拖动数据的 `QMimeData` 对象。

// 获取当前拖动事件的目标位置
QPoint pos() const;
// 获取事件发生时相对于控件的坐标。

void accept() const;
// 接受当前的拖放操作。

void ignore() const;
// 忽略当前的拖放操作。

// 获取拖动放置的 URL
QList<QUrl> urls() const;
// 获取拖动事件中所有文件的 URL 列表。

QString text() const;
// 获取拖放操作中的文本数据(如果有)。

5.2.5 QMimeData

QMimeData 是一个用于封装拖放操作中的数据的类。它可以存储多种类型的数据,如文本、URL、图片等。

// 获取所有的URL列表(通常用于文件拖放)
QList<QUrl> urls() const;
// 获取所有拖动数据的 URL 列表。

// 判断是否包含文本数据
bool hasText() const;
// 判断 `QMimeData` 是否包含文本数据。

// 获取文本数据
QString text() const;
// 获取存储的文本数据。

// 判断是否包含图片数据
bool hasImage() const;
// 判断 `QMimeData` 是否包含图片数据。

// 设置文本数据
void setText(const QString &text);
// 设置 `QMimeData` 对象的文本数据。

// 设置URL数据
void setUrls(const QList<QUrl> &urls);
// 设置 `QMimeData` 对象的 URL 数据(通常用于文件拖放)。

5.3 示例程序

#include <QTextEdit>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QMimeData>

class MyTextEdit : public QTextEdit {
    Q_OBJECT

public:
    // 构造函数,初始化控件并启用拖放功能
    MyTextEdit(QWidget *parent = nullptr) : QTextEdit(parent) {
        setAcceptDrops(true); // 启用拖放功能,允许控件接受拖动的内容
    }

protected:
    // 处理拖动进入事件:当拖动的对象进入控件区域时触发
    void dragEnterEvent(QDragEnterEvent *event) override {
        // 判断拖动的数据是否包含文件URL
        if (event->mimeData()->hasUrls()) {
            // 如果是文件URL,接受该拖放操作
            event->acceptProposedAction();
        } else {
            // 否则,忽略此拖放操作
            event->ignore();
        }
    }

    // 处理拖动离开事件:当拖动的对象离开控件区域时触发
    void dragLeaveEvent(QDragLeaveEvent *event) override {
        // 允许拖动离开控件时的事件,通常用于视觉反馈
        event->accept();
    }

    // 处理拖动移动事件:当拖动的对象在控件区域内移动时触发
    void dragMoveEvent(QDragMoveEvent *event) override {
        // 在拖动过程中持续接受操作,允许用户继续拖动
        event->acceptProposedAction();
    }

    // 处理拖放事件:当拖动的对象被放置在控件中时触发
    void dropEvent(QDropEvent *event) override {
        // 判断拖动的数据是否包含文件URL
        if (event->mimeData()->hasUrls()) {
            // 获取拖放的数据中所有的URL列表
            QList<QUrl> urlList = event->mimeData()->urls();

            // 如果URL列表不为空,则获取第一个文件的路径
            if (!urlList.isEmpty()) {
                QString filePath = urlList.first().toLocalFile(); // 转换为本地文件路径

                QFile file(filePath);  // 创建 QFile 对象以读取文件
                if (file.open(QIODevice::ReadOnly)) {  // 以只读模式打开文件
                    QTextStream in(&file);  // 创建文本流以读取文件内容
                    setPlainText(in.readAll());  // 将文件内容显示到 QTextEdit 中
                    file.close();  // 关闭文件
                }
            }
            event->acceptProposedAction(); // 接受并处理拖放操作
        }
    }
};

第六章 绘图事件

第七章 右键菜单事件

QEvent::ContextMenu 事件是在用户右键点击控件时触发的,它对应的事件类是 QContextMenuEvent。通常在该事件中你会创建和显示一个上下文菜单(右键菜单)。

7.1 处理函数

void QWidget::contextMenuEvent(QContextMenuEvent *event)

7.2 基本用法

#include <QWidget>
#include <QMenu>
#include <QAction>
#include <QContextMenuEvent>
#include <QMessageBox>

class MyWidget : public QWidget {
    Q_OBJECT

public:
    MyWidget(QWidget *parent = nullptr) : QWidget(parent) {}

protected:
    // 处理右键菜单事件
    void contextMenuEvent(QContextMenuEvent *event) override {
        // 创建右键菜单
        QMenu menu(this);

        // 添加菜单项
        QAction *action1 = menu.addAction("菜单项 1");
        QAction *action2 = menu.addAction("菜单项 2");
        QAction *action3 = menu.addAction("菜单项 3");

        // 连接菜单项的点击事件
        connect(action1, &QAction::triggered, this, &MyWidget::onMenuItem1Clicked);
        connect(action2, &QAction::triggered, this, &MyWidget::onMenuItem2Clicked);
        connect(action3, &QAction::triggered, this, &MyWidget::onMenuItem3Clicked);

        // 弹出菜单,位置为全局位置
        menu.exec(event->globalPos());
    }

private slots:
    // 菜单项 1 的槽函数
    void onMenuItem1Clicked() {
        QMessageBox::information(this, "菜单项 1", "你点击了菜单项 1");
    }

    // 菜单项 2 的槽函数
    void onMenuItem2Clicked() {
        QMessageBox::information(this, "菜单项 2", "你点击了菜单项 2");
    }

    // 菜单项 3 的槽函数
    void onMenuItem3Clicked() {
        QMessageBox::information(this, "菜单项 3", "你点击了菜单项 3");
    }
};

第八章 小项目 - 无边框窗口

8.1 项目概述

本节将通过一个小项目,展示如何创建一个无边框的窗口。在 Qt 中,窗口通常有边框和标题栏,但有时我们希望移除这些边框,创建一个自定义的、更加自由的窗口。我们将学习如何去掉窗口的边框、如何处理窗口的拖动、如何添加自定义的关闭按钮等。

8.2 无边框窗口的创建

8.2.1 基本概念

  • 介绍什么是无边框窗口,如何去掉窗口的默认边框和标题栏。
  • Qt 如何支持无边框窗口的创建。

8.2.2 实现代码

#include <QWidget>
#include <QMouseEvent>
#include <QApplication>

class MyWindow : public QWidget {
    Q_OBJECT

public:
    MyWindow(QWidget *parent = nullptr) : QWidget(parent) {
        // 去除标题栏
        setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint);
        // 设置无边框
        setWindowFlags(Qt::FramelessWindowHint); 
        // 背景透明
        setAttribute(Qt::WA_TranslucentBackground); 
        setFixedSize(400, 300); // 固定窗口大小
    }

protected:
    // 处理鼠标事件,实现窗口拖动
    void mousePressEvent(QMouseEvent *event) override {
        m_dragging = true;
        m_dragStartPosition = event->globalPos() - frameGeometry().topLeft();
    }

    void mouseMoveEvent(QMouseEvent *event) override {
        if (m_dragging) {
            move(event->globalPos() - m_dragStartPosition);
        }
    }

    void mouseReleaseEvent(QMouseEvent *event) override {
        m_dragging = false;
    }

private:
    bool m_dragging = false;
    QPoint m_dragStartPosition;
};

8.3 实现窗口拖动

8.3.1 拖动窗口的原理

  • 介绍如何利用鼠标事件来实现无边框窗口的拖动功能。
  • 鼠标按下时记录位置,鼠标移动时计算窗口的新位置,鼠标释放时结束拖动。

8.3.2 拖动代码

void MyWindow::mousePressEvent(QMouseEvent *event) {
    if (event->button() == Qt::LeftButton) {
        m_dragging = true;
        m_dragStartPosition = event->globalPos() - frameGeometry().topLeft();
    }
}

void MyWindow::mouseMoveEvent(QMouseEvent *event) {
    if (m_dragging) {
        move(event->globalPos() - m_dragStartPosition);
    }
}

void MyWindow::mouseReleaseEvent(QMouseEvent *event) {
    if (event->button() == Qt::LeftButton) {
        m_dragging = false;
    }
}

8.4 添加自定义按钮

8.4.1 自定义关闭按钮

  • 为无边框窗口添加一个自定义的关闭按钮。
  • 如何通过自定义按钮触发关闭窗口的功能。

8.4.2 代码实现

#include <QPushButton>
#include <QHBoxLayout>

MyWindow::MyWindow(QWidget *parent) : QWidget(parent) {
    setWindowFlags(Qt::FramelessWindowHint);
    setFixedSize(400, 300);

    // 创建关闭按钮
    QPushButton *closeButton = new QPushButton("关闭", this);
    connect(closeButton, &QPushButton::clicked, this, &QWidget::close);

    QHBoxLayout *layout = new QHBoxLayout(this);
    layout->addWidget(closeButton);
    setLayout(layout);
}

8.5 无边框窗口的常见应用

无边框窗口的用途

  • 无边框窗口通常用于浮动窗体、弹出窗口、游戏窗口等应用场景。
  • 在一些现代应用中,去掉边框可以增强界面的美观和用户体验。

无边框窗口与透明背景的结合

  • 结合透明背景,可以创建类似工具条、浮动提示框等界面。
  • 使用无边框窗口时,可以选择透明或半透明背景,增加界面的灵活性和美观性。