Qt C++ 开发实战:从环境搭建到跨平台部署的完整指南 在桌面应用开发领域C 以其卓越的性能和跨平台能力占据着重要地位而 Qt 框架则为 C 开发者提供了构建现代、美观 GUI 应用程序的强大工具集。然而许多开发者在入门时常被复杂的开发环境配置、信号槽机制的理解以及跨平台部署等问题困扰网上资料虽多却不成体系。本文将整合一套从零开始的 Qt 开发闭环实战方案内容涵盖环境搭建、核心机制解析、完整项目实战到打包发布并提供详尽的避坑指南。无论你是希望从零掌握 Qt 的 C 新手还是寻求项目落地最佳实践的进阶开发者都能从中获得可直接复用的代码与配置。1. Qt 与 C 开发背景与核心概念1.1 什么是 QtQt 是一个跨平台的 C 应用程序开发框架。它不仅仅是一个 GUI 工具包更是一个完整的“应用程序框架”提供了构建桌面、嵌入式及移动端应用所需的大量类库涵盖了图形用户界面、网络通信、数据库访问、多线程、XML/JSON 处理、多媒体等方方面面。通俗地讲你可以把 Qt 想象成一个功能极其丰富的“乐高积木套装”。使用 C 作为“胶水”你可以用 Qt 提供的各种“积木”类库快速搭建出功能强大、界面美观的应用程序并且同一套代码经过简单编译就能在 Windows、macOS、Linux 等多个操作系统上运行。1.2 Qt 的核心优势与常见应用场景核心优势真正的跨平台一次编写多处编译运行极大降低了多平台维护成本。丰富的组件库提供大量现成的 UI 控件按钮、表格、树视图等和非 GUI 功能模块。信号与槽机制一种强大且安全的对象间通信方式是 Qt 最核心的特性之一用于替代传统的回调函数降低了模块间的耦合度。优秀的开发工具Qt Creator IDE 集成了代码编辑、UI 设计、调试、翻译、帮助等功能极大提升了开发效率。良好的社区与商业支持拥有庞大的开源社区和成熟的商业授权选项。常见应用场景工业控制与嵌入式 HMI工厂上位机软件、设备控制面板。汽车信息娱乐系统车载中控屏应用。专业软件如 WPS Office、VirtualBox、Autodesk Maya 的部分模块。科学计算与数据可视化需要高性能和复杂交互界面的科研软件。日常工具软件如下载工具、媒体播放器、文本编辑器等。1.3 Qt 与 MFC、WPF 等框架的简单对比经常有初学者问“Qt 是不是 MFC 架构”。这是一个常见的误解。MFC (Microsoft Foundation Classes)是微软为 Windows 平台提供的 C 类库紧密绑定 Windows API是 Windows 原生开发框架不具备跨平台能力。其架构和编程模式与 Qt 有本质不同。WPF (Windows Presentation Foundation)是微软基于 .NET 的桌面应用程序框架使用 XAML 进行界面声明主要语言是 C#。它与 Qt 属于不同技术栈.NET vs C。Qt是独立的、跨平台的 C 框架。它使用自己的渲染和事件处理机制不依赖于特定操作系统的原生控件尽管可以启用原生风格。其“信号与槽”机制是其区别于 MFC 消息映射和 .NET 事件模型的核心特征。简单来说Qt 是一个独立、现代、跨平台的解决方案而 MFC 是一个较老的、仅限 Windows 的解决方案。2. 环境准备与版本说明在开始编码之前一个正确且稳定的开发环境是成功的基石。本节将详细介绍如何搭建 Qt 开发环境。2.1 操作系统与编译器选择Qt 支持主流的桌面操作系统。你需要准备操作系统Windows 10/11, macOS, 或主流的 Linux 发行版如 Ubuntu, Fedora。编译器Windows: 推荐使用 MinGW 或 MSVC。MinGW 是 GNU 工具链的 Windows 端口开源免费MSVC 是微软的编译器与 Visual Studio 集成度更高。macOS: 使用 Xcode 附带的 Clang。Linux: 使用系统自带的 GCC。注意Qt 库的版本需要与编译器版本匹配。官方安装包通常已捆绑兼容的编译器。2.2 安装 Qt 开发套件我们以Windows 平台使用Qt 6.5和MinGW编译器为例进行说明。这是目前新手入门最通用的组合。下载 Qt 在线安装器 访问 Qt 官网下载 Qt 在线安装程序。对于个人学习和开源项目可以选择开源版本。运行安装器并登录/注册 运行安装程序使用 Qt 账号登录。如果没有需要注册一个。选择安装组件关键步骤 在组件选择页面展开Qt- 选择最新的稳定版本例如Qt 6.5.3。在Qt 6.5.3下必须勾选MinGW 11.2.0 64-bit。这个就是编译器工具链。勾选Qt Creator 11.0.2 (Latest release)。这是 Qt 的官方 IDE强烈建议安装。为了教程完整性可以勾选SourcesQt源码便于调试和Qt Debug Information Files。对于初学者Additional Libraries下的模块可以先不选后续有需要再通过安装器添加。特别注意如果你之前安装过 Visual Studio 并打算使用 MSVC请勾选对应的MSVC 2019 64-bit等组件。不要同时为同一个 Qt 版本安装多个编译器以免混淆。设置安装路径 建议安装到没有中文和空格的路径例如C:\Qt。完成安装 等待安装完成这个过程可能会比较长因为需要下载数 GB 的文件。2.3 验证安装与环境变量安装完成后从开始菜单打开Qt Creator。检查工具链 打开 Qt Creator进入工具-选项-Kits。 你应该能看到一个自动检测到的Desktop Qt 6.5.3 MinGW 64-bit套件Kit。套件包含了 Qt 版本、编译器和调试器。状态应为“有效”。可选配置系统环境变量 虽然 Qt Creator 能自动管理但为了能在命令行如 CMD 或 PowerShell中使用qmake,mingw32-make等工具可以将以下路径添加到系统的PATH环境变量中C:\Qt\6.5.3\mingw_64\bin(Qt 工具如 qmake)C:\Qt\Tools\mingw1120_64\bin(MinGW 编译器工具链) 添加后打开新的命令行窗口输入qmake --version和g --version应能显示版本信息。版本说明本文示例基于 Qt 6.5.3 和 MinGW 11.2.0。不同小版本之间 API 变化不大核心概念完全通用。如果你的项目需要特定版本请根据实际情况调整。3. Qt 核心机制深度解析理解 Qt 的核心机制是高效开发的关键。本节将深入讲解两个最重要的概念元对象系统Meta-Object System与信号槽Signals Slots以及对象模型与内存管理。3.1 元对象系统与信号槽机制原理这是 Qt 区别于标准 C 的“魔法”所在。元对象系统 (Meta-Object System) Qt 通过扩展 C提供了一套用于对象内省introspection和动态属性系统的机制。任何使用了Q_OBJECT宏的类都会由 Qt 的元对象编译器moc在编译前处理生成额外的元对象代码。这使得在运行时可以查询对象的类名、属性、方法以及信号和槽。信号与槽 (Signals Slots) 这是一种用于对象间通信的松耦合机制。信号 (Signal)由对象在某种事件发生时“发出”emit。信号只有声明没有定义。它是一个函数签名。槽 (Slot)是普通的 C 成员函数可以被调用。它可以接收信号传来的参数。连接 (Connect)使用QObject::connect()函数将某个对象的信号与另一个对象或自身的槽关联起来。当信号发出时被连接的槽函数会自动被调用。工作原理当你编写一个包含signals:和slots:的类并在类声明开头添加Q_OBJECT宏后moc工具会预处理这个头文件。moc会生成一个moc_*.cpp文件其中包含了信号发射和槽调用的“胶水”代码以及元对象信息。在connect时Qt 利用元对象系统建立信号与槽的映射关系。当emit signal()被调用时Qt 运行时查找所有与该信号连接的槽并依次调用它们。示例一个简单的连接// myclass.h #include QObject class MyClass : public QObject { Q_OBJECT // 必须添加此宏 public: explicit MyClass(QObject *parent nullptr); signals: void valueChanged(int newValue); // 信号声明 public slots: void setValue(int value); // 槽声明 private: int m_value; }; // myclass.cpp #include myclass.h MyClass::MyClass(QObject *parent) : QObject(parent), m_value(0) {} void MyClass::setValue(int value) { if (value ! m_value) { m_value value; emit valueChanged(m_value); // 发出信号 } } // main.cpp 中使用 #include QCoreApplication #include myclass.h #include QDebug int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); MyClass sender, receiver; // 连接信号与槽 QObject::connect(sender, MyClass::valueChanged, receiver, MyClass::setValue); sender.setValue(10); // 这会触发 receiver.setValue(10); qDebug() Connection established.; return a.exec(); }优势类型安全编译时检查信号和槽的签名是否兼容。松耦合发送者不知道也不关心接收者是谁。支持多对多一个信号可以连接多个槽一个槽也可以接收多个信号。3.2 Qt 对象模型与内存管理Qt 在 C 的基础上引入了一套基于对象树的所有权模型以简化内存管理。父子关系 (Parent-Child Relationship)当创建一个QObject或其子类如QWidget时可以为其指定一个父对象parent。父对象拥有owns其所有子对象。当父对象被销毁时它会自动销毁其所有子对象。这通过QObject的构造函数中的parent参数来建立。QWidget *window new QWidget; // 顶层窗口没有父对象 QPushButton *button new QPushButton(Click me, window); // button 的父对象是 window // 当 delete window; 被调用时button 也会被自动删除。内存管理建议在栈上创建对象对于生命周期明确的局部对象如短时间存在的对话框可以在栈上创建退出作用域时自动析构。但要注意Qt 窗口部件通常需要exec()进入事件循环栈上对象可能过早销毁。在堆上创建并指定父对象这是 Qt 中最常见的方式。将 UI 控件的父对象设置为窗口这样你只需要管理顶层窗口的内存子控件会自动清理。使用智能指针对于没有天然父子关系的对象或者需要更灵活生命周期的对象可以使用std::unique_ptr或std::shared_ptr进行管理。Qt 5 以后与标准库智能指针兼容良好。避免手动delete如果对象已加入 Qt 的对象树即有父对象通常不应手动delete它除非你先将其父对象设置为nullptr。4. 第一个 Qt 应用程序从创建到发布让我们通过一个完整的“Hello Qt”项目串联起开发的全流程。4.1 创建新项目打开 Qt Creator点击文件-新建文件或项目。选择Application-Qt Widgets Application点击Choose...。设置项目名称如HelloQt和创建路径。路径不要包含中文或空格。在Kit Selection页面选择我们之前配置好的Desktop Qt 6.5.3 MinGW 64-bit套件。在类信息页面基类选择QMainWindow类名保持MainWindow。这将生成一个带菜单栏、工具栏和状态栏的主窗口。点击完成Qt Creator 会自动生成项目文件。4.2 项目结构解析生成的项目包含以下关键文件HelloQt.proQt 的项目文件类似于 CMakeLists.txt定义了项目源文件、头文件、依赖模块等。main.cpp程序入口。mainwindow.h/mainwindow.cpp主窗口类的声明和定义。mainwindow.ui主窗口的 UI 设计文件XML格式可以通过 Qt Designer 可视化编辑。4.3 编写与设计 UI方法一使用 Qt Designer可视化设计在 Qt Creator 左侧项目树中双击mainwindow.ui文件。左侧的Widget Box中包含了各种控件按钮、标签、输入框等。将一个Label标签和一个Push Button按钮拖拽到中间的窗口设计区。选中标签在右侧Property Editor中找到text属性将其修改为Hello, World!。你可以调整字体、大小等属性。选中按钮将其text属性修改为Click Me。保存文件。Qt Creator 会自动将.ui文件编译成对应的 C 头文件ui_mainwindow.h并在MainWindow类中生成一个ui指针来访问这些控件。方法二纯代码创建 UI打开mainwindow.cpp在构造函数中编写代码创建控件#include mainwindow.h #include QLabel #include QPushButton #include QVBoxLayout // 布局管理器 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { // 创建一个中心部件 QWidget *centralWidget new QWidget(this); this-setCentralWidget(centralWidget); // 创建标签和按钮 QLabel *label new QLabel(Hello, World!, centralWidget); QPushButton *button new QPushButton(Click Me, centralWidget); // 创建一个垂直布局并添加控件 QVBoxLayout *layout new QVBoxLayout(centralWidget); layout-addWidget(label); layout-addWidget(button); // 连接按钮的点击信号到一个自定义槽 connect(button, QPushButton::clicked, this, MainWindow::onButtonClicked); } // 在 mainwindow.h 中声明槽函数 // private slots: void onButtonClicked(); void MainWindow::onButtonClicked() { qDebug() Button clicked!; // 例如可以修改标签文字 // 如果通过代码创建需要将 label 定义为成员变量才能访问 // label-setText(Button Clicked!); }4.4 构建与运行点击 Qt Creator 左下角的绿色三角形运行按钮或者按CtrlR。Qt Creator 会依次执行qmake生成 Makefile、make编译链接步骤。如果一切顺利应用程序窗口将会弹出。4.5 打包发布以 Windows 为例开发完成后你需要将程序分发给没有 Qt 开发环境的用户。这需要将程序依赖的 Qt 库一起打包。构建 Release 版本在 Qt Creator 左下角将构建套件从Debug切换为Release。点击构建-重新构建项目。这将在release文件夹生成优化后的可执行文件如HelloQt.exe。使用windeployqt工具收集依赖windeployqt是 Qt 自带的部署工具能自动找到可执行文件所需的 Qt 动态库。打开开始菜单找到Qt 6.5.3 (MinGW 11.2.0 64-bit)-Qt 6.5.3 (MinGW 11.2.0 64-bit) Command Prompt。这是一个已经配置好 Qt 环境变量的命令行。使用cd命令导航到你的HelloQt.exe所在的release目录。执行命令windeployqt HelloQt.exe工具会自动将所需的Qt6Core.dll,Qt6Gui.dll,Qt6Widgets.dll等文件以及platforms,styles等文件夹复制到当前目录。测试与打包在文件管理器中直接双击release目录下的HelloQt.exe看是否能独立运行。将整个release目录包含 exe 和所有 dll 及子文件夹压缩即可分发给用户。注意对于更复杂的项目可能还需要手动添加插件如图像格式插件qjpeg.dll或第三方库。windeployqt的--qmldir参数可用于部署 QML 项目。5. 常见问题与深度排查指南Qt 开发过程中会遇到各种问题以下是一些典型问题的排查思路。5.1 编译与构建问题问题现象常见原因解决思路cannot find -lGL错误 (Linux)系统缺少 OpenGL 开发库。安装对应开发包Ubuntu/Debian:sudo apt install libgl1-mesa-devundefined reference to vtable for ...类声明了Q_OBJECT宏但未重新运行qmake/moc。1. 清理项目 (构建-清理项目)。2. 重新运行qmake(构建-执行 qmake)。3. 重新构建。No such slot或信号槽连接无效1. 槽函数未在类声明的slots:区域声明。2. 连接使用了错误的签名参数类型不匹配。3. 忘记在类中添加Q_OBJECT宏。1. 检查类声明确保槽函数在public/protected/private slots:下。2. 使用 Qt 5 的新语法connect(sender, Sender::signal, receiver, Receiver::slot)以获得编译时检查。3. 确保类头文件包含Q_OBJECT。程序崩溃错误涉及moc_文件元对象系统相关通常是头文件修改后未重新生成 moc 文件。执行构建-清理-执行 qmake-重新构建完整流程。5.2 运行时问题问题现象常见原因解决思路This application failed to start because no Qt platform plugin could be initialized发布程序时platforms文件夹缺失或其中的插件如qwindows.dll缺失。确保windeployqt已正确运行且可执行文件同级目录下存在platforms文件夹且里面有qwindows.dll(Windows)。可手动从Qt安装目录/plugins/platforms复制。Qt Creator 调试输出中文乱码源代码文件编码、编译器编码与控制台编码不一致。1.统一编码为 UTF-8在 Qt Creator工具-选项-文本编辑器-行为设置默认编码为 UTF-8。确保源代码文件保存为 UTF-8。2. 对于 Windows 控制台可在main函数开头添加#include QTextCodecQTextCodec::setCodecForLocale(QTextCodec::codecForName(UTF-8));(Qt5)Qt6 中QTextCodec移到了核心附加模块更推荐使用QString和QTextStream处理文本并注意文件读写时指定编码。界面布局错乱或控件显示不全未正确使用布局管理器Layout或窗口大小固定。1. 尽量使用布局管理器QHBoxLayout,QVBoxLayout,QGridLayout来排列控件而不是设置绝对坐标。2. 为顶层窗口设置一个中心部件和布局。3. 使用sizePolicy和sizeHint控制控件的尺寸策略。程序无响应界面卡死在 GUI 线程主线程中执行了耗时的操作如大文件读写、复杂计算、网络请求。1. 将耗时操作移到工作线程QThread中执行。2. 使用QtConcurrent进行并发计算。3. 在循环中调用QCoreApplication::processEvents()以保持界面响应慎用非最佳实践。5.3 环境与配置问题如何彻底卸载 Qt除了卸载程序还需手动删除安装目录如C:\Qt和用户目录下的配置文件如C:\Users\用户名\AppData\Roaming\QtProject。多个 Qt 版本/编译器如何管理在 Qt Creator 的工具-选项-Kits中可以添加、删除或禁用不同的套件。创建项目时选择正确的套件即可。Microsoft Visual C Redistributable是什么当使用 MSVC 编译器编译 Qt 程序时目标机器需要安装对应版本的 VC 运行库才能运行程序。MinGW 编译的程序则通常不需要。6. Qt 开发最佳实践与工程建议掌握基础后遵循良好的实践能提升代码质量、可维护性和开发效率。6.1 代码组织与架构合理划分模块将不同的功能模块放入不同的类中。例如数据逻辑、业务逻辑、界面展示应尽可能分离。可以考虑使用 MVC 或类似模式。使用智能指针管理资源对于非 QObject 的资源如动态数组、文件句柄或没有明确父子关系的 QObject使用std::unique_ptr或QScopedPointer来管理生命周期避免内存泄漏。善用设计模式Qt 本身大量使用了观察者模式信号槽、工厂模式等。在项目中合理应用单例模式、策略模式等可以改善架构。使用.pri文件对于大型项目可以将子模块的配置提取到.pri(include) 文件中然后在主.pro文件中include使项目文件更清晰。6.2 UI 设计与布局始终使用布局管理器这是实现自适应窗口大小的唯一可靠方法。避免使用setGeometry固定控件位置。使用 Qt Designer 提高效率对于复杂的静态界面使用 Designer 拖拽布局比纯代码更高效。可以使用提升为...功能来使用自定义控件。样式表 (QSS) 的使用使用 Qt 样式表可以轻松定制应用程序外观类似于 CSS。但要注意性能过度复杂的 QSS 会影响界面渲染速度。国际化 (i18n) 提前规划如果应用需要支持多语言使用tr()函数包裹所有用户可见的字符串并使用 Qt Linguist 工具管理翻译文件。6.3 性能与调试减少信号槽的过度连接不必要的连接会增加开销。对于高频信号如滑块拖动考虑使用QTimer进行节流或防抖。高效使用模型/视图框架对于大量数据的展示务必使用QAbstractItemModel及其子类配合QTableView、QListView等视图。自定义模型时正确实现data()和roleNames()等方法。使用 Qt 的调试输出善用qDebug(),qWarning(),qCritical()进行分级日志输出。在发布版本中可以通过定义QT_NO_DEBUG_OUTPUT宏来关闭qDebug输出。利用 Qt Creator 的强大调试器熟练使用断点、观察变量、调用栈、条件断点等功能。对于多线程调试Thread视图非常有用。6.4 跨平台注意事项路径分隔符使用QDir::separator()或/Qt 会内部转换避免直接使用\。文件系统大小写Linux/macOS 文件系统区分大小写Windows 不区分。确保代码中引用文件名的大小写与实际文件一致。平台特定代码如果必须使用平台相关功能使用预定义宏进行隔离#ifdef Q_OS_WIN // Windows 特有代码 #elif defined(Q_OS_MACOS) // macOS 特有代码 #elif defined(Q_OS_LINUX) // Linux 特有代码 #endif字体与外观不同平台的默认字体和控件风格可能不同。进行充分的跨平台测试必要时使用样式表统一外观。6.5 项目配置管理 (*.pro文件).pro文件是 Qt 项目的核心配置文件理解其语法很重要。# 指定模板类型app(应用程序), lib(库), subdirs(多级目录) TEMPLATE app # 指定目标语言 LANGUAGE C # 指定Qt模块 QT core gui widgets # Qt6中widgets模块需要显式添加 # 对于Qt5兼容性可能需要添加 network, sql 等 # QT network sql # 指定目标文件名 TARGET MyApp # 指定构建目录 DESTDIR $$PWD/build # 指定源文件、头文件、界面文件 SOURCES main.cpp \ mainwindow.cpp HEADERS mainwindow.h FORMS mainwindow.ui # 配置选项 CONFIG c17 # 使用C17标准 CONFIG warn_on # 开启警告 # CONFIG release # 发布模式 # CONFIG debug_and_release # 同时生成debug和release版本 # 定义预处理器宏 DEFINES MYAPP_VERSION\\\1.0.0\\\ # 包含第三方库 # win32: LIBS -L$$PWD/thirdparty/lib -lmylib # unix: LIBS -L$$PWD/thirdparty/lib -lmylib # INCLUDEPATH $$PWD/thirdparty/include # 引入子项目 # TEMPLATE subdirs # SUBDIRS subproject1 \ # subproject2遵循这些实践你的 Qt 项目将更加健壮、易于维护并能更好地应对跨平台开发的挑战。从环境搭建到核心机制从第一个程序到打包发布再到深入的问题排查与最佳实践这套完整的知识体系是构建复杂 Qt 应用的坚实基础。接下来你可以探索更高级的主题如 Qt Quick/QML 进行声明式 UI 开发、网络编程QNetworkAccessManager、数据库QSql模块、多线程QThread,QtConcurrent以及绘制QPainter等逐步将 Qt 的强大功能应用到你的实际项目中去。

