Qt核心应用架构深度解析:QCoreApplication, QGuiApplication与QApplication的原理、分工及选型策略

Source

Qt核心应用架构深度解析:QCoreApplication, QGuiApplication与QApplication的原理、分工及选型策略

摘要

任何Qt程序都必须有且仅有一个应用对象实例,它是程序的入口点和中央协调器。本报告将系统性地剖析QCoreApplication、QGuiApplication和QApplication这三个核心类,不仅阐述其API功能,更深入探讨其背后的设计哲学——一种通过继承实现功能分层与依赖解耦的精妙架构。核心论点在于,这三个类并非简单的选项,而是一个逻辑递进的层次结构,从无GUI的核心功能,到通用的图形界面抽象,再到为QWidget桌面应用提供的专属支持。通过本报告,读者将能理解Qt框架如何通过这种分层设计,同时支持从轻量级控制台工具到复杂QWidget桌面应用,再到现代化的QML/Qt Quick跨平台界面的广泛需求。最终目标是为架构师和开发者提供一个清晰、可靠的选型决策框架 1。


第一章:架构基石——QCoreApplication的非GUI世界

1.1 核心职责:Qt应用的“无形之手”

QCoreApplication是整个Qt应用框架的根基,位于Qt Core模块中 1。作为QObject的直接子类,它为不包含图形用户界面(UI)的应用程序提供了核心的事件处理循环和基础服务 2。所有Qt应用程序,无论其最终是否呈现图形界面,都必须创建且只能创建一个QCoreApplication或其子类的实例 2。

可以将其理解为Qt应用的“中央处理器”或“无形之手”。它不关心像素的绘制、窗口的摆放或用户的点击,而是专注于更底层的、通用的应用级服务。这些服务包括事件调度、信号与槽机制的实现、定时器、线程间通信、国际化支持以及应用程序范围内的设置管理。正是QCoreApplication的存在,使得Qt的异步编程模型得以有效运作。

1.2 事件循环机制深度解析

QCoreApplication最核心的职责是提供和管理事件循环。通过调用静态方法QCoreApplication::exec(),应用程序便进入其主事件循环 1。这是一个阻塞调用,意味着程序将在此处暂停,等待并处理事件,直到exit()或quit()槽被调用,事件循环才会终止 5。

这个事件循环并非一个简单的while(true)循环。它是一个与底层操作系统事件API(如Windows的GetMessage,Linux的epoll)高效集成的复杂机制。它负责从操作系统(例如,定时器到期、网络套接字数据到达)和应用程序内部(例如,通过postEvent()发布)等多种来源接收事件,并将它们分发给相应的QObject对象进行处理 2。在执行耗时较长的操作时,可以调用processEvents()来临时处理挂起的事件,以保持应用程序的响应性,防止程序被视为“无响应” 5。

事件的分发主要通过虚函数notify(QObject *receiver, QEvent *event)完成 1。Qt为开发者提供了从全局到局部的多层次事件控制能力。开发者可以通过以下方式拦截和处理事件:

  • 重写notify()函数:这是最强大但侵入性也最高的方式,可以完全控制事件的分发流程,但一个子类只能有一个实现 6。
  • 在QCoreApplication::instance()上安装事件过滤器:这种方式同样强大,可以处理所有对象的所有事件,甚至包括发往禁用控件的事件,并且可以安装多个全局过滤器 2。
  • 重写QObject::event():在对象级别处理事件,可以接收到如Tab键按下等特定事件 6。
  • 在特定对象上安装事件过滤器:这是最常用、最灵活的方式,可以针对性地过滤某个对象的事件 8。

