// MainWidget.cpp #include "MainWidget.h" void onThreadFinished(QThread* thread, ClientHandler* handler) { qDebug() << "Thread finished. Deleting handler and thread."; handler->deleteLater(); thread->deleteLater(); } // 初始化 UI 组件和服务器 MainWidget::MainWidget(QWidget* parent) : QWidget(parent), nextClientId(1), manualSend(false), isSendingAll(false), lastClickedGetPicCamIndex(-1), lastClickedGetPicDevIndex(-1), lastClickedGetVideoCamIndex(-1), lastClickedGetVideoDevIndex(-1), mServiceProvider(new ServiceProvider(this)), mdnsTimer(new QTimer(this)) #if TEST_UDP_BROADCAST ,multicastSocket(new QUdpSocket(this)), multicastTimer(new QTimer(this)) #endif { leftLens_imageLabel = new QLabel(this); rightLens_imageLabel = new QLabel(this); videoLabel = new QLabel(this); funcConfigLineEdit = new QLineEdit(this); licenseHwInfoEdit = new QTextEdit(this); setupUI(); // 打印线程池状态信息 setupTimerForThreadPoolInfo(); server = new QTcpServer(this); connect(server, &QTcpServer::newConnection, this, [this]() { // 检查是否有挂起的连接 while (server->hasPendingConnections()) { QTcpSocket* socket = server->nextPendingConnection(); int clientId = nextClientId++; qDebug() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"; qDebug() << "> A client is connected. ID:" << clientId; qDebug() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"; stopMdnsService(); connectedClientsCount++; 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; } } } }); QThread* thread = new QThread(this); ClientHandler* handler = new ClientHandler(socket, frontBoardOneClickTest, frontBoardTest, frontBoardFuncConfig, frontBoardDevInfoJson, frontBoardLicenseJson, backBoardDevInfoJson, getPicJson, getVideoJson, clientId, nullptr); // 将 ClientHandler 移动到线程池中的线程 handler->moveToThread(thread); // 当线程结束时删除 handler connect(thread, &QThread::finished, this, [=]() { onThreadFinished(thread, handler); }); // 将sendData信号连接到主线程中的槽上 connect(handler, &ClientHandler::sendData, this, [socket](const QByteArray& data) { socket->write(data); socket->flush(); }); connect(handler, &ClientHandler::startTimeout, this, [this, clientId](int timeout) { this->onStartTimeout(clientId, timeout); }); // 启动新的线程 thread->start(); clients.append(handler); clients_1[clientId] = handler; clientThreads[clientId] = thread; connect(handler, &ClientHandler::statusUpdated, this, &MainWidget::onStatusUpdated); connect(handler, &ClientHandler::clientDisconnected, this, &MainWidget::onClientDisconnected); connect(handler, &ClientHandler::allItemsProcessed, this, &MainWidget::onAllItemsProcessed); connect(handler, &ClientHandler::selectClientDisconnected, this, &MainWidget::onDisconnectClient); // 创建 DataHandler 对象并连接信号 DataHandler* dataHandler = new DataHandler(leftLens_imageLabel, rightLens_imageLabel, videoLabel, licenseHwInfoEdit, &devInfoLineEdits, this); connect(handler, &ClientHandler::dataReceived, dataHandler, &DataHandler::handleData); connect(dataHandler, &DataHandler::statusUpdated, this, &MainWidget::onStatusUpdated); connect(handler, &ClientHandler::startReadTimer, this, &MainWidget::startClientReadTimer); connect(handler, &ClientHandler::stopReadTimer, this, &MainWidget::stopClientReadTimer); // 创建和管理定时器 QTimer* readTimer = new QTimer(this); connect(readTimer, &QTimer::timeout, handler, &ClientHandler::onTimeoutRead); // readTimer->start(10); // 每 10ms 触发一次 // 将定时器存储到哈希表中,方便管理 clientReadTimers[clientId] = readTimer; } }); 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检查一次连接状态 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 } 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(); delete timer; } clientReadTimers.clear(); for (ClientHandler* handler : clients) { handler->deleteLater(); } server->close(); 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(); } qDebug() << "MainWidget destroyed"; } void MainWidget::startClientReadTimer(int clientId) { qDebug() << "------ startClientReadTimer clientId:" << clientId; 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; for (auto it = clientThreads.begin(); it != clientThreads.end(); ++it) { 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秒打印一次线程池信息 } 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(); testJsonConfig = readJson_testConfig(); funcJsonConfig = readJson_funcConfig(); getPicJson = readJson_getPic(); getVideoJson = readJson_getVideo(); } // 设置 UI void MainWidget::setupUI() { startServerButton = new QPushButton("开始监听\n(Start Listening...)", this); startServerButton->setFixedSize(190, 70); // 设置宽度为 190 像素,高度为 70 像素 sendAllButton = new QPushButton("一键功能测试", this); sendAllButton->setFixedSize(190, 70); // 设置宽度为 190 像素,高度为 70 像素 sendAllButton->setEnabled(false); statusListWidget = new QListWidget(this); //statusListWidget->setMinimumSize(350, 880); statusListWidget->setMinimumSize(350, 680); 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); 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(); QGroupBox* groupBox = new QGroupBox("算法 license", this); QHBoxLayout* buttonRowLayout = new QHBoxLayout; for (int i = 0; i < frontBoardLicenseJson.size(); ++i) { QJsonObject item = frontBoardLicenseJson[i].toObject(); QString buttonText = item["lable"].toString(); QPushButton* button = new QPushButton(buttonText, this); button->setProperty("licenseIndex", i); buttonRowLayout->addWidget(button); connect(button, &QPushButton::clicked, this, &MainWidget::onLicenseButtonClicked); } licenseHwInfoEdit->setReadOnly(true); licenseHwInfoEdit->setText("This is a read-only text"); licenseHwInfoEdit->setFixedHeight(80); QVBoxLayout* groupBoxLayout_license = new QVBoxLayout; groupBoxLayout_license->addLayout(buttonRowLayout); groupBoxLayout_license->addWidget(licenseHwInfoEdit); groupBox->setLayout(groupBoxLayout_license); leftLayout->addWidget(groupBox); leftLayout->setStretch(3, 1); QWidget* leftContainer = new QWidget(this); leftContainer->setLayout(leftLayout); leftContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); QTabWidget* tabWidget = new QTabWidget(this); tabWidget->setFixedSize(900, 315); // 设置 QTabWidget 的固定大小 QGroupBox* frontDeviceInfoGroupBox = new QGroupBox("前板设备信息", this); QVBoxLayout* frontDeviceInfoLayout = new QVBoxLayout(frontDeviceInfoGroupBox); QVBoxLayout* frontDeviceLabelsLayout = new QVBoxLayout; for (const QJsonValue& value : frontBoardDevInfoJson) { QJsonObject item = value.toObject(); QString label = item["lable"].toString(); QString cmd = item["cmd"].toString(); QLabel* itemLabel = new QLabel(label, this); QLineEdit* itemLineEdit = new QLineEdit(this); itemLineEdit->setReadOnly(true); QHBoxLayout* itemLayout = new QHBoxLayout; itemLayout->addWidget(itemLabel); itemLayout->addWidget(itemLineEdit); frontDeviceLabelsLayout->addLayout(itemLayout); devInfoLineEdits[cmd] = itemLineEdit; } frontDeviceInfoLayout->addLayout(frontDeviceLabelsLayout); frontDeviceInfoLayout->addStretch(); QGroupBox* backDeviceInfoGroupBox = new QGroupBox("后板设备信息", this); QVBoxLayout* backDeviceInfoLayout = new QVBoxLayout(backDeviceInfoGroupBox); QVBoxLayout* backDeviceLabelsLayout = new QVBoxLayout; for (const QJsonValue& value : backBoardDevInfoJson) { QJsonObject item = value.toObject(); QString label = item["lable"].toString(); QString cmd = item["cmd"].toString(); QLabel* itemLabel = new QLabel(label, this); QLineEdit* itemLineEdit = new QLineEdit(this); itemLineEdit->setReadOnly(true); QHBoxLayout* itemLayout = new QHBoxLayout; itemLayout->addWidget(itemLabel); itemLayout->addWidget(itemLineEdit); backDeviceLabelsLayout->addLayout(itemLayout); devInfoLineEdits[cmd] = itemLineEdit; } backDeviceInfoLayout->addLayout(backDeviceLabelsLayout); backDeviceInfoLayout->addStretch(); QHBoxLayout* groupBoxLayout = new QHBoxLayout; groupBoxLayout->addWidget(frontDeviceInfoGroupBox, 1); groupBoxLayout->addWidget(backDeviceInfoGroupBox, 1); QWidget* functionTestTab = new QWidget; QVBoxLayout* functionTestLayout = new QVBoxLayout(functionTestTab); functionTestTab->setLayout(functionTestLayout); tabWidget->addTab(functionTestTab, "功能测试区"); QGridLayout* buttonGridLayout = new QGridLayout(); int buttonsPerRow = 7; // 每行显示的按键数量,根据需要调整 // 为每个 JSON 项目创建按键,并添加到 rightLayout // 先总共放 77 个按键 //qDebug() << "testJsonConfig.size():" << testJsonConfig.size(); for (int i = 0; i < frontBoardTest.size() + (77 - frontBoardTest.size()); ++i) { QJsonObject item = frontBoardTest[i].toObject(); QString buttonText = item["lable"].toString(); // 判断 buttonText 是否为空或者只有空白字符 if (buttonText.isEmpty()) { //qDebug() << "buttonText.isEmpty():" << buttonText.isEmpty(); buttonText = QString("Send Item %1").arg(i + 1); } QPushButton* button = new QPushButton(buttonText, this); button->setProperty("frontBoardTest", i); button->setFixedSize(110, 35); // 设置按键宽度和高度 connect(button, &QPushButton::clicked, this, &MainWidget::onSendItemClicked); int row = i / buttonsPerRow; int col = i % buttonsPerRow; buttonGridLayout->addWidget(button, row, col, Qt::AlignLeft); itemButtons.append(button); } QWidget* buttonContainer = new QWidget; buttonContainer->setLayout(buttonGridLayout); QScrollArea* scrollArea = new QScrollArea; scrollArea->setWidget(buttonContainer); scrollArea->setWidgetResizable(true); functionTestLayout->addWidget(scrollArea); QWidget* functionConfigTab = new QWidget; QVBoxLayout* functionConfigLayout = new QVBoxLayout(functionConfigTab); functionConfigTab->setLayout(functionConfigLayout); tabWidget->addTab(functionConfigTab, "功能配置区"); funcConfigLineEdit->setPlaceholderText("请输入配置参数..."); functionConfigLayout->addWidget(funcConfigLineEdit); QGridLayout* configButtonGridLayout = new QGridLayout(); for (int i = 0; i < frontBoardFuncConfig.size() + (77 - frontBoardFuncConfig.size()); ++i) { QJsonObject item = frontBoardFuncConfig[i].toObject(); QString buttonText = item["lable"].toString(); // 判断 buttonText 是否为空或者只有空白字符 if (buttonText.isEmpty()) { //qDebug() << "buttonText.isEmpty():" << buttonText.isEmpty(); buttonText = QString("Cfg Item %1").arg(i + 1); } QPushButton* button = new QPushButton(buttonText, this); button->setProperty("frontBoardFuncConfig", i); button->setFixedSize(110, 35); // 设置按键宽度和高度 connect(button, &QPushButton::clicked, this, &MainWidget::onSendFuncItemClicked); int row = i / buttonsPerRow; int col = i % buttonsPerRow; configButtonGridLayout->addWidget(button, row, col, Qt::AlignLeft); funcItemButtons.append(button); } QWidget* configButtonContainer = new QWidget; configButtonContainer->setLayout(configButtonGridLayout); QScrollArea* configScrollArea = new QScrollArea; configScrollArea->setWidget(configButtonContainer); configScrollArea->setWidgetResizable(true); functionConfigLayout->addWidget(configScrollArea); QTabWidget* tabWidget_media = new QTabWidget(this); QWidget* imageDisplayTab = new QWidget; QVBoxLayout* imageDisplayLayout = new QVBoxLayout(imageDisplayTab); imageDisplayTab->setLayout(imageDisplayLayout); tabWidget_media->addTab(imageDisplayTab, "图像显示区"); QVBoxLayout* imageButtonsColumnLayout = new QVBoxLayout; for (int i = 0; i < 5; ++i) { QHBoxLayout* imageButtonsRowLayout = new QHBoxLayout; for (int j = 0; j < 2; ++j) { QPushButton* button; if (i == 0 && j == 0) { button = new QPushButton(QString("IR"), this); button->setFixedSize(73, 50); imageButtonsRowLayout->addWidget(button); button->setProperty("getPicIndex", i * 2 + j); connect(button, &QPushButton::clicked, this, &MainWidget::onSendGetPicClicked); getPicButtons.append(button); continue; } else if (i == 0 && j == 1) { button = new QPushButton(QString("RGB"), this); button->setFixedSize(73, 50); imageButtonsRowLayout->addWidget(button); button->setProperty("getPicIndex", i * 2 + j); connect(button, &QPushButton::clicked, this, &MainWidget::onSendGetPicClicked); getPicButtons.append(button); continue; } button = new QPushButton(QString("Device %1").arg(i * 2 + j - 1), this); button->setFixedSize(73, 50); imageButtonsRowLayout->addWidget(button); button->setProperty("getPicIndex", i * 2 + j); connect(button, &QPushButton::clicked, this, &MainWidget::onSendGetPicClicked); getPicButtons.append(button); } imageButtonsColumnLayout->addLayout(imageButtonsRowLayout); } QHBoxLayout* lensesLayout = new QHBoxLayout; leftLens_imageLabel = new QLabel(this); rightLens_imageLabel = new QLabel(this); lensesLayout->addWidget(leftLens_imageLabel); lensesLayout->addWidget(rightLens_imageLabel); QHBoxLayout* imageAndButtonsLayout = new QHBoxLayout; imageAndButtonsLayout->addLayout(imageButtonsColumnLayout, 1); imageAndButtonsLayout->addLayout(lensesLayout, 4); imageDisplayLayout->addLayout(imageAndButtonsLayout); QWidget* videoDisplayTab = new QWidget; QVBoxLayout* videoDisplayLayout = new QVBoxLayout(videoDisplayTab); videoDisplayTab->setLayout(videoDisplayLayout); tabWidget_media->addTab(videoDisplayTab, "视频显示区"); QVBoxLayout* videoButtonsColumnLayout = new QVBoxLayout; for (int i = 0; i < 6; ++i) { QHBoxLayout* videoButtonsRowLayout = new QHBoxLayout; for (int j = 0; j < 2; ++j) { QPushButton* button; if (i == 0 && j == 0) { button = new QPushButton(QString("IR"), this); button->setFixedSize(73, 50); videoButtonsRowLayout->addWidget(button); button->setProperty("getVideoIndex", i * 2 + j); connect(button, &QPushButton::clicked, this, &MainWidget::onSendGetVideoClicked); getVideoButtons.append(button); continue; } else if (i == 0 && j == 1) { button = new QPushButton(QString("RGB"), this); button->setFixedSize(73, 50); videoButtonsRowLayout->addWidget(button); button->setProperty("getVideoIndex", i * 2 + j); connect(button, &QPushButton::clicked, this, &MainWidget::onSendGetVideoClicked); getVideoButtons.append(button); continue; } // 调价调焦窗口按键 if (i == 1 && j == 0) { button = new QPushButton(QString("大窗口播放视频"), this); button->setFixedSize(150, 50); button->setEnabled(false); videoButtonsRowLayout->addWidget(button); button->setProperty("getVideoIndex", i * 2 + j); connect(button, &QPushButton::clicked, this, &MainWidget::onOpenFocusWindowClicked); getVideoButtons.append(button); break; // 跳出内层循环,只添加一个按键 } //int adjustedIndex = (i > 1) ? i * 2 + j - 1 : i * 2 + j; button = new QPushButton(QString("Device %1").arg(i * 2 + j - 3), this); //button = new QPushButton(QString("Device %1").arg(adjustedIndex), this); button->setFixedSize(73, 50); videoButtonsRowLayout->addWidget(button); button->setProperty("getVideoIndex", i * 2 + j + 1); //button->setProperty("getVideoIndex", adjustedIndex); connect(button, &QPushButton::clicked, this, &MainWidget::onSendGetVideoClicked); getVideoButtons.append(button); } videoButtonsColumnLayout->addLayout(videoButtonsRowLayout); } QHBoxLayout* videoAndButtonsLayout = new QHBoxLayout; videoLabel = new QLabel(this); //videoLabel->setFixedSize(640, 480); videoAndButtonsLayout->addLayout(videoButtonsColumnLayout, 1); videoAndButtonsLayout->addWidget(videoLabel, 6); videoDisplayLayout->addLayout(videoAndButtonsLayout); QVBoxLayout* rightVerticalLayout = new QVBoxLayout; rightVerticalLayout->addLayout(groupBoxLayout, 2); rightVerticalLayout->addWidget(tabWidget, 2, Qt::AlignTop | Qt::AlignLeft); rightVerticalLayout->addWidget(tabWidget_media, 5); QHBoxLayout* mainLayout = new QHBoxLayout; // 参数二:伸缩因子,leftContainer:1/3 ,rightLayout:2/3 mainLayout->addWidget(leftContainer, 1, Qt::AlignTop | Qt::AlignLeft); // 设置 leftContainer 左上对齐 mainLayout->addLayout(rightVerticalLayout, 3); setLayout(mainLayout); setWindowTitle("SL100 工厂产测工具 - V0.0.1"); resize(1340, 1000); // 设置宽度为 1440 像素,高度为 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); } 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) { if (state == Qt::Checked) { saveStatusListToFile(filePathLineEdit->text()); } } void MainWidget::saveStatusListToFile(const QString& filePath) { if (filePath.isEmpty()) { return; } QFile file(filePath); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { 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(); connectedClientsCount--; updateServerButtonText(); break; } } // 启动 mDNS 服务广播 startMdnsService(); } // 处理客户端断开连接信号 void MainWidget::onClientDisconnected(ClientHandler* handler) { int clientId = handler->getClientId(); if (clientTimers.contains(clientId)) { QTimer* timer = clientTimers[clientId]; timer->stop(); delete timer; clientTimers.remove(clientId); } clients.removeOne(handler); /* 将 ClientHandler 对象的删除操作放入事件队列中,等待事件循环处理。 在事件循环执行时,会安全地删除 ClientHandler 对象,这包括释放其占用的资源和内存 */ handler->deleteLater(); // 延迟删除 ClientHandler 对象 // 更新连接数并更新按键文本 connectedClientsCount--; if (nextClientId <= 2) nextClientId--; deviceConnected = true; updateServerButtonText(); } // 更新按键文本的函数 void MainWidget::updateServerButtonText() { if (deviceConnected) { deviceConnected = false; startServerButton->setText(tr("正在监听(Listening)")); if (connectedClientsCount == 0) startMdnsService(); } else if (connectedClientsCount == 0) { startServerButton->setText(tr("开始监听\n(Start Listening...)")); } else { startServerButton->setText(tr("正在监听(Listening)\n%1 台设备连接").arg(connectedClientsCount)); } } void MainWidget::onLicenseButtonClicked() { if (connectedClientsCount) { QPushButton* button = qobject_cast(sender()); if (button) { int index = button->property("licenseIndex").toInt(); if (index >= 0 && index < frontBoardLicenseJson.size()) { QJsonObject jsonObject = frontBoardLicenseJson[index].toObject(); //QString jsonString = QJsonDocument(jsonObject).toJson(QJsonDocument::Compact); //qDebug() << "license Button clicked, sending JSON:" << jsonString; unsigned char license_info[PIX_LICENCE_BYTES] = { 0 }; if (jsonObject["lable"].toString() == "get_license") { LicenseConfirmWindow dialog("你确定要获取此授权吗?"); if (dialog.exec() == QDialog::Accepted) licenseGenerate(license_info, license_info); } else { if (jsonObject["lable"].toString() == "write_license") { LicenseConfirmWindow dialog("你确定要发送此授权吗?"); if (dialog.exec() == QDialog::Accepted) licenseGenerate(license_info, license_info); } for (ClientHandler* handler : clients) { handler->sendLicenseItem(index); } } } } } else { QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget); listItem->setBackground(Qt::red); } } 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 = "_SL100_FactoryTool-service._tcp"; 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(); } #if TEST_UDP_BROADCAST void MainWidget::sendMulticastMessage() { QByteArray datagram = "--------------------------------- Test multicast message from MainWidget"; QHostAddress groupAddress("224.0.0.251"); quint16 port = 5353; qint64 sentBytes = multicastSocket->writeDatagram(datagram, groupAddress, port); if (sentBytes == -1) { qWarning() << "Failed to send multicast message:" << multicastSocket->errorString(); } else { qDebug() << "Multicast message sentBytes:" << sentBytes; qDebug() << "Multicast message sent:" << datagram; } } #endif // 处理开始服务器按键点击事件 void MainWidget::onStartServerClicked() { if (!server->isListening()) { startMdnsService(); #if TEST_UDP_BROADCAST sendMulticastMessage(); #endif // QHostAddress specifiedIpAddress("10.10.10.253"); quint16 specifiedPort = TCP_CONNECT_PORT; 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); stopMdnsService(); } } // 处理发送获取设备信息按键点击事件 void MainWidget::onSendGetDevInfoClicked() { if (connectedClientsCount) { QPushButton* button = qobject_cast(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) { handler->sendGetDevInfoItem(itemIndex); } } } else { QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget); listItem->setBackground(Qt::red); } } // 处理发送取图按键点击事件 void MainWidget::onSendGetPicClicked() { if (connectedClientsCount) { QPushButton* button = qobject_cast(sender()); int itemIndex = button->property("getPicIndex").toInt(); if (itemIndex < 2) { button->setStyleSheet("background-color: green;"); if (lastClickedGetPicCamIndex != -1 && lastClickedGetPicCamIndex != itemIndex) { getPicButtons[lastClickedGetPicCamIndex]->setStyleSheet(""); } 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) { QListWidgetItem* listItem = new QListWidgetItem(QString("No device %1 is connected !!!").arg(itemIndex - 1), statusListWidget); 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) { handler->sendGetPicItem(itemIndex - 2, lastClickedGetPicCamIndex); } } } } } else { QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget); listItem->setBackground(Qt::red); } } // 处理发送拉视频流按键点击事件 void MainWidget::onSendGetVideoClicked() { if (connectedClientsCount) { QPushButton* button = qobject_cast(sender()); int itemIndex = button->property("getVideoIndex").toInt(); if (itemIndex < 2) { button->setStyleSheet("background-color: green;"); if (lastClickedGetVideoCamIndex != -1 && lastClickedGetVideoCamIndex != itemIndex) { getVideoButtons[lastClickedGetVideoCamIndex]->setStyleSheet(""); } lastClickedGetVideoCamIndex = itemIndex; } else { if (lastClickedGetVideoCamIndex == -1) { QListWidgetItem* listItem = new QListWidgetItem(QString("Please select IR or RGB lens to get video!!!"), statusListWidget); listItem->setBackground(Qt::red); } else { if (itemIndex - 6 >= connectedClientsCount) { QListWidgetItem* listItem = new QListWidgetItem(QString("No device %1 is connected !!!").arg(itemIndex - 4), statusListWidget); listItem->setBackground(Qt::red); } else { button->setStyleSheet("background-color: green;"); if (lastClickedGetVideoDevIndex != -1 && lastClickedGetVideoDevIndex != itemIndex) { getVideoButtons[lastClickedGetVideoDevIndex]->setStyleSheet(""); } lastClickedGetVideoDevIndex = itemIndex; //QMutexLocker locker(&mutex); for (ClientHandler* handler : clients) { handler->sendGetVideoItem(itemIndex - 5, 1); } getVideoButtons[2]->setEnabled(true); } } } } else { QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget); listItem->setBackground(Qt::red); } } void MainWidget::onOpenFocusWindowClicked() { QPushButton* button = qobject_cast(sender()); if (button) { int itemIndex = button->property("getVideoIndex").toInt(); //qDebug() << "New Button clicked with itemIndex:" << itemIndex; if (itemIndex == 2) { // 创建并显示新窗口 NewButtonDialog dialog(this); dialog.exec(); } } } // 处理一键发送按键点击事件 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(); handler->sendNextItem(); //handler->sendDevInfoItem(); } } else { sendAllButton->setText("一键功能测试"); sendAllButton->setStyleSheet("background-color: white;"); manualSend = false; for (ClientHandler* handler : clients) { handler->resetCurrentItemIndex(); } } } else { QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget); listItem->setBackground(Qt::red); } } // 处理单独发送功能项按键点击事件 void MainWidget::onSendFuncItemClicked() { if (connectedClientsCount) { QPushButton* button = qobject_cast(sender()); int itemIndex = button->property("frontBoardFuncConfig").toInt(); for (ClientHandler* handler : clients) { QString text = funcConfigLineEdit->text(); qDebug() << "Text in funcConfigLineEdit:" << text; handler->sendFuncItem(itemIndex, text); } } else { QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget); listItem->setBackground(Qt::red); } } // 处理单独发送项按键点击事件 void MainWidget::onSendItemClicked() { if (connectedClientsCount) { QPushButton* button = qobject_cast(sender()); int itemIndex = button->property("frontBoardTest").toInt(); for (ClientHandler* handler : clients) { handler->sendItem(itemIndex); } } 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, bool success, const QString& itemData, const QString& funcItemData) { int clientId = -1; // 遍历所有的 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; 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); } statusListWidget->scrollToBottom(); } // json文件里面的配置项都测试结束 void MainWidget::onAllItemsProcessed(const QString& client, int itemsProcessedCount) { isSendingAll = false; sendAllButton->setText("一键功能测试"); sendAllButton->setStyleSheet("background-color: white;"); //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); statusListWidget->addItem(listItem); statusListWidget->scrollToBottom(); } //#include "MainWidget.h" // // //void onThreadFinished(QThread* thread, ClientHandler* handler) //{ // qDebug() << "Thread finished. Deleting handler and thread."; // handler->deleteLater(); // thread->deleteLater(); //} // //// 初始化 UI 组件和服务器 //MainWidget::MainWidget(QWidget* parent) : // QWidget(parent), // nextClientId(1), // manualSend(false), // isSendingAll(false), // lastClickedGetPicCamIndex(-1), // lastClickedGetPicDevIndex(-1), // lastClickedGetVideoCamIndex(-1), // lastClickedGetVideoDevIndex(-1), // mServiceProvider(new ServiceProvider(this)) //#if TEST_UDP_BROADCAST // , multicastSocket(new QUdpSocket(this)), // multicastTimer(new QTimer(this)) //#endif //{ // leftLens_imageLabel = new QLabel(this); // rightLens_imageLabel = new QLabel(this); // videoLabel = new QLabel(this); // funcConfigLineEdit = new QLineEdit(this); // licenseHwInfoEdit = new QTextEdit(this); // // setupUI(); // // 打印线程池状态信息 // setupTimerForThreadPoolInfo(); // server = new QTcpServer(this); // // connect(server, &QTcpServer::newConnection, this, [this]() { // // 检查是否有挂起的连接 // while (server->hasPendingConnections()) { // QTcpSocket* socket = server->nextPendingConnection(); // int clientId = nextClientId++; // qDebug() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"; // qDebug() << "> A client is connected. ID:" << clientId; // qDebug() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"; // // // 更新连接数量并更新按键文本 // connectedClientsCount++; // 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; // } // } // } // }); // // QThread* thread = new QThread(this); // ClientHandler* handler = new ClientHandler(socket, frontBoardOneClickTest, frontBoardTest, frontBoardFuncConfig, // frontBoardDevInfoJson, frontBoardLicenseJson, backBoardDevInfoJson, // getPicJson, getVideoJson, clientId, nullptr); // // // 将 ClientHandler 移动到线程池中的线程 // handler->moveToThread(thread); // // // 当线程结束时删除 handler // connect(thread, &QThread::finished, this, [=]() { // onThreadFinished(thread, handler); // }); // // // 将sendData信号连接到主线程中的槽上 // connect(handler, &ClientHandler::sendData, this, [socket](const QByteArray& data) { // socket->write(data); // socket->flush(); // }); // // connect(handler, &ClientHandler::startTimeout, this, [this, clientId](int timeout) { // this->onStartTimeout(clientId, timeout); // }); // // // 启动新的线程 // thread->start(); // // clients.append(handler); // clients_1[clientId] = handler; // clientThreads[clientId] = thread; // connect(handler, &ClientHandler::statusUpdated, this, &MainWidget::onStatusUpdated); // connect(handler, &ClientHandler::clientDisconnected, this, &MainWidget::onClientDisconnected); // connect(handler, &ClientHandler::allItemsProcessed, this, &MainWidget::onAllItemsProcessed); // connect(handler, &ClientHandler::selectClientDisconnected, this, &MainWidget::onDisconnectClient); // // // 创建 DataHandler 对象并连接信号 // DataHandler* dataHandler = new DataHandler(leftLens_imageLabel, rightLens_imageLabel, videoLabel, licenseHwInfoEdit, &devInfoLineEdits, this); // connect(handler, &ClientHandler::dataReceived, dataHandler, &DataHandler::handleData); // connect(dataHandler, &DataHandler::statusUpdated, this, &MainWidget::onStatusUpdated); // // connect(handler, &ClientHandler::startReadTimer, this, &MainWidget::startClientReadTimer); // connect(handler, &ClientHandler::stopReadTimer, this, &MainWidget::stopClientReadTimer); // // // 创建和管理定时器 // QTimer* readTimer = new QTimer(this); // connect(readTimer, &QTimer::timeout, handler, &ClientHandler::onTimeoutRead); // // readTimer->start(10); // 每 10ms 触发一次 // // 将定时器存储到哈希表中,方便管理 // clientReadTimers[clientId] = readTimer; // } // }); // // 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检查一次连接状态 // //#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 //} // //MainWidget::~MainWidget() //{ //#if TEST_UDP_BROADCAST // multicastTimer->stop(); // multicastSocket->leaveMulticastGroup(QHostAddress("224.0.0.251")); // multicastSocket->close(); //#endif // stopMdnsService(); // for (auto timer : clientReadTimers) { // timer->stop(); // delete timer; // } // clientReadTimers.clear(); // for (ClientHandler* handler : clients) { // handler->deleteLater(); // } // server->close(); // // 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(); // } // qDebug() << "MainWidget destroyed"; //} // //void MainWidget::startClientReadTimer(int clientId) { // qDebug() << "------ startClientReadTimer clientId:" << clientId; // 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; // for (auto it = clientThreads.begin(); it != clientThreads.end(); ++it) { // 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秒打印一次线程池信息 //} // //void MainWidget::readJsonConfig() //{ // frontBoardOneClickTest = readJson_frontBoardOneClickTest(); // frontBoardTest = readJson_frontBoardTest(); // frontBoardFuncConfig = readJson_frontBoardFuncConfig(); // frontBoardDevInfoJson = readJson_frontDevInfo(); // frontBoardLicenseJson = readJson_frontLicense(); // backBoardDevInfoJson = readJson_backDevInfo(); // testJsonConfig = readJson_testConfig(); // funcJsonConfig = readJson_funcConfig(); // // getPicJson = readJson_getPic(); // getVideoJson = readJson_getVideo(); //} // //// 设置 UI //void MainWidget::setupUI() //{ // startServerButton = new QPushButton("开始监听\n(Start Listening...)", this); // startServerButton->setFixedSize(190, 70); // 设置宽度为 190 像素,高度为 70 像素 // // sendAllButton = new QPushButton("一键功能测试", this); // sendAllButton->setFixedSize(190, 70); // 设置宽度为 190 像素,高度为 70 像素 // sendAllButton->setEnabled(false); // // statusListWidget = new QListWidget(this); // //statusListWidget->setMinimumSize(350, 880); // statusListWidget->setMinimumSize(350, 680); // 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); // 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(); // // QGroupBox* groupBox = new QGroupBox("算法 license", this); // QHBoxLayout* buttonRowLayout = new QHBoxLayout; // for (int i = 0; i < frontBoardLicenseJson.size(); ++i) { // QJsonObject item = frontBoardLicenseJson[i].toObject(); // QString buttonText = item["lable"].toString(); // QPushButton* button = new QPushButton(buttonText, this); // button->setProperty("licenseIndex", i); // buttonRowLayout->addWidget(button); // connect(button, &QPushButton::clicked, this, &MainWidget::onLicenseButtonClicked); // } // licenseHwInfoEdit->setReadOnly(true); // licenseHwInfoEdit->setText("This is a read-only text"); // licenseHwInfoEdit->setFixedHeight(80); // // QVBoxLayout* groupBoxLayout_license = new QVBoxLayout; // groupBoxLayout_license->addLayout(buttonRowLayout); // groupBoxLayout_license->addWidget(licenseHwInfoEdit); // groupBox->setLayout(groupBoxLayout_license); // // leftLayout->addWidget(groupBox); // leftLayout->setStretch(3, 1); // // QWidget* leftContainer = new QWidget(this); // leftContainer->setLayout(leftLayout); // leftContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); // // QTabWidget* tabWidget = new QTabWidget(this); // tabWidget->setFixedSize(900, 315); // 设置 QTabWidget 的固定大小 // // QGroupBox* frontDeviceInfoGroupBox = new QGroupBox("前板设备信息", this); // QVBoxLayout* frontDeviceInfoLayout = new QVBoxLayout(frontDeviceInfoGroupBox); // // QVBoxLayout* frontDeviceLabelsLayout = new QVBoxLayout; // for (const QJsonValue& value : frontBoardDevInfoJson) { // QJsonObject item = value.toObject(); // QString label = item["lable"].toString(); // QString cmd = item["cmd"].toString(); // QLabel* itemLabel = new QLabel(label, this); // QLineEdit* itemLineEdit = new QLineEdit(this); // itemLineEdit->setReadOnly(true); // // QHBoxLayout* itemLayout = new QHBoxLayout; // itemLayout->addWidget(itemLabel); // itemLayout->addWidget(itemLineEdit); // // frontDeviceLabelsLayout->addLayout(itemLayout); // devInfoLineEdits[cmd] = itemLineEdit; // } // frontDeviceInfoLayout->addLayout(frontDeviceLabelsLayout); // frontDeviceInfoLayout->addStretch(); // // QGroupBox* backDeviceInfoGroupBox = new QGroupBox("后板设备信息", this); // QVBoxLayout* backDeviceInfoLayout = new QVBoxLayout(backDeviceInfoGroupBox); // // QVBoxLayout* backDeviceLabelsLayout = new QVBoxLayout; // for (const QJsonValue& value : backBoardDevInfoJson) { // QJsonObject item = value.toObject(); // QString label = item["lable"].toString(); // QString cmd = item["cmd"].toString(); // QLabel* itemLabel = new QLabel(label, this); // QLineEdit* itemLineEdit = new QLineEdit(this); // itemLineEdit->setReadOnly(true); // // QHBoxLayout* itemLayout = new QHBoxLayout; // itemLayout->addWidget(itemLabel); // itemLayout->addWidget(itemLineEdit); // // backDeviceLabelsLayout->addLayout(itemLayout); // devInfoLineEdits[cmd] = itemLineEdit; // } // backDeviceInfoLayout->addLayout(backDeviceLabelsLayout); // backDeviceInfoLayout->addStretch(); // // QHBoxLayout* groupBoxLayout = new QHBoxLayout; // groupBoxLayout->addWidget(frontDeviceInfoGroupBox, 1); // groupBoxLayout->addWidget(backDeviceInfoGroupBox, 1); // // QWidget* functionTestTab = new QWidget; // QVBoxLayout* functionTestLayout = new QVBoxLayout(functionTestTab); // functionTestTab->setLayout(functionTestLayout); // tabWidget->addTab(functionTestTab, "功能测试区"); // // QGridLayout* buttonGridLayout = new QGridLayout(); // int buttonsPerRow = 7; // 每行显示的按键数量,根据需要调整 // // 为每个 JSON 项目创建按键,并添加到 rightLayout // // 先总共放 77 个按键 // //qDebug() << "testJsonConfig.size():" << testJsonConfig.size(); // for (int i = 0; i < frontBoardTest.size() + (77 - frontBoardTest.size()); ++i) { // QJsonObject item = frontBoardTest[i].toObject(); // QString buttonText = item["lable"].toString(); // // 判断 buttonText 是否为空或者只有空白字符 // if (buttonText.isEmpty()) { // //qDebug() << "buttonText.isEmpty():" << buttonText.isEmpty(); // buttonText = QString("Send Item %1").arg(i + 1); // } // QPushButton* button = new QPushButton(buttonText, this); // button->setProperty("frontBoardTest", i); // button->setFixedSize(110, 35); // 设置按键宽度和高度 // connect(button, &QPushButton::clicked, this, &MainWidget::onSendItemClicked); // // int row = i / buttonsPerRow; // int col = i % buttonsPerRow; // buttonGridLayout->addWidget(button, row, col, Qt::AlignLeft); // // itemButtons.append(button); // } // // QWidget* buttonContainer = new QWidget; // buttonContainer->setLayout(buttonGridLayout); // // QScrollArea* scrollArea = new QScrollArea; // scrollArea->setWidget(buttonContainer); // scrollArea->setWidgetResizable(true); // // functionTestLayout->addWidget(scrollArea); // // QWidget* functionConfigTab = new QWidget; // QVBoxLayout* functionConfigLayout = new QVBoxLayout(functionConfigTab); // functionConfigTab->setLayout(functionConfigLayout); // tabWidget->addTab(functionConfigTab, "功能配置区"); // // funcConfigLineEdit->setPlaceholderText("请输入配置参数..."); // functionConfigLayout->addWidget(funcConfigLineEdit); // // QGridLayout* configButtonGridLayout = new QGridLayout(); // // for (int i = 0; i < frontBoardFuncConfig.size() + (77 - frontBoardFuncConfig.size()); ++i) { // QJsonObject item = frontBoardFuncConfig[i].toObject(); // QString buttonText = item["lable"].toString(); // // 判断 buttonText 是否为空或者只有空白字符 // if (buttonText.isEmpty()) { // //qDebug() << "buttonText.isEmpty():" << buttonText.isEmpty(); // buttonText = QString("Cfg Item %1").arg(i + 1); // } // QPushButton* button = new QPushButton(buttonText, this); // button->setProperty("frontBoardFuncConfig", i); // button->setFixedSize(110, 35); // 设置按键宽度和高度 // connect(button, &QPushButton::clicked, this, &MainWidget::onSendFuncItemClicked); // // int row = i / buttonsPerRow; // int col = i % buttonsPerRow; // configButtonGridLayout->addWidget(button, row, col, Qt::AlignLeft); // // funcItemButtons.append(button); // } // // QWidget* configButtonContainer = new QWidget; // configButtonContainer->setLayout(configButtonGridLayout); // // QScrollArea* configScrollArea = new QScrollArea; // configScrollArea->setWidget(configButtonContainer); // configScrollArea->setWidgetResizable(true); // // functionConfigLayout->addWidget(configScrollArea); // // QTabWidget* tabWidget_media = new QTabWidget(this); // QWidget* imageDisplayTab = new QWidget; // QVBoxLayout* imageDisplayLayout = new QVBoxLayout(imageDisplayTab); // imageDisplayTab->setLayout(imageDisplayLayout); // tabWidget_media->addTab(imageDisplayTab, "图像显示区"); // // QVBoxLayout* imageButtonsColumnLayout = new QVBoxLayout; // for (int i = 0; i < 5; ++i) { // QHBoxLayout* imageButtonsRowLayout = new QHBoxLayout; // for (int j = 0; j < 2; ++j) { // QPushButton* button; // if (i == 0 && j == 0) { // button = new QPushButton(QString("IR"), this); // button->setFixedSize(73, 50); // imageButtonsRowLayout->addWidget(button); // button->setProperty("getPicIndex", i * 2 + j); // connect(button, &QPushButton::clicked, this, &MainWidget::onSendGetPicClicked); // getPicButtons.append(button); // continue; // } // else if (i == 0 && j == 1) { // button = new QPushButton(QString("RGB"), this); // button->setFixedSize(73, 50); // imageButtonsRowLayout->addWidget(button); // button->setProperty("getPicIndex", i * 2 + j); // connect(button, &QPushButton::clicked, this, &MainWidget::onSendGetPicClicked); // getPicButtons.append(button); // continue; // } // // button = new QPushButton(QString("Device %1").arg(i * 2 + j - 1), this); // button->setFixedSize(73, 50); // imageButtonsRowLayout->addWidget(button); // button->setProperty("getPicIndex", i * 2 + j); // connect(button, &QPushButton::clicked, this, &MainWidget::onSendGetPicClicked); // getPicButtons.append(button); // } // imageButtonsColumnLayout->addLayout(imageButtonsRowLayout); // } // // QHBoxLayout* lensesLayout = new QHBoxLayout; // leftLens_imageLabel = new QLabel(this); // rightLens_imageLabel = new QLabel(this); // lensesLayout->addWidget(leftLens_imageLabel); // lensesLayout->addWidget(rightLens_imageLabel); // // QHBoxLayout* imageAndButtonsLayout = new QHBoxLayout; // imageAndButtonsLayout->addLayout(imageButtonsColumnLayout, 1); // imageAndButtonsLayout->addLayout(lensesLayout, 4); // imageDisplayLayout->addLayout(imageAndButtonsLayout); // // QWidget* videoDisplayTab = new QWidget; // QVBoxLayout* videoDisplayLayout = new QVBoxLayout(videoDisplayTab); // videoDisplayTab->setLayout(videoDisplayLayout); // tabWidget_media->addTab(videoDisplayTab, "视频显示区"); // // QVBoxLayout* videoButtonsColumnLayout = new QVBoxLayout; // for (int i = 0; i < 6; ++i) { // QHBoxLayout* videoButtonsRowLayout = new QHBoxLayout; // for (int j = 0; j < 2; ++j) { // QPushButton* button; // if (i == 0 && j == 0) { // button = new QPushButton(QString("IR"), this); // button->setFixedSize(73, 50); // videoButtonsRowLayout->addWidget(button); // button->setProperty("getVideoIndex", i * 2 + j); // connect(button, &QPushButton::clicked, this, &MainWidget::onSendGetVideoClicked); // getVideoButtons.append(button); // continue; // } // else if (i == 0 && j == 1) { // button = new QPushButton(QString("RGB"), this); // button->setFixedSize(73, 50); // videoButtonsRowLayout->addWidget(button); // button->setProperty("getVideoIndex", i * 2 + j); // connect(button, &QPushButton::clicked, this, &MainWidget::onSendGetVideoClicked); // getVideoButtons.append(button); // continue; // } // // // 调价调焦窗口按键 // if (i == 1 && j == 0) { // button = new QPushButton(QString("大窗口播放视频"), this); // button->setFixedSize(150, 50); // button->setEnabled(false); // videoButtonsRowLayout->addWidget(button); // button->setProperty("getVideoIndex", i * 2 + j); // connect(button, &QPushButton::clicked, this, &MainWidget::onOpenFocusWindowClicked); // getVideoButtons.append(button); // break; // 跳出内层循环,只添加一个按键 // } // // //int adjustedIndex = (i > 1) ? i * 2 + j - 1 : i * 2 + j; // button = new QPushButton(QString("Device %1").arg(i * 2 + j - 3), this); // //button = new QPushButton(QString("Device %1").arg(adjustedIndex), this); // button->setFixedSize(73, 50); // videoButtonsRowLayout->addWidget(button); // button->setProperty("getVideoIndex", i * 2 + j + 1); // //button->setProperty("getVideoIndex", adjustedIndex); // connect(button, &QPushButton::clicked, this, &MainWidget::onSendGetVideoClicked); // getVideoButtons.append(button); // } // videoButtonsColumnLayout->addLayout(videoButtonsRowLayout); // } // // QHBoxLayout* videoAndButtonsLayout = new QHBoxLayout; // videoLabel = new QLabel(this); // //videoLabel->setFixedSize(640, 480); // videoAndButtonsLayout->addLayout(videoButtonsColumnLayout, 1); // videoAndButtonsLayout->addWidget(videoLabel, 6); // videoDisplayLayout->addLayout(videoAndButtonsLayout); // // QVBoxLayout* rightVerticalLayout = new QVBoxLayout; // rightVerticalLayout->addLayout(groupBoxLayout, 2); // rightVerticalLayout->addWidget(tabWidget, 2, Qt::AlignTop | Qt::AlignLeft); // rightVerticalLayout->addWidget(tabWidget_media, 5); // // QHBoxLayout* mainLayout = new QHBoxLayout; // // 参数二:伸缩因子,leftContainer:1/3 ,rightLayout:2/3 // mainLayout->addWidget(leftContainer, 1, Qt::AlignTop | Qt::AlignLeft); // 设置 leftContainer 左上对齐 // mainLayout->addLayout(rightVerticalLayout, 3); // // setLayout(mainLayout); // setWindowTitle("SL100 工厂产测工具 - V0.0.1"); // resize(1340, 1000); // 设置宽度为 1440 像素,高度为 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); //} // //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) //{ // if (state == Qt::Checked) { // saveStatusListToFile(filePathLineEdit->text()); // } //} // //void MainWidget::saveStatusListToFile(const QString& filePath) //{ // if (filePath.isEmpty()) { // return; // } // // QFile file(filePath); // if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { // 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(); // // 更新连接数并更新按键文本 // connectedClientsCount--; // updateServerButtonText(); // // break; // } // } // // // 启动 mDNS 服务广播 // startMdnsService(); //} // //// 处理客户端断开连接信号 //void MainWidget::onClientDisconnected(ClientHandler* handler) //{ // int clientId = handler->getClientId(); // if (clientTimers.contains(clientId)) { // QTimer* timer = clientTimers[clientId]; // timer->stop(); // delete timer; // clientTimers.remove(clientId); // } // // clients.removeOne(handler); // /* // 将 ClientHandler 对象的删除操作放入事件队列中,等待事件循环处理。 // 在事件循环执行时,会安全地删除 ClientHandler 对象,这包括释放其占用的资源和内存 // */ // handler->deleteLater(); // 延迟删除 ClientHandler 对象 // // // 更新连接数并更新按键文本 // connectedClientsCount--; // if (nextClientId <= 2) nextClientId--; // deviceConnected = true; // updateServerButtonText(); //} // //// 更新按键文本的函数 //void MainWidget::updateServerButtonText() //{ // if (deviceConnected) { // 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)); // } //} // //void MainWidget::onLicenseButtonClicked() //{ // if (connectedClientsCount) { // QPushButton* button = qobject_cast(sender()); // if (button) { // int index = button->property("licenseIndex").toInt(); // if (index >= 0 && index < frontBoardLicenseJson.size()) { // QJsonObject jsonObject = frontBoardLicenseJson[index].toObject(); // //QString jsonString = QJsonDocument(jsonObject).toJson(QJsonDocument::Compact); // //qDebug() << "license Button clicked, sending JSON:" << jsonString; // unsigned char license_info[PIX_LICENCE_BYTES] = { 0 }; // if (jsonObject["lable"].toString() == "get_license") { // LicenseConfirmWindow dialog("你确定要获取此授权吗?"); // if (dialog.exec() == QDialog::Accepted) // licenseGenerate(license_info, license_info); // } // else { // if (jsonObject["lable"].toString() == "write_license") { // LicenseConfirmWindow dialog("你确定要发送此授权吗?"); // if (dialog.exec() == QDialog::Accepted) // licenseGenerate(license_info, license_info); // } // for (ClientHandler* handler : clients) { // handler->sendLicenseItem(index); // } // } // } // } // } // else { // QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget); // listItem->setBackground(Qt::red); // } //} // //void MainWidget::startMdnsService() //{ // QString serviceName = "My Mdns Broadcast Service"; // 替换为你想要的服务名称 // QString serviceType = "_my-service._tcp"; // 替换为实际的服务类型 // quint16 port = 12412; // 使用的端口号,确保与 TCP 服务器监听的端口号一致 // mServiceProvider->startServiceBroadcast(serviceName, serviceType, port); //} // //void MainWidget::stopMdnsService() //{ // mServiceProvider->stopServiceBroadcast(); //} // //#if TEST_UDP_BROADCAST //void MainWidget::sendMulticastMessage() //{ // QByteArray datagram = "Test multicast message from MainWidget"; // QHostAddress groupAddress("224.0.0.251"); // quint16 port = 5353; // // qint64 sentBytes = multicastSocket->writeDatagram(datagram, groupAddress, port); // if (sentBytes == -1) { // qWarning() << "Failed to send multicast message:" << multicastSocket->errorString(); // } // else { // qDebug() << "Multicast message sentBytes:" << sentBytes; // qDebug() << "Multicast message sent:" << datagram; // } //} //#endif // //// 处理开始服务器按键点击事件 //void MainWidget::onStartServerClicked() //{ // if (!server->isListening()) { // // 启动 mDNS 服务广播 // startMdnsService(); //#if TEST_UDP_BROADCAST // sendMulticastMessage(); //#endif // // 根据需要修改 // // QHostAddress specifiedIpAddress("10.10.10.253"); // quint16 specifiedPort = 12412; // qDebug() << "" << specifiedPort; // if (server->listen(QHostAddress::Any, specifiedPort)) { // startServerButton->setText(tr("正在监听(Listening)")); // // 设置按钮背景色为绿色 // startServerButton->setStyleSheet("background-color: green;"); // sendAllButton->setEnabled(true); // // // 启动 mDNS 服务广播 // //startMdnsService(); // } // else { // qDebug() << "Failed to start server. Error:" << server->errorString(); // } // } // else { // server->close(); // startServerButton->setText(tr("开始监听\n(Start Listening...)")); // startServerButton->setStyleSheet(""); // sendAllButton->setEnabled(false); // // // 停止 mDNS 服务广播 // //stopMdnsService(); // } //} // //// 处理发送获取设备信息按键点击事件 //void MainWidget::onSendGetDevInfoClicked() //{ // if (connectedClientsCount) { // QPushButton* button = qobject_cast(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) { // handler->sendGetDevInfoItem(itemIndex); // } // } // } // else { // QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget); // listItem->setBackground(Qt::red); // } //} // //// 处理发送取图按键点击事件 //void MainWidget::onSendGetPicClicked() //{ // if (connectedClientsCount) { // QPushButton* button = qobject_cast(sender()); // int itemIndex = button->property("getPicIndex").toInt(); // // if (itemIndex < 2) { // button->setStyleSheet("background-color: green;"); // if (lastClickedGetPicCamIndex != -1 && lastClickedGetPicCamIndex != itemIndex) { // getPicButtons[lastClickedGetPicCamIndex]->setStyleSheet(""); // } // 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) { // QListWidgetItem* listItem = new QListWidgetItem(QString("No device %1 is connected !!!").arg(itemIndex - 1), statusListWidget); // 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) { // handler->sendGetPicItem(itemIndex - 2, lastClickedGetPicCamIndex); // } // } // } // } // } // else { // QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget); // listItem->setBackground(Qt::red); // } //} // //// 处理发送拉视频流按键点击事件 //void MainWidget::onSendGetVideoClicked() //{ // if (connectedClientsCount) { // QPushButton* button = qobject_cast(sender()); // int itemIndex = button->property("getVideoIndex").toInt(); // // if (itemIndex < 2) { // button->setStyleSheet("background-color: green;"); // if (lastClickedGetVideoCamIndex != -1 && lastClickedGetVideoCamIndex != itemIndex) { // getVideoButtons[lastClickedGetVideoCamIndex]->setStyleSheet(""); // } // lastClickedGetVideoCamIndex = itemIndex; // } // else { // if (lastClickedGetVideoCamIndex == -1) { // QListWidgetItem* listItem = new QListWidgetItem(QString("Please select IR or RGB lens to get video!!!"), statusListWidget); // listItem->setBackground(Qt::red); // } // else { // if (itemIndex - 6 >= connectedClientsCount) { // QListWidgetItem* listItem = new QListWidgetItem(QString("No device %1 is connected !!!").arg(itemIndex - 4), statusListWidget); // listItem->setBackground(Qt::red); // } // else { // button->setStyleSheet("background-color: green;"); // if (lastClickedGetVideoDevIndex != -1 && lastClickedGetVideoDevIndex != itemIndex) { // getVideoButtons[lastClickedGetVideoDevIndex]->setStyleSheet(""); // } // lastClickedGetVideoDevIndex = itemIndex; // //QMutexLocker locker(&mutex); // for (ClientHandler* handler : clients) { // handler->sendGetVideoItem(itemIndex - 5, 1); // } // getVideoButtons[2]->setEnabled(true); // } // } // } // } // else { // QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget); // listItem->setBackground(Qt::red); // } //} // //void MainWidget::onOpenFocusWindowClicked() //{ // QPushButton* button = qobject_cast(sender()); // if (button) { // int itemIndex = button->property("getVideoIndex").toInt(); // //qDebug() << "New Button clicked with itemIndex:" << itemIndex; // if (itemIndex == 2) { // // 创建并显示新窗口 // NewButtonDialog dialog(this); // dialog.exec(); // } // } //} // //// 处理一键发送按键点击事件 //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(); // handler->sendNextItem(); // //handler->sendDevInfoItem(); // } // } // else { // sendAllButton->setText("一键功能测试"); // sendAllButton->setStyleSheet("background-color: white;"); // manualSend = false; // for (ClientHandler* handler : clients) { // handler->resetCurrentItemIndex(); // } // } // } // else { // QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget); // listItem->setBackground(Qt::red); // } //} // //// 处理单独发送功能项按键点击事件 //void MainWidget::onSendFuncItemClicked() //{ // if (connectedClientsCount) { // QPushButton* button = qobject_cast(sender()); // int itemIndex = button->property("frontBoardFuncConfig").toInt(); // for (ClientHandler* handler : clients) { // QString text = funcConfigLineEdit->text(); // qDebug() << "Text in funcConfigLineEdit:" << text; // handler->sendFuncItem(itemIndex, text); // } // } // else { // QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget); // listItem->setBackground(Qt::red); // } //} // //// 处理单独发送项按键点击事件 //void MainWidget::onSendItemClicked() //{ // if (connectedClientsCount) { // QPushButton* button = qobject_cast(sender()); // int itemIndex = button->property("frontBoardTest").toInt(); // for (ClientHandler* handler : clients) { // handler->sendItem(itemIndex); // } // } // 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, // bool success, const QString& itemData, const QString& funcItemData) //{ // int clientId = -1; // // 遍历所有的 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; // 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); // } // statusListWidget->scrollToBottom(); //} // //// json文件里面的配置项都测试结束 //void MainWidget::onAllItemsProcessed(const QString& client, int itemsProcessedCount) //{ // isSendingAll = false; // sendAllButton->setText("一键功能测试"); // sendAllButton->setStyleSheet("background-color: white;"); // //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); // statusListWidget->addItem(listItem); // statusListWidget->scrollToBottom(); //}