相关新闻

最新新闻

信息化集成化机能实验信号采集系统,生物信号采集处理系统

信息化集成化机能实验信号采集系统,生物信号采集处理系统

MedLab-FEA集成化一体机生物信号采集处理系统采用一体化设计原则,同时集成了可移动实验平台、生物采集系统、呼吸系统、测温系统、照明系统以及同步演示系统。实验数据、报告处理无纸化,协助教师进行实验信息化管理。帮助科研工作者获取更客观、全面的实…

2026/8/22 1:28:50
小说下载器新手指南:4 步把整本网页小说存进硬盘

小说下载器新手指南:4 步把整本网页小说存进硬盘

小说下载器新手指南:4 步把整本网页小说存进硬盘 【免费下载链接】novel-downloader 一个可扩展的通用型小说下载器。 项目地址: https://gitcode.com/gh_mirrors/no/novel-downloader 你正在重读几年前追完的一本老网页小说,点开收藏夹里的链接&…

2026/8/22 1:28:50
蔚蓝档案鼠标指针主题 3 步装好,免费开源

蔚蓝档案鼠标指针主题 3 步装好,免费开源

蔚蓝档案鼠标指针主题 3 步装好,免费开源 【免费下载链接】BlueArchive-Cursors Custom mouse cursor theme based on the school RPG Blue Archive. 项目地址: https://gitcode.com/gh_mirrors/bl/BlueArchive-Cursors 还在用 Windows 系统默认光标&#xf…