这种分层、灵活的事件处理机制是Qt强大功能的基础。它不仅仅是一个简单的应用容器,更是整个Qt异步、事件驱动编程范式的底层引擎。Qt的核心特性——信号与槽机制,特别是跨线程的QueuedConnection连接类型,其实现就深度依赖于事件循环。当一个跨线程信号被触发时,Qt会创建一个QMetaCallEvent事件并将其放入接收者线程的事件队列中,由该线程的事件循环取出并执行对应的槽函数。同样,QTimer的定时触发、QTcpSocket等网络类的异步readyRead()信号,都是通过事件循环监听并分发底层操作系统事件来实现的。没有QCoreApplication提供的事件循环,Qt将退化为一个普通的同步类库,其核心优势将不复存在。

1.3 应用程序生命周期与环境管理

QCoreApplication负责管理应用程序从启动到退出的整个生命周期,并提供访问环境信息的能力。

  • 生命周期管理:静态函数startingUp()和closingDown()可用于判断应用程序是否正处于启动或关闭阶段 。 aboutToQuit()信号在事件循环即将退出、应用程序关闭前发射,这是执行保存数据、释放资源等清理工作的理想时机。
  • 环境与命令行:其构造函数接收main函数传入的argc和argv,用于解析Qt自身能识别的命令行参数(如-qmljsdebugger),并将剩余参数通过arguments()函数提供给开发者使用。
  • 应用元数据:通过setOrganizationName(), setOrganizationDomain(), setApplicationName(), 和setApplicationVersion()等函数设置的元数据,会被QSettings等类用作默认路径来存储和读取配置文件,从而实现跨平台的、标准化的配置管理。
  • 路径管理:applicationDirPath()返回可执行文件所在的目录路径,applicationFilePath()返回包含文件名的完整路径 。 libraryPaths()相关函数则用于管理动态库和插件的搜索路径,对构建可扩展的应用程序至关重要。

1.4 国际化与翻译支持

QCoreApplication在框架的最底层提供了国际化支持。通过installTranslator()函数可以加载一个或多个QTranslator翻译文件(通常是.qm文件)。加载后,使用QObject::tr()或QCoreApplication::translate()包裹的字符串将自动被查找并替换为当前语言环境对应的译文 1。这意味着即使是无GUI的控制台应用程序,其输出的提示信息、错误报告等也可以被轻松地翻译成多种语言,这充分体现了Qt框架设计的全面性和专业性。

1.5 架构应用场景分析

QCoreApplication的存在是Qt框架分层设计和依赖最小化原则的直接体现。一个纯粹的非GUI应用只需要链接Qt::Core库,这极大地减小了最终生成的可执行文件的体积和运行时内存占用,对于资源受限的嵌入式系统或追求极致性能的服务器应用至关重要 1。它允许开发者根据实际需求“按需付费”,只引入必要的模块,避免了不必要的开销。

其典型的应用场景包括:

  • 控制台工具:需要解析命令行参数、执行文件I/O、网络通信或复杂计算的命令行程序 2。
  • 后台服务与守护进程:作为服务器应用或系统服务长期运行,通过网络、定时器或系统信号等事件驱动,无需任何图形界面 5。
  • 无GUI的嵌入式与物联网(IoT)设备:在这些设备上,程序可能仅负责数据采集、处理和通信,完全不需要图形化交互。
  • 自动化测试脚本:用于驱动Qt应用程序进行单元测试或集成测试的后端逻辑,模拟事件和验证结果 9。

第二章:通往图形界面的桥梁——QGuiApplication

2.1 继承与扩展:从核心到图形

QGuiApplication是连接底层核心功能与上层视觉呈现的“中间件”。它继承自QCoreApplication,位于gui模块,因此它包含了QCoreApplication的所有功能,并在此基础上进行了扩展 4。其核心任务是增加处理窗口系统、屏幕、输入设备以及其他GUI相关的功能,但关键在于,这些功能是通用的,与具体的UI控件库(如QWidget)无关 3。它抽象了不同操作系统(如Windows, macOS, Linux/X11/Wayland)在窗口管理和事件处理上的差异,为上层应用提供了一套统一、跨平台的API。

