1.添加图片注册和前后板主题图片上传;2.修改mdns连接方式
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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", "前 板");
|
||||
|
||||
Reference in New Issue
Block a user