当前位置: 首页 > news >正文

项目实践5—全球证件智能识别系统(Qt客户端开发+FastAPI后端人工智能服务开发)

目录

  • 一、任务概述
  • 二、客户端功能优化:可控的大模型调用
    • 2.1 设计思路与UI变更
    • 2.2 更新客户端请求逻辑
    • 2.3 更新服务端接收与处理逻辑
  • 三、自动切换紫外曝光
    • 3.1 功能背景与设计思路
    • 3.2 客户端代码实现
      • 3.2.1 新增状态重置辅助函数
      • 3.2.2 更新`onRecognize`槽函数
  • 四、后端服务地址的可配置化改造
    • 4.1 功能背景与设计思路
    • 4.2 扩展参数设置对话框
      • 4.2.1 更新`settingsdialog.h`
      • 4.2.2 更新`settingsdialog.cpp`
    • 4.3 在主窗口中集成URL配置
      • 4.3.1 更新`mainwindow.h`
      • 4.3.2 更新配置加载与保存逻辑
      • 4.3.3 更新`onSettingsClicked`槽函数
    • 4.4 应用动态URL构建请求

一、任务概述

在前四篇系列博客中,已经系统性地构建了“证照智能识别系统”的客户端与后端服务。客户端从一个基础的Qt应用程序框架出发,逐步集成了专业的用户界面、多光谱硬件的非阻塞式图像采集、基于OpenCV的图像自动矫正与标准化处理,并最终实现了与后端服务的异步通信,能够高效地上传图像数据并动态展示识别结果。后端服务则基于FastAPI构建,实现了基于图像特征向量的证照快速检索功能,能够准确识别待查证件的类型。

本篇博客将对现有系统进行两项关键的功能升级:

  1. 实现可控的大模型调用:考虑到图文多模态大模型的版面识别功能虽然强大,但其推理过程相对耗时。为了给予用户更大的自主权,将在客户端界面上新增一个控制开关。用户可以根据实际需求,选择是否在证件类型匹配成功后,继续调用大模型进行深度的版面信息识别与翻译。这使得系统可以在“快速检索”与“深度识别”两种模式间灵活切换。

  2. 集成本地检测大模型:在本地部署通义千问Qwen3-VL-8B-Thinking图文多模态大模型,并完成局域网调用。从源头保证数据隐私不被泄露,并且可以解决因互联网图像传输延时所造成的不良体验。


二、客户端功能优化:可控的大模型调用

2.1 设计思路与UI变更

为了让用户能够自主选择是否启用耗时较长的大模型版面识别功能,最直观的交互方式是在主界面的工具栏上提供一个明确的开关。基于此思路,将在“智能识别”按钮旁边添加一个复选框(QCheckBox),标签为“启用版面识别”,并默认设置为未勾选状态。

首先,需要在mainwindow.h头文件中为这个新的UI控件添加声明。

代码清单: mainwindow.h

// ... (保留原有 #include)
#include <QCheckBox> // <-- 新增:包含QCheckBox头文件// ... (保留原有类前置声明)
QT_BEGIN_NAMESPACE
class QComboBox;
class QCompleter;
class QNetworkAccessManager;
class QNetworkReply;
class QProgressDialog;
class QCheckBox; // <-- 新增:QCheckBox的前置声明
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{// ... (保留原有 Q_OBJECT, public, private slots)private:// ... (保留原有私有方法)// ... (保留原有成员变量)QComboBox *countryComboBox;// --- 新增复选框成员变量 ---QCheckBox *enableLlmCheckBox; // 用于控制是否启用大模型识别
};

接下来,在mainwindow.cppcreateToolBars方法中,实例化QCheckBox并将其添加到工具栏的合适位置。

代码清单: mainwindow.cpp (更新 createToolBars)

