1.添加图片注册和前后板主题图片上传;2.修改mdns连接方式

This commit is contained in:
2024-12-10 16:15:55 +08:00
parent 9d506e1cfc
commit d2bccd9c49
177 changed files with 4381 additions and 5709 deletions

View File

@@ -1,6 +1,6 @@
// MainWidget.cpp
#include "MainWidget.h"
#include <qrencode.h>
void onThreadFinished(QThread* thread, ClientHandler* handler, DataHandler* dataHandler)
{
qDebug() << "Thread finished. Deleting handler and thread.";
@@ -9,6 +9,25 @@ void onThreadFinished(QThread* thread, ClientHandler* handler, DataHandler* data
thread->deleteLater();
}
bool initializeMdns() {
#ifdef _WIN32
WORD versionWanted = MAKEWORD(1, 1);
WSADATA wsaData;
if (WSAStartup(versionWanted, &wsaData)) {
qDebug() << "Failed to initialize WinSock";
return false;
}
#else
// 设置中断信号处理器
signal(SIGINT, [](int signal) {
qDebug() << "SIGINT received, cleaning up...";
// 处理退出信号的资源释放逻辑(如果需要)
});
#endif
qDebug() << "mDNS initialization completed.";
return true;
}
// 初始化 UI 组件和服务器
MainWidget::MainWidget(QWidget* parent) :
QWidget(parent),
@@ -19,15 +38,16 @@ MainWidget::MainWidget(QWidget* parent) :
lastClickedGetPicDevIndex(-1),
lastClickedGetVideoCamIndex(-1),
lastClickedGetVideoDevIndex(-1),
mServiceProvider(new ServiceProvider(this)),
//mServiceProvider(new ServiceProvider(this)),
mdnsTimer(new QTimer(this)),
httpClient(new HttpClient(this))
httpClient(new HttpClient(this)),
httpServer(new QTcpServer(this)),
mdnsThread(nullptr)
#if TEST_UDP_BROADCAST
,multicastSocket(new QUdpSocket(this)),
multicastTimer(new QTimer(this))
#endif
{
QString configFilePath = QDir::currentPath() + "/UI_config.ini";
TOOL_UI = loadConfig(configFilePath);
@@ -46,6 +66,12 @@ MainWidget::MainWidget(QWidget* parent) :
UuidHwInfoEdit = new QTextEdit(this);
setupUI();
// 初始化 mDNS
if (!initializeMdns()) {
qDebug() << "Failed to initialize mDNS. Exiting...";
return;
}
setupHttpServer();
// 打印线程池状态信息
setupTimerForThreadPoolInfo();
server = new QTcpServer(this);
@@ -58,6 +84,7 @@ MainWidget::MainWidget(QWidget* parent) :
QHostAddress clientIp = socket->peerAddress();
quint16 clientPort = socket->peerPort();
QString ipString = clientIp.toString();
isReplyOrTimeout = true;
if (ipString.startsWith("::ffff:")) {
ipString = ipString.mid(7);
}
@@ -67,14 +94,16 @@ MainWidget::MainWidget(QWidget* parent) :
qDebug() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>";
if (ipString.startsWith("10.10.10")) {
//if (1) {
qDebug() << "The client IP address is front board !!!";
isBackBoardOrAllBoard = 0;
}
else {
onDisconnectClient(clientId - 1);
qDebug() << "The client IP address is back board or all board";
isBackBoardOrAllBoard = clientId;
}
stopMdnsService();
//stopMdnsService();
connectedClientsCount ++;
updateServerButtonText();
@@ -126,12 +155,14 @@ MainWidget::MainWidget(QWidget* parent) :
connect(handler, &ClientHandler::HandleInvalidOperate, this, &MainWidget::onHandleInvalidOperate);
connect(handler, &ClientHandler::clientDisconnected, this, &MainWidget::onClientDisconnected);
connect(handler, &ClientHandler::allItemsProcessed, this, &MainWidget::onAllItemsProcessed);
connect(handler, &ClientHandler::selectClientDisconnected, this, &MainWidget::onDisconnectClient);
//connect(handler, &ClientHandler::selectClientDisconnected, this, &MainWidget::onDisconnectClient);
dataHandlers[clientId] = dataHandler;
connect(handler, &ClientHandler::dataReceived, dataHandler, &DataHandler::handleData);
connect(dataHandler, &DataHandler::picRecvFinished, handler, &ClientHandler::onPicRecvFinished);
connect(dataHandler, &DataHandler::statusUpdated, this, &MainWidget::onStatusUpdated);
connect(handler, &ClientHandler::dataReceived, dataHandler, &DataHandler::handleData);
connect(handler, &ClientHandler::currentSendItem, dataHandler, &DataHandler::getCurrentSendItem);
connect(dataHandler, &DataHandler::picRecvFinished, handler, &ClientHandler::onPicRecvFinished);
connect(dataHandler, &DataHandler::commandError, handler, &ClientHandler::onCommandError);
connect(dataHandler, &DataHandler::statusUpdated, this, &MainWidget::onStatusUpdated);
// 当线程结束时删除 handler
connect(thread, &QThread::finished, this, [=]() {
onThreadFinished(thread, handler, dataHandler);
@@ -163,7 +194,9 @@ MainWidget::MainWidget(QWidget* parent) :
clientReadTimers[clientId] = readTimer;
connect(handler, &ClientHandler::sendDataToSomeClient, this, &MainWidget::sendDataToClient);
if (isBackBoardOrAllBoard == 1) {
connect(handler, &ClientHandler::startImageSharing, this, &MainWidget::onStartImageSharing);
if (isBackBoardOrAllBoard != 0) {
handler->sendDevInfoItem();
}
}
@@ -178,8 +211,6 @@ MainWidget::MainWidget(QWidget* parent) :
connectionStatusCheckTimer = new QTimer(this);
connect(connectionStatusCheckTimer, &QTimer::timeout, this, &MainWidget::onCheckConnectionStatus);
//connectionStatusCheckTimer->start(100); // 每100ms检查一次连接状态
connect(mdnsTimer, &QTimer::timeout, this, &MainWidget::startMdnsService);
#if TEST_UDP_BROADCAST
// 设置组播地址
@@ -205,15 +236,6 @@ MainWidget::MainWidget(QWidget* parent) :
MainWidget::~MainWidget()
{
#if TEST_UDP_BROADCAST
multicastTimer->stop();
multicastSocket->leaveMulticastGroup(QHostAddress("224.0.0.251"));
multicastSocket->close();
#endif
if (mdnsTimer->isActive()) {
mdnsTimer->stop();
}
delete mdnsTimer;
stopMdnsService();
for (auto timer : clientReadTimers) {
timer->stop();
@@ -283,7 +305,7 @@ void MainWidget::onClientDisconnected(ClientHandler* handler)
// 更新连接数并更新按键文本
connectedClientsCount--;
qDebug() << " connectedClientsCount :" << connectedClientsCount;
//qDebug() << " connectedClientsCount :" << connectedClientsCount;
if (nextClientId <= 2) nextClientId --;
deviceConnected = true;
@@ -311,6 +333,60 @@ void MainWidget::onClientDisconnected(ClientHandler* handler)
}
}
void MainWidget::onDisconnectClient(int clientId)
{
for (ClientHandler* handler : clients) {
if (handler->getClientId() == clientId) {
// 断开与该客户端的连接
if (clientTimers.contains(clientId)) {
QTimer* timer = clientTimers[clientId];
timer->stop();
delete timer;
clientTimers.remove(clientId);
}
clients.removeOne(handler);
handler->deleteLater();
if (dataHandlers.contains(clientId)) {
DataHandler* dataHandler = dataHandlers[clientId];
dataHandlers.remove(clientId); // 从容器中移除
dataHandler->deleteLater(); // 延迟删除 DataHandler 对象
}
int count = 200;
int preVideoId = handler->preVideoClientId;
int boardTpye = isBackBoardOrAllBoard;
while (count--);
qDebug() << " preVideoClientId :" << preVideoId;
qDebug() << " clientId :" << clientId;
if ((boardTpye != 0) || (preVideoId == clientId)) {
qDebug() << "Current path: " << QDir::currentPath();
QString filePath = QDir::currentPath() + "/add1.h264";
if (QFile::exists(filePath)) {
QFile file(filePath);
if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
qDebug() << "File add1.h264 cleared successfully.";
}
else {
qDebug() << "Failed to clear file add1.h264:" << file.errorString();
}
}
else {
qDebug() << "File add1.h264 does not exist.";
}
}
connectedClientsCount--;
//qDebug() << " connectedClientsCount :" << connectedClientsCount;
updateServerButtonText();
break;
}
}
stopMdnsService();
//if (connectedClientsCount == 0) {
// // 启动 mDNS 服务广播
// startMdnsService();
//}
}
// 更新按键文本的函数
void MainWidget::updateServerButtonText()
{
@@ -428,6 +504,201 @@ void MainWidget::setupUI()
connect(saveCheckBox, &QCheckBox::stateChanged, this, &MainWidget::onSaveCheckBoxStateChanged);
}
void MainWidget::onStartImageSharing(int width, int height, QString img_type, std::function<void(QString)> callback) {
imagePath = QFileDialog::getOpenFileName(this, "选择图片", QDir::homePath(), "Images (*.png *.jpg *.jpeg)");
if (imagePath.isEmpty()) {
qDebug() << "No image selected.";
return;
}
// 加载图片并获取尺寸
QImage image(imagePath);
if (image.isNull()) {
qDebug() << "Failed to load image.";
return;
}
QSize imageSize = image.size();
qDebug() << "Original image dimensions:" << imageSize.width() << "x" << imageSize.height();
// 判断是否需要裁剪
if (imageSize.width() > width || imageSize.height() > height) {
int x = (imageSize.width() - width) / 2; // 左右裁剪
int y = (imageSize.height() - height) / 2; // 上下裁剪
// 裁剪图片中间部分
image = image.copy(x, y, width, height);
qDebug() << "Cropped image dimensions:" << image.width() << "x" << image.height();
}
else if(imageSize.width() < width || imageSize.height() < height) {
isReplyOrTimeout = true;
QString info = QString("您选择的图片尺寸小于 %1 x %2请重新操作并选择正确的尺寸的图片").arg(width).arg(height);
LicenseConfirmWindow dialog(info);
dialog.exec();
callback("");
return;
}
// 保存裁剪后的图片到服务器目录
QString croppedImagePath = QCoreApplication::applicationDirPath() + QString("/%1_image.jpg").arg(img_type);
if (!image.save(croppedImagePath, "JPEG")) {
qDebug() << "Failed to save cropped image.";
return;
}
qDebug() << "Cropped image saved to:" << croppedImagePath;
// 更新服务使用裁剪后的图片路径
this->imagePath = croppedImagePath;
// 获取本地 IP 地址
QString localIP;
QList<QHostAddress> addresses = QNetworkInterface::allAddresses();
for (const QHostAddress& addr : addresses) {
if (addr.protocol() == QAbstractSocket::IPv4Protocol && addr != QHostAddress::LocalHost) {
localIP = addr.toString();
break;
}
}
if (localIP.isEmpty()) {
qDebug() << "Failed to determine local IP address.";
return;
}
// 构建下载 URL
QString downloadUrl = QString("http://%1:%2/%3_image.jpg").arg(localIP).arg(serverPort).arg(img_type);
qDebug() << "Download URL:" << downloadUrl;
// 回调返回下载地址
callback(downloadUrl);
}
void MainWidget::setupHttpServer() {
connect(httpServer, &QTcpServer::newConnection, this, [this]() {
QTcpSocket* clientSocket = httpServer->nextPendingConnection();
connect(clientSocket, &QTcpSocket::readyRead, this, [this, clientSocket]() {
handleHttpRequest(clientSocket);
});
});
if (!httpServer->listen(QHostAddress::Any, serverPort)) {
qDebug() << "Failed to start HTTP server:" << httpServer->errorString();
}
else {
qDebug() << "HTTP server started on port" << serverPort;
}
}
void MainWidget::handleHttpRequest(QTcpSocket* clientSocket) {
QByteArray requestData = clientSocket->readAll();
qDebug() << "HTTP Request:" << requestData;
if (imagePath.isEmpty()) {
clientSocket->write("HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n");
clientSocket->disconnectFromHost();
return;
}
QFile file(imagePath);
if (!file.open(QIODevice::ReadOnly)) {
clientSocket->write("HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n");
clientSocket->disconnectFromHost();
return;
}
QByteArray imageData = file.readAll();
file.close();
QString response = QString("HTTP/1.1 200 OK\r\nContent-Type: image/jpeg\r\nContent-Length: %1\r\n\r\n")
.arg(imageData.size());
clientSocket->write(response.toUtf8());
clientSocket->write(imageData);
clientSocket->disconnectFromHost();
}
//void MainWidget::setupHttpServer() {
// connect(httpServer, &QTcpServer::newConnection, this, [this]() {
// QTcpSocket* clientSocket = httpServer->nextPendingConnection();
// connect(clientSocket, &QTcpSocket::readyRead, this, [this, clientSocket]() {
// handleHttpRequest(clientSocket);
// });
// });
//
// if (!httpServer->listen(QHostAddress::Any, serverPort)) {
// qDebug() << "Failed to start HTTP server:" << httpServer->errorString();
// }
// else {
// qDebug() << "HTTP server started on port" << serverPort;
// }
//}
//
//void MainWidget::handleHttpRequest(QTcpSocket* clientSocket) {
// QByteArray requestData = clientSocket->readAll();
// //qDebug() << "HTTP Request:" << requestData;
// if (imagePath.isEmpty()) {
// clientSocket->write("HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n");
// clientSocket->disconnectFromHost();
// return;
// }
//
// QFile file(imagePath);
// if (!file.open(QIODevice::ReadOnly)) {
// clientSocket->write("HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n");
// clientSocket->disconnectFromHost();
// return;
// }
//
// QByteArray imageData = file.readAll();
// file.close();
//
// QString response = QString("HTTP/1.1 200 OK\r\nContent-Type: image/jpeg\r\nContent-Length: %1\r\n\r\n")
// .arg(imageData.size());
// clientSocket->write(response.toUtf8());
// clientSocket->write(imageData);
// clientSocket->disconnectFromHost();
//}
//
////注意事项
////端口冲突:确保 8080 端口未被其他程序占用,可以更换为其他端口。
////防火墙规则:确保防火墙允许外部设备访问该端口。
////图片格式:上述代码默认处理 PNG/JPG/JPEG 格式,如果需要支持其他格式,可根据 MIME 类型调整 Content - Type
//void MainWidget::onStartImageSharing(int width, int height, std::function<void(QString)> callback) {
// imagePath = QFileDialog::getOpenFileName(this, "选择图片", QDir::homePath(), "Images (*.png *.jpg *.jpeg)");
//
// if (imagePath.isEmpty()) {
// qDebug() << "No image selected.";
// return;
// }
//
// // 加载图片并获取尺寸
// QImage image(imagePath);
// if (image.isNull()) {
// qDebug() << "Failed to load image.";
// return;
// }
// QSize imageSize = image.size();
// qDebug() << "Image dimensions:" << imageSize.width() << "x" << imageSize.height();
//
// QString localIP;
// QList<QHostAddress> addresses = QNetworkInterface::allAddresses();
// for (const QHostAddress& addr : addresses) {
// if (addr.protocol() == QAbstractSocket::IPv4Protocol && addr != QHostAddress::LocalHost) {
// localIP = addr.toString();
// break;
// }
// }
//
// if (localIP.isEmpty()) {
// qDebug() << "Failed to determine local IP address.";
// return;
// }
//
// QString downloadUrl = QString("http://%1:%2/").arg(localIP).arg(serverPort);
// qDebug() << "Download URL:" << downloadUrl;
//
// callback(downloadUrl);
//}
// 服务器响应
void MainWidget::onHttpRequestFinished(const QJsonObject& response)
{
@@ -501,9 +772,10 @@ QString calculateSignature(const QMap<QString, QString>& params, const QString&
// 3. 构造 BaseString
//QString baseString = params["batch"] + params["label"] + params["model"] + params["request_id"] + params["timestamp"] + params["factory_id"];
QString baseString = "1TEST_SL100_20240826SL100" + request_id + timestamp + "TEST";
//QString baseString = "1TEST_SL100_20240826SL100" + request_id + timestamp + FACTORY_ID;
QString baseString = QString::number(BATCH) + QString(LABEL) + QString(MODEL) + request_id + timestamp + QString(FACTORY_ID);
qDebug() << "baseString:" << baseString;
// 4. 构造 stringToSign
QString stringToSign = httpMethod + "&" + baseString + "&" + canonicalizedQueryString.replace("+", "%20");
qDebug() << "stringToSign:" << stringToSign;
@@ -513,10 +785,10 @@ QString calculateSignature(const QMap<QString, QString>& params, const QString&
// 请求头
void prepareRequestHeaders(QNetworkRequest& request, const QString& sign, const QString& request_id) {
request.setRawHeader("factory_id", "TEST");
request.setRawHeader("label", "TEST_SL100_20240826");
request.setRawHeader("batch", QString::number(1).toUtf8());
request.setRawHeader("model", "SL100");
request.setRawHeader("factory_id", QByteArray(FACTORY_ID));
request.setRawHeader("label", QByteArray(LABEL));
request.setRawHeader("batch", QString::number(BATCH).toUtf8());
request.setRawHeader("model", QByteArray(MODEL));
request.setRawHeader("timestamp", QString::number(QDateTime::currentSecsSinceEpoch()).toUtf8());
request.setRawHeader("request_id", request_id.toUtf8());
request.setRawHeader("sign", sign.toUtf8());
@@ -602,8 +874,6 @@ void MainWidget::FactoryToolSendPostTestToHttpServer() {
{"id", "123456"},
{"location", "allMachine"}
};
//QString itemString = "function=faceVerify,result=false,msg=timeout";
//QString itemString = "function=faceVerify,result=false,msg=timeout";
QString itemString = "[{\"function\":\"faceVerify\",\"msg\":\"timeout\",\"result\":false}]";
params["items"] = itemString;
@@ -724,25 +994,28 @@ void MainWidget::setupTimerForThreadPoolInfo()
void MainWidget::readJsonConfig()
{
frontBoardOneClickTest = readJson_frontBoardOneClickTest();
frontBoardTest = readJson_frontBoardTest();
frontBoardFuncConfig = readJson_frontBoardFuncConfig();
frontBoardDevInfoJson = readJson_frontDevInfo();
frontBoardLicenseJson = readJson_frontLicense();
frontBoardOneClickTest = readJson_frontBoardOneClickTest();
frontBoardTest = readJson_frontBoardTest();
frontBoardFuncConfig = readJson_frontBoardFuncConfig();
frontBoardDevInfoJson = readJson_frontDevInfo();
frontBoardLicenseJson = readJson_frontLicense();
//frontBoardCmdConfigJson = readJson_frontCmd_config();
backBoardOneClickTest = readJson_backBoardOneClickTest();
backBoardTest = readJson_backBoardTest();
backBoardFuncConfig = readJson_backBoardFuncConfig();
backBoardDevInfoJson = readJson_backDevInfo();
backBoardUuidJson = readJson_backUuid();
backBoardOneClickTest = readJson_backBoardOneClickTest();
backBoardTest = readJson_backBoardTest();
backBoardFuncConfig = readJson_backBoardFuncConfig();
backBoardDevInfoJson = readJson_backDevInfo();
backBoardUuidJson = readJson_backUuid();
//backBoardCmdConfigJson = readJson_backCmd_config();
factoryProductInfo = readJson_factoryProductInfo();
factoryProductInfo = readJson_factoryProductInfo();
testJsonConfig = readJson_testConfig();
funcJsonConfig = readJson_funcConfig();
getPicJson = readJson_getPic();
getVideoJson = readJson_getVideo();
}
void MainWidget::onSelectFileButtonClicked()
@@ -813,32 +1086,6 @@ void MainWidget::scrollToBottom()
statusListWidget->scrollToBottom();
}
void MainWidget::onDisconnectClient(int clientId)
{
for (ClientHandler* handler : clients) {
if (handler->getClientId() == clientId) {
// 断开与该客户端的连接
handler->getSocket()->disconnectFromHost();
handler->getSocket()->waitForDisconnected();
clients.removeOne(handler);
if (clientTimers.contains(clientId)) {
QTimer* timer = clientTimers[clientId];
timer->stop();
delete timer;
clientTimers.remove(clientId);
}
handler->deleteLater();
connectedClientsCount --;
updateServerButtonText();
break;
}
}
if (connectedClientsCount == 0) {
// 启动 mDNS 服务广播
startMdnsService();
}
}
QString formatLicenseKey(const QString& licenseKey) {
QString formattedKey;
qDebug() << "licenseKey.length():" << licenseKey.length();
@@ -1061,27 +1308,41 @@ void MainWidget::onUuidButtonClicked()
}
}
void MainWidget::startMdnsService()
{
QDateTime currentTime = QDateTime::currentDateTime();
QString formattedTime = currentTime.toString("yyyy-MM-dd hh:mm:ss.zzz");
qDebug() << "[" << formattedTime << "]:" << "Start Mdns Broadcast Service";
QString serviceName = "SL100 FactoryTool Mdns Broadcast Service";
QString serviceType = "_myservice._tcp.local";
quint16 port = TCP_CONNECT_PORT;
mServiceProvider->startServiceBroadcast(serviceName, serviceType, port);
void MainWidget::startMdnsService() {
const char* hostname = "SL100-FactoryTool-Mdns";
const char* service_name = "_myservice._tcp.local.";
int service_port = TCP_CONNECT_PORT;
if (!mdnsTimer->isActive()) {
mdnsTimer->start(1000);
// 如果线程已经存在且正在运行,先停止
if (mdnsThread && mdnsThread->isRunning()) {
qDebug() << "Stopping previous mDNS service thread...";
mdnsThread->stop();
mdnsThread->quit();
mdnsThread->wait();
delete mdnsThread;
}
// 创建新的线程并启动
mdnsThread = new MdnsServiceThread(hostname, service_name, service_port, this);
connect(mdnsThread, &QThread::finished, mdnsThread, &QObject::deleteLater); // 确保线程资源释放
mdnsThread->start();
}
void MainWidget::stopMdnsService()
{
if (mdnsTimer->isActive()) {
mdnsTimer->stop(); // 停止定时器
void MainWidget::stopMdnsService() {
if (mdnsThread) {
qDebug() << "Stopping mDNS service...";
mdnsThread->stop(); // 通知线程退出
if (mdnsThread->isRunning()) {
mdnsThread->quit(); // 退出线程事件循环
mdnsThread->wait(); // 等待线程完全退出
}
delete mdnsThread; // 释放线程资源
mdnsThread = nullptr;
qDebug() << "mDNS service stopped.";
}
else {
qDebug() << "mDNS service is not running.";
}
mServiceProvider->stopServiceBroadcast();
}
// 处理开始服务器按键点击事件
@@ -1409,10 +1670,11 @@ void MainWidget::onSendFrontFuncItemClicked()
QPushButton* button = qobject_cast<QPushButton*>(sender());
int itemIndex = button->property("frontBoardFuncConfig").toInt();
for (ClientHandler* handler : clients) {
if ((isBackBoardOrAllBoard) || (handler->getClientId() == handler->controlClientId)) {
if (isReplyOrTimeout && ((isBackBoardOrAllBoard) || (handler->getClientId() == handler->controlClientId))) {
QString text = frontFuncConfigLineEdit->text();
qDebug() << "Text in frontFuncConfigLineEdit:" << text;
handler->sendFrontFuncItem(itemIndex, text);
isReplyOrTimeout = false;
break;
}
}
@@ -1429,10 +1691,11 @@ void MainWidget::onSendBackFuncItemClicked()
QPushButton* button = qobject_cast<QPushButton*>(sender());
int itemIndex = button->property("backBoardFuncConfig").toInt();
for (ClientHandler* handler : clients) {
if ((isBackBoardOrAllBoard) || (handler->getClientId() == handler->controlClientId)) {
if (isReplyOrTimeout && ((isBackBoardOrAllBoard) || (handler->getClientId() == handler->controlClientId))) {
QString text = backFuncConfigLineEdit->text();
qDebug() << "Text in backFuncConfigLineEdit:" << text;
handler->sendBackFuncItem(itemIndex, text);
isReplyOrTimeout = false;
break;
}
}
@@ -1451,8 +1714,9 @@ void MainWidget::onSendFrontItemClicked()
QPushButton* button = qobject_cast<QPushButton*>(sender());
int itemIndex = button->property("frontBoardTest").toInt();
for (ClientHandler* handler : clients) {
if ((isBackBoardOrAllBoard) || (handler->getClientId() == handler->controlClientId)) {
if (isReplyOrTimeout && ((isBackBoardOrAllBoard) || (handler->getClientId() == handler->controlClientId))) {
handler->sendFrontItem(itemIndex);
isReplyOrTimeout = false;
break;
}
}
@@ -1470,8 +1734,9 @@ void MainWidget::onSendBackItemClicked()
QPushButton* button = qobject_cast<QPushButton*>(sender());
int itemIndex = button->property("backBoardTest").toInt();
for (ClientHandler* handler : clients) {
if ((isBackBoardOrAllBoard) || (handler->getClientId() == handler->controlClientId)) {
if (isReplyOrTimeout && ((isBackBoardOrAllBoard) || (handler->getClientId() == handler->controlClientId))) {
handler->sendBackItem(itemIndex);
isReplyOrTimeout = false;
break;
}
}
@@ -1484,6 +1749,7 @@ void MainWidget::onSendBackItemClicked()
void MainWidget::onStatusUpdated(const QString& client, bool success, const QJsonArray& jsonArray, int itemJsonIndex)
{
isReplyOrTimeout = true;
int clientId = -1;
QString label;
for (ClientHandler* handler : clients) {

View File

@@ -44,22 +44,29 @@
#include <QMessageAuthenticationCode>
#include <QCoreApplication>
#include <QSettings>
#include <QImage>
#include <QPainter>
#include <winsock2.h>
#include <iphlpapi.h>
#include "./UI_Widget/UI_Name.h"
#include "../Json/readJsonFile.h"
#include "../RecvDataHandler/RecvDataHandler.h"
#include "../LicenseGenerate/LicenseGenerate.h"
#include "../LicenseGenerate/LicenseConfirmWindow.h"
#include "../Network/mdns/servicemodel.h"
//#include "../Network/mdns/servicemodel.h"
#include "../Network/ClientHandler.h"
#include "../Network/httpClient.h"
#include "../Network/mdns/MdnsServiceThread.h"
#include "../Network/mdns/mdns.h"
#include "../Network/mdns/qmdnsengine/include/server.h"
#include "../Network/mdns/qmdnsengine/include/hostname.h"
#include "../Network/mdns/qmdnsengine/include/provider.h"
#include "../Network/mdns/qmdnsengine/include/service.h"
#include "../Network/mdns/qmdnsengine/include/message.h"
#include "../Network/mdns/qmdnsengine/include/query.h"
//#include "../Network/mdns/qmdnsengine/include/server.h"
//#include "../Network/mdns/qmdnsengine/include/hostname.h"
//#include "../Network/mdns/qmdnsengine/include/provider.h"
//#include "../Network/mdns/qmdnsengine/include/service.h"
//#include "../Network/mdns/qmdnsengine/include/message.h"
//#include "../Network/mdns/qmdnsengine/include/query.h"
#define TEST_UDP_BROADCAST 0 // 用于测试 UDP 组播实现 mdns 功能 非标准 mdns
#define MANUAL_UPLOAD_LICENSE 0 // 打开手动上传 License的功能
@@ -70,6 +77,12 @@
#define NEW_MAP 1
#define FACTORY_ID "TEST" // 工厂ID
#define LABEL "TEST_SL100_20240826" // 出货标签
#define BATCH 1 // 出货批次
#define MODEL "SL100" // 出货型号
class MainWidget : public QWidget
{
Q_OBJECT
@@ -79,6 +92,8 @@ public:
explicit MainWidget(QWidget* parent = nullptr);
~MainWidget();
void startHttpServer(const QString& imagePath);
signals:
void openFocusWindowRequested(int itemIndex);
@@ -86,6 +101,8 @@ private slots:
// 发送HTTP请求
//void onSomeButtonClicked();
// 处理HTTP响应
// 启动图片共享服务
void onStartImageSharing(int width, int height, QString img_type, std::function<void(QString)> callback);
void onHttpRequestFinished(const QJsonObject& response);
// 处理HTTP错误
void onHttpRequestError(const QString& errorString);
@@ -187,11 +204,13 @@ private:
QJsonArray frontBoardFuncConfig; // 前板功能配置参数 JSON
QJsonArray frontBoardDevInfoJson; // 前板设备信息参数 JSON
QJsonArray frontBoardLicenseJson; // 前板License JSON
QJsonArray frontBoardCmdConfigJson;
QJsonArray backBoardOneClickTest; // 后板一键功能测试 JSON
QJsonArray backBoardTest; // 后板单项测试 JSON
QJsonArray backBoardFuncConfig; // 后板功能配置参数 JSON
QJsonArray backBoardDevInfoJson; // 后板设备信息参数 JSON
QJsonArray backBoardUuidJson; // 后板UUID JSON
QJsonArray backBoardCmdConfigJson;
QJsonArray factoryProductInfo; // 整机:工厂生产信息
QJsonArray testJsonConfig; // 功能测试区 JSON 配置
QJsonArray funcJsonConfig; // 功能配置区 JSON 配置
@@ -213,6 +232,7 @@ private:
bool deviceConnected = false; // 判断是否有设备连接过
bool isSendingAll; // 一键功能测试 状态
bool checkBoxState = true;
bool isReplyOrTimeout = true;
QJsonObject licenseDataArray; // 用于保存从服务器获取的 data 字段对象
@@ -266,7 +286,7 @@ private:
QMap<int, QTimer*> clientReadTimers;
QMap<int, ClientHandler*> clients_1;
ServiceProvider* mServiceProvider;
//ServiceProvider* mServiceProvider;
QTimer* mdnsTimer;
void startMdnsService();
void stopMdnsService();
@@ -274,6 +294,14 @@ private:
QUdpSocket* multicastSocket;
QTimer* multicastTimer;
#endif
QTcpServer* httpServer; // HTTP 服务器
QString imagePath; // 当前选择的图片路径
quint16 serverPort = 8080; // HTTP 服务器端口
void setupHttpServer(); // 初始化 HTTP 服务器
void handleHttpRequest(QTcpSocket* clientSocket); // 处理 HTTP 请求
MdnsServiceThread* mdnsThread; // mDNS 线程指针
};
#endif // MAINWIDGET_H

View File

@@ -41,10 +41,12 @@ UI_config loadConfig(const QString& filePath)
{
UI_config config;
QMap<QString, QString> settings = parseIniFile(filePath);
// 可直接修改 UI_config.ini 文件
// 如果删除 UI_config.ini 文件中的 Labels 项,则使用如下代码的默认命名配置
// Labels 项 默认命名配置
config.SL100_FACTORY_TOOL_W = settings.value("Window/width", "1340").toInt();
config.SL100_FACTORY_TOOL_H = settings.value("Window/height", "900").toInt();
config.TOOL_VERSION = settings.value("Labels/tool_version", "SL100 工厂产测工具 - V0.0.8");
config.TOOL_VERSION = settings.value("Labels/tool_version", "SL100 工厂产测工具 - V0.0.10");
config.START_LISTENING = settings.value("Labels/start_listening", "开始监听\n(Start Listening...)");
config.ONE_CLICKED_TEST = settings.value("Labels/one_clicked_test", "一键功能测试");
config.FRONT_BOARD_NAME = settings.value("Labels/front_board_name", "前 板");