QGuiApplication的出现是Qt框架的一次重大架构演进。在Qt 5之前,所有GUI功能都强耦合在QApplication和QWidget体系中。为了引入一种全新的、基于场景图和GPU加速的UI技术(即Qt Quick),Qt需要一个不依赖于传统QWidget绘制模型的GUI基础层。QGuiApplication的诞生正是为了这个目的,它将通用的GUI能力从QWidget的特定实现中剥离出来,形成了一个独立的gui模块。这不仅是一种技术实现,更是一种战略决策,标志着Qt从一个以桌面QWidget为中心的框架,转变为一个能够同时支持传统UI和现代(移动、嵌入式)UI的、更具平台无关性的多元化框架。

2.2 窗口系统集成与抽象

QGuiApplication通过QWindow类实现了对原生窗口的轻量级、直接的控制。与重量级的QWidget不同,QWindow是原生窗口句柄的一个薄封装。这种设计为需要极致性能或与第三方图形库深度集成的应用提供了可能性,代表了从“控件”为中心到以“窗口”为中心的GUI编程模型的转变,更符合现代GPU驱动的渲染管线。

其主要功能包括:

  • 屏幕管理:screens()静态方法返回一个QScreen对象列表,代表所有可用的物理屏幕;primaryScreen()则返回主屏幕 10。通过连接
    screenAdded、screenRemoved和primaryScreenChanged等信号,应用程序可以动态地响应显示设备的插拔或主屏幕的变更 10。
  • 窗口管理:allWindows()和topLevelWindows()返回应用程序中所有QWindow实例的列表 10。
    topLevelAt()可以根据屏幕坐标获取该位置最上层的窗口。
  • 平台交互:platformName()返回当前所使用的平台插件名称(如"windows", “cocoa”, “wayland”),便于进行平台相关的特殊处理 10。
    nativeInterface()则提供了访问更底层平台原生句柄(如HWND)的接口,用于与原生API进行深度交互 10。
  • 剪贴板访问:提供静态方法clipboard(),返回一个指向系统剪贴板QClipboard的指针,用于进行复制粘贴操作 10。

2.3 图形化事件处理模型

在继承了QCoreApplication的事件循环基础上,QGuiApplication扩展了事件处理能力,使其能够理解和分发来自窗口系统的图形化事件 12。

  • 焦点管理:focusWindow()返回当前拥有键盘焦点的QWindow,focusObject()返回拥有焦点的QObject。当焦点在不同窗口或对象间切换时,会分别发射focusWindowChanged和focusObjectChanged信号 10。
  • 应用状态:applicationState()返回应用的当前状态(如Qt::ApplicationActive, Qt::ApplicationInactive),并在状态变化时发射applicationStateChanged信号 10。这在移动应用开发中至关重要,例如,当应用切换到后台时,可以暂停CPU密集型任务或保存当前状态。
  • 输入状态查询:提供了一系列静态方法来随时查询全局输入状态,如keyboardModifiers()查询Shift、Ctrl等修饰键是否被按下,mouseButtons()查询鼠标按键状态 10。

2.4 全局GUI环境配置

QGuiApplication在应用程序启动时,会查询并初始化用户的桌面设置,确保应用的观感与系统环境保持一致。

  • 全局视觉属性:它管理着应用的默认字体font()、调色板palette()和风格提示styleHints() 11。开发者也可以通过setFont()、setPalette()等静态方法来全局覆盖这些设置。
  • 图标与光标:setWindowIcon()用于设置所有窗口的默认图标。setOverrideCursor()则可以临时改变整个应用程序的光标形状,常用于表示程序正忙等状态 11。
  • 会话管理:提供了复杂的会话管理支持,允许应用程序在用户注销或系统关闭时,通过commitDataRequest和saveStateRequest信号优雅地保存状态,甚至可以取消关机过程 10。

2.5 架构应用场景分析