void MainWindow::createToolBars()
{// ... (实例化主工具栏 mainToolBar 的代码保持不变)// ... (添加采集、分隔符、识别等Action的代码保持不变)mainToolBar->addAction(recognizeAct);// --- 新增:创建并配置“启用版面识别”复选框 ---enableLlmCheckBox = new QCheckBox(QStringLiteral("启用版面识别"), this);enableLlmCheckBox->setChecked(false); // 默认不勾选mainToolBar->addWidget(enableLlmCheckBox); // 将复选框添加到工具栏mainToolBar->addAction(compareFrontAct);mainToolBar->addAction(compareBackAct);mainToolBar->addAction(showOriginalsAct);mainToolBar->addSeparator();// ... (添加保存、设置、国家选择框等控件的代码保持不变)
}

完成以上修改后,重新编译并运行客户端程序。此时,主界面的工具栏在“智能识别”按钮右侧将出现一个新的复选框,如下图所示。
在这里插入图片描述

2.2 更新客户端请求逻辑

UI变更完成后,下一步是修改网络请求的发起逻辑,将复选框的状态作为一个新的参数包含在发送给后端服务的JSON数据中。

此项修改集中在onRecognize槽函数内部。在构建JSON对象时,需读取enableLlmCheckBoxisChecked()状态,并将其作为一个布尔值添加到请求体中。

代码清单: mainwindow.cpp (更新 onRecognize)

void MainWindow::onRecognize()
{// ... (保留图像存在性检查、国家代码提取等前置逻辑)// ... (将所有采集图像转换为Base64字符串的逻辑保持不变)// 3. 构建JSON请求体QJsonObject jsonObject;jsonObject["country_code"] = countryCode;jsonObject["image_front_white"] = frontWhiteBase64;jsonObject["image_front_uv"] = frontUvBase64;jsonObject["image_front_ir"] = frontIrBase64;jsonObject["image_back_white"] = backWhiteBase64;jsonObject["image_back_uv"] = backUvBase64;jsonObject["image_back_ir"] = backIrBase64;// --- 新增:读取复选框状态并添加到JSON中 ---jsonObject["enable_llm"] = enableLlmCheckBox->isChecked();QJsonDocument jsonDoc(jsonObject);QByteArray postData = jsonDoc.toJson();// ... (配置并发送HTTP POST请求、显示等待对话框的逻辑保持不变)
}

通过这处简单的增补,客户端现在具备了向后端传递“是否启用大模型”这一指令的能力,为后端实现条件化处理流程奠定了基础。

2.3 更新服务端接收与处理逻辑

客户端的请求逻辑更新后,后端服务必须相应地进行升级,以识别并处理这个新增的enable_llm参数。此项修改将直接影响/api/recognize端点的行为,使其具备根据客户端指令条件化执行大模型推理的能力。

首先,需要更新用于验证请求体的Pydantic数据模型RecognitionRequest,为其添加enable_llm字段。

代码清单: main.py (更新RecognitionRequest模型)

# ... (保留其他原有导入)
from pydantic import BaseModel, Field# --- 定义请求体的数据模型 ---
class RecognitionRequest(BaseModel):country_code: str = Field(..., description="国家三位数字代码")image_front_white: str = Field(..., description="正面白光图像 (Base64)")image_front_uv: str = Field(..., description="正面紫外图像 (Base64)")image_front_ir: str = Field(..., description="正面红外图像 (Base64)")image_back_white: str = Field(..., description="反面白光图像 (Base64)")image_back_uv: str = Field(..., description="反面紫外图像 (Base64)")image_back_ir: str = Field(..., description="反面红外图像 (Base64)")# --- 新增:接收客户端的控制参数 ---# default=False确保即使旧版客户端未发送此字段,也能正常处理enable_llm: bool = Field(default=False, description="是否启用大模型进行版面识别")# ... (其他数据模型和代码保持不变)

接下来,在主API端点recognize_document的实现中,将原有的国家代码判断逻辑与新的enable_llm参数进行组合,形成一个更精确的复合条件。

代码清单: main.py (更新recognize_document函数)

