SL100_FactoryTestTool/FactoryTestTool/SourceCode/Widget/MainWidget.cpp

2233 lines
91 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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;
// 参数二伸缩因子leftContainer1/3 rightLayout2/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<QPushButton*>(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<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) {
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<QPushButton*>(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<QPushButton*>(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<QPushButton*>(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<QPushButton*>(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<QPushButton*>(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;
// // 参数二伸缩因子leftContainer1/3 rightLayout2/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<QPushButton*>(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<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) {
// 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<QPushButton*>(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<QPushButton*>(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<QPushButton*>(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<QPushButton*>(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<QPushButton*>(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();
//}