由于QGuiApplication提供了QWidget无关的GUI基础能力,它的主要应用场景是那些不使用传统QWidget控件的现代化UI项目。

  • Qt Quick/QML应用:这是QGuiApplication最核心的应用场景。QQmlApplicationEngine或QQuickView在内部获取QGuiApplication的单例,并利用其创建和管理用于渲染QML场景的QQuickWindow 14。
  • 纯OpenGL/Vulkan应用:开发者可以直接使用QOpenGLWindow或QVulkanWindow进行高性能的2D/3D图形渲染,而无需引入整个QWidget模块的开销。
  • 无窗口的图形处理:在服务器端,可以利用QOffscreenSurface和QOpenGLContext进行离屏渲染,用于生成图像、视频流或进行GPU加速计算,而无需创建任何可见窗口。

第三章:经典桌面范式——QApplication的Widget世界

3.1 针对Widgets模块的特化

QApplication是Qt经典桌面UI开发的基石。它继承自QGuiApplication,位于widgets模块,是专门为基于QWidget的应用程序设计的 4。它在QGuiApplication提供的通用GUI能力之上,添加了管理和协调大量QWidget实例所需的一切基础设施,并处理QWidget特有的初始化和终结化逻辑 17。如果说QGuiApplication是为所有GUI应用铺设的“高速公路”,那么QApplication就是为QWidget这辆“经典轿车”修建的专属匝道和服务区。

3.2 以Widget为中心的管理体系

QApplication提供了大量静态方法,用于在整个应用程序范围内查询和管理QWidget实例,形成了一个以Widget为中心的管理体系。

  • 全局查询:allWidgets()和topLevelWidgets()分别返回应用程序中所有QWidget和所有顶级窗口QWidget的列表 17。
  • 焦点与活动状态:focusWidget()返回当前拥有键盘焦点的QWidget;activeWindow()返回用户当前正在交互的窗口 17。
    activeModalWidget()和activePopupWidget()则用于查询活动的模态对话框和弹出菜单,这对于管理复杂的UI交互流程至关重要 17。
  • 空间定位:widgetAt()可以根据屏幕的绝对坐标或某个QWidget的相对坐标,精确地找到该位置下的QWidget实例 17。
  • 生命周期控制:closeAllWindows()可以方便地关闭所有顶级窗口。如果quitOnLastWindowClosed属性为真(默认值),最后一个窗口的关闭将自动触发应用程序的退出 17。

QApplication不仅仅是QWidget的容器,更是整个QWidget框架得以协同工作的核心。它通过管理QStyle、分发事件和应用样式,确保了所有QWidget在视觉和行为上的一致性和整体性。例如,QWidget的绘制是基于QPainter的,但按钮的具体形状、滚动条的外观等都由QStyle决定,而QApplication正是QStyle的管理者 17。所有发往QWidget的事件,都必须先经过QApplication::notify(),由它负责将事件正确地路由到目标QWidget并沿着父子链传播。

3.3 样式与主题系统

QApplication引入了强大的样式和主题系统,使得QWidget应用的外观可以被深度定制。

  • QStyle系统:QApplication定义了应用程序的整体“观感”(look and feel),这被封装在一个QStyle对象中。通过setStyle()静态方法,可以在运行时动态切换应用的整体风格,例如从"windows"风格切换到"fusion"风格,从而改变所有控件的默认外观 17。
  • 全局样式表:setStyleSheet()方法允许使用类似Web中CSS的语法,为整个应用程序或特定类型的控件设置全局样式表 18。这极大地简化了UI的个性化定制,是Qt QWidget最受欢迎的特性之一。
  • 颜色规格:setColorSpec()用于控制应用程序在颜色数量受限的环境下(如8位色显示器)的颜色分配策略,确保UI在各种显示设备上都能正确渲染 19。

3.4 Widget专属行为与设置

