2024-08-19 01:39:32 +00:00
|
|
|
|
// MainWidget.cpp
|
2024-08-01 01:17:17 +00:00
|
|
|
|
#include "MainWidget.h"
|
2024-08-19 01:39:32 +00:00
|
|
|
|
|
2024-09-02 10:37:24 +00:00
|
|
|
|
void onThreadFinished(QThread* thread, ClientHandler* handler, DataHandler* dataHandler)
|
2024-08-01 01:17:17 +00:00
|
|
|
|
{
|
|
|
|
|
qDebug() << "Thread finished. Deleting handler and thread.";
|
2024-08-19 01:39:32 +00:00
|
|
|
|
handler->deleteLater();
|
2024-09-02 10:37:24 +00:00
|
|
|
|
dataHandler->deleteLater();
|
2024-08-19 01:39:32 +00:00
|
|
|
|
thread->deleteLater();
|
2024-08-01 01:17:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-08-06 12:32:02 +00:00
|
|
|
|
// 初始化 UI 组件和服务器
|
2024-08-01 01:17:17 +00:00
|
|
|
|
MainWidget::MainWidget(QWidget* parent) :
|
|
|
|
|
QWidget(parent),
|
|
|
|
|
nextClientId(1),
|
|
|
|
|
manualSend(false),
|
|
|
|
|
isSendingAll(false),
|
|
|
|
|
lastClickedGetPicCamIndex(-1),
|
|
|
|
|
lastClickedGetPicDevIndex(-1),
|
|
|
|
|
lastClickedGetVideoCamIndex(-1),
|
2024-08-19 01:39:32 +00:00
|
|
|
|
lastClickedGetVideoDevIndex(-1),
|
|
|
|
|
mServiceProvider(new ServiceProvider(this)),
|
2024-08-26 10:33:55 +00:00
|
|
|
|
mdnsTimer(new QTimer(this)),
|
|
|
|
|
httpClient(new HttpClient(this))
|
2024-08-19 01:39:32 +00:00
|
|
|
|
#if TEST_UDP_BROADCAST
|
|
|
|
|
,multicastSocket(new QUdpSocket(this)),
|
|
|
|
|
multicastTimer(new QTimer(this))
|
|
|
|
|
#endif
|
2024-08-01 01:17:17 +00:00
|
|
|
|
{
|
2024-09-02 02:22:41 +00:00
|
|
|
|
leftLens_imageLabel = new QLabel(this);
|
|
|
|
|
rightLens_imageLabel = new QLabel(this);
|
|
|
|
|
videoLabel = new QLabel(this);
|
2024-08-26 10:33:55 +00:00
|
|
|
|
frontFuncConfigLineEdit = new QLineEdit(this);
|
2024-09-02 02:22:41 +00:00
|
|
|
|
backFuncConfigLineEdit = new QLineEdit(this);
|
|
|
|
|
licenseHwInfoEdit = new QTextEdit(this);
|
|
|
|
|
UuidHwInfoEdit = new QTextEdit(this);
|
|
|
|
|
|
2024-08-01 01:17:17 +00:00
|
|
|
|
setupUI();
|
|
|
|
|
// 打印线程池状态信息
|
|
|
|
|
setupTimerForThreadPoolInfo();
|
|
|
|
|
server = new QTcpServer(this);
|
2024-09-02 10:37:24 +00:00
|
|
|
|
|
2024-08-19 01:39:32 +00:00
|
|
|
|
connect(server, &QTcpServer::newConnection, this, [this]() {
|
2024-08-01 01:17:17 +00:00
|
|
|
|
// 检查是否有挂起的连接
|
|
|
|
|
while (server->hasPendingConnections()) {
|
2024-09-03 07:58:23 +00:00
|
|
|
|
QTcpSocket* socket = server->nextPendingConnection();
|
|
|
|
|
int clientId = nextClientId ++;
|
|
|
|
|
QHostAddress clientIp = socket->peerAddress();
|
|
|
|
|
quint16 clientPort = socket->peerPort();
|
|
|
|
|
QString ipString = clientIp.toString();
|
2024-09-02 02:22:41 +00:00
|
|
|
|
if (ipString.startsWith("::ffff:")) {
|
|
|
|
|
ipString = ipString.mid(7);
|
|
|
|
|
}
|
2024-08-01 01:17:17 +00:00
|
|
|
|
qDebug() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>";
|
|
|
|
|
qDebug() << "> A client is connected. ID:" << clientId;
|
2024-09-03 07:58:23 +00:00
|
|
|
|
qDebug() << "> Client IP:" << ipString << " Port:" << clientPort;
|
2024-08-01 01:17:17 +00:00
|
|
|
|
qDebug() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>";
|
|
|
|
|
|
2024-09-02 02:22:41 +00:00
|
|
|
|
if (ipString.startsWith("10.10.10")) {
|
|
|
|
|
qDebug() << "The client IP address is front board !!!";
|
|
|
|
|
isBackBoardOrAllBoard = 0;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
qDebug() << "The client IP address is back board or all board";
|
|
|
|
|
isBackBoardOrAllBoard = clientId;
|
|
|
|
|
}
|
2024-08-19 01:39:32 +00:00
|
|
|
|
stopMdnsService();
|
2024-09-02 02:22:41 +00:00
|
|
|
|
connectedClientsCount ++;
|
2024-08-01 01:17:17 +00:00
|
|
|
|
updateServerButtonText();
|
|
|
|
|
|
|
|
|
|
QTimer* timer = new QTimer(this);
|
|
|
|
|
timer->setSingleShot(true);
|
|
|
|
|
clientTimers[clientId] = timer;
|
|
|
|
|
|
|
|
|
|
// 连接定时器超时信号到槽函数
|
|
|
|
|
connect(timer, &QTimer::timeout, this, [this, clientId]() {
|
|
|
|
|
//qDebug() << "Timeout occurred for client ID:" << clientId;
|
|
|
|
|
for (ClientHandler* handler : clients) {
|
|
|
|
|
if (handler->getClientId() == clientId) {
|
|
|
|
|
bool invoked = QMetaObject::invokeMethod(handler, "onTimeout", Qt::DirectConnection);
|
|
|
|
|
if (!invoked) {
|
|
|
|
|
qWarning() << "Failed to invoke onTimeout for client ID:" << clientId;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2024-09-02 02:22:41 +00:00
|
|
|
|
QThread* thread = new QThread(this);
|
2024-09-04 03:32:19 +00:00
|
|
|
|
#if TEST_TCP_MOVE_TO_MAIN
|
2024-08-06 12:32:02 +00:00
|
|
|
|
ClientHandler* handler = new ClientHandler(socket, frontBoardOneClickTest, frontBoardTest, frontBoardFuncConfig,
|
2024-08-26 10:33:55 +00:00
|
|
|
|
frontBoardDevInfoJson, frontBoardLicenseJson,
|
|
|
|
|
backBoardOneClickTest, backBoardTest, backBoardFuncConfig, backBoardDevInfoJson,
|
2024-09-02 02:22:41 +00:00
|
|
|
|
backBoardUuidJson, getPicJson, getVideoJson, clientId, isBackBoardOrAllBoard, nullptr);
|
2024-09-04 03:32:19 +00:00
|
|
|
|
#else
|
|
|
|
|
ClientHandler* handler = new ClientHandler(frontBoardOneClickTest, frontBoardTest, frontBoardFuncConfig,
|
|
|
|
|
frontBoardDevInfoJson, frontBoardLicenseJson,
|
|
|
|
|
backBoardOneClickTest, backBoardTest, backBoardFuncConfig, backBoardDevInfoJson,
|
|
|
|
|
backBoardUuidJson, getPicJson, getVideoJson, clientId, isBackBoardOrAllBoard, nullptr);
|
|
|
|
|
/*
|
|
|
|
|
* 一定要先取消父对象,否则报错:QObject::moveToThread: Cannot move objects with a parent
|
|
|
|
|
* 父对象负责管理子对象的生命周期,如果子对象被移动到其他线程,可能会导致线程安全问题或不一致的对象状态
|
|
|
|
|
*/
|
|
|
|
|
socket->setParent(nullptr);
|
|
|
|
|
// 将 socket 移动到新的线程中
|
|
|
|
|
socket->moveToThread(thread);
|
|
|
|
|
// 将 socket 传递到 handler
|
|
|
|
|
handler->initialize(socket);
|
|
|
|
|
#endif
|
2024-09-02 10:37:24 +00:00
|
|
|
|
// 将 ClientHandler 移到线程池中的线程
|
2024-08-01 01:17:17 +00:00
|
|
|
|
handler->moveToThread(thread);
|
|
|
|
|
|
2024-09-02 10:37:24 +00:00
|
|
|
|
// 创建 DataHandler 对象并连接信号
|
2024-09-03 07:58:23 +00:00
|
|
|
|
DataHandler* dataHandler = new DataHandler(videoLabel, VideoResolutionEdit, leftLens_imageLabel->size(), &devInfoLineEdits,
|
2024-09-02 10:37:24 +00:00
|
|
|
|
frontBoardOneClickTest, frontBoardTest, frontBoardFuncConfig,
|
|
|
|
|
frontBoardDevInfoJson, frontBoardLicenseJson,
|
|
|
|
|
backBoardOneClickTest, backBoardTest, backBoardFuncConfig, backBoardDevInfoJson,
|
|
|
|
|
backBoardUuidJson, getPicJson, getVideoJson, nullptr);
|
|
|
|
|
// 将 DataHandler 移到线程池中的线程
|
|
|
|
|
dataHandler->moveToThread(thread);
|
2024-09-04 03:32:19 +00:00
|
|
|
|
#if TEST_TCP_MOVE_TO_MAIN
|
2024-08-01 01:17:17 +00:00
|
|
|
|
// 将sendData信号连接到主线程中的槽上
|
2024-09-02 02:22:41 +00:00
|
|
|
|
connect(handler, &ClientHandler::sendData, this, [socket](const QByteArray& data, int isBoardType) {
|
2024-08-26 10:33:55 +00:00
|
|
|
|
/*socket->write(data);
|
|
|
|
|
socket->flush();*/
|
|
|
|
|
//qDebug() << "---------------------data.size():" << data.size();
|
|
|
|
|
QByteArray prefix;
|
|
|
|
|
QDataStream stream(&prefix, QIODevice::WriteOnly);
|
|
|
|
|
stream.setByteOrder(QDataStream::LittleEndian);
|
|
|
|
|
stream << quint32(0x55AA55AA);
|
2024-09-02 02:22:41 +00:00
|
|
|
|
if (isBoardType != 0) {
|
|
|
|
|
stream << quint16(0x0421);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
stream << quint16(0x0420);
|
|
|
|
|
}
|
2024-08-26 10:33:55 +00:00
|
|
|
|
stream << quint32(data.size());
|
|
|
|
|
prefix.append(data);
|
|
|
|
|
|
|
|
|
|
qDebug() << "Sending data:" << prefix.toHex();
|
|
|
|
|
|
|
|
|
|
socket->write(prefix);
|
2024-08-01 01:17:17 +00:00
|
|
|
|
socket->flush();
|
|
|
|
|
});
|
2024-09-04 03:32:19 +00:00
|
|
|
|
#else
|
|
|
|
|
connect(handler, &ClientHandler::sendData, handler, &ClientHandler::onSendData, Qt::QueuedConnection);
|
|
|
|
|
#endif
|
2024-08-01 01:17:17 +00:00
|
|
|
|
connect(handler, &ClientHandler::startTimeout, this, [this, clientId](int timeout) {
|
|
|
|
|
this->onStartTimeout(clientId, timeout);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
clients.append(handler);
|
|
|
|
|
clients_1[clientId] = handler;
|
|
|
|
|
clientThreads[clientId] = thread;
|
2024-08-29 03:49:55 +00:00
|
|
|
|
connect(handler, &ClientHandler::statusUpdated, this, &MainWidget::onStatusUpdated);
|
|
|
|
|
connect(handler, &ClientHandler::clientDisconnected, this, &MainWidget::onClientDisconnected);
|
|
|
|
|
connect(handler, &ClientHandler::allItemsProcessed, this, &MainWidget::onAllItemsProcessed);
|
2024-08-01 01:17:17 +00:00
|
|
|
|
connect(handler, &ClientHandler::selectClientDisconnected, this, &MainWidget::onDisconnectClient);
|
2024-09-04 03:32:19 +00:00
|
|
|
|
|
2024-09-02 02:22:41 +00:00
|
|
|
|
dataHandlers[clientId] = dataHandler;
|
2024-09-02 10:37:24 +00:00
|
|
|
|
connect(handler, &ClientHandler::dataReceived, dataHandler, &DataHandler::handleData);
|
|
|
|
|
connect(dataHandler, &DataHandler::statusUpdated, this, &MainWidget::onStatusUpdated);
|
|
|
|
|
// 当线程结束时删除 handler
|
|
|
|
|
connect(thread, &QThread::finished, this, [=]() {
|
|
|
|
|
onThreadFinished(thread, handler, dataHandler);
|
|
|
|
|
});
|
2024-09-03 07:58:23 +00:00
|
|
|
|
connect(dataHandler, &DataHandler::updateLicenseHwInfoEdit, this, [this](const QString& text) {
|
|
|
|
|
licenseHwInfoEdit->setPlainText(text);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
connect(dataHandler, &DataHandler::updateLeftLensImage, leftLens_imageLabel, &QLabel::setPixmap);
|
|
|
|
|
connect(dataHandler, &DataHandler::updateRightLensImage, rightLens_imageLabel, &QLabel::setPixmap);
|
|
|
|
|
connect(dataHandler, &DataHandler::updateVideoLabel, videoLabel, &QLabel::setPixmap);
|
|
|
|
|
connect(dataHandler, &DataHandler::updateVideoResolution, VideoResolutionEdit, &QLineEdit::setText);
|
|
|
|
|
|
2024-09-02 10:37:24 +00:00
|
|
|
|
// 启动新的线程
|
|
|
|
|
thread->start();
|
|
|
|
|
|
2024-09-04 03:32:19 +00:00
|
|
|
|
connect(handler, &ClientHandler::startReadTimer, this, &MainWidget::startClientReadTimer);
|
|
|
|
|
connect(handler, &ClientHandler::stopReadTimer, this, &MainWidget::stopClientReadTimer);
|
|
|
|
|
connect(this, &MainWidget::openFocusWindowRequested, dataHandler, &DataHandler::handleOpenFocusWindow);
|
2024-08-01 01:17:17 +00:00
|
|
|
|
|
|
|
|
|
// 创建和管理定时器
|
|
|
|
|
QTimer* readTimer = new QTimer(this);
|
|
|
|
|
connect(readTimer, &QTimer::timeout, handler, &ClientHandler::onTimeoutRead);
|
|
|
|
|
// readTimer->start(10); // 每 10ms 触发一次
|
|
|
|
|
// 将定时器存储到哈希表中,方便管理
|
|
|
|
|
clientReadTimers[clientId] = readTimer;
|
2024-08-26 10:33:55 +00:00
|
|
|
|
|
|
|
|
|
connect(handler, &ClientHandler::sendDataToSomeClient, this, &MainWidget::sendDataToClient);
|
2024-08-01 01:17:17 +00:00
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2024-08-26 10:33:55 +00:00
|
|
|
|
connect(httpClient, &HttpClient::requestFinished, this, &MainWidget::onHttpRequestFinished);
|
|
|
|
|
connect(httpClient, &HttpClient::requestError, this, &MainWidget::onHttpRequestError);
|
|
|
|
|
|
2024-08-01 01:17:17 +00:00
|
|
|
|
threadStatusTimer = new QTimer(this);
|
|
|
|
|
connect(threadStatusTimer, &QTimer::timeout, this, &MainWidget::onCheckThreadStatus);
|
|
|
|
|
//threadStatusTimer->start(100); // 每100ms检查一次线程状态
|
|
|
|
|
|
|
|
|
|
connectionStatusCheckTimer = new QTimer(this);
|
|
|
|
|
connect(connectionStatusCheckTimer, &QTimer::timeout, this, &MainWidget::onCheckConnectionStatus);
|
|
|
|
|
//connectionStatusCheckTimer->start(100); // 每100ms检查一次连接状态
|
2024-08-19 01:39:32 +00:00
|
|
|
|
connect(mdnsTimer, &QTimer::timeout, this, &MainWidget::startMdnsService);
|
|
|
|
|
|
|
|
|
|
#if TEST_UDP_BROADCAST
|
|
|
|
|
// 设置组播地址
|
|
|
|
|
QHostAddress groupAddress("224.0.0.251");
|
|
|
|
|
quint16 port = 5353;
|
|
|
|
|
|
|
|
|
|
// 绑定UDP套接字
|
|
|
|
|
if (!multicastSocket->bind(QHostAddress::AnyIPv4, port, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint)) {
|
|
|
|
|
qWarning() << "Failed to bind multicast socket";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 加入组播组
|
|
|
|
|
bool joined = multicastSocket->joinMulticastGroup(groupAddress);
|
|
|
|
|
if (!joined) {
|
|
|
|
|
qWarning() << "Failed to join multicast group";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 定期发送组播消息
|
|
|
|
|
connect(multicastTimer, &QTimer::timeout, this, &MainWidget::sendMulticastMessage);
|
|
|
|
|
multicastTimer->start(1000); // 每秒发送一次组播消息
|
|
|
|
|
#endif
|
2024-08-01 01:17:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-08-19 01:39:32 +00:00
|
|
|
|
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();
|
2024-08-01 01:17:17 +00:00
|
|
|
|
for (auto timer : clientReadTimers) {
|
|
|
|
|
timer->stop();
|
|
|
|
|
delete timer;
|
|
|
|
|
}
|
|
|
|
|
clientReadTimers.clear();
|
2024-09-02 02:22:41 +00:00
|
|
|
|
|
|
|
|
|
for (auto dataHandler : dataHandlers) {
|
|
|
|
|
dataHandler->deleteLater();
|
|
|
|
|
}
|
|
|
|
|
dataHandlers.clear();
|
|
|
|
|
|
2024-08-01 01:17:17 +00:00
|
|
|
|
for (ClientHandler* handler : clients) {
|
|
|
|
|
handler->deleteLater();
|
|
|
|
|
}
|
|
|
|
|
server->close();
|
2024-08-06 12:32:02 +00:00
|
|
|
|
|
|
|
|
|
for (auto thread : clientThreads) {
|
|
|
|
|
thread->quit();
|
|
|
|
|
thread->wait();
|
|
|
|
|
delete thread;
|
|
|
|
|
}
|
|
|
|
|
clientThreads.clear();
|
|
|
|
|
|
|
|
|
|
for (auto handler : clients_1) {
|
|
|
|
|
handler->deleteLater();
|
|
|
|
|
}
|
|
|
|
|
clients_1.clear();
|
|
|
|
|
|
|
|
|
|
for (auto timer : clientTimers) {
|
|
|
|
|
timer->stop();
|
|
|
|
|
delete timer;
|
|
|
|
|
}
|
|
|
|
|
clientTimers.clear();
|
|
|
|
|
|
|
|
|
|
if (server->isListening()) {
|
|
|
|
|
server->close();
|
|
|
|
|
}
|
2024-08-01 01:17:17 +00:00
|
|
|
|
qDebug() << "MainWidget destroyed";
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-02 02:22:41 +00:00
|
|
|
|
// 处理客户端断开连接信号
|
|
|
|
|
void MainWidget::onClientDisconnected(ClientHandler* handler)
|
|
|
|
|
{
|
|
|
|
|
int clientId = handler->getClientId();
|
|
|
|
|
qDebug() << " preVideoClientId :" << handler->preVideoClientId;
|
|
|
|
|
qDebug() << " clientId :" << clientId;
|
|
|
|
|
if (handler->preVideoClientId == 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.";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (clientTimers.contains(clientId)) {
|
|
|
|
|
QTimer* timer = clientTimers[clientId];
|
|
|
|
|
timer->stop();
|
|
|
|
|
delete timer;
|
|
|
|
|
clientTimers.remove(clientId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
clients.removeOne(handler);
|
|
|
|
|
/*
|
|
|
|
|
将 ClientHandler 对象的删除操作放入事件队列中,等待事件循环处理。
|
|
|
|
|
在事件循环执行时,会安全地删除 ClientHandler 对象,这包括释放其占用的资源和内存
|
|
|
|
|
*/
|
|
|
|
|
handler->deleteLater(); // 延迟删除 ClientHandler 对象
|
|
|
|
|
|
|
|
|
|
if (dataHandlers.contains(clientId)) {
|
|
|
|
|
DataHandler* dataHandler = dataHandlers[clientId];
|
|
|
|
|
dataHandlers.remove(clientId); // 从容器中移除
|
|
|
|
|
dataHandler->deleteLater(); // 延迟删除 DataHandler 对象
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 更新连接数并更新按键文本
|
|
|
|
|
connectedClientsCount--;
|
|
|
|
|
qDebug() << " connectedClientsCount :" << connectedClientsCount;
|
|
|
|
|
if (nextClientId <= 2) nextClientId--;
|
|
|
|
|
deviceConnected = true;
|
|
|
|
|
|
|
|
|
|
updateServerButtonText();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 更新按键文本的函数
|
|
|
|
|
void MainWidget::updateServerButtonText()
|
|
|
|
|
{
|
|
|
|
|
if (deviceConnected) {
|
|
|
|
|
if (connectedClientsCount > 0) {
|
|
|
|
|
startServerButton->setText(tr("正在监听(Listening)\n%1 台设备连接").arg(connectedClientsCount));
|
|
|
|
|
}
|
|
|
|
|
else if (connectedClientsCount == 0) {
|
|
|
|
|
#if START_MDNS // 这里会开启多个mdns广播,去掉
|
|
|
|
|
startMdnsService();
|
|
|
|
|
#endif
|
|
|
|
|
deviceConnected = false;
|
|
|
|
|
startServerButton->setText(tr("正在监听(Listening)"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (connectedClientsCount == 0) {
|
|
|
|
|
startServerButton->setText(tr("开始监听\n(Start Listening...)"));
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
startServerButton->setText(tr("正在监听(Listening)\n%1 台设备连接").arg(connectedClientsCount));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 设置 UI
|
|
|
|
|
void MainWidget::setupUI()
|
|
|
|
|
{
|
|
|
|
|
startServerButton = new QPushButton("开始监听\n(Start Listening...)", this);
|
|
|
|
|
startServerButton->setFixedSize(190, 70);
|
|
|
|
|
|
|
|
|
|
sendAllButton = new QPushButton("一键功能测试", this);
|
|
|
|
|
sendAllButton->setFixedSize(190, 70);
|
|
|
|
|
sendAllButton->setEnabled(false);
|
|
|
|
|
|
|
|
|
|
statusListWidget = new QListWidget(this);
|
|
|
|
|
statusListWidget->setMinimumSize(350, 840);
|
|
|
|
|
statusListWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
|
|
|
|
|
|
|
|
QHBoxLayout* buttonLayout = new QHBoxLayout;
|
|
|
|
|
buttonLayout->addWidget(startServerButton);
|
|
|
|
|
buttonLayout->addWidget(sendAllButton);
|
|
|
|
|
buttonLayout->addStretch();
|
|
|
|
|
|
|
|
|
|
QVBoxLayout* leftLayout = new QVBoxLayout;
|
|
|
|
|
leftLayout->addLayout(buttonLayout);
|
|
|
|
|
leftLayout->setStretch(0, 1);
|
|
|
|
|
leftLayout->addWidget(statusListWidget);
|
|
|
|
|
leftLayout->setStretch(1, 200);
|
|
|
|
|
|
|
|
|
|
saveCheckBox = new QCheckBox("", this);
|
|
|
|
|
saveCheckBox->setChecked(true);
|
|
|
|
|
selectFileButton = new QPushButton("Save", this);
|
|
|
|
|
selectFileButton->setFixedSize(45, 28);
|
|
|
|
|
clearLogButton = new QPushButton("Clear", this);
|
|
|
|
|
clearLogButton->setFixedSize(55, 28);
|
|
|
|
|
filePathLineEdit = new QLineEdit(this);
|
|
|
|
|
filePathLineEdit->setFixedSize(250, 28);
|
|
|
|
|
filePathLineEdit->setReadOnly(true);
|
|
|
|
|
|
|
|
|
|
QHBoxLayout* fileLayout = new QHBoxLayout;
|
|
|
|
|
fileLayout->addWidget(saveCheckBox);
|
|
|
|
|
fileLayout->addWidget(selectFileButton);
|
|
|
|
|
fileLayout->addWidget(filePathLineEdit);
|
|
|
|
|
fileLayout->addWidget(clearLogButton);
|
|
|
|
|
|
|
|
|
|
leftLayout->addLayout(fileLayout);
|
|
|
|
|
leftLayout->setStretch(2, 1);
|
|
|
|
|
|
|
|
|
|
// 读取 JSON 配置文件
|
|
|
|
|
readJsonConfig();
|
|
|
|
|
|
|
|
|
|
QWidget* leftContainer = new QWidget(this);
|
|
|
|
|
leftContainer->setLayout(leftLayout);
|
|
|
|
|
leftContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
|
|
|
|
|
|
|
|
// 前板
|
|
|
|
|
QGroupBox* frontDeviceInfoGroupBox = createFrontDeviceInfoGroupBox();
|
|
|
|
|
QGroupBox* frontLicenseGroupBox = createLicenseGroupBox();
|
|
|
|
|
|
|
|
|
|
QHBoxLayout* frontGroupBoxLayout = new QHBoxLayout;
|
|
|
|
|
frontGroupBoxLayout->addWidget(frontDeviceInfoGroupBox, 1);
|
|
|
|
|
frontGroupBoxLayout->addWidget(frontLicenseGroupBox, 1);
|
|
|
|
|
|
|
|
|
|
QTabWidget* frontTabWidget = new QTabWidget(this);
|
|
|
|
|
frontTabWidget->setFixedSize(900, 315);
|
|
|
|
|
QWidget* frontFunctionTestTab = createFunctionTestTab(frontBoardTest, "frontBoardTest");
|
|
|
|
|
QWidget* frontFunctionConfigTab = createFunctionConfigTab(frontBoardFuncConfig, "frontBoardFuncConfig");
|
|
|
|
|
frontTabWidget->addTab(frontFunctionTestTab, "前板测试项");
|
|
|
|
|
frontTabWidget->addTab(frontFunctionConfigTab, "前板配置项");
|
|
|
|
|
|
|
|
|
|
QTabWidget* mainTabWidget = new QTabWidget(this);
|
|
|
|
|
QWidget* frontDevAreaTab = new QWidget(this);
|
|
|
|
|
QVBoxLayout* frontDevLayout = new QVBoxLayout(frontDevAreaTab);
|
|
|
|
|
frontDevLayout->addLayout(frontGroupBoxLayout);
|
|
|
|
|
frontDevLayout->addWidget(frontTabWidget, 2, Qt::AlignTop | Qt::AlignLeft);
|
|
|
|
|
mainTabWidget->addTab(frontDevAreaTab, "前 板");
|
|
|
|
|
|
|
|
|
|
// 后板
|
|
|
|
|
QGroupBox* backDeviceInfoGroupBox1 = createBackDeviceInfoGroupBox();
|
|
|
|
|
QGroupBox* BackConnectServerGroupBox = createBackConnectServerGroupBox();
|
|
|
|
|
|
|
|
|
|
QHBoxLayout* backGroupBoxLayout = new QHBoxLayout;
|
|
|
|
|
backGroupBoxLayout->addWidget(backDeviceInfoGroupBox1, 1);
|
|
|
|
|
backGroupBoxLayout->addWidget(BackConnectServerGroupBox, 1);
|
|
|
|
|
|
|
|
|
|
QTabWidget* backTabWidget = new QTabWidget(this);
|
|
|
|
|
backTabWidget->setFixedSize(900, 315);
|
|
|
|
|
QWidget* backFunctionTestTab = createFunctionTestTab(backBoardTest, "backBoardTest");
|
|
|
|
|
QWidget* backFunctionConfigTab = createFunctionConfigTab(backBoardFuncConfig, "backBoardFuncConfig");
|
|
|
|
|
backTabWidget->addTab(backFunctionTestTab, "后板测试项");
|
|
|
|
|
backTabWidget->addTab(backFunctionConfigTab, "后板配置项");
|
|
|
|
|
|
|
|
|
|
QWidget* backDevAreaTab = new QWidget(this);
|
|
|
|
|
QVBoxLayout* backDevLayout = new QVBoxLayout(backDevAreaTab);
|
|
|
|
|
backDevLayout->addLayout(backGroupBoxLayout);
|
|
|
|
|
backDevLayout->addWidget(backTabWidget, 2, Qt::AlignTop | Qt::AlignLeft);
|
|
|
|
|
mainTabWidget->addTab(backDevAreaTab, "后 板");
|
|
|
|
|
|
|
|
|
|
// 整机
|
|
|
|
|
QWidget* allDevAreaTab = new QWidget(this);
|
|
|
|
|
QVBoxLayout* allDevLayout = new QVBoxLayout(allDevAreaTab);
|
|
|
|
|
mainTabWidget->addTab(allDevAreaTab, "整 机");
|
|
|
|
|
|
|
|
|
|
QTabWidget* tabWidget_media = new QTabWidget(this);
|
|
|
|
|
QWidget* imageDisplayTab = createImageDisplayTab();
|
|
|
|
|
QWidget* videoDisplayTab = createVideoDisplayTab();
|
|
|
|
|
tabWidget_media->addTab(imageDisplayTab, "图像显示区");
|
|
|
|
|
tabWidget_media->addTab(videoDisplayTab, "视频显示区");
|
|
|
|
|
|
|
|
|
|
QVBoxLayout* rightVerticalLayout = new QVBoxLayout;
|
|
|
|
|
rightVerticalLayout->addWidget(mainTabWidget, 5);
|
|
|
|
|
rightVerticalLayout->addWidget(tabWidget_media, 4);
|
|
|
|
|
|
|
|
|
|
QHBoxLayout* mainLayout = new QHBoxLayout;
|
|
|
|
|
mainLayout->addWidget(leftContainer, 1, Qt::AlignTop | Qt::AlignLeft);
|
|
|
|
|
mainLayout->addLayout(rightVerticalLayout, 3);
|
|
|
|
|
|
|
|
|
|
setLayout(mainLayout);
|
2024-09-03 07:58:23 +00:00
|
|
|
|
setWindowTitle("SL100 工厂产测工具 - V0.0.4");
|
2024-09-02 02:22:41 +00:00
|
|
|
|
resize(1340, 900);
|
|
|
|
|
|
|
|
|
|
connect(startServerButton, &QPushButton::clicked, this, &MainWidget::onStartServerClicked);
|
|
|
|
|
connect(sendAllButton, &QPushButton::clicked, this, &MainWidget::onSendAllClicked);
|
|
|
|
|
connect(statusListWidget, &QListWidget::itemChanged, this, &MainWidget::scrollToBottom);
|
|
|
|
|
connect(selectFileButton, &QPushButton::clicked, this, &MainWidget::onSelectFileButtonClicked);
|
|
|
|
|
connect(clearLogButton, &QPushButton::clicked, this, &MainWidget::onclearLogButtonClicked);
|
|
|
|
|
connect(saveCheckBox, &QCheckBox::stateChanged, this, &MainWidget::onSaveCheckBoxStateChanged);
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-26 10:33:55 +00:00
|
|
|
|
// 服务器响应
|
|
|
|
|
void MainWidget::onHttpRequestFinished(const QJsonObject& response)
|
|
|
|
|
{
|
|
|
|
|
isRequestSuccessful = 0;
|
|
|
|
|
if (response.contains("msg") && response["msg"].toString() == "ok") {
|
|
|
|
|
if (response.contains("data") && response["data"].isObject()) {
|
|
|
|
|
licenseDataArray = response["data"].toObject();
|
|
|
|
|
isRequestSuccessful = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
isRequestSuccessful = 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWidget::onHttpRequestError(const QString& errorString)
|
|
|
|
|
{
|
|
|
|
|
qWarning() << "HTTP request failed:" << errorString;
|
|
|
|
|
isRequestSuccessful = 2;
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-29 03:49:55 +00:00
|
|
|
|
// 生成随机字符串
|
|
|
|
|
QString generateRandomRequestID(int minBitStr, int maxBitStr) {
|
2024-08-26 10:33:55 +00:00
|
|
|
|
const QString possibleCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~";
|
2024-08-29 03:49:55 +00:00
|
|
|
|
int length = QRandomGenerator::global()->bounded(minBitStr, maxBitStr); // 生成长度在minBitStr到maxBitStr之间
|
2024-08-26 10:33:55 +00:00
|
|
|
|
QString randomString;
|
|
|
|
|
for (int i = 0; i < length; ++i) {
|
|
|
|
|
int index = QRandomGenerator::global()->bounded(possibleCharacters.size());
|
|
|
|
|
randomString.append(possibleCharacters.at(index));
|
|
|
|
|
}
|
|
|
|
|
qDebug() << "randomString request_id:" << randomString;
|
|
|
|
|
return randomString;
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-29 03:49:55 +00:00
|
|
|
|
// 哈希256 转 base64
|
2024-08-26 10:33:55 +00:00
|
|
|
|
QString HmacSha256ToBase64(const QString& data, const QString& secret) {
|
|
|
|
|
QByteArray keyBytes = secret.toUtf8();
|
|
|
|
|
QByteArray dataBytes = data.toUtf8();
|
|
|
|
|
|
|
|
|
|
// 使用 HMAC-SHA256 计算哈希值
|
|
|
|
|
QByteArray hash = QMessageAuthenticationCode::hash(dataBytes, keyBytes, QCryptographicHash::Sha256);
|
|
|
|
|
qDebug() << "secret:" << secret;
|
|
|
|
|
qDebug() << "hash (hex):" << hash.toHex();
|
|
|
|
|
qDebug() << "hash.toBase64():" << hash.toHex().toBase64();
|
|
|
|
|
// 将哈希值编码为 Base64 字符串
|
|
|
|
|
return hash.toHex().toBase64();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 计算签名
|
|
|
|
|
QString calculateSignature(const QMap<QString, QString>& params, const QString& httpMethod, const QString& secret, const QString& request_id, const QString& timestamp) {
|
|
|
|
|
// 1. 按字典序排序参数
|
|
|
|
|
QList<QPair<QString, QString>> sortedParams;
|
|
|
|
|
for (auto it = params.begin(); it != params.end(); ++it) {
|
|
|
|
|
qDebug() << it.key() << ":" << it.value();
|
|
|
|
|
sortedParams.append(qMakePair(it.key(), it.value()));
|
|
|
|
|
}
|
|
|
|
|
std::sort(sortedParams.begin(), sortedParams.end());
|
|
|
|
|
qDebug() << "Sorted Params:";
|
|
|
|
|
for (const auto& param : sortedParams) {
|
|
|
|
|
qDebug() << param.first << ":" << param.second;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 2. URL 编码参数
|
|
|
|
|
QString canonicalizedQueryString;
|
|
|
|
|
for (auto& param : sortedParams) {
|
|
|
|
|
if (!canonicalizedQueryString.isEmpty()) {
|
|
|
|
|
canonicalizedQueryString += "&";
|
|
|
|
|
}
|
|
|
|
|
canonicalizedQueryString += QUrl::toPercentEncoding(param.first) + "=" + QUrl::toPercentEncoding(param.second);
|
|
|
|
|
}
|
|
|
|
|
qDebug() << "URL Canonicalized Query String:" << canonicalizedQueryString;
|
|
|
|
|
|
|
|
|
|
// 3. 构造 BaseString
|
|
|
|
|
//QString baseString = params["batch"] + params["label"] + params["model"] + params["request_id"] + params["timestamp"] + params["factory_id"];
|
|
|
|
|
QString baseString = "240830SL100LabelSL100" + request_id + timestamp + "TEST";
|
|
|
|
|
qDebug() << "baseString:" << baseString;
|
|
|
|
|
|
|
|
|
|
// 4. 构造 stringToSign
|
|
|
|
|
QString stringToSign = httpMethod + "&" + baseString + "&" + canonicalizedQueryString.replace("+", "%20");
|
|
|
|
|
qDebug() << "stringToSign:" << stringToSign;
|
|
|
|
|
// 5. 计算签名
|
|
|
|
|
return HmacSha256ToBase64(stringToSign, secret);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 请求头
|
|
|
|
|
void prepareRequestHeaders(QNetworkRequest& request, const QString& sign, const QString& request_id) {
|
|
|
|
|
request.setRawHeader("factory_id", "TEST");
|
|
|
|
|
request.setRawHeader("label", "SL100Label");
|
|
|
|
|
request.setRawHeader("batch", QString::number(240830).toUtf8());
|
|
|
|
|
request.setRawHeader("model", "SL100");
|
|
|
|
|
request.setRawHeader("timestamp", QString::number(QDateTime::currentSecsSinceEpoch()).toUtf8());
|
|
|
|
|
request.setRawHeader("request_id", request_id.toUtf8());
|
|
|
|
|
request.setRawHeader("sign", sign.toUtf8());
|
|
|
|
|
request.setRawHeader("Content-Type", "application/json");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GET 请求
|
|
|
|
|
void sendGetRequest(HttpClient* httpClient, const QUrl& url, const QMap<QString, QString>& params, const QString& secret) {
|
2024-08-29 03:49:55 +00:00
|
|
|
|
QString request_id = generateRandomRequestID(1, 33);
|
2024-08-26 10:33:55 +00:00
|
|
|
|
qDebug() << "request_id:" << request_id;
|
|
|
|
|
QUrl modifiedUrl = url;
|
|
|
|
|
QUrlQuery query;
|
|
|
|
|
for (auto it = params.begin(); it != params.end(); ++it) {
|
|
|
|
|
query.addQueryItem(it.key(), it.value());
|
|
|
|
|
}
|
|
|
|
|
modifiedUrl.setQuery(query.query());
|
|
|
|
|
QString sign = calculateSignature(params, "GET", secret, request_id, QString::number(QDateTime::currentSecsSinceEpoch()));
|
|
|
|
|
qDebug() << "sendGetRequest URL:" << modifiedUrl.toString();
|
|
|
|
|
QNetworkRequest request(modifiedUrl);
|
|
|
|
|
prepareRequestHeaders(request, sign, request_id);
|
|
|
|
|
//return;
|
|
|
|
|
httpClient->sendGetRequest(request);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// POST 请求
|
|
|
|
|
void sendPostRequest(HttpClient* httpClient, const QUrl& url, const QMap<QString, QString>& params, const QJsonObject& jsonData, const QString& secret) {
|
2024-08-29 03:49:55 +00:00
|
|
|
|
QString request_id = generateRandomRequestID(1, 33);
|
2024-08-26 10:33:55 +00:00
|
|
|
|
qDebug() << "request_id:" << request_id;
|
|
|
|
|
QString sign = calculateSignature(params, "POST", secret, request_id, QString::number(QDateTime::currentSecsSinceEpoch()));
|
|
|
|
|
qDebug() << "sendPostRequest URL:" << url.toString();
|
|
|
|
|
QNetworkRequest request(url);
|
|
|
|
|
prepareRequestHeaders(request, sign, request_id);
|
|
|
|
|
QByteArray jsonDataByteArray = QJsonDocument(jsonData).toJson();
|
|
|
|
|
//return;
|
|
|
|
|
httpClient->sendPostRequest(request, jsonDataByteArray);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GET 获取 UUID
|
|
|
|
|
void MainWidget::FactoryToolSendGetUuidToHttpServer(const QString& mac_addr) {
|
|
|
|
|
QUrl url("http://admin.hassecurity.cn/v1/getUuid");
|
|
|
|
|
QMap<QString, QString> params = {
|
|
|
|
|
{"label", "TEST_SL100_20240826"},
|
|
|
|
|
{"model", "SL100"},
|
|
|
|
|
{"batch", "1"},
|
|
|
|
|
{"mac", mac_addr}
|
|
|
|
|
};
|
|
|
|
|
QString secret = "rCeOzwisLFLasvlt";
|
|
|
|
|
sendGetRequest(httpClient, url, params, secret);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GET 查询 License
|
|
|
|
|
void MainWidget::FactoryToolSendGetLicenseToHttpServer(const QString& hw_info) {
|
|
|
|
|
QUrl url("http://admin.hassecurity.cn/v1/getAlgorithmKey");
|
|
|
|
|
QMap<QString, QString> params = {
|
|
|
|
|
{"id", hw_info}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
QString secret = "rCeOzwisLFLasvlt";
|
|
|
|
|
sendGetRequest(httpClient, url, params, secret);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// POST 确认烧录
|
|
|
|
|
void MainWidget::FactoryToolSendPostComfirmToHttpServer(const QString& mac_addr, const QString& uuid) {
|
|
|
|
|
QUrl url("http://admin.hassecurity.cn/v1/confirm");
|
|
|
|
|
QMap<QString, QString> params = {
|
|
|
|
|
{"mac", mac_addr},
|
|
|
|
|
{"uuid", uuid}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
QJsonObject jsonData = {
|
|
|
|
|
{"mac", mac_addr},
|
|
|
|
|
{"uuid", uuid}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
QString secret = "rCeOzwisLFLasvlt";
|
|
|
|
|
sendPostRequest(httpClient, url, params, jsonData, secret);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// POST 上报测试结果
|
|
|
|
|
void MainWidget::FactoryToolSendPostTestToHttpServer() {
|
|
|
|
|
QUrl url("http://admin.hassecurity.cn/v1/testRecords");
|
|
|
|
|
QMap<QString, QString> params = {
|
|
|
|
|
{"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;
|
|
|
|
|
|
|
|
|
|
QJsonObject jsonItem = {
|
|
|
|
|
{"function", "faceVerify"},
|
|
|
|
|
{"result", false},
|
|
|
|
|
{"msg", "timeout"}
|
|
|
|
|
};
|
|
|
|
|
QJsonArray itemsArray;
|
|
|
|
|
itemsArray.append(jsonItem);
|
|
|
|
|
|
|
|
|
|
QJsonObject jsonData = {
|
|
|
|
|
{"id", "123456"},
|
|
|
|
|
{"location", "allMachine"},
|
|
|
|
|
{"items", itemsArray}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
QString secret = "rCeOzwisLFLasvlt";
|
|
|
|
|
sendPostRequest(httpClient, url, params, jsonData, secret);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// POST 图语 License 上报
|
|
|
|
|
void MainWidget::FactoryToolSendPostLicenseToHttpServer(const QString& hardware_info, const QString& license_info) {
|
|
|
|
|
QUrl url("http://admin.hassecurity.cn/v1/algorithmKey");
|
2024-08-29 03:49:55 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
qint64 UTC_time = QDateTime::currentSecsSinceEpoch();
|
|
|
|
|
|
2024-08-26 10:33:55 +00:00
|
|
|
|
QMap<QString, QString> params = {
|
|
|
|
|
{"id", hardware_info},
|
|
|
|
|
{"key", license_info},
|
2024-08-29 03:49:55 +00:00
|
|
|
|
{"time", QString::number(UTC_time)}
|
2024-08-26 10:33:55 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
QJsonObject jsonData = {
|
|
|
|
|
{"id", hardware_info},
|
|
|
|
|
{"key", license_info},
|
|
|
|
|
{"time", UTC_time}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
QString secret = "rCeOzwisLFLasvlt";
|
|
|
|
|
sendPostRequest(httpClient, url, params, jsonData, secret);
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-01 01:17:17 +00:00
|
|
|
|
void MainWidget::startClientReadTimer(int clientId) {
|
2024-09-03 07:58:23 +00:00
|
|
|
|
//qDebug() << "------ startClientReadTimer clientId:" << clientId;
|
2024-08-01 01:17:17 +00:00
|
|
|
|
if (clientReadTimers.contains(clientId)) {
|
|
|
|
|
clientReadTimers[clientId]->start(10);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWidget::stopClientReadTimer(int clientId) {
|
|
|
|
|
qDebug() << "------ stopClientReadTimer clientId:" << clientId;
|
|
|
|
|
if (clientReadTimers.contains(clientId)) {
|
|
|
|
|
clientReadTimers[clientId]->stop();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWidget::onCheckConnectionStatus()
|
|
|
|
|
{
|
|
|
|
|
int activeThreadCount = clients_1.size();
|
|
|
|
|
//qDebug() << "------Number of active threads:" << activeThreadCount;
|
|
|
|
|
for (auto it = clients_1.begin(); it != clients_1.end(); ++it) {
|
|
|
|
|
int clientId = it.key();
|
|
|
|
|
ClientHandler* handler = it.value();
|
|
|
|
|
QTcpSocket* socket = handler->getSocket();
|
|
|
|
|
if (socket->state() != QTcpSocket::ConnectedState) {
|
|
|
|
|
qCritical() << "--------------Connection lost for clientId:" << clientId << ". Socket state:" << socket->state();
|
|
|
|
|
emit handler->clientDisconnected(handler);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
qDebug() << "Connection for clientId:" << clientId << "is active.";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWidget::onCheckThreadStatus()
|
|
|
|
|
{
|
|
|
|
|
//qDebug() << "Checking thread status...";
|
|
|
|
|
int activeThreadCount = clientThreads.size();
|
|
|
|
|
//qDebug() << "Number of active threads:" << activeThreadCount;
|
2024-08-19 01:39:32 +00:00
|
|
|
|
for (auto it = clientThreads.begin(); it != clientThreads.end(); ++it) {
|
2024-08-01 01:17:17 +00:00
|
|
|
|
int clientId = it.key();
|
|
|
|
|
QThread* thread = it.value();
|
|
|
|
|
ClientHandler* handler = nullptr;
|
|
|
|
|
for (ClientHandler* h : clients) {
|
|
|
|
|
if (h->getClientId() == clientId) {
|
|
|
|
|
handler = h;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (handler && handler->isData_Stuck()) {
|
|
|
|
|
qDebug() << "Thread for clientId:" << clientId << "is stuck.";
|
|
|
|
|
// 处理线程卡住的情况,比如重启线程或记录更多日志
|
|
|
|
|
}
|
|
|
|
|
else if (thread->isRunning()) {
|
|
|
|
|
qDebug() << "isData_Stuck = :" << handler->isData_Stuck();
|
|
|
|
|
qDebug() << "Thread for clientId:" << clientId << "is running.";
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
qDebug() << "Thread for clientId:" << clientId << "is not running.";
|
|
|
|
|
// 处理线程意外停止的情况
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 打印线程池信息
|
|
|
|
|
void MainWidget::printThreadPoolInfo()
|
|
|
|
|
{
|
|
|
|
|
QThreadPool* threadPool = QThreadPool::globalInstance();
|
|
|
|
|
//qDebug() << "Active threads:" << threadPool->activeThreadCount();
|
|
|
|
|
//qDebug() << "Max threads:" << threadPool->maxThreadCount();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWidget::setupTimerForThreadPoolInfo()
|
|
|
|
|
{
|
|
|
|
|
QTimer* timer = new QTimer(this);
|
|
|
|
|
connect(timer, &QTimer::timeout, this, &MainWidget::printThreadPoolInfo);
|
|
|
|
|
timer->start(5000); // 每5秒打印一次线程池信息
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-19 01:39:32 +00:00
|
|
|
|
void MainWidget::readJsonConfig()
|
|
|
|
|
{
|
|
|
|
|
frontBoardOneClickTest = readJson_frontBoardOneClickTest();
|
|
|
|
|
frontBoardTest = readJson_frontBoardTest();
|
|
|
|
|
frontBoardFuncConfig = readJson_frontBoardFuncConfig();
|
|
|
|
|
frontBoardDevInfoJson = readJson_frontDevInfo();
|
|
|
|
|
frontBoardLicenseJson = readJson_frontLicense();
|
|
|
|
|
|
|
|
|
|
backBoardOneClickTest = readJson_backBoardOneClickTest();
|
|
|
|
|
backBoardTest = readJson_backBoardTest();
|
|
|
|
|
backBoardFuncConfig = readJson_backBoardFuncConfig();
|
|
|
|
|
backBoardDevInfoJson = readJson_backDevInfo();
|
2024-08-26 10:33:55 +00:00
|
|
|
|
backBoardUuidJson = readJson_backUuid();
|
2024-08-19 01:39:32 +00:00
|
|
|
|
|
|
|
|
|
testJsonConfig = readJson_testConfig();
|
|
|
|
|
funcJsonConfig = readJson_funcConfig();
|
|
|
|
|
|
2024-08-26 10:33:55 +00:00
|
|
|
|
getPicJson = readJson_getPic();
|
|
|
|
|
getVideoJson = readJson_getVideo();
|
2024-08-19 01:39:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-08-01 01:17:17 +00:00
|
|
|
|
void MainWidget::onSelectFileButtonClicked()
|
|
|
|
|
{
|
|
|
|
|
QString filePath = QFileDialog::getSaveFileName(this, tr("选择文件路径"), "", tr("Text Files (*.txt);;All Files (*)"));
|
|
|
|
|
if (!filePath.isEmpty()) {
|
|
|
|
|
filePathLineEdit->setText(filePath);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWidget::onclearLogButtonClicked()
|
|
|
|
|
{
|
|
|
|
|
statusListWidget->clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWidget::onSaveCheckBoxStateChanged(int state)
|
|
|
|
|
{
|
2024-08-29 03:49:55 +00:00
|
|
|
|
if (state == Qt::Checked) checkBoxState = true;
|
|
|
|
|
else checkBoxState = false;
|
2024-08-01 01:17:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWidget::saveStatusListToFile(const QString& filePath)
|
|
|
|
|
{
|
2024-08-29 03:49:55 +00:00
|
|
|
|
QString actualFilePath = filePath;
|
|
|
|
|
if (actualFilePath.isEmpty()) {
|
|
|
|
|
QString defaultDirPath = QDir::currentPath() + "/TestLog";
|
|
|
|
|
QDir dir(defaultDirPath);
|
|
|
|
|
if (!dir.exists()) {
|
|
|
|
|
if (!dir.mkpath(defaultDirPath)) {
|
|
|
|
|
qWarning() << "Failed to create directory:" << defaultDirPath;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
QString currentTime = QDateTime::currentDateTime().toString("yyyyMMdd_HHmmss");
|
|
|
|
|
actualFilePath = defaultDirPath + "/" + currentTime + ".txt";
|
2024-08-01 01:17:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-08-29 03:49:55 +00:00
|
|
|
|
QFile file(actualFilePath);
|
2024-08-01 01:17:17 +00:00
|
|
|
|
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
2024-08-29 03:49:55 +00:00
|
|
|
|
qWarning() << "Failed to open file:" << actualFilePath;
|
2024-08-01 01:17:17 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QTextStream out(&file);
|
|
|
|
|
for (int i = 0; i < statusListWidget->count(); ++i) {
|
|
|
|
|
QListWidgetItem* item = statusListWidget->item(i);
|
|
|
|
|
out << item->text() << "\n";
|
|
|
|
|
}
|
|
|
|
|
file.close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWidget::onStartTimeout(int clientId, int timeout)
|
|
|
|
|
{
|
|
|
|
|
//qDebug() << "---------------> onStartTimeout :" << clientId << "timeout :" << timeout;
|
|
|
|
|
if (clientTimers.contains(clientId)) {
|
|
|
|
|
QTimer* timer = clientTimers[clientId];
|
|
|
|
|
if (timeout > 0) {
|
|
|
|
|
timer->start(timeout);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
timer->stop();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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();
|
2024-09-02 02:22:41 +00:00
|
|
|
|
connectedClientsCount --;
|
2024-08-01 01:17:17 +00:00
|
|
|
|
updateServerButtonText();
|
2024-08-19 01:39:32 +00:00
|
|
|
|
break;
|
2024-08-01 01:17:17 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-09-02 02:22:41 +00:00
|
|
|
|
if (connectedClientsCount == 0) {
|
|
|
|
|
// 启动 mDNS 服务广播
|
|
|
|
|
startMdnsService();
|
2024-08-01 01:17:17 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-26 10:33:55 +00:00
|
|
|
|
QString formatLicenseKey(const QString& licenseKey) {
|
|
|
|
|
QString formattedKey;
|
|
|
|
|
qDebug() << "licenseKey.length():" << licenseKey.length();
|
|
|
|
|
for (int i = 0; i < licenseKey.length(); i += 2) {
|
|
|
|
|
QString byteStr = licenseKey.mid(i, 2); // 每次取两个字符
|
|
|
|
|
formattedKey.append(QString("0x%1, ").arg(byteStr));
|
|
|
|
|
}
|
|
|
|
|
if (!formattedKey.isEmpty()) {
|
|
|
|
|
formattedKey.chop(2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return formattedKey;
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-06 12:32:02 +00:00
|
|
|
|
void MainWidget::onLicenseButtonClicked()
|
|
|
|
|
{
|
|
|
|
|
if (connectedClientsCount) {
|
|
|
|
|
QPushButton* button = qobject_cast<QPushButton*>(sender());
|
|
|
|
|
if (button) {
|
|
|
|
|
int index = button->property("licenseIndex").toInt();
|
|
|
|
|
if (index >= 0 && index < frontBoardLicenseJson.size()) {
|
|
|
|
|
QJsonObject jsonObject = frontBoardLicenseJson[index].toObject();
|
2024-08-26 10:33:55 +00:00
|
|
|
|
unsigned char hardware_info[PIX_HARDWARE_INFO_BYTES] = { 0 };
|
|
|
|
|
unsigned char license_info[PIX_LICENCE_BYTES] = { 0 };
|
|
|
|
|
QString dataStr = "";
|
|
|
|
|
if (jsonObject["lable"].toString() == "get_license") {
|
|
|
|
|
QString hwInfoText = licenseHwInfoEdit->toPlainText();
|
2024-09-02 10:37:24 +00:00
|
|
|
|
if (hwInfoText.count("0x") != PIX_HARDWARE_INFO_BYTES) {
|
|
|
|
|
isRequestSuccessful = 0;
|
|
|
|
|
//licenseHwInfoEdit->setPlainText("您使用了License去获取License,这是不允许的!!!");
|
|
|
|
|
LicenseConfirmWindow dialog("您使用了License去获取License,这是不允许的!!!");
|
|
|
|
|
dialog.exec();
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-08-26 10:33:55 +00:00
|
|
|
|
dataStr = hwInfoText.remove(","); // 去掉所有的逗号
|
|
|
|
|
QString sendToHttpServerDataStr = dataStr.replace("0x", "").replace(" ", ""); // 去掉0x和空格
|
|
|
|
|
#if 1
|
|
|
|
|
qDebug() << "sendToHttpServerDataStr:" << sendToHttpServerDataStr;
|
|
|
|
|
FactoryToolSendGetLicenseToHttpServer(sendToHttpServerDataStr);
|
|
|
|
|
while (isRequestSuccessful == 0) {
|
2024-09-02 10:37:24 +00:00
|
|
|
|
QCoreApplication::processEvents(); // 防止阻塞线程
|
2024-08-26 10:33:55 +00:00
|
|
|
|
}
|
|
|
|
|
qDebug() << "isRequestSuccessful:" << isRequestSuccessful;
|
|
|
|
|
if (isRequestSuccessful == 2) {
|
2024-08-29 03:49:55 +00:00
|
|
|
|
isRequestSuccessful = 0;
|
2024-08-26 10:33:55 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
else if(isRequestSuccessful == 1) {
|
|
|
|
|
if (licenseDataArray.contains("has") && licenseDataArray["has"].toBool()) {
|
|
|
|
|
qDebug() << "Found item with 'has' = true";
|
|
|
|
|
if (licenseDataArray.contains("key")) {
|
|
|
|
|
QString licenseKey = licenseDataArray["key"].toString();
|
|
|
|
|
licenseKey = formatLicenseKey(licenseKey);
|
|
|
|
|
licenseHwInfoEdit->setPlainText(licenseKey);
|
|
|
|
|
qDebug() << "HTTP Server License is:" << licenseKey;
|
2024-08-29 03:49:55 +00:00
|
|
|
|
isRequestSuccessful = 0;
|
2024-08-26 10:33:55 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (licenseDataArray.contains("has")) {
|
|
|
|
|
qDebug() << "licenseDataArray[\"has\"].toBool():" << licenseDataArray["has"].toBool();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
QString licenseKey = "128532C1D2A8";
|
|
|
|
|
licenseKey = formatLicenseKey(licenseKey);
|
|
|
|
|
licenseHwInfoEdit->setPlainText(licenseKey);
|
|
|
|
|
qDebug() << "License Key set in licenseHwInfoEdit:" << licenseKey;
|
|
|
|
|
return;
|
|
|
|
|
#endif
|
2024-09-02 10:37:24 +00:00
|
|
|
|
QByteArray dataByteArray = QByteArray::fromHex(dataStr.toUtf8());
|
2024-08-26 10:33:55 +00:00
|
|
|
|
memcpy(hardware_info, dataByteArray.data(), qMin(dataByteArray.size(), PIX_HARDWARE_INFO_BYTES));
|
|
|
|
|
//unsigned char hardware_info[PIX_HARDWARE_INFO_BYTES] = { 0x46,0x0b,0x5d,0x11,0x58,0x17,0x4d,0x5e,0x55,0x5c,0x51,0x4a,0x5a,0x07,0x59,0x4c,0x5f,0x45,0x5b,0x5f,0x5a,0x45,0x1c,0x5a,0x45,0x43,0x44,0x47,0x51,0x5e,0x44,0x30 };
|
2024-08-29 03:49:55 +00:00
|
|
|
|
LicenseConfirmWindow dialog("你确定要获取此授权吗?\n请确认你的hw_info是否正确");
|
2024-08-26 10:33:55 +00:00
|
|
|
|
if (dialog.exec() == QDialog::Accepted) {
|
2024-08-29 03:49:55 +00:00
|
|
|
|
#if !MANUAL_UPLOAD_LICENSE
|
|
|
|
|
if (!(licenseGenerate(hardware_info, license_info))) {
|
2024-09-02 10:37:24 +00:00
|
|
|
|
qDebug() << "从U盘获取License失败";
|
2024-08-29 03:49:55 +00:00
|
|
|
|
isRequestSuccessful = 0;
|
|
|
|
|
licenseHwInfoEdit->setPlainText("从U盘获取License失败,请检查U盘是否插入电脑!!!");
|
|
|
|
|
return;
|
2024-09-02 10:37:24 +00:00
|
|
|
|
}
|
2024-08-26 10:33:55 +00:00
|
|
|
|
QString licenseInfoHex = QByteArray(reinterpret_cast<char*>(license_info), PIX_LICENCE_BYTES).toHex().toUpper();
|
|
|
|
|
#else
|
2024-08-29 03:49:55 +00:00
|
|
|
|
//unsigned char license_info_1[PIX_LICENCE_BYTES] = { 0x07, 0xe8, 0xf3, 0x80, 0xa8, 0x07, 0x72, 0xa1, 0x17, 0xfe, 0xda, 0x67, 0xbd, 0x4a, 0x5a, 0xb5, 0xbb, 0x8b, 0x2d, 0xb2, 0xbf, 0x89, 0x74, 0xe5, 0xb0, 0x99, 0x70, 0x74, 0x3c, 0x6f, 0xf8, 0x82, 0x79, 0xab, 0x31, 0x9c, 0xdf, 0xe8, 0x9e, 0x75, 0x8f, 0x42, 0xb3, 0xcf, 0x00, 0x60, 0xa0, 0x38, 0xa4, 0xb8, 0xbe, 0xa6, 0x5d, 0x9f, 0x8b, 0x41, 0xf3, 0x0a, 0x69, 0xf6, 0x50, 0x94, 0x3f, 0xd0, 0xa5, 0xee, 0x88, 0x20, 0x93, 0x9a, 0x1c, 0xe9, 0x64, 0xd3, 0xaf, 0x9f, 0xc7, 0x66, 0x00, 0x7d, 0x7d, 0x68, 0xf1, 0xa4, 0xe1, 0x58, 0x00, 0x1d, 0x03, 0x0d, 0x40, 0x08, 0xa4, 0xcc, 0x0b, 0xd8, 0x19, 0x70, 0x9a, 0x83, 0x81, 0xbf, 0x27, 0x35, 0xb8, 0xec, 0x59, 0xa8, 0xd0, 0x03, 0xdb, 0xf6, 0xcf, 0x83, 0xaa, 0x0e, 0xfc, 0x95, 0x29, 0x77, 0xec, 0x89, 0xc5, 0x79, 0x10, 0x40, 0xd8, 0xbb };
|
|
|
|
|
unsigned char license_info_1[PIX_LICENCE_BYTES] = { 0x6a, 0x70, 0xc0, 0x40, 0xc9, 0x20, 0xf5, 0xd2, 0x78, 0xac, 0x05, 0x80, 0xa6, 0xcf, 0x3f, 0xd5, 0x72, 0xf6, 0xc3, 0x82, 0x11, 0x0d, 0x56, 0x37, 0xb3, 0x87, 0x19, 0x13, 0x79, 0xa5, 0x9b, 0x37, 0xf2, 0xab, 0xcb, 0xa3, 0xea, 0xc4, 0x45, 0xc6, 0xae, 0xc4, 0xa4, 0x72, 0xe9, 0x36, 0x1e, 0xbe, 0x78, 0xd6, 0xcd, 0x85, 0xd, 0x63, 0x93, 0x7a, 0x84, 0x9a, 0x31, 0x99, 0xe1, 0x09, 0xc1, 0xfa, 0xbe, 0x32, 0x42, 0xc5, 0xc9, 0x89, 0x03, 0x7e, 0x81, 0xe5, 0x25, 0xf, 0x4d, 0x68, 0x9d, 0x53, 0xd1, 0x04, 0x29, 0x34, 0x53, 0x09, 0x22, 0x5, 0x29, 0xce, 0xb1, 0xc9, 0x01, 0xed, 0x2a, 0xd2, 0x16, 0xfb, 0x3c, 0x27, 0xba, 0x4a, 0x69, 0x10, 0x3a, 0x54, 0x5a, 0x8f, 0xca, 0x47, 0x8d, 0x34, 0x2b, 0x57, 0xad, 0x27, 0x9a, 0x15, 0x37, 0x86, 0x60, 0xd6, 0x34, 0xd8, 0x32, 0xee, 0x9c, 0x46 };
|
2024-08-26 10:33:55 +00:00
|
|
|
|
QString licenseInfoHex = QByteArray(reinterpret_cast<char*>(license_info_1), PIX_LICENCE_BYTES).toHex().toUpper();
|
|
|
|
|
#endif
|
|
|
|
|
qDebug() << "上报服务器 licenseInfoHex:" << licenseInfoHex;
|
|
|
|
|
// License上报服务器
|
|
|
|
|
FactoryToolSendPostLicenseToHttpServer(sendToHttpServerDataStr, licenseInfoHex);
|
|
|
|
|
QString licenseInfoStr;
|
|
|
|
|
printf("U盘 Get License is\n");
|
|
|
|
|
for (int j = 0; j < PIX_LICENCE_BYTES; ++j) {
|
2024-08-29 03:49:55 +00:00
|
|
|
|
#if !MANUAL_UPLOAD_LICENSE
|
|
|
|
|
printf("0x%02x, ", license_info[j]);
|
|
|
|
|
licenseInfoStr.append(QString::asprintf("0x%02x, ", license_info[j]));
|
|
|
|
|
#else
|
2024-08-26 10:33:55 +00:00
|
|
|
|
printf("0x%02x, ", license_info_1[j]);
|
|
|
|
|
licenseInfoStr.append(QString::asprintf("0x%02x, ", license_info_1[j]));
|
2024-08-29 03:49:55 +00:00
|
|
|
|
#endif
|
2024-08-26 10:33:55 +00:00
|
|
|
|
}
|
|
|
|
|
printf("\n");
|
|
|
|
|
licenseHwInfoEdit->setPlainText(licenseInfoStr);
|
2024-08-29 03:49:55 +00:00
|
|
|
|
isRequestSuccessful = 0;
|
2024-09-02 10:37:24 +00:00
|
|
|
|
}
|
2024-08-26 10:33:55 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
#if 0
|
|
|
|
|
if (jsonObject["lable"].toString() == "write_license") {
|
|
|
|
|
QString hwInfoText = licenseHwInfoEdit->toPlainText();
|
|
|
|
|
dataStr = hwInfoText.remove(","); // 去掉所有的逗号
|
|
|
|
|
QByteArray dataByteArray = QByteArray::fromHex(dataStr.toUtf8());
|
|
|
|
|
memcpy(hardware_info, dataByteArray.data(), qMin(dataByteArray.size(), PIX_HARDWARE_INFO_BYTES));
|
|
|
|
|
qDebug() << "hardware_info:" << QByteArray(reinterpret_cast<char*>(hardware_info), PIX_HARDWARE_INFO_BYTES).toHex();
|
|
|
|
|
licenseGenerate(hardware_info, license_info);
|
|
|
|
|
QString licenseInfoStr;
|
|
|
|
|
printf("License is\n");
|
|
|
|
|
for (int j = 0; j < PIX_LICENCE_BYTES; ++j) {
|
|
|
|
|
printf("0x%02x, ", license_info[j]);
|
|
|
|
|
licenseInfoStr.append(QString::asprintf("0x%02x, ", license_info[j]));
|
|
|
|
|
}
|
|
|
|
|
printf("\n");
|
|
|
|
|
licenseHwInfoEdit->setPlainText(licenseInfoStr);
|
|
|
|
|
dataStr = QByteArray(reinterpret_cast<char*>(license_info), PIX_LICENCE_BYTES).toHex();
|
|
|
|
|
qDebug() << "license_info:" << dataStr;
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
if (jsonObject["lable"].toString() == "write_license") {
|
|
|
|
|
QString licenseInfoText = licenseHwInfoEdit->toPlainText();
|
|
|
|
|
qDebug() << "licenseInfoText:" << licenseInfoText;
|
|
|
|
|
dataStr = licenseInfoText.remove(","); // 去掉所有的逗号
|
|
|
|
|
dataStr = dataStr.replace("0x", "").replace(" ", ""); // 去掉0x和空格
|
|
|
|
|
QByteArray dataByteArray = QByteArray::fromHex(dataStr.toUtf8());
|
|
|
|
|
memcpy(license_info, dataByteArray.data(), qMin(dataByteArray.size(), PIX_LICENCE_BYTES));
|
|
|
|
|
QString licenseInfoStr;
|
|
|
|
|
for (int j = 0; j < PIX_LICENCE_BYTES; ++j) {
|
|
|
|
|
licenseInfoStr.append(QString::asprintf("0x%02x, ", license_info[j]));
|
|
|
|
|
}
|
|
|
|
|
dataStr = QByteArray(reinterpret_cast<char*>(license_info), PIX_LICENCE_BYTES).toHex();
|
|
|
|
|
qDebug() << "license_info:" << dataStr;
|
2024-08-29 03:49:55 +00:00
|
|
|
|
dataStr = dataByteArray.toBase64();
|
|
|
|
|
qDebug() << "Base64 Encoded:" << dataStr;
|
2024-08-26 10:33:55 +00:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
for (ClientHandler* handler : clients) {
|
|
|
|
|
handler->sendLicenseItem(index, dataStr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget);
|
|
|
|
|
listItem->setBackground(Qt::red);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWidget::onUuidButtonClicked()
|
|
|
|
|
{
|
|
|
|
|
if (connectedClientsCount) {
|
|
|
|
|
QPushButton* button = qobject_cast<QPushButton*>(sender());
|
|
|
|
|
if (button) {
|
|
|
|
|
int index = button->property("UuidIndex").toInt();
|
|
|
|
|
if (index >= 0 && index < backBoardUuidJson.size()) {
|
|
|
|
|
QJsonObject jsonObject = backBoardUuidJson[index].toObject();
|
2024-08-29 03:49:55 +00:00
|
|
|
|
QString dataStr = "";
|
|
|
|
|
if (jsonObject["lable"].toString() == "get_UUID_SN") {
|
|
|
|
|
QString sendToHttpServerDataStr = UuidHwInfoEdit->toPlainText();
|
|
|
|
|
qDebug() << "sendToHttpServerDataStr:" << sendToHttpServerDataStr;
|
|
|
|
|
// 测试随机生成8-12位字符串
|
|
|
|
|
sendToHttpServerDataStr = generateRandomRequestID(8, 13);
|
|
|
|
|
FactoryToolSendGetUuidToHttpServer(sendToHttpServerDataStr);
|
|
|
|
|
while (isRequestSuccessful == 0) {
|
|
|
|
|
QCoreApplication::processEvents(); // 防止阻塞UI线程
|
|
|
|
|
}
|
|
|
|
|
qDebug() << "isRequestSuccessful:" << isRequestSuccessful;
|
|
|
|
|
if (isRequestSuccessful == 2) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
else if (isRequestSuccessful == 1) {
|
|
|
|
|
|
|
|
|
|
}
|
2024-08-19 01:39:32 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
2024-08-29 03:49:55 +00:00
|
|
|
|
if (jsonObject["lable"].toString() == "write_UUID_SN") {
|
|
|
|
|
|
2024-08-19 01:39:32 +00:00
|
|
|
|
}
|
|
|
|
|
for (ClientHandler* handler : clients) {
|
2024-08-26 10:33:55 +00:00
|
|
|
|
handler->sendUuidItem(index, "");
|
2024-08-19 01:39:32 +00:00
|
|
|
|
}
|
2024-08-06 12:32:02 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget);
|
|
|
|
|
listItem->setBackground(Qt::red);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-19 01:39:32 +00:00
|
|
|
|
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";
|
2024-09-02 02:22:41 +00:00
|
|
|
|
QString serviceType = "_myservice._tcp.local";
|
2024-08-19 01:39:32 +00:00
|
|
|
|
quint16 port = TCP_CONNECT_PORT;
|
|
|
|
|
mServiceProvider->startServiceBroadcast(serviceName, serviceType, port);
|
|
|
|
|
|
|
|
|
|
if (!mdnsTimer->isActive()) {
|
|
|
|
|
mdnsTimer->start(1000);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWidget::stopMdnsService()
|
|
|
|
|
{
|
|
|
|
|
if (mdnsTimer->isActive()) {
|
|
|
|
|
mdnsTimer->stop(); // 停止定时器
|
|
|
|
|
}
|
|
|
|
|
mServiceProvider->stopServiceBroadcast();
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-01 01:17:17 +00:00
|
|
|
|
// 处理开始服务器按键点击事件
|
|
|
|
|
void MainWidget::onStartServerClicked()
|
|
|
|
|
{
|
|
|
|
|
if (!server->isListening()) {
|
2024-08-19 01:39:32 +00:00
|
|
|
|
startMdnsService();
|
|
|
|
|
#if TEST_UDP_BROADCAST
|
|
|
|
|
sendMulticastMessage();
|
|
|
|
|
#endif
|
|
|
|
|
// QHostAddress specifiedIpAddress("10.10.10.253");
|
|
|
|
|
quint16 specifiedPort = TCP_CONNECT_PORT;
|
2024-08-01 01:17:17 +00:00
|
|
|
|
qDebug() << "" << specifiedPort;
|
|
|
|
|
if (server->listen(QHostAddress::Any, specifiedPort)) {
|
|
|
|
|
startServerButton->setText(tr("正在监听(Listening)"));
|
|
|
|
|
startServerButton->setStyleSheet("background-color: green;");
|
|
|
|
|
sendAllButton->setEnabled(true);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
qDebug() << "Failed to start server. Error:" << server->errorString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
server->close();
|
|
|
|
|
startServerButton->setText(tr("开始监听\n(Start Listening...)"));
|
|
|
|
|
startServerButton->setStyleSheet("");
|
|
|
|
|
sendAllButton->setEnabled(false);
|
2024-08-19 01:39:32 +00:00
|
|
|
|
stopMdnsService();
|
2024-08-01 01:17:17 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-26 10:33:55 +00:00
|
|
|
|
void MainWidget::sendDataToClient(int clientId, const QByteArray& data)
|
|
|
|
|
{
|
2024-09-02 02:22:41 +00:00
|
|
|
|
if ((clientId == 0) && (isBackBoardOrAllBoard)) {
|
|
|
|
|
clientId = isBackBoardOrAllBoard;
|
|
|
|
|
}
|
2024-08-26 10:33:55 +00:00
|
|
|
|
if (clients_1.contains(clientId)) {
|
|
|
|
|
ClientHandler* handler = clients_1[clientId];
|
|
|
|
|
handler->sendDataToClient(data); // 调用 ClientHandler 中的方法发送数据
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
qWarning() << "没有找到 ID 为" << clientId << "的客户端!";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-01 01:17:17 +00:00
|
|
|
|
// 处理发送获取设备信息按键点击事件
|
|
|
|
|
void MainWidget::onSendGetDevInfoClicked()
|
|
|
|
|
{
|
|
|
|
|
if (connectedClientsCount) {
|
|
|
|
|
QPushButton* button = qobject_cast<QPushButton*>(sender());
|
|
|
|
|
int itemIndex = button->property("deviceInfoIndex").toInt();
|
|
|
|
|
if (itemIndex + 1 > connectedClientsCount) {
|
|
|
|
|
QListWidgetItem* listItem = new QListWidgetItem(QString("No device %1 is connected !!!").arg(itemIndex + 1), statusListWidget);
|
|
|
|
|
listItem->setBackground(Qt::red);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
for (ClientHandler* handler : clients) {
|
2024-08-29 03:49:55 +00:00
|
|
|
|
if (handler->getClientId() == handler->controlClientId) {
|
|
|
|
|
handler->sendGetDevInfoItem(itemIndex);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2024-08-01 01:17:17 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget);
|
|
|
|
|
listItem->setBackground(Qt::red);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理发送取图按键点击事件
|
|
|
|
|
void MainWidget::onSendGetPicClicked()
|
|
|
|
|
{
|
|
|
|
|
if (connectedClientsCount) {
|
|
|
|
|
QPushButton* button = qobject_cast<QPushButton*>(sender());
|
|
|
|
|
int itemIndex = button->property("getPicIndex").toInt();
|
|
|
|
|
if (itemIndex < 2) {
|
|
|
|
|
button->setStyleSheet("background-color: green;");
|
|
|
|
|
if (lastClickedGetPicCamIndex != -1 && lastClickedGetPicCamIndex != itemIndex) {
|
|
|
|
|
getPicButtons[lastClickedGetPicCamIndex]->setStyleSheet("");
|
2024-09-02 10:37:24 +00:00
|
|
|
|
if (lastClickedGetPicDevIndex != -1) {
|
|
|
|
|
getPicButtons[lastClickedGetPicDevIndex]->setStyleSheet("");
|
|
|
|
|
}
|
2024-08-01 01:17:17 +00:00
|
|
|
|
}
|
|
|
|
|
lastClickedGetPicCamIndex = itemIndex;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (lastClickedGetPicCamIndex == -1) {
|
|
|
|
|
QListWidgetItem* listItem = new QListWidgetItem(QString("Please select IR or RGB lens to get image!!!"), statusListWidget);
|
|
|
|
|
listItem->setBackground(Qt::red);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (itemIndex - 2 >= connectedClientsCount) {
|
2024-08-29 03:49:55 +00:00
|
|
|
|
QListWidgetItem* listItem = new QListWidgetItem(QString("This device is not connected !!!"), statusListWidget);
|
2024-08-01 01:17:17 +00:00
|
|
|
|
listItem->setBackground(Qt::red);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
button->setStyleSheet("background-color: green;");
|
|
|
|
|
if (lastClickedGetPicDevIndex != -1 && lastClickedGetPicDevIndex != itemIndex) {
|
|
|
|
|
getPicButtons[lastClickedGetPicDevIndex]->setStyleSheet("");
|
|
|
|
|
}
|
|
|
|
|
lastClickedGetPicDevIndex = itemIndex;
|
|
|
|
|
//QMutexLocker locker(&mutex);
|
|
|
|
|
for (ClientHandler* handler : clients) {
|
2024-08-29 03:49:55 +00:00
|
|
|
|
if (handler->getClientId() == handler->controlClientId) {
|
|
|
|
|
handler->sendGetPicItem(itemIndex - 2, lastClickedGetPicCamIndex);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2024-08-01 01:17:17 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget);
|
|
|
|
|
listItem->setBackground(Qt::red);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理发送拉视频流按键点击事件
|
|
|
|
|
void MainWidget::onSendGetVideoClicked()
|
|
|
|
|
{
|
|
|
|
|
if (connectedClientsCount) {
|
|
|
|
|
QPushButton* button = qobject_cast<QPushButton*>(sender());
|
|
|
|
|
int itemIndex = button->property("getVideoIndex").toInt();
|
|
|
|
|
|
2024-09-02 10:37:24 +00:00
|
|
|
|
if (itemIndex < 4) {
|
2024-08-01 01:17:17 +00:00
|
|
|
|
button->setStyleSheet("background-color: green;");
|
|
|
|
|
if (lastClickedGetVideoCamIndex != -1 && lastClickedGetVideoCamIndex != itemIndex) {
|
|
|
|
|
getVideoButtons[lastClickedGetVideoCamIndex]->setStyleSheet("");
|
2024-09-02 10:37:24 +00:00
|
|
|
|
if (lastClickedGetVideoDevIndex != -1) {
|
|
|
|
|
getVideoButtons[lastClickedGetVideoDevIndex - 2]->setStyleSheet("");
|
|
|
|
|
}
|
2024-08-01 01:17:17 +00:00
|
|
|
|
}
|
|
|
|
|
lastClickedGetVideoCamIndex = itemIndex;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (lastClickedGetVideoCamIndex == -1) {
|
2024-09-02 10:37:24 +00:00
|
|
|
|
QListWidgetItem* listItem = new QListWidgetItem(QString("Please select lens to get video!!!"), statusListWidget);
|
2024-08-01 01:17:17 +00:00
|
|
|
|
listItem->setBackground(Qt::red);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2024-09-02 10:37:24 +00:00
|
|
|
|
if (itemIndex - 8 >= connectedClientsCount) {
|
|
|
|
|
QListWidgetItem* listItem = new QListWidgetItem(QString("This device is not connected !!!").arg(itemIndex - 6), statusListWidget);
|
2024-08-01 01:17:17 +00:00
|
|
|
|
listItem->setBackground(Qt::red);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
button->setStyleSheet("background-color: green;");
|
|
|
|
|
if (lastClickedGetVideoDevIndex != -1 && lastClickedGetVideoDevIndex != itemIndex) {
|
2024-08-29 03:49:55 +00:00
|
|
|
|
//qDebug() << "itemIndex:" << itemIndex;
|
|
|
|
|
getVideoButtons[lastClickedGetVideoDevIndex - 2]->setStyleSheet("");
|
2024-08-01 01:17:17 +00:00
|
|
|
|
}
|
|
|
|
|
lastClickedGetVideoDevIndex = itemIndex;
|
|
|
|
|
//QMutexLocker locker(&mutex);
|
|
|
|
|
for (ClientHandler* handler : clients) {
|
2024-08-29 03:49:55 +00:00
|
|
|
|
if (handler->getClientId() == handler->controlClientId) {
|
2024-09-03 07:58:23 +00:00
|
|
|
|
qDebug() << "lens number:" << lastClickedGetVideoCamIndex;
|
2024-09-02 10:37:24 +00:00
|
|
|
|
handler->sendGetVideoItem(itemIndex - 7, lastClickedGetVideoCamIndex);
|
2024-08-29 03:49:55 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
2024-08-01 01:17:17 +00:00
|
|
|
|
}
|
2024-09-02 10:37:24 +00:00
|
|
|
|
getVideoButtons[FOCUS_WINDOWS_BUTTON]->setEnabled(true);
|
2024-08-01 01:17:17 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget);
|
|
|
|
|
listItem->setBackground(Qt::red);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWidget::onOpenFocusWindowClicked()
|
|
|
|
|
{
|
|
|
|
|
QPushButton* button = qobject_cast<QPushButton*>(sender());
|
|
|
|
|
if (button) {
|
|
|
|
|
int itemIndex = button->property("getVideoIndex").toInt();
|
2024-09-02 10:37:24 +00:00
|
|
|
|
qDebug() << "New Button clicked with itemIndex:" << itemIndex;
|
|
|
|
|
if (itemIndex == FOCUS_WINDOWS_BUTTON) {
|
|
|
|
|
for (ClientHandler* handler : clients) {
|
|
|
|
|
if (handler->getClientId() == handler->preVideoClientId) {
|
|
|
|
|
emit openFocusWindowRequested(itemIndex); // 发送信号
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-01 01:17:17 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理一键发送按键点击事件
|
|
|
|
|
void MainWidget::onSendAllClicked()
|
|
|
|
|
{
|
|
|
|
|
if (connectedClientsCount) {
|
|
|
|
|
QMutexLocker locker(&mutex);
|
|
|
|
|
isSendingAll = !isSendingAll;
|
|
|
|
|
if (isSendingAll) {
|
|
|
|
|
sendAllButton->setText("一键功能测试中...\n再次点击取消");
|
|
|
|
|
sendAllButton->setStyleSheet("background-color: green;");
|
|
|
|
|
manualSend = true;
|
|
|
|
|
for (ClientHandler* handler : clients) {
|
|
|
|
|
// 重置索引
|
|
|
|
|
handler->resetCurrentItemIndex();
|
2024-08-29 03:49:55 +00:00
|
|
|
|
if (handler->getClientId() == handler->controlClientId) {
|
|
|
|
|
handler->sendNextItem();
|
|
|
|
|
//handler->sendDevInfoItem();
|
|
|
|
|
break;
|
|
|
|
|
}
|
2024-08-01 01:17:17 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
sendAllButton->setText("一键功能测试");
|
2024-08-19 01:39:32 +00:00
|
|
|
|
sendAllButton->setStyleSheet("background-color: white;");
|
2024-08-01 01:17:17 +00:00
|
|
|
|
manualSend = false;
|
|
|
|
|
for (ClientHandler* handler : clients) {
|
|
|
|
|
handler->resetCurrentItemIndex();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget);
|
|
|
|
|
listItem->setBackground(Qt::red);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理单独发送功能项按键点击事件
|
2024-08-26 10:33:55 +00:00
|
|
|
|
void MainWidget::onSendFrontFuncItemClicked()
|
2024-08-01 01:17:17 +00:00
|
|
|
|
{
|
|
|
|
|
if (connectedClientsCount) {
|
|
|
|
|
QPushButton* button = qobject_cast<QPushButton*>(sender());
|
|
|
|
|
int itemIndex = button->property("frontBoardFuncConfig").toInt();
|
|
|
|
|
for (ClientHandler* handler : clients) {
|
2024-08-29 03:49:55 +00:00
|
|
|
|
if (handler->getClientId() == handler->controlClientId) {
|
|
|
|
|
QString text = frontFuncConfigLineEdit->text();
|
|
|
|
|
qDebug() << "Text in frontFuncConfigLineEdit:" << text;
|
|
|
|
|
handler->sendFrontFuncItem(itemIndex, text);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2024-08-26 10:33:55 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget);
|
|
|
|
|
listItem->setBackground(Qt::red);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWidget::onSendBackFuncItemClicked()
|
|
|
|
|
{
|
|
|
|
|
if (connectedClientsCount) {
|
|
|
|
|
QPushButton* button = qobject_cast<QPushButton*>(sender());
|
|
|
|
|
int itemIndex = button->property("backBoardFuncConfig").toInt();
|
|
|
|
|
for (ClientHandler* handler : clients) {
|
2024-09-02 02:22:41 +00:00
|
|
|
|
if ((isBackBoardOrAllBoard) || (handler->getClientId() == handler->controlClientId)) {
|
2024-08-29 03:49:55 +00:00
|
|
|
|
QString text = backFuncConfigLineEdit->text();
|
|
|
|
|
qDebug() << "Text in backFuncConfigLineEdit:" << text;
|
|
|
|
|
handler->sendBackFuncItem(itemIndex, text);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2024-08-01 01:17:17 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget);
|
|
|
|
|
listItem->setBackground(Qt::red);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理单独发送项按键点击事件
|
2024-08-26 10:33:55 +00:00
|
|
|
|
void MainWidget::onSendFrontItemClicked()
|
2024-08-01 01:17:17 +00:00
|
|
|
|
{
|
2024-08-26 10:33:55 +00:00
|
|
|
|
qDebug() << "onSendFrontItemClicked" ;
|
2024-08-01 01:17:17 +00:00
|
|
|
|
if (connectedClientsCount) {
|
|
|
|
|
QPushButton* button = qobject_cast<QPushButton*>(sender());
|
|
|
|
|
int itemIndex = button->property("frontBoardTest").toInt();
|
|
|
|
|
for (ClientHandler* handler : clients) {
|
2024-08-29 03:49:55 +00:00
|
|
|
|
if (handler->getClientId() == handler->controlClientId) {
|
|
|
|
|
handler->sendFrontItem(itemIndex);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2024-08-26 10:33:55 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget);
|
|
|
|
|
listItem->setBackground(Qt::red);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWidget::onSendBackItemClicked()
|
|
|
|
|
{
|
|
|
|
|
qDebug() << "onSendBackItemClicked";
|
|
|
|
|
if (connectedClientsCount) {
|
|
|
|
|
QPushButton* button = qobject_cast<QPushButton*>(sender());
|
|
|
|
|
int itemIndex = button->property("backBoardTest").toInt();
|
|
|
|
|
for (ClientHandler* handler : clients) {
|
2024-09-02 02:22:41 +00:00
|
|
|
|
if ((isBackBoardOrAllBoard) || (handler->getClientId() == handler->controlClientId)) {
|
2024-08-29 03:49:55 +00:00
|
|
|
|
handler->sendBackItem(itemIndex);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2024-08-01 01:17:17 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget);
|
|
|
|
|
listItem->setBackground(Qt::red);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理状态更新信号
|
|
|
|
|
void MainWidget::onStatusUpdated(const QString& client, int itemIndex, int FuncItemIndex,
|
2024-08-29 03:49:55 +00:00
|
|
|
|
bool success, const QString& itemData, const QString& funcItemData,
|
|
|
|
|
const QJsonArray& jsonArray, int itemJsonIndex)
|
2024-08-01 01:17:17 +00:00
|
|
|
|
{
|
|
|
|
|
int clientId = -1;
|
2024-08-29 03:49:55 +00:00
|
|
|
|
QString label;
|
2024-08-01 01:17:17 +00:00
|
|
|
|
// 遍历所有的 ClientHandler,找到匹配的 client
|
|
|
|
|
for (ClientHandler* handler : clients) {
|
|
|
|
|
if (handler->getClientAddress() == client) {
|
|
|
|
|
clientId = handler->getClientId();
|
|
|
|
|
QString lable = handler->getCurrentItemLable();
|
|
|
|
|
lable = handler->getCurrentFuncItemLable();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//qDebug() << "" << __FUNCTION__ << "handler->getClientAddress() != client" ;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//qDebug() << "itemIndex :" << itemIndex;
|
|
|
|
|
//qDebug() << "FuncItemIndex:" << FuncItemIndex;
|
2024-08-29 03:49:55 +00:00
|
|
|
|
//if (itemIndex > 0) {
|
|
|
|
|
// QListWidgetItem* listItem = new QListWidgetItem(QString("device ID: %1 - Item %2: %3 ---> %4")
|
|
|
|
|
// .arg(clientId)
|
|
|
|
|
// .arg(itemIndex)
|
|
|
|
|
// .arg(itemData) // data 字段
|
|
|
|
|
// .arg(success ? "OK" : "NG"), statusListWidget);
|
|
|
|
|
|
|
|
|
|
// listItem->setBackground(success ? Qt::green : Qt::red);
|
|
|
|
|
// statusListWidget->addItem(listItem);
|
|
|
|
|
//}
|
|
|
|
|
//else if (FuncItemIndex > 0) {
|
|
|
|
|
// QListWidgetItem* listItem = new QListWidgetItem(QString("device ID: %1 - funcItem %2: %3 ---> %4")
|
|
|
|
|
// .arg(clientId)
|
|
|
|
|
// .arg(FuncItemIndex)
|
|
|
|
|
// .arg(funcItemData) // data 字段
|
|
|
|
|
// .arg(success ? "OK" : "NG"), statusListWidget);
|
|
|
|
|
|
|
|
|
|
// listItem->setBackground(success ? Qt::green : Qt::red);
|
|
|
|
|
// statusListWidget->addItem(listItem);
|
|
|
|
|
//}
|
2024-08-01 01:17:17 +00:00
|
|
|
|
|
2024-08-29 03:49:55 +00:00
|
|
|
|
|
|
|
|
|
qDebug() << "itemJsonIndex :" << itemJsonIndex;
|
|
|
|
|
if (itemJsonIndex >= 0 && itemJsonIndex < jsonArray.size()) {
|
|
|
|
|
QJsonObject jsonObject = jsonArray.at(itemJsonIndex).toObject();
|
|
|
|
|
if (jsonObject.contains("lable")) {
|
|
|
|
|
label = jsonObject["lable"].toString();
|
|
|
|
|
qDebug() << "label :" << label;
|
|
|
|
|
}
|
2024-08-01 01:17:17 +00:00
|
|
|
|
}
|
2024-08-29 03:49:55 +00:00
|
|
|
|
QListWidgetItem* listItem = new QListWidgetItem(QString("device ID: %1 - Item %2: %3 ---> %4")
|
2024-08-01 01:17:17 +00:00
|
|
|
|
.arg(clientId)
|
2024-08-29 03:49:55 +00:00
|
|
|
|
.arg(itemJsonIndex + 1)
|
|
|
|
|
.arg(label) // data 字段
|
2024-08-01 01:17:17 +00:00
|
|
|
|
.arg(success ? "OK" : "NG"), statusListWidget);
|
2024-08-29 03:49:55 +00:00
|
|
|
|
listItem->setBackground(success ? Qt::green : Qt::red);
|
|
|
|
|
statusListWidget->addItem(listItem);
|
|
|
|
|
|
2024-08-01 01:17:17 +00:00
|
|
|
|
statusListWidget->scrollToBottom();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// json文件里面的配置项都测试结束
|
|
|
|
|
void MainWidget::onAllItemsProcessed(const QString& client, int itemsProcessedCount)
|
|
|
|
|
{
|
|
|
|
|
isSendingAll = false;
|
|
|
|
|
sendAllButton->setText("一键功能测试");
|
2024-08-19 01:39:32 +00:00
|
|
|
|
sendAllButton->setStyleSheet("background-color: white;");
|
2024-08-01 01:17:17 +00:00
|
|
|
|
//qDebug() << "onAllItemsProcessed called for client:" << client << "itemsProcessedCount:" << itemsProcessedCount;
|
|
|
|
|
int clientId = -1;
|
|
|
|
|
for (ClientHandler* handler : clients) {
|
|
|
|
|
if (handler->getClientAddress() == client) {
|
|
|
|
|
clientId = handler->getClientId();
|
|
|
|
|
qDebug() << "Current clientId:" << clientId;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//qDebug() << "" << __FUNCTION__ << "handler->getClientAddress() != client";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QListWidgetItem* listItem = new QListWidgetItem(QString("device ID:-%1 ---> All %2 items test completed !!!")
|
|
|
|
|
.arg(clientId)
|
|
|
|
|
.arg(itemsProcessedCount), statusListWidget);
|
2024-08-29 03:49:55 +00:00
|
|
|
|
if(checkBoxState)
|
|
|
|
|
saveStatusListToFile(filePathLineEdit->text());
|
2024-08-01 01:17:17 +00:00
|
|
|
|
statusListWidget->addItem(listItem);
|
|
|
|
|
statusListWidget->scrollToBottom();
|
|
|
|
|
}
|
|
|
|
|
|