2026/8/22 1:28:50
高等工程数学第七章习题解析与常见误区

高等工程数学第七章习题解析与常见误区

我无法根据当前输入生成符合要求的博文。 原因如下: 项目标题为“高等工程数学张韵华版第七章课后题”,属于教材习题解析类内容,本质是学术辅导场景; 但项目正文、关键词、摘要描述全部为空,且未提供任何具体题目、…

2026/8/22 1:28:50
网络工程师面试高频技术问题解析与实战指南

网络工程师面试高频技术问题解析与实战指南

1. 网工面试技术问题全景解析作为网络工程师职业发展的重要关卡,技术面试往往聚焦于基础理论、设备配置和故障排查三大核心能力域。根据近三年一线厂商和集成商的真实面试反馈,我将从协议原理、设备操作、场景设计三个维度拆解高频考点。1.1 协议原理类问…

2026/8/22 1:28:50
从春运临客到高并发架构:资源超卖与服务降级的工程实践

从春运临客到高并发架构:资源超卖与服务降级的工程实践

凌晨三点,我站在北京站的月台上,看着眼前这列绿皮车,心里只有一个念头:这趟旅程,恐怕和我想象的不太一样。车次是T4162,一趟春运期间加开的临客。票面上印着“软卧代软座”,一个听起来有点矛盾、…

2026/8/22 1:23:50