SL100_FactoryTestTool/FactoryTestTool/SourceCode/Widget/MainWidget.cpp

2233 lines
91 KiB
C++
Raw Normal View History

2024-08-19 01:39:32 +00:00
// MainWidget.cpp
2024-08-01 01:17:17 +00:00
#include "MainWidget.h"
2024-08-19 01:39:32 +00:00
2024-08-01 01:17:17 +00:00
void onThreadFinished(QThread* thread, ClientHandler* handler)
{
qDebug() << "Thread finished. Deleting handler and thread.";
2024-08-19 01:39:32 +00:00
handler->deleteLater();
thread->deleteLater();
2024-08-01 01:17:17 +00:00
}
2024-08-06 12:32:02 +00:00
// 初始化 UI 组件和服务器
2024-08-01 01:17:17 +00:00
MainWidget::MainWidget(QWidget* parent) :
QWidget(parent),
nextClientId(1),
manualSend(false),
isSendingAll(false),
lastClickedGetPicCamIndex(-1),
lastClickedGetPicDevIndex(-1),
lastClickedGetVideoCamIndex(-1),
2024-08-19 01:39:32 +00:00
lastClickedGetVideoDevIndex(-1),
mServiceProvider(new ServiceProvider(this)),
mdnsTimer(new QTimer(this))
#if TEST_UDP_BROADCAST
,multicastSocket(new QUdpSocket(this)),
multicastTimer(new QTimer(this))
#endif
2024-08-01 01:17:17 +00:00
{
2024-08-19 01:39:32 +00:00
leftLens_imageLabel = new QLabel(this);
2024-08-01 01:17:17 +00:00
rightLens_imageLabel = new QLabel(this);
2024-08-19 01:39:32 +00:00
videoLabel = new QLabel(this);
funcConfigLineEdit = new QLineEdit(this);
licenseHwInfoEdit = new QTextEdit(this);
2024-08-01 01:17:17 +00:00
setupUI();
// 打印线程池状态信息
setupTimerForThreadPoolInfo();
server = new QTcpServer(this);
2024-08-19 01:39:32 +00:00
connect(server, &QTcpServer::newConnection, this, [this]() {
2024-08-01 01:17:17 +00:00
// 检查是否有挂起的连接
while (server->hasPendingConnections()) {
QTcpSocket* socket = server->nextPendingConnection();
2024-08-19 01:39:32 +00:00
int clientId = nextClientId++;
2024-08-01 01:17:17 +00:00
qDebug() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>";
qDebug() << "> A client is connected. ID:" << clientId;
qDebug() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>";
2024-08-19 01:39:32 +00:00
stopMdnsService();
connectedClientsCount++;
2024-08-01 01:17:17 +00:00
updateServerButtonText();
QTimer* timer = new QTimer(this);
timer->setSingleShot(true);
clientTimers[clientId] = timer;
// 连接定时器超时信号到槽函数
connect(timer, &QTimer::timeout, this, [this, clientId]() {
//qDebug() << "Timeout occurred for client ID:" << clientId;
for (ClientHandler* handler : clients) {
if (handler->getClientId() == clientId) {
bool invoked = QMetaObject::invokeMethod(handler, "onTimeout", Qt::DirectConnection);
if (!invoked) {
qWarning() << "Failed to invoke onTimeout for client ID:" << clientId;
}
}
}
});
2024-08-19 01:39:32 +00:00
QThread* thread = new QThread(this);
2024-08-06 12:32:02 +00:00
ClientHandler* handler = new ClientHandler(socket, frontBoardOneClickTest, frontBoardTest, frontBoardFuncConfig,
frontBoardDevInfoJson, frontBoardLicenseJson, backBoardDevInfoJson,
2024-08-01 01:17:17 +00:00
getPicJson, getVideoJson, clientId, nullptr);
// 将 ClientHandler 移动到线程池中的线程
handler->moveToThread(thread);
// 当线程结束时删除 handler
connect(thread, &QThread::finished, this, [=]() {
onThreadFinished(thread, handler);
});
// 将sendData信号连接到主线程中的槽上
2024-08-19 01:39:32 +00:00
connect(handler, &ClientHandler::sendData, this, [socket](const QByteArray& data) {
2024-08-01 01:17:17 +00:00
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;
2024-08-19 01:39:32 +00:00
connect(handler, &ClientHandler::statusUpdated, this, &MainWidget::onStatusUpdated);
connect(handler, &ClientHandler::clientDisconnected, this, &MainWidget::onClientDisconnected);
connect(handler, &ClientHandler::allItemsProcessed, this, &MainWidget::onAllItemsProcessed);
2024-08-01 01:17:17 +00:00
connect(handler, &ClientHandler::selectClientDisconnected, this, &MainWidget::onDisconnectClient);
// 创建 DataHandler 对象并连接信号
2024-08-19 01:39:32 +00:00
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);
2024-08-01 01:17:17 +00:00
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检查一次连接状态
2024-08-19 01:39:32 +00:00
connect(mdnsTimer, &QTimer::timeout, this, &MainWidget::startMdnsService);
#if TEST_UDP_BROADCAST
// 设置组播地址
QHostAddress groupAddress("224.0.0.251");
quint16 port = 5353;
// 绑定UDP套接字
if (!multicastSocket->bind(QHostAddress::AnyIPv4, port, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint)) {
qWarning() << "Failed to bind multicast socket";
}
// 加入组播组
bool joined = multicastSocket->joinMulticastGroup(groupAddress);
if (!joined) {
qWarning() << "Failed to join multicast group";
}
// 定期发送组播消息
connect(multicastTimer, &QTimer::timeout, this, &MainWidget::sendMulticastMessage);
multicastTimer->start(1000); // 每秒发送一次组播消息
#endif
2024-08-01 01:17:17 +00:00
}
2024-08-19 01:39:32 +00:00
MainWidget::~MainWidget()
{
#if TEST_UDP_BROADCAST
multicastTimer->stop();
multicastSocket->leaveMulticastGroup(QHostAddress("224.0.0.251"));
multicastSocket->close();
#endif
if (mdnsTimer->isActive()) {
mdnsTimer->stop();
}
delete mdnsTimer;
stopMdnsService();
2024-08-01 01:17:17 +00:00
for (auto timer : clientReadTimers) {
timer->stop();
delete timer;
}
clientReadTimers.clear();
for (ClientHandler* handler : clients) {
handler->deleteLater();
}
server->close();
2024-08-06 12:32:02 +00:00
for (auto thread : clientThreads) {
thread->quit();
thread->wait();
delete thread;
}
clientThreads.clear();
for (auto handler : clients_1) {
handler->deleteLater();
}
clients_1.clear();
for (auto timer : clientTimers) {
timer->stop();
delete timer;
}
clientTimers.clear();
if (server->isListening()) {
server->close();
}
2024-08-01 01:17:17 +00:00
qDebug() << "MainWidget destroyed";
}
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;
2024-08-19 01:39:32 +00:00
for (auto it = clientThreads.begin(); it != clientThreads.end(); ++it) {
2024-08-01 01:17:17 +00:00
int clientId = it.key();
QThread* thread = it.value();
ClientHandler* handler = nullptr;
for (ClientHandler* h : clients) {
if (h->getClientId() == clientId) {
handler = h;
break;
}
}
if (handler && handler->isData_Stuck()) {
qDebug() << "Thread for clientId:" << clientId << "is stuck.";
// 处理线程卡住的情况,比如重启线程或记录更多日志
}
else if (thread->isRunning()) {
qDebug() << "isData_Stuck = :" << handler->isData_Stuck();
qDebug() << "Thread for clientId:" << clientId << "is running.";
}
else {
qDebug() << "Thread for clientId:" << clientId << "is not running.";
// 处理线程意外停止的情况
}
}
}
// 打印线程池信息
void MainWidget::printThreadPoolInfo()
{
QThreadPool* threadPool = QThreadPool::globalInstance();
//qDebug() << "Active threads:" << threadPool->activeThreadCount();
//qDebug() << "Max threads:" << threadPool->maxThreadCount();
}
void MainWidget::setupTimerForThreadPoolInfo()
{
QTimer* timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &MainWidget::printThreadPoolInfo);
timer->start(5000); // 每5秒打印一次线程池信息
}
2024-08-19 01:39:32 +00:00
void MainWidget::readJsonConfig()
{
frontBoardOneClickTest = readJson_frontBoardOneClickTest();
frontBoardTest = readJson_frontBoardTest();
frontBoardFuncConfig = readJson_frontBoardFuncConfig();
frontBoardDevInfoJson = readJson_frontDevInfo();
frontBoardLicenseJson = readJson_frontLicense();
backBoardOneClickTest = readJson_backBoardOneClickTest();
backBoardTest = readJson_backBoardTest();
backBoardFuncConfig = readJson_backBoardFuncConfig();
backBoardDevInfoJson = readJson_backDevInfo();
testJsonConfig = readJson_testConfig();
funcJsonConfig = readJson_funcConfig();
getPicJson = readJson_getPic();
getVideoJson = readJson_getVideo();
}
2024-08-01 01:17:17 +00:00
// 设置 UI
void MainWidget::setupUI()
{
startServerButton = new QPushButton("开始监听\n(Start Listening...)", this);
startServerButton->setFixedSize(190, 70); // 设置宽度为 190 像素,高度为 70 像素
2024-08-19 01:39:32 +00:00
sendAllButton = new QPushButton("一键功能测试", this);
2024-08-01 01:17:17 +00:00
sendAllButton->setFixedSize(190, 70); // 设置宽度为 190 像素,高度为 70 像素
sendAllButton->setEnabled(false);
2024-08-19 01:39:32 +00:00
statusListWidget = new QListWidget(this);
2024-08-06 12:32:02 +00:00
//statusListWidget->setMinimumSize(350, 880);
statusListWidget->setMinimumSize(350, 680);
2024-08-01 01:17:17 +00:00
statusListWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); // 设置大小策略为扩展
QHBoxLayout* buttonLayout = new QHBoxLayout;
buttonLayout->addWidget(startServerButton);
buttonLayout->addWidget(sendAllButton);
2024-08-19 01:39:32 +00:00
buttonLayout->addStretch();
2024-08-01 01:17:17 +00:00
2024-08-19 01:39:32 +00:00
QVBoxLayout* leftLayout = new QVBoxLayout;
2024-08-01 01:17:17 +00:00
leftLayout->addLayout(buttonLayout);
leftLayout->setStretch(0, 1);
leftLayout->addWidget(statusListWidget);
2024-08-06 12:32:02 +00:00
leftLayout->setStretch(1, 200);
2024-08-01 01:17:17 +00:00
2024-08-19 01:39:32 +00:00
saveCheckBox = new QCheckBox("", this);
2024-08-01 01:17:17 +00:00
selectFileButton = new QPushButton("Save", this);
selectFileButton->setFixedSize(45, 28);
2024-08-19 01:39:32 +00:00
clearLogButton = new QPushButton("Clear", this);
2024-08-01 01:17:17 +00:00
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);
2024-08-19 01:39:32 +00:00
leftLayout->addLayout(fileLayout);
2024-08-01 01:17:17 +00:00
leftLayout->setStretch(2, 1);
2024-08-06 12:32:02 +00:00
// 读取 JSON 配置文件
readJsonConfig();
2024-08-19 01:39:32 +00:00
QGroupBox* groupBox = new QGroupBox("算法 license", this);
2024-08-06 12:32:02 +00:00
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);
}
2024-08-19 01:39:32 +00:00
licenseHwInfoEdit->setReadOnly(true);
licenseHwInfoEdit->setText("This is a read-only text");
licenseHwInfoEdit->setFixedHeight(80);
2024-08-06 12:32:02 +00:00
QVBoxLayout* groupBoxLayout_license = new QVBoxLayout;
groupBoxLayout_license->addLayout(buttonRowLayout);
2024-08-19 01:39:32 +00:00
groupBoxLayout_license->addWidget(licenseHwInfoEdit);
2024-08-06 12:32:02 +00:00
groupBox->setLayout(groupBoxLayout_license);
leftLayout->addWidget(groupBox);
leftLayout->setStretch(3, 1);
2024-08-01 01:17:17 +00:00
QWidget* leftContainer = new QWidget(this);
leftContainer->setLayout(leftLayout);
leftContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
QTabWidget* tabWidget = new QTabWidget(this);
tabWidget->setFixedSize(900, 315); // 设置 QTabWidget 的固定大小
2024-08-19 01:39:32 +00:00
QGroupBox* frontDeviceInfoGroupBox = new QGroupBox("前板设备信息", this);
QVBoxLayout* frontDeviceInfoLayout = new QVBoxLayout(frontDeviceInfoGroupBox);
2024-08-01 01:17:17 +00:00
2024-08-06 12:32:02 +00:00
QVBoxLayout* frontDeviceLabelsLayout = new QVBoxLayout;
for (const QJsonValue& value : frontBoardDevInfoJson) {
QJsonObject item = value.toObject();
2024-08-19 01:39:32 +00:00
QString label = item["lable"].toString();
QString cmd = item["cmd"].toString();
2024-08-06 12:32:02 +00:00
QLabel* itemLabel = new QLabel(label, this);
QLineEdit* itemLineEdit = new QLineEdit(this);
2024-08-19 01:39:32 +00:00
itemLineEdit->setReadOnly(true);
2024-08-06 12:32:02 +00:00
QHBoxLayout* itemLayout = new QHBoxLayout;
itemLayout->addWidget(itemLabel);
itemLayout->addWidget(itemLineEdit);
frontDeviceLabelsLayout->addLayout(itemLayout);
2024-08-19 01:39:32 +00:00
devInfoLineEdits[cmd] = itemLineEdit;
2024-08-01 01:17:17 +00:00
}
2024-08-06 12:32:02 +00:00
frontDeviceInfoLayout->addLayout(frontDeviceLabelsLayout);
2024-08-01 01:17:17 +00:00
frontDeviceInfoLayout->addStretch();
2024-08-19 01:39:32 +00:00
QGroupBox* backDeviceInfoGroupBox = new QGroupBox("后板设备信息", this);
QVBoxLayout* backDeviceInfoLayout = new QVBoxLayout(backDeviceInfoGroupBox);
2024-08-06 12:32:02 +00:00
QVBoxLayout* backDeviceLabelsLayout = new QVBoxLayout;
for (const QJsonValue& value : backBoardDevInfoJson) {
QJsonObject item = value.toObject();
2024-08-19 01:39:32 +00:00
QString label = item["lable"].toString();
QString cmd = item["cmd"].toString();
2024-08-06 12:32:02 +00:00
QLabel* itemLabel = new QLabel(label, this);
QLineEdit* itemLineEdit = new QLineEdit(this);
2024-08-19 01:39:32 +00:00
itemLineEdit->setReadOnly(true);
2024-08-06 12:32:02 +00:00
QHBoxLayout* itemLayout = new QHBoxLayout;
itemLayout->addWidget(itemLabel);
itemLayout->addWidget(itemLineEdit);
backDeviceLabelsLayout->addLayout(itemLayout);
2024-08-19 01:39:32 +00:00
devInfoLineEdits[cmd] = itemLineEdit;
2024-08-06 12:32:02 +00:00
}
backDeviceInfoLayout->addLayout(backDeviceLabelsLayout);
backDeviceInfoLayout->addStretch();
2024-08-01 01:17:17 +00:00
QHBoxLayout* groupBoxLayout = new QHBoxLayout;
groupBoxLayout->addWidget(frontDeviceInfoGroupBox, 1);
2024-08-19 01:39:32 +00:00
groupBoxLayout->addWidget(backDeviceInfoGroupBox, 1);
2024-08-01 01:17:17 +00:00
2024-08-19 01:39:32 +00:00
QWidget* functionTestTab = new QWidget;
2024-08-01 01:17:17 +00:00
QVBoxLayout* functionTestLayout = new QVBoxLayout(functionTestTab);
functionTestTab->setLayout(functionTestLayout);
tabWidget->addTab(functionTestTab, "功能测试区");
2024-08-19 01:39:32 +00:00
QGridLayout* buttonGridLayout = new QGridLayout();
2024-08-01 01:17:17 +00:00
int buttonsPerRow = 7; // 每行显示的按键数量,根据需要调整
// 为每个 JSON 项目创建按键,并添加到 rightLayout
// 先总共放 77 个按键
//qDebug() << "testJsonConfig.size():" << testJsonConfig.size();
for (int i = 0; i < frontBoardTest.size() + (77 - frontBoardTest.size()); ++i) {
2024-08-19 01:39:32 +00:00
QJsonObject item = frontBoardTest[i].toObject();
QString buttonText = item["lable"].toString();
2024-08-01 01:17:17 +00:00
// 判断 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);
2024-08-19 01:39:32 +00:00
QScrollArea* scrollArea = new QScrollArea;
2024-08-01 01:17:17 +00:00
scrollArea->setWidget(buttonContainer);
scrollArea->setWidgetResizable(true);
functionTestLayout->addWidget(scrollArea);
2024-08-19 01:39:32 +00:00
QWidget* functionConfigTab = new QWidget;
QVBoxLayout* functionConfigLayout = new QVBoxLayout(functionConfigTab);
2024-08-01 01:17:17 +00:00
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);
2024-08-19 01:39:32 +00:00
QScrollArea* configScrollArea = new QScrollArea;
2024-08-01 01:17:17 +00:00
configScrollArea->setWidget(configButtonContainer);
configScrollArea->setWidgetResizable(true);
functionConfigLayout->addWidget(configScrollArea);
2024-08-19 01:39:32 +00:00
QTabWidget* tabWidget_media = new QTabWidget(this);
QWidget* imageDisplayTab = new QWidget;
2024-08-01 01:17:17 +00:00
QVBoxLayout* imageDisplayLayout = new QVBoxLayout(imageDisplayTab);
imageDisplayTab->setLayout(imageDisplayLayout);
tabWidget_media->addTab(imageDisplayTab, "图像显示区");
2024-08-19 01:39:32 +00:00
QVBoxLayout* imageButtonsColumnLayout = new QVBoxLayout;
2024-08-01 01:17:17 +00:00
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);
2024-08-19 01:39:32 +00:00
button->setFixedSize(73, 50);
2024-08-01 01:17:17 +00:00
imageButtonsRowLayout->addWidget(button);
button->setProperty("getPicIndex", i * 2 + j);
connect(button, &QPushButton::clicked, this, &MainWidget::onSendGetPicClicked);
2024-08-19 01:39:32 +00:00
getPicButtons.append(button);
2024-08-01 01:17:17 +00:00
continue;
}
else if (i == 0 && j == 1) {
button = new QPushButton(QString("RGB"), this);
2024-08-19 01:39:32 +00:00
button->setFixedSize(73, 50);
2024-08-01 01:17:17 +00:00
imageButtonsRowLayout->addWidget(button);
button->setProperty("getPicIndex", i * 2 + j);
connect(button, &QPushButton::clicked, this, &MainWidget::onSendGetPicClicked);
getPicButtons.append(button);
continue;
}
2024-08-19 01:39:32 +00:00
2024-08-01 01:17:17 +00:00
button = new QPushButton(QString("Device %1").arg(i * 2 + j - 1), this);
2024-08-19 01:39:32 +00:00
button->setFixedSize(73, 50);
2024-08-01 01:17:17 +00:00
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;
2024-08-19 01:39:32 +00:00
leftLens_imageLabel = new QLabel(this);
rightLens_imageLabel = new QLabel(this);
2024-08-01 01:17:17 +00:00
lensesLayout->addWidget(leftLens_imageLabel);
lensesLayout->addWidget(rightLens_imageLabel);
QHBoxLayout* imageAndButtonsLayout = new QHBoxLayout;
imageAndButtonsLayout->addLayout(imageButtonsColumnLayout, 1);
imageAndButtonsLayout->addLayout(lensesLayout, 4);
imageDisplayLayout->addLayout(imageAndButtonsLayout);
2024-08-19 01:39:32 +00:00
QWidget* videoDisplayTab = new QWidget;
2024-08-01 01:17:17 +00:00
QVBoxLayout* videoDisplayLayout = new QVBoxLayout(videoDisplayTab);
videoDisplayTab->setLayout(videoDisplayLayout);
tabWidget_media->addTab(videoDisplayTab, "视频显示区");
2024-08-19 01:39:32 +00:00
QVBoxLayout* videoButtonsColumnLayout = new QVBoxLayout;
2024-08-01 01:17:17 +00:00
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);
}
2024-08-19 01:39:32 +00:00
2024-08-01 01:17:17 +00:00
QHBoxLayout* videoAndButtonsLayout = new QHBoxLayout;
videoLabel = new QLabel(this);
//videoLabel->setFixedSize(640, 480);
videoAndButtonsLayout->addLayout(videoButtonsColumnLayout, 1);
videoAndButtonsLayout->addWidget(videoLabel, 6);
videoDisplayLayout->addLayout(videoAndButtonsLayout);
2024-08-19 01:39:32 +00:00
QVBoxLayout* rightVerticalLayout = new QVBoxLayout;
2024-08-01 01:17:17 +00:00
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 像素
2024-08-19 01:39:32 +00:00
connect(startServerButton, &QPushButton::clicked, this, &MainWidget::onStartServerClicked);
connect(sendAllButton, &QPushButton::clicked, this, &MainWidget::onSendAllClicked);
connect(statusListWidget, &QListWidget::itemChanged, this, &MainWidget::scrollToBottom);
connect(selectFileButton, &QPushButton::clicked, this, &MainWidget::onSelectFileButtonClicked);
connect(clearLogButton, &QPushButton::clicked, this, &MainWidget::onclearLogButtonClicked);
connect(saveCheckBox, &QCheckBox::stateChanged, this, &MainWidget::onSaveCheckBoxStateChanged);
2024-08-01 01:17:17 +00:00
}
void MainWidget::onSelectFileButtonClicked()
{
QString filePath = QFileDialog::getSaveFileName(this, tr("选择文件路径"), "", tr("Text Files (*.txt);;All Files (*)"));
if (!filePath.isEmpty()) {
filePathLineEdit->setText(filePath);
}
}
void MainWidget::onclearLogButtonClicked()
{
statusListWidget->clear();
}
void MainWidget::onSaveCheckBoxStateChanged(int state)
{
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();
2024-08-19 01:39:32 +00:00
connectedClientsCount--;
2024-08-01 01:17:17 +00:00
updateServerButtonText();
2024-08-19 01:39:32 +00:00
break;
2024-08-01 01:17:17 +00:00
}
}
2024-08-19 01:39:32 +00:00
// 启动 mDNS 服务广播
startMdnsService();
2024-08-01 01:17:17 +00:00
}
// 处理客户端断开连接信号
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 对象
// 更新连接数并更新按键文本
2024-08-19 01:39:32 +00:00
connectedClientsCount--;
if (nextClientId <= 2) nextClientId--;
2024-08-01 01:17:17 +00:00
deviceConnected = true;
updateServerButtonText();
}
// 更新按键文本的函数
void MainWidget::updateServerButtonText()
{
if (deviceConnected) {
deviceConnected = false;
startServerButton->setText(tr("正在监听(Listening)"));
2024-08-19 01:39:32 +00:00
if (connectedClientsCount == 0) startMdnsService();
2024-08-01 01:17:17 +00:00
}
else if (connectedClientsCount == 0) {
startServerButton->setText(tr("开始监听\n(Start Listening...)"));
}
else {
startServerButton->setText(tr("正在监听(Listening)\n%1 台设备连接").arg(connectedClientsCount));
}
}
2024-08-06 12:32:02 +00:00
void MainWidget::onLicenseButtonClicked()
{
if (connectedClientsCount) {
QPushButton* button = qobject_cast<QPushButton*>(sender());
if (button) {
int index = button->property("licenseIndex").toInt();
if (index >= 0 && index < frontBoardLicenseJson.size()) {
QJsonObject jsonObject = frontBoardLicenseJson[index].toObject();
2024-08-19 01:39:32 +00:00
//QString jsonString = QJsonDocument(jsonObject).toJson(QJsonDocument::Compact);
2024-08-06 12:32:02 +00:00
//qDebug() << "license Button clicked, sending JSON:" << jsonString;
2024-08-19 01:39:32 +00:00
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);
}
2024-08-06 12:32:02 +00:00
}
}
}
}
else {
QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget);
listItem->setBackground(Qt::red);
}
}
2024-08-19 01:39:32 +00:00
void MainWidget::startMdnsService()
{
QDateTime currentTime = QDateTime::currentDateTime();
QString formattedTime = currentTime.toString("yyyy-MM-dd hh:mm:ss.zzz");
qDebug() << "[" << formattedTime << "]:" << "Start Mdns Broadcast Service";
QString serviceName = "SL100 FactoryTool Mdns Broadcast Service";
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
2024-08-01 01:17:17 +00:00
// 处理开始服务器按键点击事件
void MainWidget::onStartServerClicked()
{
if (!server->isListening()) {
2024-08-19 01:39:32 +00:00
startMdnsService();
#if TEST_UDP_BROADCAST
sendMulticastMessage();
#endif
// QHostAddress specifiedIpAddress("10.10.10.253");
quint16 specifiedPort = TCP_CONNECT_PORT;
2024-08-01 01:17:17 +00:00
qDebug() << "" << specifiedPort;
if (server->listen(QHostAddress::Any, specifiedPort)) {
startServerButton->setText(tr("正在监听(Listening)"));
startServerButton->setStyleSheet("background-color: green;");
sendAllButton->setEnabled(true);
}
else {
qDebug() << "Failed to start server. Error:" << server->errorString();
}
}
else {
server->close();
startServerButton->setText(tr("开始监听\n(Start Listening...)"));
startServerButton->setStyleSheet("");
sendAllButton->setEnabled(false);
2024-08-19 01:39:32 +00:00
stopMdnsService();
2024-08-01 01:17:17 +00:00
}
}
// 处理发送获取设备信息按键点击事件
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();
2024-08-19 01:39:32 +00:00
2024-08-01 01:17:17 +00:00
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) {
2024-08-19 01:39:32 +00:00
handler->sendGetPicItem(itemIndex - 2, lastClickedGetPicCamIndex);
2024-08-01 01:17:17 +00:00
}
}
}
}
}
else {
QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget);
listItem->setBackground(Qt::red);
}
}
// 处理发送拉视频流按键点击事件
void MainWidget::onSendGetVideoClicked()
{
if (connectedClientsCount) {
QPushButton* button = qobject_cast<QPushButton*>(sender());
int itemIndex = button->property("getVideoIndex").toInt();
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 {
2024-08-19 01:39:32 +00:00
if (itemIndex - 6 >= connectedClientsCount) {
2024-08-01 01:17:17 +00:00
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();
2024-08-19 01:39:32 +00:00
handler->sendNextItem();
//handler->sendDevInfoItem();
2024-08-01 01:17:17 +00:00
}
}
else {
sendAllButton->setText("一键功能测试");
2024-08-19 01:39:32 +00:00
sendAllButton->setStyleSheet("background-color: white;");
2024-08-01 01:17:17 +00:00
manualSend = false;
for (ClientHandler* handler : clients) {
handler->resetCurrentItemIndex();
}
}
}
else {
QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget);
listItem->setBackground(Qt::red);
}
}
// 处理单独发送功能项按键点击事件
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("一键功能测试");
2024-08-19 01:39:32 +00:00
sendAllButton->setStyleSheet("background-color: white;");
2024-08-01 01:17:17 +00:00
//qDebug() << "onAllItemsProcessed called for client:" << client << "itemsProcessedCount:" << itemsProcessedCount;
int clientId = -1;
for (ClientHandler* handler : clients) {
if (handler->getClientAddress() == client) {
clientId = handler->getClientId();
qDebug() << "Current clientId:" << clientId;
break;
}
else
{
//qDebug() << "" << __FUNCTION__ << "handler->getClientAddress() != client";
}
}
QListWidgetItem* listItem = new QListWidgetItem(QString("device ID:-%1 ---> All %2 items test completed !!!")
.arg(clientId)
.arg(itemsProcessedCount), statusListWidget);
statusListWidget->addItem(listItem);
statusListWidget->scrollToBottom();
}
2024-08-19 01:39:32 +00:00
//#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();
//}