Qt二维码生成器项目开发教程 - 从零开始构建专业级QR码生成工具

项目概述

本项目是一个基于Qt框架开发的专业级二维码生成器,集成了开源的qrencode库,提供完整的QR码生成、预览、保存和分享功能。项目采用C++语言开发,使用Qt的信号槽机制实现界面交互,通过qrencode库实现高质量的二维码编码算法。
在这里插入图片描述

项目特点:

  • 🎨 现代化UI设计,支持自定义颜色和样式
  • 🔧 完整的参数配置(纠错级别、尺寸、边距)
  • 📱 实时预览功能
  • 💾 多种输出格式(保存图片、复制到剪贴板)
  • 🌍 多语言国际化支持(中文/英文)
  • 🛡️ 完善的错误处理和用户提示
  • 📊 进度条显示生成状态

源代码下载: https://download.csdn.net/download/weixin_42059464/91726317

技术栈

  • 开发语言: C++
  • GUI框架: Qt 5.9.9
  • 编译器: MinGW32
  • 第三方库: qrencode(QR码编码库)
  • 开发工具: Qt Creator
  • 操作系统: Windows 10
  • 国际化: Qt Linguist

项目结构

20_QRCodeGenerator/
├── 20_QRCodeGenerator.pro      # Qt项目配置文件
├── main.cpp                    # 程序入口文件
├── widget.h                    # 主窗口类头文件
├── widget.cpp                  # 主窗口类实现文件
├── widget.ui                   # UI设计文件
├── resources.qrc               # 资源文件
├── qrcode/                     # qrencode库源码
│   ├── qrencode.h             # 主要API头文件
│   ├── qrencode.c             # 核心编码实现
│   ├── qrinput.c              # 输入处理
│   ├── qrspec.c               # QR码规格
│   ├── rscode.c               # Reed-Solomon编码
│   └── ...                    # 其他库文件
└── translations/               # 国际化翻译文件├── qrcodegen_zh_CN.ts     # 中文翻译└── qrcodegen_en_US.ts     # 英文翻译

核心功能实现

1. 界面设计

在这里插入图片描述

1.1 整体布局设计

采用左右分栏布局,左侧为控制面板,右侧为预览区域:

void Widget::setupUI()
{// 创建中央部件QWidget *centralWidget = new QWidget(this);setCentralWidget(centralWidget);// 创建主布局QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget);// 创建内容区域QHBoxLayout *contentLayout = new QHBoxLayout();// 左侧输入和控制面板QVBoxLayout *leftLayout = new QVBoxLayout();// 右侧预览区域QVBoxLayout *rightLayout = new QVBoxLayout();contentLayout->addLayout(leftLayout, 1);  // 左侧占1份contentLayout->addLayout(rightLayout, 2); // 右侧占2份
}
1.2 分组框设计

使用QGroupBox将功能模块分组,提高界面组织性:

// 文本输入区域
inputGroup = new QGroupBox(getText("input_content"));
inputGroup->setStyleSheet("QGroupBox { font-weight: bold; font-size: 14px; }");
QVBoxLayout *inputLayout = new QVBoxLayout(inputGroup);// 参数设置区域
settingsGroup = new QGroupBox(getText("settings"));
settingsGroup->setStyleSheet("QGroupBox { font-weight: bold; font-size: 14px; }");
QGridLayout *settingsLayout = new QGridLayout(settingsGroup);// 操作按钮区域
actionGroup = new QGroupBox(getText("actions"));
actionGroup->setStyleSheet("QGroupBox { font-weight: bold; font-size: 14px; }");
QGridLayout *actionLayout = new QGridLayout(actionGroup);
1.3 样式设计

采用现代化的Fusion风格,自定义CSS样式表:

void Widget::applyStyle()
{// 设置应用程序样式QApplication::setStyle(QStyleFactory::create("Fusion"));// 自定义样式表QString styleSheet = R"(QWidget {font-family: "Microsoft YaHei", "SimHei", sans-serif;font-size: 12px;}QGroupBox {font-weight: bold;border: 2px solid #cccccc;border-radius: 8px;margin-top: 1ex;padding-top: 10px;background-color: #f8f9fa;}QPushButton {border: 2px solid #3498db;border-radius: 5px;padding: 8px 16px;background-color: #3498db;color: white;font-weight: bold;}QPushButton:hover {background-color: #2980b9;border-color: #2980b9;})";setStyleSheet(styleSheet);
}