# ... (保留文件顶部、辅助函数、数据模型、FastAPI实例等)@app.post("/api/recognize", response_model=RecognitionResponse, summary="证照智能识别接口")
async def recognize_document(request: RecognitionRequest, session: Session = Depends(get_session)):# ... (保留特征提取、数据库检索、相似度比对、阈值判断、紫外二次校验等逻辑)# --- 更新:调用大模型进行版面信息识别 ---llm_result_text = ""greater_china_codes = ["156", "344", "446", "158"]# --- 复合条件判断:仅当证件为国内 且 客户端明确启用时,才调用大模型 ---if request.country_code not in greater_china_codes and request.enable_llm:print(f"国家代码({request.country_code})非中国,且客户端已启用版面识别。启动大模型...")try:# a. 获取客户端上传的原始正反面白光图像数据front_white_bytes_llm = base64.b64decode(request.image_front_white)back_white_bytes_llm = base64.b64decode(request.image_back_white)# b. 异步调用函数,将两张图像拼接merged_image_bytes = await merge_images_vertically(front_white_bytes_llm, back_white_bytes_llm)# c. 异步调用大模型进行识别llm_result_text = await recognize_text_with_llm(merged_image_bytes)print("大模型版面识别完成。")except Exception as e:print(f"在处理大模型识别流程时发生错误: {e}")llm_result_text = "版面信息识别失败,请稍后重试。"else:# 打印跳过原因,便于调试if request.country_code in greater_china_codes:print(f"国家代码({request.country_code})属于中国,跳过大模型识别。")if not request.enable_llm:print("客户端未启用版面识别,跳过大模型调用。")# ... (保留准备返回图像数据、构建最终响应体的逻辑)

通过将if条件修改为if request.country_code not in greater_china_codes and request.enable_llm:,现在大模型的调用行为将完全由客户端的复选框状态精确控制,实现了功能的可控性。


三、自动切换紫外曝光

3.1 功能背景与设计思路

在多光谱图像采集中,紫外(UV)光照下的成像是鉴别证件真伪、检验防伪特征的关键环节。然而,不同国家和地区的证件,其制作工艺、防伪油墨和纸张材质存在显著差异,导致它们对紫外光的响应特性各不相同。例如,国内证件的紫外荧光特征通常在较低的曝光强度(如40)下成像最为明显,而许多国外证件则需要在更高的曝光强度(如200)下才能充分激发其荧光效果。

在之前的开发中,紫外曝光强度作为一个可配置参数,需要用户在“参数设置”对话框中手动调整。这种方式虽然灵活,但在高频次的业务操作中存在不便,且容易因操作员忘记切换参数而导致采集到次优的紫外图像,影响后续的智能分析。

为了提升系统的智能化水平和易用性,本节将引入一项自动化优化功能:根据待识别证件的国别,自动调整并设定最优的紫外曝光参数。该功能的设计思路如下:

  1. 模式判定:在用户点击“智能识别”按钮后,系统首先检查“国家/地区”下拉框中选定的国家代码。以中国的国别代码“156”为界,将识别任务划分为“国内证件识别模式”和“国外证件识别模式”。
  2. 参数核查
    • 若进入国内模式,系统将检查当前的紫外曝光参数m_uvcBrightness。如果该值偏高(例如,大于等于100),则判定当前可能处于为国外证件优化的设置,需要调整。
    • 若进入国外模式,系统将反向检查。如果该值偏低(例如,小于等于150),则判定当前可能处于为国内证件优化的设置,需要调整。
  3. 自动校正与引导:一旦检测到参数与模式不匹配,系统将自动执行以下一系列操作:
    • 将紫外曝光参数更新为对应模式下的最优值(国内为40,国外为200)。
    • 将新参数持久化写入配置文件,以便后续采集直接生效。
    • 清空当前已采集的所有图像及界面显示,因为它们是在不合适的曝光参数下获取的。
    • 弹出一个明确的提示框,告知用户系统已自动完成参数校正,并引导其重新采集正反面图像。
    • 中断本次识别请求,等待用户重新操作。

通过这一自动化流程,可以确保每次采集任务,尤其是关键的紫外图像采集,都是在最优的光照条件下进行,从而为后续的防伪特征检测和智能识别提供最高质量的数据输入。

3.2 客户端代码实现

此功能的实现主要涉及对主窗口类MainWindow的修改。需要增加一个用于清空采集状态的辅助函数,并在“智能识别”按钮的槽函数onRecognize()的入口处,植入上述的自动化判断与校正逻辑。