QApplication引入了许多影响QWidget交互细节的属性,这些属性的管理体现了QWidget框架作为传统桌面UI解决方案的成熟度。它不仅仅是绘制控件,更深入地考虑了人机交互的细微之处。这些属性通常会读取并遵循操作系统的原生用户体验设置(如Windows控制面板中的鼠标设置),从而确保Qt QWidget应用在不同平台上的行为尽可能地“原生”,符合用户的操作习惯。

  • 鼠标交互:doubleClickInterval属性定义了系统识别为双击的最大时间间隔。startDragDistance和startDragTime则定义了启动拖放操作所需的最小鼠标移动距离和按键持续时间 18。
  • 键盘交互:cursorFlashTime控制文本输入框中光标的闪烁速率。keyboardInputInterval用于区分单次按键和因长按产生的连续按键。
  • 滚动行为:wheelScrollLines定义了鼠标滚轮滚动一格时,滚动视图应该滚动的行数。

3.5 架构应用场景分析

QApplication是所有基于QWidget模块开发应用程序的必然选择。

  • 传统桌面应用程序:几乎所有使用QMainWindow、QDialog、QPushButton等标准QWidget控件构建的桌面软件,如文本编辑器、文件管理器、媒体播放器等。
  • 复杂数据密集型UI:例如CAD软件、集成开发环境(IDE)、金融交易终端等。这些应用受益于QWidget成熟、强大且性能稳定的布局管理系统和丰富的控件集。
  • 迁移旧版本Qt项目:从Qt 4或更早版本迁移而来的项目,几乎都是基于QWidget的,因此必须使用QApplication 15。

第四章:综合对比与架构选型指南

4.1 功能特性对比矩阵

为了直观地展示QCoreApplication, QGuiApplication, 和QApplication之间的差异与联系,下表从多个维度对它们的功能特性进行了总结。

特性/功能 QCoreApplication QGuiApplication QApplication
所属模块 Core 1 Gui 10 Widgets 15
事件循环 ✓ (核心功能) 2 ✓ (继承) ✓ (继承)
信号/槽 ✓ (来自QObject) ✓ (继承) ✓ (继承)
命令行解析 ✓ 5 ✓ (继承) ✓ (继承,并增加-style等) 24
国际化 ✓ 5 ✓ (继承) ✓ (继承)
窗口管理 (QWindow) ✓ (核心功能) 10 ✓ (继承)
屏幕管理 (QScreen) ✓ 10 ✓ (继承)
GUI事件处理 ✓ (鼠标, 键盘等) 12 ✓ (继承)
剪贴板 ✓ 10 ✓ (继承)
全局字体/调色板 ✓ 10 ✓ (继承并扩展) 17
QML/Qt Quick支持 ✓ (基础) 14 ✓ (可混合使用,但基础是QGuiApp)
QWidget管理 ✓ (核心功能) 17
QStyle系统 ✓ 17
全局样式表 ✓ 24
典型场景 控制台, 服务器 2 QML, OpenGL 3 传统桌面应用 17

4.2 决策框架:如何选择正确的应用类

选择哪个应用类,取决于项目的具体需求。以下决策流程可以帮助开发者做出正确的选择:

  1. 我的应用程序有图形用户界面(GUI)吗?
    • :如果应用程序是一个控制台工具、后台服务或任何不需要显示窗口的程序,那么**QCoreApplication**是唯一且正确的选择。它提供了最轻量级的核心功能。
    • :进入下一步。
  2. 我的GUI是基于QWidget还是基于QML/自定义渲染(如OpenGL)?
    • 基于QWidget:如果你的main.cpp中包含了<QtWidgets>头文件,或者使用了任何QWidget的子类(如QMainWindow, QPushButton),那么你必须使用**QApplication**。只有它提供了QWidget体系正常工作所需的支持。
    • 基于QML/自定义渲染:如果你的项目是使用QQmlApplicationEngine或QQuickView来加载QML文件,或者是直接使用QOpenGLWindow进行绘图,并且完全不使用任何QWidget控件,那么**QGuiApplication最佳选择**。它提供了必要的GUI基础服务,同时避免了加载不必要的QtWidgets模块。

