931 lines
38 KiB
C++
931 lines
38 KiB
C++
|
// MainWidget.cpp
|
|||
|
#include "MainWidget.h"
|
|||
|
#include "../RecvDataHandler/RecvDataHandler.h"
|
|||
|
#include "../Json/readJsonFile.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)
|
|||
|
{
|
|||
|
leftLens_imageLabel = new QLabel(this);
|
|||
|
rightLens_imageLabel = new QLabel(this);
|
|||
|
videoLabel = new QLabel(this);
|
|||
|
funcConfigLineEdit = new QLineEdit(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, testJsonConfig, funcJsonConfig, getDevInfoJson,
|
|||
|
getPicJson, getVideoJson, clientId, nullptr);*/
|
|||
|
ClientHandler* handler = new ClientHandler(socket, frontBoardOneClickTest, frontBoardTest, frontBoardFuncConfig, getDevInfoJson,
|
|||
|
getPicJson, getVideoJson, clientId, nullptr);
|
|||
|
|
|||
|
// 将 ClientHandler 移动到线程池中的线程
|
|||
|
handler->moveToThread(thread);
|
|||
|
|
|||
|
// 当线程结束时删除 handler
|
|||
|
//connect(thread, &QThread::finished, handler, &QObject::deleteLater);
|
|||
|
//connect(thread, &QThread::finished, thread, &QObject::deleteLater);
|
|||
|
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 对象并连接信号
|
|||
|
//QLabel* imageDisplayLabel = new QLabel;
|
|||
|
DataHandler* dataHandler = new DataHandler(leftLens_imageLabel, rightLens_imageLabel, videoLabel, 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检查一次连接状态
|
|||
|
}
|
|||
|
|
|||
|
MainWidget::~MainWidget() {
|
|||
|
for (auto timer : clientReadTimers) {
|
|||
|
timer->stop();
|
|||
|
delete timer;
|
|||
|
}
|
|||
|
clientReadTimers.clear();
|
|||
|
for (ClientHandler* handler : clients) {
|
|||
|
handler->deleteLater();
|
|||
|
}
|
|||
|
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秒打印一次线程池信息
|
|||
|
}
|
|||
|
|
|||
|
// 设置 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->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, 20);
|
|||
|
|
|||
|
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);
|
|||
|
|
|||
|
QWidget* leftContainer = new QWidget(this);
|
|||
|
leftContainer->setLayout(leftLayout);
|
|||
|
leftContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|||
|
|
|||
|
// 读取 JSON 配置文件
|
|||
|
readJsonConfig();
|
|||
|
|
|||
|
QTabWidget* tabWidget = new QTabWidget(this);
|
|||
|
tabWidget->setFixedSize(900, 315); // 设置 QTabWidget 的固定大小
|
|||
|
|
|||
|
QGroupBox* frontDeviceInfoGroupBox = new QGroupBox("前板设备信息", this);
|
|||
|
QVBoxLayout* frontDeviceInfoLayout = new QVBoxLayout(frontDeviceInfoGroupBox);
|
|||
|
|
|||
|
QHBoxLayout* frontDeviceButtonsLayout = new QHBoxLayout;
|
|||
|
for (int i = 0; i < 2; ++i) {
|
|||
|
QPushButton* button = new QPushButton(QString("Device %1").arg(i + 1), this);
|
|||
|
button->setProperty("deviceInfoIndex", i);
|
|||
|
frontDeviceButtonsLayout->addWidget(button);
|
|||
|
connect(button, &QPushButton::clicked, this, &MainWidget::onSendGetDevInfoClicked);
|
|||
|
}
|
|||
|
frontDeviceInfoLayout->addLayout(frontDeviceButtonsLayout);
|
|||
|
frontDeviceInfoLayout->addStretch();
|
|||
|
|
|||
|
QGroupBox* backDeviceInfoGroupBox = new QGroupBox("后板设备信息", this);
|
|||
|
QVBoxLayout* backDeviceInfoLayout = new QVBoxLayout(backDeviceInfoGroupBox);
|
|||
|
|
|||
|
QHBoxLayout* groupBoxLayout = new QHBoxLayout;
|
|||
|
groupBoxLayout->addWidget(frontDeviceInfoGroupBox, 1);
|
|||
|
groupBoxLayout->addWidget(backDeviceInfoGroupBox, 1);
|
|||
|
|
|||
|
QWidget* functionTestTab = new QWidget;
|
|||
|
QVBoxLayout* functionTestLayout = new QVBoxLayout(functionTestTab);
|
|||
|
functionTestTab->setLayout(functionTestLayout);
|
|||
|
tabWidget->addTab(functionTestTab, "功能测试区");
|
|||
|
|
|||
|
QGridLayout* buttonGridLayout = new QGridLayout();
|
|||
|
|
|||
|
int buttonsPerRow = 7; // 每行显示的按键数量,根据需要调整
|
|||
|
|
|||
|
// 为每个 JSON 项目创建按键,并添加到 rightLayout
|
|||
|
// 先总共放 77 个按键
|
|||
|
//qDebug() << "testJsonConfig.size():" << testJsonConfig.size();
|
|||
|
for (int i = 0; i < frontBoardTest.size() + (77 - frontBoardTest.size()); ++i) {
|
|||
|
QJsonObject item = frontBoardTest[i].toObject();
|
|||
|
QString buttonText = item["lable"].toString();
|
|||
|
// 判断 buttonText 是否为空或者只有空白字符
|
|||
|
if (buttonText.isEmpty()) {
|
|||
|
//qDebug() << "buttonText.isEmpty():" << buttonText.isEmpty();
|
|||
|
buttonText = QString("Send Item %1").arg(i + 1);
|
|||
|
}
|
|||
|
QPushButton* button = new QPushButton(buttonText, this);
|
|||
|
button->setProperty("frontBoardTest", i);
|
|||
|
button->setFixedSize(110, 35); // 设置按键宽度和高度
|
|||
|
connect(button, &QPushButton::clicked, this, &MainWidget::onSendItemClicked);
|
|||
|
|
|||
|
int row = i / buttonsPerRow;
|
|||
|
int col = i % buttonsPerRow;
|
|||
|
buttonGridLayout->addWidget(button, row, col, Qt::AlignLeft);
|
|||
|
|
|||
|
itemButtons.append(button);
|
|||
|
}
|
|||
|
|
|||
|
QWidget* buttonContainer = new QWidget;
|
|||
|
buttonContainer->setLayout(buttonGridLayout);
|
|||
|
|
|||
|
QScrollArea* scrollArea = new QScrollArea;
|
|||
|
scrollArea->setWidget(buttonContainer);
|
|||
|
scrollArea->setWidgetResizable(true);
|
|||
|
|
|||
|
functionTestLayout->addWidget(scrollArea);
|
|||
|
|
|||
|
QWidget* functionConfigTab = new QWidget;
|
|||
|
QVBoxLayout* functionConfigLayout = new QVBoxLayout(functionConfigTab);
|
|||
|
functionConfigTab->setLayout(functionConfigLayout);
|
|||
|
tabWidget->addTab(functionConfigTab, "功能配置区");
|
|||
|
|
|||
|
funcConfigLineEdit->setPlaceholderText("请输入配置参数...");
|
|||
|
functionConfigLayout->addWidget(funcConfigLineEdit);
|
|||
|
|
|||
|
QGridLayout* configButtonGridLayout = new QGridLayout();
|
|||
|
|
|||
|
for (int i = 0; i < frontBoardFuncConfig.size() + (77 - frontBoardFuncConfig.size()); ++i) {
|
|||
|
QJsonObject item = frontBoardFuncConfig[i].toObject();
|
|||
|
QString buttonText = item["lable"].toString();
|
|||
|
// 判断 buttonText 是否为空或者只有空白字符
|
|||
|
if (buttonText.isEmpty()) {
|
|||
|
//qDebug() << "buttonText.isEmpty():" << buttonText.isEmpty();
|
|||
|
buttonText = QString("Cfg Item %1").arg(i + 1);
|
|||
|
}
|
|||
|
QPushButton* button = new QPushButton(buttonText, this);
|
|||
|
button->setProperty("frontBoardFuncConfig", i);
|
|||
|
button->setFixedSize(110, 35); // 设置按键宽度和高度
|
|||
|
connect(button, &QPushButton::clicked, this, &MainWidget::onSendFuncItemClicked);
|
|||
|
|
|||
|
int row = i / buttonsPerRow;
|
|||
|
int col = i % buttonsPerRow;
|
|||
|
configButtonGridLayout->addWidget(button, row, col, Qt::AlignLeft);
|
|||
|
|
|||
|
funcItemButtons.append(button);
|
|||
|
}
|
|||
|
|
|||
|
QWidget* configButtonContainer = new QWidget;
|
|||
|
configButtonContainer->setLayout(configButtonGridLayout);
|
|||
|
|
|||
|
QScrollArea* configScrollArea = new QScrollArea;
|
|||
|
configScrollArea->setWidget(configButtonContainer);
|
|||
|
configScrollArea->setWidgetResizable(true);
|
|||
|
|
|||
|
functionConfigLayout->addWidget(configScrollArea);
|
|||
|
|
|||
|
QTabWidget* tabWidget_media = new QTabWidget(this);
|
|||
|
QWidget* imageDisplayTab = new QWidget;
|
|||
|
QVBoxLayout* imageDisplayLayout = new QVBoxLayout(imageDisplayTab);
|
|||
|
imageDisplayTab->setLayout(imageDisplayLayout);
|
|||
|
tabWidget_media->addTab(imageDisplayTab, "图像显示区");
|
|||
|
|
|||
|
QVBoxLayout* imageButtonsColumnLayout = new QVBoxLayout;
|
|||
|
for (int i = 0; i < 5; ++i) {
|
|||
|
QHBoxLayout* imageButtonsRowLayout = new QHBoxLayout;
|
|||
|
for (int j = 0; j < 2; ++j) {
|
|||
|
QPushButton* button;
|
|||
|
if (i == 0 && j == 0) {
|
|||
|
button = new QPushButton(QString("IR"), this);
|
|||
|
button->setFixedSize(73, 50);
|
|||
|
imageButtonsRowLayout->addWidget(button);
|
|||
|
button->setProperty("getPicIndex", i * 2 + j);
|
|||
|
connect(button, &QPushButton::clicked, this, &MainWidget::onSendGetPicClicked);
|
|||
|
getPicButtons.append(button);
|
|||
|
continue;
|
|||
|
}
|
|||
|
else if (i == 0 && j == 1) {
|
|||
|
button = new QPushButton(QString("RGB"), this);
|
|||
|
button->setFixedSize(73, 50);
|
|||
|
imageButtonsRowLayout->addWidget(button);
|
|||
|
button->setProperty("getPicIndex", i * 2 + j);
|
|||
|
connect(button, &QPushButton::clicked, this, &MainWidget::onSendGetPicClicked);
|
|||
|
getPicButtons.append(button);
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
button = new QPushButton(QString("Device %1").arg(i * 2 + j - 1), this);
|
|||
|
button->setFixedSize(73, 50);
|
|||
|
imageButtonsRowLayout->addWidget(button);
|
|||
|
button->setProperty("getPicIndex", i * 2 + j);
|
|||
|
connect(button, &QPushButton::clicked, this, &MainWidget::onSendGetPicClicked);
|
|||
|
getPicButtons.append(button);
|
|||
|
}
|
|||
|
imageButtonsColumnLayout->addLayout(imageButtonsRowLayout);
|
|||
|
}
|
|||
|
|
|||
|
QHBoxLayout* lensesLayout = new QHBoxLayout;
|
|||
|
leftLens_imageLabel = new QLabel(this);
|
|||
|
rightLens_imageLabel = new QLabel(this);
|
|||
|
lensesLayout->addWidget(leftLens_imageLabel);
|
|||
|
lensesLayout->addWidget(rightLens_imageLabel);
|
|||
|
|
|||
|
QHBoxLayout* imageAndButtonsLayout = new QHBoxLayout;
|
|||
|
imageAndButtonsLayout->addLayout(imageButtonsColumnLayout, 1);
|
|||
|
imageAndButtonsLayout->addLayout(lensesLayout, 4);
|
|||
|
imageDisplayLayout->addLayout(imageAndButtonsLayout);
|
|||
|
|
|||
|
QWidget* videoDisplayTab = new QWidget;
|
|||
|
QVBoxLayout* videoDisplayLayout = new QVBoxLayout(videoDisplayTab);
|
|||
|
videoDisplayTab->setLayout(videoDisplayLayout);
|
|||
|
tabWidget_media->addTab(videoDisplayTab, "视频显示区");
|
|||
|
|
|||
|
QVBoxLayout* videoButtonsColumnLayout = new QVBoxLayout;
|
|||
|
for (int i = 0; i < 6; ++i) {
|
|||
|
QHBoxLayout* videoButtonsRowLayout = new QHBoxLayout;
|
|||
|
for (int j = 0; j < 2; ++j) {
|
|||
|
QPushButton* button;
|
|||
|
if (i == 0 && j == 0) {
|
|||
|
button = new QPushButton(QString("IR"), this);
|
|||
|
button->setFixedSize(73, 50);
|
|||
|
videoButtonsRowLayout->addWidget(button);
|
|||
|
button->setProperty("getVideoIndex", i * 2 + j);
|
|||
|
connect(button, &QPushButton::clicked, this, &MainWidget::onSendGetVideoClicked);
|
|||
|
getVideoButtons.append(button);
|
|||
|
continue;
|
|||
|
}
|
|||
|
else if (i == 0 && j == 1) {
|
|||
|
button = new QPushButton(QString("RGB"), this);
|
|||
|
button->setFixedSize(73, 50);
|
|||
|
videoButtonsRowLayout->addWidget(button);
|
|||
|
button->setProperty("getVideoIndex", i * 2 + j);
|
|||
|
connect(button, &QPushButton::clicked, this, &MainWidget::onSendGetVideoClicked);
|
|||
|
getVideoButtons.append(button);
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
// 调价调焦窗口按键
|
|||
|
if (i == 1 && j == 0) {
|
|||
|
button = new QPushButton(QString("大窗口播放视频"), this);
|
|||
|
button->setFixedSize(150, 50);
|
|||
|
button->setEnabled(false);
|
|||
|
videoButtonsRowLayout->addWidget(button);
|
|||
|
button->setProperty("getVideoIndex", i * 2 + j);
|
|||
|
connect(button, &QPushButton::clicked, this, &MainWidget::onOpenFocusWindowClicked);
|
|||
|
getVideoButtons.append(button);
|
|||
|
break; // 跳出内层循环,只添加一个按键
|
|||
|
}
|
|||
|
|
|||
|
//int adjustedIndex = (i > 1) ? i * 2 + j - 1 : i * 2 + j;
|
|||
|
button = new QPushButton(QString("Device %1").arg(i * 2 + j - 3), this);
|
|||
|
//button = new QPushButton(QString("Device %1").arg(adjustedIndex), this);
|
|||
|
button->setFixedSize(73, 50);
|
|||
|
videoButtonsRowLayout->addWidget(button);
|
|||
|
button->setProperty("getVideoIndex", i * 2 + j + 1);
|
|||
|
//button->setProperty("getVideoIndex", adjustedIndex);
|
|||
|
connect(button, &QPushButton::clicked, this, &MainWidget::onSendGetVideoClicked);
|
|||
|
getVideoButtons.append(button);
|
|||
|
}
|
|||
|
videoButtonsColumnLayout->addLayout(videoButtonsRowLayout);
|
|||
|
}
|
|||
|
|
|||
|
QHBoxLayout* videoAndButtonsLayout = new QHBoxLayout;
|
|||
|
videoLabel = new QLabel(this);
|
|||
|
//videoLabel->setFixedSize(640, 480);
|
|||
|
videoAndButtonsLayout->addLayout(videoButtonsColumnLayout, 1);
|
|||
|
videoAndButtonsLayout->addWidget(videoLabel, 6);
|
|||
|
videoDisplayLayout->addLayout(videoAndButtonsLayout);
|
|||
|
|
|||
|
QVBoxLayout* rightVerticalLayout = new QVBoxLayout;
|
|||
|
rightVerticalLayout->addLayout(groupBoxLayout, 2);
|
|||
|
rightVerticalLayout->addWidget(tabWidget, 2, Qt::AlignTop | Qt::AlignLeft);
|
|||
|
rightVerticalLayout->addWidget(tabWidget_media, 5);
|
|||
|
|
|||
|
QHBoxLayout* mainLayout = new QHBoxLayout;
|
|||
|
// 参数二:伸缩因子,leftContainer:1/3 ,rightLayout:2/3
|
|||
|
mainLayout->addWidget(leftContainer, 1, Qt::AlignTop | Qt::AlignLeft); // 设置 leftContainer 左上对齐
|
|||
|
mainLayout->addLayout(rightVerticalLayout, 3);
|
|||
|
|
|||
|
setLayout(mainLayout);
|
|||
|
setWindowTitle("SL100 工厂产测工具 - V0.0.1");
|
|||
|
resize(1340, 1000); // 设置宽度为 1440 像素,高度为 900 像素
|
|||
|
|
|||
|
connect(startServerButton, &QPushButton::clicked, this, &MainWidget::onStartServerClicked);
|
|||
|
connect(sendAllButton, &QPushButton::clicked, this, &MainWidget::onSendAllClicked);
|
|||
|
connect(statusListWidget, &QListWidget::itemChanged, this, &MainWidget::scrollToBottom);
|
|||
|
connect(selectFileButton, &QPushButton::clicked, this, &MainWidget::onSelectFileButtonClicked);
|
|||
|
connect(clearLogButton, &QPushButton::clicked, this, &MainWidget::onclearLogButtonClicked);
|
|||
|
connect(saveCheckBox, &QCheckBox::stateChanged, this, &MainWidget::onSaveCheckBoxStateChanged);
|
|||
|
}
|
|||
|
|
|||
|
void MainWidget::onSelectFileButtonClicked()
|
|||
|
{
|
|||
|
QString filePath = QFileDialog::getSaveFileName(this, tr("选择文件路径"), "", tr("Text Files (*.txt);;All Files (*)"));
|
|||
|
if (!filePath.isEmpty()) {
|
|||
|
filePathLineEdit->setText(filePath);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void MainWidget::onclearLogButtonClicked()
|
|||
|
{
|
|||
|
statusListWidget->clear();
|
|||
|
}
|
|||
|
|
|||
|
void MainWidget::onSaveCheckBoxStateChanged(int state)
|
|||
|
{
|
|||
|
if (state == Qt::Checked) {
|
|||
|
saveStatusListToFile(filePathLineEdit->text());
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void MainWidget::saveStatusListToFile(const QString& filePath)
|
|||
|
{
|
|||
|
if (filePath.isEmpty()) {
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
QFile file(filePath);
|
|||
|
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
QTextStream out(&file);
|
|||
|
for (int i = 0; i < statusListWidget->count(); ++i) {
|
|||
|
QListWidgetItem* item = statusListWidget->item(i);
|
|||
|
out << item->text() << "\n";
|
|||
|
}
|
|||
|
file.close();
|
|||
|
}
|
|||
|
|
|||
|
void MainWidget::onStartTimeout(int clientId, int timeout)
|
|||
|
{
|
|||
|
//qDebug() << "---------------> onStartTimeout :" << clientId << "timeout :" << timeout;
|
|||
|
if (clientTimers.contains(clientId)) {
|
|||
|
QTimer* timer = clientTimers[clientId];
|
|||
|
if (timeout > 0) {
|
|||
|
timer->start(timeout);
|
|||
|
}
|
|||
|
else {
|
|||
|
timer->stop();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void MainWidget::scrollToBottom()
|
|||
|
{
|
|||
|
statusListWidget->scrollToBottom();
|
|||
|
}
|
|||
|
|
|||
|
void MainWidget::readJsonConfig()
|
|||
|
{
|
|||
|
frontBoardOneClickTest = readJson_frontBoardOneClickTest();
|
|||
|
frontBoardTest = readJson_frontBoardTest();
|
|||
|
frontBoardFuncConfig = readJson_frontBoardFuncConfig();
|
|||
|
frontBoardDevInfoJson = readJson_frontDevInfo();
|
|||
|
backBoardDevInfoJson = readJson_backDevInfo();
|
|||
|
testJsonConfig = readJson_testConfig();
|
|||
|
funcJsonConfig = readJson_funcConfig();
|
|||
|
|
|||
|
getPicJson = readJson_getPic();
|
|||
|
getVideoJson = readJson_getVideo();
|
|||
|
}
|
|||
|
|
|||
|
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;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 处理客户端断开连接信号
|
|||
|
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::onStartServerClicked()
|
|||
|
{
|
|||
|
if (!server->isListening()) {
|
|||
|
// 根据需要修改
|
|||
|
//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);
|
|||
|
}
|
|||
|
else {
|
|||
|
qDebug() << "Failed to start server. Error:" << server->errorString();
|
|||
|
}
|
|||
|
}
|
|||
|
else {
|
|||
|
server->close();
|
|||
|
startServerButton->setText(tr("开始监听\n(Start Listening...)"));
|
|||
|
startServerButton->setStyleSheet("");
|
|||
|
sendAllButton->setEnabled(false);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 处理发送获取设备信息按键点击事件
|
|||
|
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);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
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 - 5 >= 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();
|
|||
|
qDebug() << "------> handler->sendNextItem()";
|
|||
|
handler->sendNextItem();
|
|||
|
}
|
|||
|
}
|
|||
|
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();
|
|||
|
}
|
|||
|
|