3.2.1 新增状态重置辅助函数

为了避免在代码中重复编写清空图像列表和UI的逻辑,首先在MainWindow类中添加一个私有的辅助函数resetCaptureState()

代码清单: mainwindow.h

// ... (保留原有 #include 和类声明)class MainWindow : public QMainWindow
{// ... (保留 Q_OBJECT, public, private slots)private:// ... (保留原有私有方法)void updateCompositeImage(const QList<QPixmap>& pixmaps, int columns);// --- 新增:用于清空采集图像和显示状态的辅助函数 ---void resetCaptureState();// ... (保留原有成员变量)
};

mainwindow.cpp中实现该函数。它负责将存储所有原始图像和矫正后图像的QList清空,并将主界面的imageLabel恢复到初始状态。

代码清单: mainwindow.cpp (实现resetCaptureState)

// ... (保留文件顶部 #include)// --- 新增:实现状态重置辅助函数 ---
/*** @brief 重置图像采集和显示状态** 该函数负责清空所有用于存储采集图像(原始及矫正后)的列表,* 并清除主界面图像显示区域的内容,使其恢复到初始提示状态。*/
void MainWindow::resetCaptureState()
{// 清空存储原始采集图像的列表m_frontImages.clear();m_backImages.clear();// 清空存储矫正后图像的列表m_correctedFrontImages.clear();m_correctedBackImages.clear();// 清空主界面的图像显示 QLabelimageLabel->clear();// 重新设置初始的占位提示文本imageLabel->setText(QStringLiteral("图像展示区域"));// 清空识别结果文本框resultTextEdit->clear();
}// ... (其他原有函数)

3.2.2 更新onRecognize槽函数

接下来,对核心的onRecognize()槽函数进行改造,在其最开始的位置加入曝光参数的自动调整逻辑。

代码清单: mainwindow.cpp (更新 onRecognize)

void MainWindow::onRecognize()
{// 1. 提取国家代码的数字部分QString currentCountry = countryComboBox->currentText();QString countryCode;QRegularExpression re("_(\\d{3})$"); // 匹配末尾的 "_三位数字"QRegularExpressionMatch match = re.match(currentCountry);if (match.hasMatch()) {countryCode = match.captured(1); // 提取数字部分} else {QMessageBox::warning(this, QStringLiteral("提示"), QStringLiteral("请先选择证照来源国家/地区。"));return;}// --- 新增:根据国家代码自动调整紫外曝光参数 ---if (countryCode == "156") { // 判断是否为国内证件识别模式// 国内证件最佳紫外曝光为40。若当前值大于等于100,则判定为国外模式,需要调整。if (m_uvcBrightness >= 100) {m_uvcBrightness = 40; // 自动校正为国内模式的最佳参数saveSettings();       // 将新参数持久化保存到配置文件resetCaptureState();  // 清空当前无效的采集图像和显示// 弹出提示框,引导用户重新操作QMessageBox::information(this, QStringLiteral("模式切换提示"),QStringLiteral("检测到当前为国外证照识别模式,已自动调整曝光参数使其符合国内证照识别,请重新采集正反面图像再识别。"));return; // 中断本次识别流程,等待用户重新采集}} else { // 国外证件识别模式// 国外证件最佳紫外曝光为200。若当前值小于等于150,则判定为国内模式,需要调整。if (m_uvcBrightness <= 150) {m_uvcBrightness = 200; // 自动校正为国外模式的最佳参数saveSettings();resetCaptureState();// 弹出对应的提示框QMessageBox::information(this, QStringLiteral("模式切换提示"),QStringLiteral("检测到当前为国内证照识别模式,已自动调整曝光参数使其符合国外证照识别,请重新采集正反面图像再识别。"));return; // 中断本次识别流程}}// --- 自动曝光调整逻辑结束 ---// 检查是否已采集到必须的图像if (m_correctedFrontImages.isEmpty() || m_correctedBackImages.isEmpty()) {QMessageBox::warning(this, QStringLiteral("提示"), QStringLiteral("请先采集证件的正反面图像。"));return;}// ... (后续构建JSON、发送网络请求等逻辑保持不变)
}