4.3 高级议题:子类化与定制化

在某些复杂应用中,开发者可能会选择继承QApplication(或其基类)来创建自定义的应用类,以实现全局功能。

  • 优点:通过子类化,可以方便地为应用程序添加全局可访问的成员变量(如全局配置、数据库连接池)或方法。此外,通过重写notify()等虚函数,可以实现全局的事件拦截,例如实现一个全局快捷键系统或自定义事件分发逻辑 2。
  • 缺点:过度使用这种模式可能导致代码高度耦合,形成一个难以维护和测试的“上帝对象”(God Object)。在多数情况下,应优先考虑使用专门的单例服务类来管理全局状态,而不是直接污染应用对象本身 9。
  • 实践:一个常见的实践是,在子类化QApplication后,通过宏定义来创建一个方便访问子类实例的全局指针,从而简化代码 26。
// 示例:自定义Application类并提供便捷访问
class MyApplication : public QApplication {
    
      
    //... 自定义方法和成员
public:
    MyApplication(int &argc, char **argv) : QApplication(argc, argv) {
    
      }
    void customGlobalMethod() {
    
       /*... */ }
};

#define myApp (static_cast<MyApplication*>(QCoreApplication::instance()))

// 在代码其他地方使用:
// myApp->customGlobalMethod();

结论

QCoreApplication, QGuiApplication, 和 QApplication 并非三个孤立的类,而是一个精心设计的、功能渐进的架构体系。这个体系清晰地体现了软件设计中的分层与关注点分离原则:

  • QCoreApplication 构成了所有Qt应用共享的、与平台和UI无关的核心引擎,提供了事件循环和基础服务。
  • QGuiApplication 在核心之上,构建了一个平台无关的图形抽象层,负责与窗口系统交互,为所有类型的GUI应用(无论是QWidget还是QML)奠定基础。
  • QApplication 则是这个体系的顶层,为成熟且功能丰富的QWidget工具箱提供了最终的、特化的支持。

理解这个继承链和功能分层,是做出正确技术选型、构建可维护、高性能Qt应用的关键第一步。对于开发者而言,最终的建议是:选择恰好满足项目需求的、最“轻量”的基类。这不仅能减少应用的体积和资源消耗,更是遵循优秀软件工程实践的直接体现。