2. 信号槽机制

2.1 信号槽连接

通过connect函数建立界面组件与处理函数的连接:

void Widget::createConnections()
{// 核心功能按钮连接connect(generateBtn, &QPushButton::clicked, this, &Widget::generateQRCode);connect(saveBtn, &QPushButton::clicked, this, &Widget::saveQRCode);connect(copyBtn, &QPushButton::clicked, this, &Widget::copyQRCode);connect(clearBtn, &QPushButton::clicked, this, &Widget::clearContent);// 参数设置连接connect(foregroundColorBtn, &QPushButton::clicked, this, &Widget::selectForegroundColor);connect(backgroundColorBtn, &QPushButton::clicked, this, &Widget::selectBackgroundColor);// 实时更新连接connect(sizeSlider, &QSlider::valueChanged, this, &Widget::updatePreview);connect(marginSlider, &QSlider::valueChanged, this, &Widget::updatePreview);connect(errorCorrectionCombo, QOverload<const QString &>::of(&QComboBox::currentTextChanged),this, &Widget::updatePreview);
}
2.2 菜单栏信号槽

实现菜单栏的功能连接:

void Widget::setupMenuBar()
{menuBarPtr = menuBar();// 文件菜单fileMenu = menuBarPtr->addMenu(getText("file_menu"));QAction *newAction = fileMenu->addAction(getText("new"));QAction *saveAction = fileMenu->addAction(getText("save"));QAction *printAction = fileMenu->addAction(getText("print"));fileMenu->addSeparator();QAction *exitAction = fileMenu->addAction(getText("exit"));// 连接菜单动作connect(newAction, &QAction::triggered, this, &Widget::clearContent);connect(saveAction, &QAction::triggered, this, &Widget::saveQRCode);connect(printAction, &QAction::triggered, this, &Widget::printQRCode);connect(exitAction, &QAction::triggered, this, &QApplication::quit);
}

3. QR码生成算法

3.1 qrencode库集成

项目集成了开源的qrencode库,提供高质量的QR码编码功能:

QImage Widget::generateQRCodeImage(const QString &text, int size, QRecLevel errorCorrectionLevel)
{// 输入验证if (text.isEmpty()) {return QImage();}// 使用qrencode库生成二维码数据结构QRcode *qrcode = QRcode_encodeString(text.toUtf8().constData(), 2,  // 版本 (1-40)errorCorrectionLevel,  // 纠错级别QR_MODE_8,     // 编码模式1);            // 大小写敏感if (!qrcode) {return QImage();}// 计算二维码的实际尺寸(包含边距)int qrWidth = qrcode->width;int finalSize = size;int margin = marginSize;// 创建图像QImage image(finalSize, finalSize, QImage::Format_RGB32);image.fill(backgroundColor);// 计算缩放比例int scale = (finalSize - 2 * margin) / qrWidth;int offset = (finalSize - qrWidth * scale) / 2;// 绘制二维码QPainter painter(&image);painter.setPen(Qt::NoPen);painter.setBrush(foregroundColor);for (int y = 0; y < qrWidth; y++) {for (int x = 0; x < qrWidth; x++) {if (qrcode->data[y * qrWidth + x] & 1) {painter.drawRect(offset + x * scale, offset + y * scale, scale, scale);}}}// 释放QR码数据结构QRcode_free(qrcode);return image;
}
3.2 纠错级别支持

支持四种纠错级别,适应不同的使用场景:

void Widget::generateQRCode()
{// 获取当前设置的参数qrCodeSize = sizeSlider->value();marginSize = marginSlider->value();// 根据下拉框选择确定纠错级别QRecLevel errorCorrectionLevel = QR_ECLEVEL_Q; // 默认Q级别QString currentErrorCorrection = errorCorrectionCombo->currentText();if (currentErrorCorrection.contains("L")) {errorCorrectionLevel = QR_ECLEVEL_L;  // L级别:7%纠错能力} else if (currentErrorCorrection.contains("M")) {errorCorrectionLevel = QR_ECLEVEL_M;  // M级别:15%纠错能力} else if (currentErrorCorrection.contains("Q")) {errorCorrectionLevel = QR_ECLEVEL_Q;  // Q级别:25%纠错能力} else if (currentErrorCorrection.contains("H")) {errorCorrectionLevel = QR_ECLEVEL_H;  // H级别:30%纠错能力}// 调用核心算法生成二维码图像currentQRCode = generateQRCodeImage(text, qrCodeSize, errorCorrectionLevel);
}

4. 国际化支持

4.1 翻译文件结构

使用Qt Linguist工具管理多语言翻译:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="zh_CN">
<context><name>Widget</name><message><source>QR Code Generator v1.0</source><translation>二维码生成器 v1.0</translation></message><message><source>Input Content</source><translation>输入内容</translation></message><message><source>Generate QR Code</source><translation>生成二维码</translation></message>
</context>
</TS>
4.2 语言切换实现

动态加载翻译文件,支持运行时语言切换:

void Widget::loadLanguage(const QString &language)
{// 移除当前翻译器if (translator) {QApplication::removeTranslator(translator);}// 加载新的翻译文件QString translationFile = QString(":/translations/qrcodegen_%1.qm").arg(language);if (translator->load(translationFile)) {QApplication::installTranslator(translator);currentLanguage = language;}
}void Widget::retranslateUI()
{// 重新翻译界面文本setWindowTitle(getText("window_title"));inputGroup->setTitle(getText("input_content"));settingsGroup->setTitle(getText("settings"));actionGroup->setTitle(getText("actions"));previewGroup->setTitle(getText("qr_code_preview"));// 更新按钮文本generateBtn->setText(getText("generate_qr_code"));saveBtn->setText(getText("save_image"));copyBtn->setText(getText("copy_to_clipboard"));clearBtn->setText(getText("clear_content"));
}

5. 文件操作功能

5.1 图片保存功能

支持多种图片格式的保存:

void Widget::saveQRCode()
{if (currentQRCode.isNull()) {QMessageBox::warning(this, getText("warning"), getText("no_qr_code_to_save"));return;}QString fileName = QFileDialog::getSaveFileName(this,getText("save_image"), QString("QRCode_%1.png").arg(QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss")),"PNG Files (*.png);;JPEG Files (*.jpg);;BMP Files (*.bmp);;All Files (*)");if (!fileName.isEmpty()) {if (currentQRCode.save(fileName)) {showStatusMessage(getText("saved_success"));QMessageBox::information(this, getText("success"), getText("saved_success"));} else {QMessageBox::critical(this, getText("error"), getText("save_failed"));}}
}
5.2 剪贴板复制功能

支持一键复制到系统剪贴板:

void Widget::copyQRCode()
{if (currentQRCode.isNull()) {QMessageBox::warning(this, getText("warning"), getText("no_qr_code_to_copy"));return;}QClipboard *clipboard = QApplication::clipboard();clipboard->setPixmap(QPixmap::fromImage(currentQRCode));showStatusMessage(getText("copied_to_clipboard"));QMessageBox::information(this, getText("success"), getText("copied_to_clipboard"));
}

6. 状态管理和用户反馈

6.1 进度条显示

在生成过程中显示进度条,提供用户反馈:

void Widget::generateQRCode()
{// 显示进度条,提示用户正在生成progressBar->setVisible(true);progressBar->setRange(0, 0); // 设置为不确定模式showStatusMessage(getText("generating"));// 生成二维码...// 隐藏进度条progressBar->setVisible(false);
}
6.2 状态栏消息

通过状态栏显示操作结果和提示信息:

void Widget::showStatusMessage(const QString &message, int timeout)
{if (statusBarPtr) {statusBarPtr->showMessage(message, timeout);}
}void Widget::setupStatusBar()
{statusBarPtr = statusBar();statusBarPtr->setStyleSheet("QStatusBar { background-color: #f0f0f0; border-top: 1px solid #ccc; }");showStatusMessage(getText("ready"));
}

开发环境搭建

1. 安装Qt开发环境

  1. 下载并安装Qt 5.9.9
  2. 配置MinGW32编译器
  3. 安装Qt Creator IDE

2. 项目配置

在.pro文件中配置项目依赖:

# 包含Qt核心模块和GUI模块
QT       += core gui# Qt5及以上版本需要包含widgets模块
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets# 启用C++11标准
CONFIG += c++11# 包含路径设置
INCLUDEPATH += $$PWD/qrcode       # 添加qrencode库头文件路径# 源文件列表
SOURCES += \main.cpp \widget.cpp \qrcode/qrencode.c \qrcode/qrinput.c \qrcode/qrspec.c \qrcode/rscode.c \# ... 其他qrencode库文件

3. 编译运行

  1. 在Qt Creator中打开项目
  2. 配置构建套件(选择MinGW32)
  3. 点击运行按钮编译并执行程序

项目特色功能

1. 实时预览

支持参数调整时的实时预览,用户可以立即看到效果

2. 自定义样式

支持自定义前景色和背景色,满足不同场景需求

3. 多种输出方式

支持保存为图片文件、复制到剪贴板等多种输出方式

4. 参数化配置

提供完整的参数配置,包括纠错级别、尺寸、边距等

5. 多语言支持

内置中英文双语支持,可扩展其他语言

6. 错误处理

完善的错误处理机制,提供友好的用户提示

扩展功能建议

1. 批量生成

  • 支持批量生成多个二维码
  • 从文件导入文本列表
  • 批量保存功能

2. 高级样式

  • 支持Logo嵌入
  • 渐变色彩效果
  • 圆角二维码

3. 扫描功能

  • 集成二维码扫描功能
  • 摄像头实时扫描
  • 图片文件扫描

4. 历史记录

  • 保存生成历史
  • 历史记录管理
  • 快速重用功能

5. 网络功能

  • 在线二维码生成
  • 云端保存功能
  • 分享功能

性能优化建议

1. 内存管理

  • 及时释放QR码数据结构
  • 优化图像处理算法
  • 使用智能指针管理资源

2. 界面优化

  • 异步生成避免界面卡顿
  • 优化大尺寸二维码生成
  • 实现生成进度显示

3. 算法优化

  • 优化qrencode库调用
  • 实现缓存机制
  • 支持多线程生成

常见问题解决

1. 编译错误

问题: 找不到qrencode头文件
解决: 检查.pro文件中的INCLUDEPATH配置

2. 链接错误

问题: 链接qrencode库失败
解决: 确保所有qrencode源文件都已添加到SOURCES中

3. 运行时错误

问题: 生成二维码失败
解决: 检查输入文本是否为空,纠错级别设置是否合理

4. 界面显示问题

问题: 翻译文件未加载
解决: 检查翻译文件路径和格式

总结

本项目展示了Qt框架在专业级应用开发中的强大功能,通过集成第三方库和合理的架构设计,构建了一个功能完整、界面美观的二维码生成器。项目涵盖了Qt开发的核心技术点:

  • 信号槽机制: 实现界面交互和事件处理
  • 布局管理: 创建响应式和美观的界面布局
  • 样式设计: 使用QSS实现现代化界面风格
  • 第三方库集成: 集成qrencode库实现专业级QR码生成
  • 国际化支持: 实现多语言界面
  • 文件操作: 支持多种格式的图片保存和剪贴板操作
  • 错误处理: 完善的用户反馈和错误提示机制

这个项目适合作为Qt进阶学习的实践项目,展示了如何将Qt框架与第三方库结合,构建功能丰富的桌面应用程序。通过这个项目,可以学习到Qt开发的最佳实践和高级技术。

希望这个教程对您的Qt学习有所帮助!如有问题,欢迎在评论区讨论。


相关资源:

  • Qt官方文档
  • qrencode库文档
  • Qt Linguist使用指南
  • QR码技术规范
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/96346.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/96346.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/96346.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LLaVA-3D,Video-3D LLM,VG-LLM,SPAR论文解读

目录 一、LLaVA-3D 1、概述 2、方法 3、训练过程 4、实验 二、Video-3D LLM 1、概述 2、方法 3、训练过程 4、实验 三、SPAR 1、概述 2、方法 4、实验 四、VG-LLM 1、概述 2、方法 3、方法 4、实验 一、LLaVA-3D 1、概述 空间关系不足&#xff1a;传…

Spring两个核心IoCDI(二)

DI&#xff08;依赖注入&#xff09;就是从IoC容器中获取对象并赋值给某个属性&#xff0c;这就是依赖注入的过程。 关于依赖注入有3种方式&#xff1a; 1、属性注入 2、构造方法注入 3、setter注入 目录 1、属性注入 2、 构造方法注入 3、Setter方法注入 4、3种注入方式优…

广东省省考备考(第八十三天8.21)——言语、判断推理(强化训练)

言语理解与表达 错题解析 文段开篇介绍足够的执法权限对于基层治理高效运行的重要性&#xff0c;接着从两方面进行论证&#xff0c;介绍权限不足和权限过度下放对基层治理的负面影响&#xff0c;最后通过“因此”进行总结&#xff0c;强调一方面要完善执法目录动态调整机制和制…

字符串与算法题详解:最长回文子串、IP 地址转换、字符串排序、蛇形矩阵与字符串加密

字符串与算法题详解&#xff1a;最长回文子串、IP 地址转换、字符串排序、蛇形矩阵与字符串加密 前言 在编程题训练中&#xff0c;字符串相关的题目非常常见。本文将结合几个典型的例题&#xff0c;详细解析它们的解题思路和实现方式&#xff0c;帮助初学者循序渐进地掌握常用技…

从协同设计到绿色制造:工业云渲染的价值闭环

在智能制造、建筑工程、能源电力、船舶海工等工业场景中&#xff0c;3D可视化已从传统的桌面端逐步向Web端迁移&#xff0c;Web 3D凭借其跨平台、轻量化、实时交互等特性&#xff0c;已成为企业构建数字孪生、实现远程协作、推动云端交付的重要工具。这场技术变革不仅改变了工业…

算法第五十一天:图论part02(第十一章)

1.岛屿数量 99. 岛屿数量 &#x1f31f; 思路总结 — DFS 版 1️⃣ 问题本质 给定一个二维矩阵 grid&#xff0c;1 表示陆地&#xff0c;0 表示水 统计岛屿数量&#xff0c;每个岛屿由上下左右相邻的陆地组成 本质是 在二维网格中找连通块 的问题。 2️⃣ 核心思路 遍历矩阵…

杰里708n tws api 简介

/** 通过搜索码搜索tws设备*/int tws_api_search_sibling_by_code();/**打开可发现, 可连接&#xff0c;可被手机和tws搜索到*/int tws_api_wait_pair_by_code(u16 code, const char *name, int timeout_ms);int tws_api_wait_pair_by_ble(u16 code, const char *name, int tim…

高调光比 LED 恒流驱动芯片方案详解AP5165B:36V/1A

AP5165B 是深圳市世微半导体有限公司推出的一款高性能、连续电流模式的降压型&#xff08;Buck&#xff09;LED 恒流驱动芯片。该芯片适用于输入电压高于 LED 电压的应用场景&#xff0c;可驱动单颗或多颗串联的 LED&#xff0c;输出电流最高可达 1A&#xff0c;广泛用于非隔离…

【从零构建企业级线程池管理系统:Python并发编程实战指南】

从零构建企业级线程池管理系统&#xff1a;Python并发编程实战指南 技术博客 | 深入探索Python并发编程、Web开发与现代软件架构设计的完整实践 &#x1f680; 项目背景 在当今高并发的互联网时代&#xff0c;线程池作为并发编程的核心组件&#xff0c;其管理和监控能力直接影…

飞牛系统总是死机,安装个工具查看一下日志

崩溃转储 (kernel crash dump)如果你怀疑是内核 panic&#xff0c;可以开启 kdump 或 kernel crash dump。 安装&#xff1a;sudo apt install kdump-tools # Debian/Ubuntu sudo systemctl enable kdump 下次死机时&#xff0c;系统会把内存 dump 到 /var/crash 里。sudo syst…

2025年AI Agent技术深度解析:原理、应用与未来趋势

一、引言随着人工智能技术的飞速发展&#xff0c;AI Agent&#xff08;智能体&#xff09;作为人工智能领域的重要分支&#xff0c;正逐渐成为推动各行业智能化转型的关键力量。AI Agent具备自主感知、决策和执行能力&#xff0c;能够在复杂环境中完成特定任务&#xff0c;为人…

linux内核 - 内存分配机制介绍

在linux内核中&#xff0c;下面这张图说明了系统中存在一个可以满足各种内存请求的分配机制。根据你需要内存的用途&#xff0c;你可以选择最接近你目标的分配方式。最底层、最基础的分配器是 页分配器&#xff08;page allocator&#xff09;&#xff0c;它以页为单位分配内存…

PyTorch生成式人工智能——ACGAN详解与实现

PyTorch生成式人工智能——ACGAN详解与实现0. 前言1. ACGAN 简介1.1 ACGAN 技术原理1.2 ACGAN 核心思想1.3 损失函数2. 模型训练流程3. 使用 PyTorch 构建 ACGAN3.1 数据处理3.2 模型构建3.3 模型训练3.4 模型测试相关链接0. 前言 在生成对抗网络 (Generative Adversarial Net…

Python + 淘宝 API 开发:自动化采集商品数据的完整流程​

在电商数据分析、竞品监控和市场调研等场景中&#xff0c;高效采集淘宝商品数据是关键环节。本文将详细介绍如何利用 Python 结合 API&#xff0c;构建一套自动化的商品数据采集系统&#xff0c;涵盖从 API 申请到数据存储的完整流程&#xff0c;并提供可直接运行的代码实现。​…

2025.8.21总结

工作一年多了&#xff0c;在这期间&#xff0c;确实也有不少压力&#xff0c;但每当工作有压力的时候&#xff0c;最后面都会解决。好像每次遇到解决不了的事情&#xff0c;都有同事给我兜底。这种压力&#xff0c;确实会加速一个人的成长。这种狼性文化&#xff0c;这种环境&a…

VS2022 - C#程序简单打包操作

文章目录VS2022 - C#程序简单打包操作概述笔记实验过程新建工程让依赖的运行时程序安装包在安装时运行(如果发现运行时不能每次都安装程序&#xff0c;就不要做这步)关于”运行时安装程序无法每次都安装成功“的应对知识点尝试打包旧工程bug修复从需求属性中&#xff0c;可以原…

在JAVA中如何给Main方法传参?

一、在IDEA中进行传参&#xff1a;先创建一个类&#xff1a;MainTestimport java.util.Arrays;public class MainTest {public static void main(String[] args) {System.out.println(args.length);System.out.println(Arrays.toString(args));} }1.IDEA ---> 在运行的按钮上…

ORACLE中如何批量重置序列

背景&#xff1a;数据库所有序列都重置为1了&#xff0c;所以要将所有的序列都更新为对应的表主键&#xff08;这里是id&#xff09;的最大值1。我这里序列的规则是SEQ_表名。BEGINENHANCED_SYNC_SEQUENCES(WJ_CPP); -- 替换为你的模式名 END; / CREATE OR REPLACE PROCEDURE E…

公号文章排版教程:图文双排、添加图片超链接、往期推荐、推文采集(2025-08-21)

文章目录 排版的基本原则 I 图片超链接 方式1: 利用公号原生编辑器 方式2:在CSDN平台使用markdown编辑器, 利用标签实现图片链接。 II 排版小技巧 自定义页面模版教程 使用壹伴进行文章素材的采集 美编助手的往期推荐还不错 利用365编辑器创建图文双排效果 排版的基本原则 亲…

计算两幅图像在特定交点位置的置信度评分。置信度评分反映了该位置特征匹配的可靠性,通常用于图像处理任务(如特征匹配、立体视觉等)

这段代码定义了一个名为compute_confidence的函数&#xff0c;用于计算两幅图像在特定交点位置的置信度评分。置信度评分反映了该位置特征匹配的可靠性&#xff0c;通常用于图像处理任务&#xff08;如特征匹配、立体视觉等&#xff09;。以下是逐部分解析&#xff1a; 3. 结果…