完成以上代码修改后,重新编译并运行客户端。现在,系统已具备了根据识别目标国别,智能判断并自动校正紫外曝光参数的能力。当识别模式与曝光参数不匹配时,系统将弹出相应的提示框,引导用户在最优参数下重新采集图像,从而从源头上保障了数据质量,为后续所有智能分析任务的准确性提供了坚实基础。

四、后端服务地址的可配置化改造

4.1 功能背景与设计思路

在当前客户端的实现中,与后端服务通信的URL地址被硬编码在onRecognize槽函数内部:

QUrl url("http://127.0.0.1:5000/api/recognize");

这种硬编码的方式存在明显的局限性:

  • 缺乏灵活性:一旦后端服务的部署地址(IP或域名)或端口发生变更,就必须修改客户端源代码并重新编译、分发整个应用程序,这在生产环境中是极其低效和不便的。
  • 可维护性差:对于非开发人员(如系统管理员或最终用户)而言,无法自行调整服务地址以适应不同的网络环境(如从测试环境切换到生产环境)。

为了克服这些问题,提升系统的灵活性和可维护性,需要对服务地址进行可配置化改造。其核心思路是将URL的基础部分(如http://127.0.0.1:5000)从代码中剥离,作为一个可配置的参数,允许用户在运行时进行修改和持久化保存。

该功能的实现将遵循以下技术路径:

  1. 扩展UI界面:在已有的“参数设置”对话框(SettingsDialog)中,新增一个文本输入框(QLineEdit),专门用于输入和显示后端服务的基础URL。
  2. 持久化存储:利用现有的QSettings机制,将用户配置的服务URL地址与曝光参数一并保存在本地的INI配置文件中。程序启动时自动加载,关闭时自动保存。
  3. 动态URL构建:在发起网络请求时,将不再使用固定的URL字符串,而是通过拼接“从配置中读取的基础URL”和“固定的API端点路径(/api/recognize)”来动态构建最终的请求地址。

通过这一改造,系统将具备更强的环境适应能力,使得后端服务的地址变更对客户端而言,仅仅是一次简单的配置修改。

4.2 扩展参数设置对话框

首先,需要对SettingsDialog类进行扩展,为其增加一个用于输入服务器地址的QLineEdit控件。

4.2.1 更新settingsdialog.h

在头文件中,添加QLineEdit的前置声明和成员变量,并更新setValuesgetValues两个公共接口的函数签名,使其能够处理QString类型的URL地址。

代码清单: settingsdialog.h

#ifndef SETTINGSDIALOG_H
#define SETTINGSDIALOG_H#include <QDialog>
#include <QString> // <-- 新增:包含QString头文件// 前置声明
class QSpinBox;
class QDialogButtonBox;
class QLineEdit; // <-- 新增:QLineEdit的前置声明class SettingsDialog : public QDialog
{Q_OBJECTpublic:explicit SettingsDialog(QWidget *parent = nullptr);~SettingsDialog();// 公共接口:更新函数签名以接收URLvoid setValues(int rgb, int infrared, int uvc, const QString &serverUrl);// 公共接口:更新函数签名以返回URLvoid getValues(int &rgb, int &infrared, int &uvc, QString &serverUrl) const;private:// UI控件成员变量QSpinBox *rgbSpinBox;QSpinBox *infraredSpinBox;QSpinBox *uvcSpinBox;QLineEdit *serverUrlLineEdit; // <-- 新增:服务器地址输入框QDialogButtonBox *buttonBox;
};#endif // SETTINGSDIALOG_H

4.2.2 更新settingsdialog.cpp

在源文件中,完成QLineEdit的实例化、布局添加以及setValues/getValues方法的逻辑实现。

代码清单: settingsdialog.cpp

#include "settingsdialog.h"
#include <QSpinBox>
#include <QDialogButtonBox>
#include <QFormLayout>
#include <QVBoxLayout>
#include <QLabel>
#include <QLineEdit> // <-- 新增:包含QLineEdit头文件SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent)
{// ... (实例化QSpinBox和QDialogButtonBox的代码保持不变)// --- 新增:实例化服务器地址输入框 ---serverUrlLineEdit = new QLineEdit(this);serverUrlLineEdit->setPlaceholderText(QStringLiteral("例如:http://127.0.0.1:5000"));// ... (创建QDialogButtonBox的代码保持不变)// --- 2. 布局设计 ---QFormLayout *formLayout = new QFormLayout;formLayout->addRow(new QLabel(QStringLiteral("白光曝光强度:"), this), rgbSpinBox);formLayout->addRow(new QLabel(QStringLiteral("红外曝光强度:"), this), infraredSpinBox);formLayout->addRow(new QLabel(QStringLiteral("紫外曝光强度:"), this), uvcSpinBox);// --- 新增:将服务器地址输入框添加到表单布局中 ---formLayout->addRow(new QLabel(QStringLiteral("服务器地址:"), this), serverUrlLineEdit);// ... (后续布局和信号槽连接代码保持不变)// --- 4. 设置窗体属性 ---this->setWindowTitle(QStringLiteral("参数设置"));this->setFixedSize(400, 250); // 适当增加对话框尺寸以容纳新控件
}SettingsDialog::~SettingsDialog()
{
}// 实现更新后的setValues方法
void SettingsDialog::setValues(int rgb, int infrared, int uvc, const QString &serverUrl)
{rgbSpinBox->setValue(rgb);infraredSpinBox->setValue(infrared);uvcSpinBox->setValue(uvc);serverUrlLineEdit->setText(serverUrl); // <-- 新增:设置URL文本
}// 实现更新后的getValues方法
void SettingsDialog::getValues(int &rgb, int &infrared, int &uvc, QString &serverUrl) const
{rgb = rgbSpinBox->value();infrared = infraredSpinBox->value();uvc = uvcSpinBox->value();serverUrl = serverUrlLineEdit->text(); // <-- 新增:获取URL文本
}

4.3 在主窗口中集成URL配置

对话框改造完成后,需要在主窗口MainWindow中添加相应的成员变量和逻辑,以管理这个新的配置项。

4.3.1 更新mainwindow.h

mainwindow.h中添加一个QString类型的成员变量m_serverBaseUrl,用于在内存中存储当前生效的服务器地址。

代码清单: mainwindow.h

// ... (保留原有代码)class MainWindow : public QMainWindow
{// ... (保留 Q_OBJECT 等)
private:// ... (保留原有私有方法)// ... (保留原有成员变量)// --- 新增:曝光参数与服务器地址成员变量 ---int m_rgbBrightness;int m_infraredBrightness;int m_uvcBrightness;QString m_serverBaseUrl; // <-- 新增:用于存储服务器基础URL
};

4.3.2 更新配置加载与保存逻辑

mainwindow.cpp中,对loadSettings()saveSettings()方法进行扩展,使其能够读写服务器地址配置。

代码清单: mainwindow.cpp (更新loadSettingssaveSettings)

// ... (保留文件顶部 #include)
#include <QSettings>// --- 更新:实现加载配置方法 ---
void MainWindow::loadSettings()
{QSettings settings;// 读取曝光参数m_rgbBrightness = settings.value("Brightness/RGB", 100).toInt();m_infraredBrightness = settings.value("Brightness/Infrared", 100).toInt();m_uvcBrightness = settings.value("Brightness/UVC", 40).toInt();// --- 新增:读取服务器地址,若不存在则使用默认值 ---m_serverBaseUrl = settings.value("Server/BaseUrl", "http://127.0.0.1:5000").toString();
}// --- 更新:实现保存配置方法 ---
void MainWindow::saveSettings()
{QSettings settings;// 写入曝光参数settings.setValue("Brightness/RGB", m_rgbBrightness);settings.setValue("Brightness/Infrared", m_infraredBrightness);settings.setValue("Brightness/UVC", m_uvcBrightness);// --- 新增:写入服务器地址 ---settings.setValue("Server/BaseUrl", m_serverBaseUrl);
}

4.3.3 更新onSettingsClicked槽函数

修改onSettingsClicked()槽函数,使其在打开和关闭“参数设置”对话框时,能够正确传递服务器URL地址。

代码清单: mainwindow.cpp (更新onSettingsClicked)

#include "settingsdialog.h"
// ...void MainWindow::onSettingsClicked()
{SettingsDialog dlg(this);// 将当前的曝光参数和服务器URL设置到对话框中作为初始值dlg.setValues(m_rgbBrightness, m_infraredBrightness, m_uvcBrightness, m_serverBaseUrl);if (dlg.exec() == QDialog::Accepted) {// 如果用户点击了“确定”,从对话框获取更新后的所有值dlg.getValues(m_rgbBrightness, m_infraredBrightness, m_uvcBrightness, m_serverBaseUrl);// 保存新的设置到INI文件saveSettings();statusBar()->showMessage(QStringLiteral("参数已更新并保存"), 3000);}
}

4.4 应用动态URL构建请求

最后一步,也是最关键的一步,是修改onRecognize()槽函数,用动态构建的URL替换掉原来硬编码的地址。

代码清单: mainwindow.cpp (更新onRecognize)

// ... (保留 onRecognize 函数的前置逻辑)void MainWindow::onRecognize()
{// ... (保留国家代码提取、自动曝光调整、图像存在性检查等逻辑)// ... (保留构建JSON请求体的逻辑)QJsonDocument jsonDoc(jsonObject);QByteArray postData = jsonDoc.toJson();// --- 更新:动态构建HTTP POST请求URL ---// 拼接基础URL和固定的API端点路径QUrl url(m_serverBaseUrl + "/api/recognize");QNetworkRequest request(url);request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");networkManager->post(request, postData);// ... (后续显示等待对话框的逻辑保持不变)
}

完成以上所有修改后,重新编译并运行项目。现在,可以通过点击工具栏上的“参数设置”按钮,打开对话框来自由修改后端服务的地址。修改并确认后,新的地址将被自动保存,并在下一次点击“智能识别”时立即生效。这一改进彻底解除了客户端与特定服务器地址的硬性绑定,极大地增强了系统的灵活性和在不同部署环境下的适应能力。

http://www.dtcms.com/a/537691.html

相关文章:

  • 苏州网网站建设企业网站源码带后台
  • 做学术研究的网站惠州市住房和城乡建设厅网站
  • iis应用程序池 网站塘沽网站制作公司
  • 海外网站哪个最好沈阳网站建设58同城
  • ArcGIS Pro与Python下空间数据采集与管理
  • 单片机跑飞原因及解决方法
  • 什么是网站交互全国最大工地招工网
  • 推广网站有哪些平台海外运营工作内容
  • 响应式网站开发 三合一建站备案后修改网站名称
  • 佘山做网站wordpress底部footer
  • 哪个网站做漂流瓶任务做网站外国的
  • 可以做设计赚钱的网站外包公司辞退员工补偿标准
  • 网站共享备案可以申请支付接口网站维护协议
  • 信息技术应用创新 | 基于KylinV10的达梦数据库DM8基本操作
  • 如何租用服务器做网站温州做网站公司
  • 泉州网站开发公司旺道seo软件
  • AOI设备在光伏制造领域的核心应用
  • 网页网站建设的步骤流程图网上搞钱的野路子
  • 安徽池州做企业网站新东方英语线下培训学校
  • 2025年mathorcup大数据竞赛B题【物流理赔风险识别及服务升级问题】原创论文分享
  • EECS 498 Deep Learning for Computer Vision Winter 2022 A2
  • 爱网站站长工具免费网站建设的
  • 从0开始学python(day1)
  • 无人机工厂如何透明化管理?ESOP+安灯系统来辅助
  • 前端系列之:兼容性
  • 网站代码开发方式烟台建站价格
  • 大同招聘网站建设官网是怎么做的
  • 重庆 手机网站制作wordpress 主要
  • 如何伪原创 网站各地平台网站
  • DFS专题(二)洪水填充问题(C++实现,结合lc经典习题讲解)