引用的著作
  1. QCoreApplication Class | Qt Core | Qt 6.9.2 - Qt Documentation, 访问时间为 九月 30, 2025, https://doc.qt.io/qt-6/qcoreapplication.html
  2. Qt 4.1: QCoreApplication Class Reference, 访问时间为 九月 30, 2025, https://spice.dmcs.p.lodz.pl/po/qt-tutorial/docs/qt/qcoreapplication.html
  3. Thread: QApplication, QGuiApplication and QCoreApplication - Qt Centre Forum, 访问时间为 九月 30, 2025, https://www.qtcentre.org/threads/60203-QApplication-QGuiApplication-and-QCoreApplication
  4. QT – QApplication QGuiApplication QCoreApplication 区别和联系- 手磨咖啡 - 博客园, 访问时间为 九月 30, 2025, https://www.cnblogs.com/zzzsj/p/14420025.html
  5. QCoreApplication Class | Qt Core 5.7 - MIT, 访问时间为 九月 30, 2025, https://stuff.mit.edu/afs/athena/software/texmaker_v5.0.2/qt57/doc/qtcore/qcoreapplication.html
  6. QCoreApplication Class Reference - Huihoo, 访问时间为 九月 30, 2025, https://docs.huihoo.com/pyqt/pyqt/html/qcoreapplication.html
  7. QCoreApplication Class Reference - CopperSpice API, 访问时间为 九月 30, 2025, https://www.copperspice.com/docs/cs_api/class_qcoreapplication.html
  8. Qt 4.8: QCoreApplication Class Reference - DreamSworK, 访问时间为 九月 30, 2025, https://dreamswork.github.io/qt4/classQCoreApplication.html
  9. Subclassing QApplication – yes or no? : r/pyqt - Reddit, 访问时间为 九月 30, 2025, https://www.reddit.com/r/pyqt/comments/k63yg7/subclassing_qapplication_yes_or_no/
  10. QGuiApplication Class | Qt GUI | Qt 6.9.2 - Qt Documentation, 访问时间为 九月 30, 2025, https://doc.qt.io/qt-6/qguiapplication.html
  11. QGuiApplication Class | Qt GUI 5.7, 访问时间为 九月 30, 2025, https://stuff.mit.edu/afs/athena/software/texmaker_v5.0.2/qt57/doc/qtgui/qguiapplication.html
  12. QGuiApplication Class - Qt 5.0 - Developpez.com, 访问时间为 九月 30, 2025, https://qt.developpez.com/doc/5.0-snapshot/qguiapplication/
  13. QGuiApplication - Qt for Python, 访问时间为 九月 30, 2025, https://doc.qt.io/qtforpython-6.5/PySide6/QtGui/QGuiApplication.html
  14. Qt: How does QGuiApplication and QQmlApplicationEngine interact? - Stack Overflow, 访问时间为 九月 30, 2025, https://stackoverflow.com/questions/39865039/qt-how-does-qguiapplication-and-qqmlapplicationengine-interact
  15. How to convert QGuiApplication to QApplication in QtCreator 10 with Qt 6? - Stack Overflow, 访问时间为 九月 30, 2025, https://stackoverflow.com/questions/76797967/how-to-convert-qguiapplication-to-qapplication-in-qtcreator-10-with-qt-6
  16. When to use what classes in Qt Quick 2 and how? - Stack Overflow, 访问时间为 九月 30, 2025, https://stackoverflow.com/questions/17936624/when-to-use-what-classes-in-qt-quick-2-and-how
  17. QApplication Class | Qt Widgets 5.15.1, 访问时间为 九月 30, 2025, https://qthub.com/static/doc/qt5/qtwidgets/qapplication.html
  18. PySide6.QtWidgets.QApplication - Qt for Python, 访问时间为 九月 30, 2025, https://doc.qt.io/qtforpython-6/PySide6/QtWidgets/QApplication.html
  19. Qt 5.0: QApplication Class - Developpez.com, 访问时间为 九月 30, 2025, https://qt.developpez.com/doc/5.0-snapshot/qapplication/
  20. QApplication Class Reference - CopperSpice API, 访问时间为 九月 30, 2025, https://www.copperspice.com/docs/cs_api/class_qapplication.html
  21. QApplication Class Reference, 访问时间为 九月 30, 2025, http://osr600doc.xinuos.com/en/SDK_qt3/qapplication.html
  22. Qt 4.4: QApplication Class Reference - GitHub Pages, 访问时间为 九月 30, 2025, https://radekp.github.io/qtmoko/api/qapplication.html
  23. PyQt5 - QApplication - GeeksforGeeks, 访问时间为 九月 30, 2025, https://www.geeksforgeeks.org/python/pyqt5-qapplication/
  24. QApplication Class | Qt Widgets | Qt 6.9.3 - Qt Documentation, 访问时间为 九月 30, 2025, https://doc.qt.io/qt-6/qapplication.html
  25. QApplication Class | Qt Widgets 5.7, 访问时间为 九月 30, 2025, https://stuff.mit.edu/afs/athena/software/texmaker_v5.0.2/qt57/doc/qtwidgets/qapplication.html
  26. Thread: Subclassing QApplication for global members and methods. - Qt Centre Forum, 访问时间为 九月 30, 2025, https://www.qtcentre.org/threads/61234-Subclassing-QApplication-for-global-members-and-methods