diff --git a/FactoryTestTool/FactoryTestTool.vcxproj b/FactoryTestTool/FactoryTestTool.vcxproj
index 6742ba2..15f2471 100644
--- a/FactoryTestTool/FactoryTestTool.vcxproj
+++ b/FactoryTestTool/FactoryTestTool.vcxproj
@@ -105,6 +105,7 @@
+
diff --git a/FactoryTestTool/FactoryTestTool.vcxproj.filters b/FactoryTestTool/FactoryTestTool.vcxproj.filters
index ebd5a7a..dbe674a 100644
--- a/FactoryTestTool/FactoryTestTool.vcxproj.filters
+++ b/FactoryTestTool/FactoryTestTool.vcxproj.filters
@@ -160,6 +160,9 @@
Network
+
+ Media\VideoDecoder
+
diff --git a/FactoryTestTool/SourceCode/Media/VideoDecoder/FFmpegDecoder.cpp b/FactoryTestTool/SourceCode/Media/VideoDecoder/FFmpegDecoder.cpp
index 270f516..0e3b4ec 100644
--- a/FactoryTestTool/SourceCode/Media/VideoDecoder/FFmpegDecoder.cpp
+++ b/FactoryTestTool/SourceCode/Media/VideoDecoder/FFmpegDecoder.cpp
@@ -15,7 +15,7 @@ FFmpegDecoder::FFmpegDecoder(QObject* parent) :
{
av_log_set_level(AV_LOG_QUIET); // 设置日志级别为安静模式
avformat_network_init(); // 初始化网络
- //qDebug() << "FFmpegDecoder created";
+ qDebug() << "FFmpegDecoder created";
}
FFmpegDecoder::~FFmpegDecoder()
@@ -31,16 +31,54 @@ FFmpegDecoder::~FFmpegDecoder()
qDebug() << "FFmpegDecoder destroyed";
}
+void FFmpegDecoder::processVideo(int itemIndex)
+{
+#if 0
+ int width = 720;
+ int height = 1280;
+#elif 1
+ int width = 640;
+ int height = 480;
+#else
+ int width = 480;
+ int height = 640;
+#endif
+ if (width * 16 == height * 9) {
+ FocusWindowDialog* dialog = new FocusWindowDialog(nullptr, QSize(540, 960));
+ dialog->exec();
+ }
+ else if (width * 9 == height * 16) {
+ FocusWindowDialog* dialog = new FocusWindowDialog(nullptr, QSize(960, 540));
+ dialog->exec();
+ }
+ else if (width * 4 == height * 3) {
+ FocusWindowDialog* dialog = new FocusWindowDialog(nullptr, QSize(480, 640));
+ dialog->exec();
+ }
+ else if (width * 3 == height * 4) {
+ FocusWindowDialog* dialog = new FocusWindowDialog(nullptr, QSize(640, 480));
+ dialog->exec();
+ }
+}
+
void FFmpegDecoder::initialize()
{
// 初始化FFmpeg库
avformat_network_init();
}
+void FFmpegDecoder::stopFFmpegDecoder()
+{
+ mutex.lock();
+ abort = true;
+ condition.wakeOne(); // 唤醒等待的线程
+ mutex.unlock();
+}
+
void FFmpegDecoder::decodeFile(const QString& filePath, QLabel* videoDisplayLabel)
{
QMutexLocker locker(&mutex);
- this->filePath = filePath;
+ this->filePath = filePath;
this->videoLabel = videoDisplayLabel;
if (!isRunning()) {
qDebug() << "Starting decoder thread";
@@ -55,7 +93,7 @@ void FFmpegDecoder::run()
QFile file(filePath);
qint64 fileSize = 0;
- while (true) {
+ while (!isInterruptionRequested()) {
mutex.lock();
while (!restart && !abort) {
condition.wait(&mutex);
@@ -65,14 +103,12 @@ void FFmpegDecoder::run()
qDebug() << "Decoder thread aborting";
break;
}
- restart = false;
QLabel* currentVideoLabel = videoLabel;
QSize labelSize = currentVideoLabel->size();
mutex.unlock();
- if (labelSize.width() <= 0 || labelSize.height() <= 0) {
- // 自动调整 QLabel 大小
- labelSize = QSize(800, 600); // 例如设置为默认大小
+ if (labelSize.width() < 740 || labelSize.height() < 357) {
+ labelSize = QSize(740, 357);
currentVideoLabel->setFixedSize(labelSize);
qDebug() << "Adjusting video label size to: Width =" << labelSize.width() << ", Height =" << labelSize.height();
}
@@ -88,14 +124,18 @@ void FFmpegDecoder::run()
file.close();
continue;
}
+ restart = false;
while (!abort) {
qint64 currentFileSize = file.size();
+ //qDebug() << "Decoder thread currentFileSize:" << currentFileSize;
+ //qDebug() << "Decoder thread fileSize:" << fileSize;
if (currentFileSize > fileSize) {
fileSize = currentFileSize;
file.seek(fileSize); // 设置文件读取位置到末尾
-
+ //qDebug() << "---------------1---------------";
// 读取并处理数据包
while (av_read_frame(formatContext, packet) >= 0) {
+ //qDebug() << "---------------2---------------";
if (packet->stream_index == videoStreamIndex) {
int ret = avcodec_send_packet(codecContext, packet);
if (ret < 0) {
@@ -103,6 +143,7 @@ void FFmpegDecoder::run()
av_packet_unref(packet);
continue;
}
+ //qDebug() << "---------------3---------------";
while (ret >= 0) {
ret = avcodec_receive_frame(codecContext, frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
@@ -113,28 +154,31 @@ void FFmpegDecoder::run()
qWarning() << "Error during decoding";
break;
}
-
- qDebug() << "H264 video resolution: Width =" << frame->width << ", Height =" << frame->height;
-
+ //qDebug() << "---------------4---------------";
QImage img = avFrameToQImage(frame);
+ //qDebug() << "---------------5---------------";
QImage scaledImage = img.scaled(labelSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ //qDebug() << "---------------6---------------";
currentVideoLabel->setPixmap(QPixmap::fromImage(scaledImage));
QThread::msleep(10); // Simulate 25 FPS frame rate
+ //qDebug() << "---------------7---------------";
}
}
av_packet_unref(packet);
+ //qDebug() << "---------------8---------------";
}
}
-
+ //qDebug() << "---------------9---------------";
mutex.lock();
if (restart) {
restart = false;
mutex.unlock();
break;
}
+ //qDebug() << "---------------10---------------";
mutex.unlock();
}
-
+ //qDebug() << "---------------11---------------";
cleanup();
file.close();
@@ -148,6 +192,10 @@ void FFmpegDecoder::run()
bool FFmpegDecoder::initializeFFmpeg(const QString& filePath)
{
+ if (!QFile::exists(filePath)) {
+ qWarning() << "FFmpeg File does not exist:" << filePath;
+ return false;
+ }
if (avformat_open_input(&formatContext, filePath.toStdString().c_str(), nullptr, nullptr) != 0) {
qWarning() << "Failed to open file with FFmpeg:" << filePath;
return false;
@@ -227,6 +275,8 @@ QImage FFmpegDecoder::avFrameToQImage(AVFrame* frame)
{
int width = frame->width;
int height = frame->height;
+ qDebug() << "H264 video resolution: Width =" << frame->width << ", Height =" << frame->height;
+
AVPixelFormat pixFmt = (AVPixelFormat)frame->format;
if (!swsContext) {
diff --git a/FactoryTestTool/SourceCode/Media/VideoDecoder/FFmpegDecoder.h b/FactoryTestTool/SourceCode/Media/VideoDecoder/FFmpegDecoder.h
index 54219fa..908f654 100644
--- a/FactoryTestTool/SourceCode/Media/VideoDecoder/FFmpegDecoder.h
+++ b/FactoryTestTool/SourceCode/Media/VideoDecoder/FFmpegDecoder.h
@@ -14,8 +14,10 @@
#include
#include
#include
+#include
#include "RingBuffer.h"
+#include "FocusWindow.h"
extern "C" {
#include
@@ -38,9 +40,10 @@ public:
void initialize();
void decodeFile(const QString& filePath, QLabel* videoLabel);
void decodeSingleFrame(const QByteArray& data, QLabel* videoLabel); // 添加 videoLabel 参数
-
+ void FFmpegDecoder::processVideo(int itemIndex);
bool initializeFFmpeg(const QString& filePath);
void cleanup();
+ void stopFFmpegDecoder();
protected:
void run() override;
@@ -48,19 +51,19 @@ protected:
private:
QImage avFrameToQImage(AVFrame* frame);
- QMutex mutex;
- QWaitCondition condition;
- QString filePath;
- QLabel* videoLabel;
- bool abort;
- bool restart;
+ QMutex mutex;
+ QWaitCondition condition;
+ QString filePath;
+ QLabel* videoLabel;
+ bool abort;
+ bool restart;
AVFormatContext* formatContext;
- AVCodecContext* codecContext;
- AVFrame* frame;
- AVPacket* packet;
- SwsContext* swsContext;
- int videoStreamIndex;
+ AVCodecContext* codecContext;
+ AVFrame* frame;
+ AVPacket* packet;
+ SwsContext* swsContext;
+ int videoStreamIndex;
RingBuffer* ringBuffer;
//QLabel* singleFrameLabel; // 用于解码单帧的标签
diff --git a/FactoryTestTool/SourceCode/Media/VideoDecoder/FocusWindow.h b/FactoryTestTool/SourceCode/Media/VideoDecoder/FocusWindow.h
new file mode 100644
index 0000000..2686b0f
--- /dev/null
+++ b/FactoryTestTool/SourceCode/Media/VideoDecoder/FocusWindow.h
@@ -0,0 +1,26 @@
+#include
+#include
+#include
+#include
+
+class FocusWindowDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ FocusWindowDialog(QWidget* parent = nullptr, const QSize& labelSize = QSize(480, 640)) : QDialog(parent)
+ {
+ QVBoxLayout* layout = new QVBoxLayout(this);
+ QLabel* label = new QLabel("1111 This is a new window opened by clicking the new button.", this);
+ label->setFixedSize(labelSize); // 设置QLabel的固定大小
+ layout->addWidget(label);
+
+ QPushButton* closeButton = new QPushButton("Close", this);
+ layout->addWidget(closeButton);
+ connect(closeButton, &QPushButton::clicked, this, &FocusWindowDialog::accept);
+
+ setLayout(layout);
+ setWindowTitle("SL100 视频播放窗口");
+ //resize(500, 700); // 设置对话框的大小
+ }
+};
diff --git a/FactoryTestTool/SourceCode/Network/ClientHandler.cpp b/FactoryTestTool/SourceCode/Network/ClientHandler.cpp
index 2371a26..c6ed2c8 100644
--- a/FactoryTestTool/SourceCode/Network/ClientHandler.cpp
+++ b/FactoryTestTool/SourceCode/Network/ClientHandler.cpp
@@ -9,7 +9,7 @@ ClientHandler::ClientHandler(QTcpSocket* socket,
QJsonArray frontBoardDevInfoJson, QJsonArray frontBoardLicenseJson,
QJsonArray backBoardOneClickTest, QJsonArray backBoardTest, QJsonArray backBoardFuncConfig,
QJsonArray backBoardDevInfoJson, QJsonArray backBoardUuidJson,
- QJsonArray getPicJson, QJsonArray getVideoJson, int clientId, QObject* parent)
+ QJsonArray getPicJson, QJsonArray getVideoJson, int clientId, int isBackBoardOrAllBoard, QObject* parent)
: QObject(parent), socket(socket),
frontBoardOneClickTest(frontBoardOneClickTest), frontBoardTest(frontBoardTest),
frontBoardFuncConfig(frontBoardFuncConfig), frontBoardDevInfoJson(frontBoardDevInfoJson),
@@ -17,7 +17,7 @@ ClientHandler::ClientHandler(QTcpSocket* socket,
backBoardOneClickTest(backBoardOneClickTest), backBoardTest(backBoardTest),
backBoardFuncConfig(backBoardFuncConfig), backBoardDevInfoJson(backBoardDevInfoJson),
backBoardUuidJson(backBoardUuidJson), getPicJson(getPicJson), getVideoJson(getVideoJson),
- currentItemIndex(0), clientId(clientId),
+ currentItemIndex(0), clientId(clientId), isBackBoardOrAllBoard(isBackBoardOrAllBoard),
isManualSend(false), isSingleSend(false), isClickedSend(false), size(0),
isFirstDataReceived(true), processDataFunction(nullptr),
isDataStuck(false), dataProcessingActive(false), isRecvVideoData(true),
@@ -35,6 +35,37 @@ ClientHandler::~ClientHandler() {
qDebug() << "ClientHandler destroyed for clientId:" << clientId;
}
+// 实现 QRunnable 的 run 函数,在线程池中执行
+void ClientHandler::run()
+{
+ start();
+}
+
+// 重置索引
+void ClientHandler::resetCurrentItemIndex()
+{
+ currentItemIndex = 0;
+ currentFuncItemIndex = 0;
+ itemsProcessedCount = 0;
+ emit startTimeout(0);
+}
+
+// 开始处理客户端
+void ClientHandler::start()
+{
+ resetCurrentItemIndex(); // 初始化计数器和索引
+ sendNextItem();
+}
+
+// 处理客户端断开连接
+void ClientHandler::onDisconnected() {
+ qDebug() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>";
+ qDebug() << "> A device is disconnected. ID:" << clientId;
+ qDebug() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>";
+ emit clientDisconnected(this);
+ socket->deleteLater();
+}
+
void ClientHandler::startReadVideoDataTimer(int client_Id)
{
//emit startReadTimer(clientId);
@@ -94,31 +125,9 @@ QString ClientHandler::getClientAddress() const
return socket->peerAddress().toString() + ":" + QString::number(socket->peerPort());
}
-// 实现 QRunnable 的 run 函数,在线程池中执行
-void ClientHandler::run()
-{
- start();
-}
-
-// 重置索引
-void ClientHandler::resetCurrentItemIndex()
-{
- currentItemIndex = 0;
- currentFuncItemIndex = 0;
- itemsProcessedCount = 0;
- emit startTimeout(0);
-}
-
-// 开始处理客户端
-void ClientHandler::start()
-{
- resetCurrentItemIndex(); // 初始化计数器和索引
- sendNextItem();
-}
-
void ClientHandler::sendDataToClient(const QByteArray& data)
{
- emit sendData(data);
+ emit sendData(data, isBackBoardOrAllBoard);
}
void ClientHandler::sendJsonItem(const QJsonArray& jsonArray, int itemIndex, const QString text, const QString& itemType)
@@ -470,6 +479,8 @@ bool ClientHandler::RNDISFirstData(QByteArray& data) {
setThreadPriority(QThread::LowPriority);
socket->setReadBufferSize(20 * 1024);
controlClientId = clientId;
+ // 前板有设备连接自动发送获取设备信息
+ //sendDevInfoItem();
break;
default:
qWarning() << "Unhandled client type:" << clientType;
@@ -671,15 +682,6 @@ void ClientHandler::processPendingData()
}
}
-// 处理客户端断开连接
-void ClientHandler::onDisconnected() {
- qDebug() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>";
- qDebug() << "> A device is disconnected. ID:" << clientId;
- qDebug() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>";
- emit clientDisconnected(this);
- socket->deleteLater();
-}
-
// 处理超时
void ClientHandler::onTimeout()
{
diff --git a/FactoryTestTool/SourceCode/Network/ClientHandler.h b/FactoryTestTool/SourceCode/Network/ClientHandler.h
index 26959c8..9539721 100644
--- a/FactoryTestTool/SourceCode/Network/ClientHandler.h
+++ b/FactoryTestTool/SourceCode/Network/ClientHandler.h
@@ -33,7 +33,7 @@ public:
QJsonArray frontBoardFuncConfig, QJsonArray frontBoardDevInfoJson, QJsonArray frontBoardLicenseJson,
QJsonArray backBoardOneClickTest, QJsonArray backBoardTest, QJsonArray backBoardFuncConfig, QJsonArray backBoardDevInfoJson,
QJsonArray backBoardUuidJson, QJsonArray getPicJson, QJsonArray getVideoJson,
- int clientId, QObject* parent = nullptr);
+ int clientId, int isBackBoardOrAllBoard, QObject* parent = nullptr);
~ClientHandler();
int preVideoClientId = 0;
@@ -92,7 +92,7 @@ signals:
const QJsonArray& jsonArray, int itemJsonIndex);
void handleData(QByteArray& data);
// 数据发送信号
- void sendData(const QByteArray& data);
+ void sendData(const QByteArray& data, int isBoardType);
// 状态更新信号
void statusUpdated(const QString& client, int itemIndex, int funcItemIndex,
bool success, const QString& itemData, const QString& funcItemData,
@@ -144,6 +144,7 @@ private:
int currentItemIndex; // 当前处理的测试 JSON 项目索引
int currentFuncItemIndex; // 当前处理的功能 JSON 项目索引
int clientId; // 新增的客户端编号
+ int isBackBoardOrAllBoard;
int itemsProcessedCount; // 跟踪处理项目的数量
diff --git a/FactoryTestTool/SourceCode/Network/mdns/qmdnsengine/include/qmdnsengine_export.h b/FactoryTestTool/SourceCode/Network/mdns/qmdnsengine/include/qmdnsengine_export.h
index 03d7334..93343e1 100644
--- a/FactoryTestTool/SourceCode/Network/mdns/qmdnsengine/include/qmdnsengine_export.h
+++ b/FactoryTestTool/SourceCode/Network/mdns/qmdnsengine/include/qmdnsengine_export.h
@@ -27,6 +27,8 @@
#include
+#define BUILD_SHARED_LIBS
+#define QMDNSENGINE_LIBRARY
#if defined(BUILD_SHARED_LIBS)
# if defined(QMDNSENGINE_LIBRARY)
# define QMDNSENGINE_EXPORT Q_DECL_EXPORT
diff --git a/FactoryTestTool/SourceCode/Network/mdns/qmdnsengine/src/dns.cpp b/FactoryTestTool/SourceCode/Network/mdns/qmdnsengine/src/dns.cpp
index f25bcbd..a17bfcd 100644
--- a/FactoryTestTool/SourceCode/Network/mdns/qmdnsengine/src/dns.cpp
+++ b/FactoryTestTool/SourceCode/Network/mdns/qmdnsengine/src/dns.cpp
@@ -339,7 +339,10 @@ void toPacket(const Message &message, QByteArray &packet)
{
quint16 offset = 0;
quint16 flags = (message.isResponse() ? 0x8400 : 0) |
- (message.isTruncated() ? 0x200 : 0);
+ (message.isTruncated() ? 0x200 : 0);
+
+ qDebug() << "Flags set in toPacket:" << QString::number(flags, 16);
+
writeInteger(packet, offset, message.transactionId());
writeInteger(packet, offset, flags);
writeInteger(packet, offset, message.queries().length());
diff --git a/FactoryTestTool/SourceCode/Network/mdns/qmdnsengine/src/prober.cpp b/FactoryTestTool/SourceCode/Network/mdns/qmdnsengine/src/prober.cpp
index 3a58f58..60ecb5a 100644
--- a/FactoryTestTool/SourceCode/Network/mdns/qmdnsengine/src/prober.cpp
+++ b/FactoryTestTool/SourceCode/Network/mdns/qmdnsengine/src/prober.cpp
@@ -71,7 +71,6 @@ void ProberPrivate::assertRecord()
message.addQuery(query);
message.addRecord(proposedRecord);
server->sendMessageToAll(message);
-
// Wait two seconds to confirm it is unique
timer.stop();
timer.start(2 * 1000);
@@ -80,14 +79,15 @@ void ProberPrivate::assertRecord()
void ProberPrivate::onMessageReceived(const Message &message)
{
// If the response matches the proposed record, increment the suffix and
- // try with the new name
-
- if (confirmed || !message.isResponse()) {
+ // try with the new name
+ //if (confirmed || !message.isResponse()) {
+ if (confirmed) {
return;
}
const auto records = message.records();
for (const Record &record : records) {
if (record.name() == proposedRecord.name() && record.type() == proposedRecord.type()) {
+ qDebug() << "Conflict detected for name:" << proposedRecord.name() << "with type:" << record.type();
++suffix;
assertRecord();
}
diff --git a/FactoryTestTool/SourceCode/Network/mdns/qmdnsengine/src/provider.cpp b/FactoryTestTool/SourceCode/Network/mdns/qmdnsengine/src/provider.cpp
index e1ed2a5..7c24e2d 100644
--- a/FactoryTestTool/SourceCode/Network/mdns/qmdnsengine/src/provider.cpp
+++ b/FactoryTestTool/SourceCode/Network/mdns/qmdnsengine/src/provider.cpp
@@ -79,8 +79,8 @@ void ProviderPrivate::confirm()
delete prober;
}
prober = new Prober(server, srvProposed, this);
- connect(prober, &Prober::nameConfirmed, [this](const QByteArray &name) {
+ connect(prober, &Prober::nameConfirmed, [this](const QByteArray &name) {
// If existing records were confirmed, indicate that they are no
// longer valid
if (confirmed) {
@@ -128,7 +128,7 @@ void ProviderPrivate::onMessageReceived(const Message &message)
if (!confirmed || message.isResponse()) {
return;
}
-
+ //qDebug() << "Failed to start server. Error:" << server->errorString();
bool sendBrowsePtr = false;
bool sendPtr = false;
bool sendSrv = false;
@@ -227,13 +227,16 @@ void Provider::update(const Service &service)
return;
}
bool registered = d->hostname->isRegistered();
- //qDebug() << "Hostname registered:" << registered;
if(registered) {
+ // 不确认服务名称,直接进行广播
+ d->publish();
//if (d->hostname->isRegistered()) {
- if (!d->confirmed || fqName != d->srvRecord.name()) {
+ /*if (!d->confirmed || fqName != d->srvRecord.name()) {
+ qDebug() << "confirm()";
d->confirm();
} else {
+ qDebug() << "publish()";
d->publish();
- }
+ }*/
}
}
diff --git a/FactoryTestTool/SourceCode/Network/mdns/qmdnsengine/src/server.cpp b/FactoryTestTool/SourceCode/Network/mdns/qmdnsengine/src/server.cpp
index b295a15..5369600 100644
--- a/FactoryTestTool/SourceCode/Network/mdns/qmdnsengine/src/server.cpp
+++ b/FactoryTestTool/SourceCode/Network/mdns/qmdnsengine/src/server.cpp
@@ -129,8 +129,6 @@ void Server::sendMessageToAll(const Message &message)
{
QByteArray packet;
toPacket(message, packet);
- //qDebug() << "MdnsMsg :" << packet.toHex();
- qDebug() << "MdnsPort:" << MdnsPort;
qint64 sentBytes = d->ipv4Socket.writeDatagram(packet, MdnsIpv4Address, MdnsPort);
qDebug() << "ipv4Socket sentBytes:" << sentBytes;
sentBytes = d->ipv6Socket.writeDatagram(packet, MdnsIpv6Address, MdnsPort);
diff --git a/FactoryTestTool/SourceCode/Network/mdns/servicemodel.cpp b/FactoryTestTool/SourceCode/Network/mdns/servicemodel.cpp
index 38f05ae..de3d148 100644
--- a/FactoryTestTool/SourceCode/Network/mdns/servicemodel.cpp
+++ b/FactoryTestTool/SourceCode/Network/mdns/servicemodel.cpp
@@ -1,4 +1,4 @@
-// #include "servicemodel.cpp"
+// servicemodel.cpp
#include "servicemodel.h"
Q_DECLARE_METATYPE(QMdnsEngine::Service)
diff --git a/FactoryTestTool/SourceCode/Network/mdns/servicemodel.h b/FactoryTestTool/SourceCode/Network/mdns/servicemodel.h
index 0db827b..ed1d958 100644
--- a/FactoryTestTool/SourceCode/Network/mdns/servicemodel.h
+++ b/FactoryTestTool/SourceCode/Network/mdns/servicemodel.h
@@ -1,3 +1,4 @@
+// servicemodel.h
#ifndef SERVICEMODEL_H
#define SERVICEMODEL_H
@@ -7,7 +8,8 @@
#include "qmdnsengine/include/hostname.h"
#include "qmdnsengine/include/provider.h"
#include "qmdnsengine/include/service.h"
-
+#include "qmdnsengine/include/message.h"
+#include "qmdnsengine/include/query.h"
class ServiceProvider : public QObject
{
diff --git a/FactoryTestTool/SourceCode/RecvDataHandler/RecvDataHandler.cpp b/FactoryTestTool/SourceCode/RecvDataHandler/RecvDataHandler.cpp
index 04551c3..d7eac15 100644
--- a/FactoryTestTool/SourceCode/RecvDataHandler/RecvDataHandler.cpp
+++ b/FactoryTestTool/SourceCode/RecvDataHandler/RecvDataHandler.cpp
@@ -27,11 +27,14 @@ DataHandler::DataHandler(QLabel* leftLens_imageLabel, QLabel* rightLens_imageLab
ffmpegDecoder->initialize(); // 初始化解码器
clearAllRecvData();
initializeMsgIdToCmdMap();
+ qDebug() << "DataHandler created";
}
DataHandler::~DataHandler()
{
+ qDebug() << "---1--- DataHandler destroyed";
if (ffmpegDecoder) {
+ ffmpegDecoder->stopFFmpegDecoder();
ffmpegDecoder->requestInterruption();
ffmpegDecoder->wait(); // 等待解码器线程完成
delete ffmpegDecoder;
@@ -39,6 +42,14 @@ DataHandler::~DataHandler()
}
delete buffer;
buffer = nullptr;
+ qDebug() << "---2--- DataHandler destroyed";
+}
+
+void DataHandler::handleOpenFocusWindow(int itemIndex)
+{
+ if (ffmpegDecoder) {
+ ffmpegDecoder->processVideo(itemIndex); // 调用 FFmpegDecoder 的处理函数
+ }
}
QByteArray DataHandler::hexStringToByteArray(const QString& hexString)
@@ -50,16 +61,17 @@ QByteArray DataHandler::hexStringToByteArray(const QString& hexString)
return byteArray;
}
-const QString filePath_1 = "add1.h264";
+const QString filePath_1 = "/add1.h264";
// 显示视频的函数
void DataHandler::showVideo(const QString& client, const QByteArray& valData)
{
- static QFile file(filePath_1);
+ QString h264filePath = QDir::currentPath() + filePath_1;
+ static QFile file(h264filePath);
if (!file.isOpen()) {
- if (QFile::exists(filePath_1)) {
- QFile::remove(filePath_1);
+ if (QFile::exists(h264filePath)) {
+ QFile::remove(h264filePath);
}
if (!file.open(QIODevice::Append | QIODevice::WriteOnly)) {
qWarning() << "无法打开H264文件:" << file.errorString();
@@ -74,7 +86,7 @@ void DataHandler::showVideo(const QString& client, const QByteArray& valData)
if (!start_run) {
start_run = 1;
- ffmpegDecoder->decodeFile(filePath_1, videoLabel);
+ ffmpegDecoder->decodeFile(h264filePath, videoLabel);
}
//ffmpegDecoder->decodeFile(filePath_1, videoLabel);
}
diff --git a/FactoryTestTool/SourceCode/RecvDataHandler/RecvDataHandler.h b/FactoryTestTool/SourceCode/RecvDataHandler/RecvDataHandler.h
index f3d6c71..fe0e1e0 100644
--- a/FactoryTestTool/SourceCode/RecvDataHandler/RecvDataHandler.h
+++ b/FactoryTestTool/SourceCode/RecvDataHandler/RecvDataHandler.h
@@ -46,7 +46,7 @@ public slots:
void handleData(const QString& client, const QByteArray& data, int msg_id, int currentRecvItemIndex,
int currentRecvFuncItemIndex, const QString& itemData, const QString& funcItemData,
const QJsonArray& jsonArray, int itemJsonIndex);
-
+ void handleOpenFocusWindow(int itemIndex);
signals:
void statusUpdated(const QString& clientAddress, int currentItemIndex, int currentFuncItemIndex,
bool success, const QString& currentItemLabel, const QString& currentFuncItemLabel,
diff --git a/FactoryTestTool/SourceCode/Widget/FocusWindow.h b/FactoryTestTool/SourceCode/Widget/FocusWindow.h
index 600f50a..cdf5a7c 100644
--- a/FactoryTestTool/SourceCode/Widget/FocusWindow.h
+++ b/FactoryTestTool/SourceCode/Widget/FocusWindow.h
@@ -8,10 +8,11 @@ class NewButtonDialog : public QDialog
Q_OBJECT
public:
- NewButtonDialog(QWidget* parent = nullptr) : QDialog(parent)
+ NewButtonDialog(QWidget* parent = nullptr, const QSize& labelSize = QSize(480, 640)) : QDialog(parent)
{
QVBoxLayout* layout = new QVBoxLayout(this);
QLabel* label = new QLabel("This is a new window opened by clicking the new button.", this);
+ label->setFixedSize(labelSize); // 设置QLabel的固定大小
layout->addWidget(label);
QPushButton* closeButton = new QPushButton("Close", this);
@@ -20,6 +21,6 @@ public:
setLayout(layout);
setWindowTitle("SL100 视频播放窗口");
- resize(480, 640); // 设置对话框的大小
+ //resize(500, 700); // 设置对话框的大小
}
};
diff --git a/FactoryTestTool/SourceCode/Widget/MainWidget.cpp b/FactoryTestTool/SourceCode/Widget/MainWidget.cpp
index 2ff610d..a6f40f7 100644
--- a/FactoryTestTool/SourceCode/Widget/MainWidget.cpp
+++ b/FactoryTestTool/SourceCode/Widget/MainWidget.cpp
@@ -1,7 +1,6 @@
// MainWidget.cpp
#include "MainWidget.h"
-
void onThreadFinished(QThread* thread, ClientHandler* handler)
{
qDebug() << "Thread finished. Deleting handler and thread.";
@@ -27,36 +26,79 @@ MainWidget::MainWidget(QWidget* parent) :
multicastTimer(new QTimer(this))
#endif
{
- leftLens_imageLabel = new QLabel(this);
- rightLens_imageLabel = new QLabel(this);
- videoLabel = new QLabel(this);
+ leftLens_imageLabel = new QLabel(this);
+ rightLens_imageLabel = new QLabel(this);
+ videoLabel = new QLabel(this);
frontFuncConfigLineEdit = new QLineEdit(this);
- backFuncConfigLineEdit = new QLineEdit(this);
- licenseHwInfoEdit = new QTextEdit(this);
- UuidHwInfoEdit = new QTextEdit(this);
+ backFuncConfigLineEdit = new QLineEdit(this);
+ licenseHwInfoEdit = new QTextEdit(this);
+ UuidHwInfoEdit = new QTextEdit(this);
+
+
+
+ // 创建 mDNS 服务的 Server 和 Hostname 对象
+ QMdnsEngine::Server myserver;
+ QMdnsEngine::Hostname hostname(&myserver);
+
+ // 创建服务提供者(Provider)
+ QMdnsEngine::Provider provider(&myserver, &hostname);
+
+ // 定义要广播的服务
+ QMdnsEngine::Service service;
+ service.setName("Test Service");
+ service.setType("_test._tcp"); // 服务类型,包括 _tcp 或 _udp
+ service.setPort(12345); // 服务使用的端口号
+
+ // 启动服务广播
+ provider.update(service);
+
+ qDebug() << "mDNS service started. Broadcasting service:"
+ << service.name() << service.type() << "on port" << service.port();
+
+
setupUI();
// 打印线程池状态信息
setupTimerForThreadPoolInfo();
server = new QTcpServer(this);
+ /*
+ // 创建 DataHandler 对象并连接信号
+ DataHandler* dataHandler = new DataHandler(leftLens_imageLabel, rightLens_imageLabel, videoLabel, licenseHwInfoEdit, &devInfoLineEdits,
+ frontBoardOneClickTest, frontBoardTest, frontBoardFuncConfig,
+ frontBoardDevInfoJson, frontBoardLicenseJson,
+ backBoardOneClickTest, backBoardTest, backBoardFuncConfig, backBoardDevInfoJson,
+ backBoardUuidJson, getPicJson, getVideoJson, this);
- //FactoryToolSendGetUuidToHttpServer();
- //FactoryToolSendGetLicenseToHttpServer();
- //FactoryToolSendPostComfirmToHttpServer();
- //FactoryToolSendPostTestToHttpServer();
- //FactoryToolSendPostLicenseToHttpServer();
-
+ connect(this, &MainWidget::openFocusWindowRequested, dataHandler, &DataHandler::handleOpenFocusWindow);
+ connect(dataHandler, &DataHandler::statusUpdated, this, &MainWidget::onStatusUpdated);
+ */
connect(server, &QTcpServer::newConnection, this, [this]() {
// 检查是否有挂起的连接
while (server->hasPendingConnections()) {
QTcpSocket* socket = server->nextPendingConnection();
- int clientId = nextClientId++;
+ int clientId = nextClientId ++;
+ QHostAddress clientIp = socket->peerAddress();
+ quint16 clientPort = socket->peerPort();
+ QString ipString = clientIp.toString();
+ if (ipString.startsWith("::ffff:")) {
+ ipString = ipString.mid(7);
+ }
qDebug() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>";
qDebug() << "> A client is connected. ID:" << clientId;
+ qDebug() << "> Client IP:" << ipString << " Port:" << clientPort;
qDebug() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>";
+ if (ipString.startsWith("10.10.10")) {
+ qDebug() << "The client IP address is front board !!!";
+ isBackBoardOrAllBoard = 0;
+ }
+ else {
+ qDebug() << "The client IP address is back board or all board";
+ isBackBoardOrAllBoard = clientId;
+ }
+
stopMdnsService();
- connectedClientsCount++;
+ connectedClientsCount ++;
updateServerButtonText();
QTimer* timer = new QTimer(this);
@@ -76,11 +118,11 @@ MainWidget::MainWidget(QWidget* parent) :
}
});
- QThread* thread = new QThread(this);
+ QThread* thread = new QThread(this);
ClientHandler* handler = new ClientHandler(socket, frontBoardOneClickTest, frontBoardTest, frontBoardFuncConfig,
frontBoardDevInfoJson, frontBoardLicenseJson,
backBoardOneClickTest, backBoardTest, backBoardFuncConfig, backBoardDevInfoJson,
- backBoardUuidJson, getPicJson, getVideoJson, clientId, nullptr);
+ backBoardUuidJson, getPicJson, getVideoJson, clientId, isBackBoardOrAllBoard, nullptr);
// 将 ClientHandler 移动到线程池中的线程
handler->moveToThread(thread);
@@ -91,7 +133,7 @@ MainWidget::MainWidget(QWidget* parent) :
});
// 将sendData信号连接到主线程中的槽上
- connect(handler, &ClientHandler::sendData, this, [socket](const QByteArray& data) {
+ connect(handler, &ClientHandler::sendData, this, [socket](const QByteArray& data, int isBoardType) {
/*socket->write(data);
socket->flush();*/
//qDebug() << "---------------------data.size():" << data.size();
@@ -99,7 +141,12 @@ MainWidget::MainWidget(QWidget* parent) :
QDataStream stream(&prefix, QIODevice::WriteOnly);
stream.setByteOrder(QDataStream::LittleEndian);
stream << quint32(0x55AA55AA);
- stream << quint16(0x0420);
+ if (isBoardType != 0) {
+ stream << quint16(0x0421);
+ }
+ else {
+ stream << quint16(0x0420);
+ }
stream << quint32(data.size());
prefix.append(data);
@@ -124,15 +171,20 @@ MainWidget::MainWidget(QWidget* parent) :
connect(handler, &ClientHandler::allItemsProcessed, this, &MainWidget::onAllItemsProcessed);
connect(handler, &ClientHandler::selectClientDisconnected, this, &MainWidget::onDisconnectClient);
+#if 1
// 创建 DataHandler 对象并连接信号
DataHandler* dataHandler = new DataHandler(leftLens_imageLabel, rightLens_imageLabel, videoLabel, licenseHwInfoEdit, &devInfoLineEdits,
frontBoardOneClickTest, frontBoardTest, frontBoardFuncConfig,
frontBoardDevInfoJson, frontBoardLicenseJson,
backBoardOneClickTest, backBoardTest, backBoardFuncConfig, backBoardDevInfoJson,
backBoardUuidJson, getPicJson, getVideoJson, this);
- connect(handler, &ClientHandler::dataReceived, dataHandler, &DataHandler::handleData);
- connect(dataHandler, &DataHandler::statusUpdated, this, &MainWidget::onStatusUpdated);
-
+ dataHandlers[clientId] = dataHandler;
+ connect(this, &MainWidget::openFocusWindowRequested, dataHandler, &DataHandler::handleOpenFocusWindow);
+ connect(handler, &ClientHandler::dataReceived, dataHandler, &DataHandler::handleData);
+ connect(dataHandler, &DataHandler::statusUpdated, this, &MainWidget::onStatusUpdated);
+#else
+ connect(handler, &ClientHandler::dataReceived, dataHandler, &DataHandler::handleData);
+#endif
connect(handler, &ClientHandler::startReadTimer, this, &MainWidget::startClientReadTimer);
connect(handler, &ClientHandler::stopReadTimer, this, &MainWidget::stopClientReadTimer);
@@ -157,7 +209,6 @@ MainWidget::MainWidget(QWidget* parent) :
connectionStatusCheckTimer = new QTimer(this);
connect(connectionStatusCheckTimer, &QTimer::timeout, this, &MainWidget::onCheckConnectionStatus);
//connectionStatusCheckTimer->start(100); // 每100ms检查一次连接状态
-
connect(mdnsTimer, &QTimer::timeout, this, &MainWidget::startMdnsService);
#if TEST_UDP_BROADCAST
@@ -199,6 +250,12 @@ MainWidget::~MainWidget()
delete timer;
}
clientReadTimers.clear();
+
+ for (auto dataHandler : dataHandlers) {
+ dataHandler->deleteLater();
+ }
+ dataHandlers.clear();
+
for (ClientHandler* handler : clients) {
handler->deleteLater();
}
@@ -228,6 +285,206 @@ MainWidget::~MainWidget()
qDebug() << "MainWidget destroyed";
}
+// 处理客户端断开连接信号
+void MainWidget::onClientDisconnected(ClientHandler* handler)
+{
+ int clientId = handler->getClientId();
+ qDebug() << " preVideoClientId :" << handler->preVideoClientId;
+ qDebug() << " clientId :" << clientId;
+ if (handler->preVideoClientId == clientId) {
+ qDebug() << "Current path: " << QDir::currentPath();
+ QString filePath = QDir::currentPath() + "/add1.h264";
+ if (QFile::exists(filePath)) {
+ QFile file(filePath);
+ if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
+ qDebug() << "File add1.h264 cleared successfully.";
+ }
+ else {
+ qDebug() << "Failed to clear file add1.h264:" << file.errorString();
+ }
+ }
+ else {
+ qDebug() << "File add1.h264 does not exist.";
+ }
+ }
+ if (clientTimers.contains(clientId)) {
+ QTimer* timer = clientTimers[clientId];
+ timer->stop();
+ delete timer;
+ clientTimers.remove(clientId);
+ }
+
+ clients.removeOne(handler);
+ /*
+ 将 ClientHandler 对象的删除操作放入事件队列中,等待事件循环处理。
+ 在事件循环执行时,会安全地删除 ClientHandler 对象,这包括释放其占用的资源和内存
+ */
+ handler->deleteLater(); // 延迟删除 ClientHandler 对象
+
+ qDebug() << "-----------dataHandlers-----------";
+ if (dataHandlers.contains(clientId)) {
+ DataHandler* dataHandler = dataHandlers[clientId];
+ dataHandlers.remove(clientId); // 从容器中移除
+ dataHandler->deleteLater(); // 延迟删除 DataHandler 对象
+ }
+
+ // 更新连接数并更新按键文本
+ connectedClientsCount--;
+ qDebug() << " connectedClientsCount :" << connectedClientsCount;
+ if (nextClientId <= 2) nextClientId--;
+ deviceConnected = true;
+
+ updateServerButtonText();
+}
+
+// 更新按键文本的函数
+void MainWidget::updateServerButtonText()
+{
+ if (deviceConnected) {
+ if (connectedClientsCount > 0) {
+ startServerButton->setText(tr("正在监听(Listening)\n%1 台设备连接").arg(connectedClientsCount));
+ }
+ else if (connectedClientsCount == 0) {
+#if START_MDNS // 这里会开启多个mdns广播,去掉
+ startMdnsService();
+#endif
+ deviceConnected = false;
+ startServerButton->setText(tr("正在监听(Listening)"));
+ }
+ }
+ else if (connectedClientsCount == 0) {
+ startServerButton->setText(tr("开始监听\n(Start Listening...)"));
+ }
+ else {
+ startServerButton->setText(tr("正在监听(Listening)\n%1 台设备连接").arg(connectedClientsCount));
+ }
+}
+
+// 设置 UI
+void MainWidget::setupUI()
+{
+ startServerButton = new QPushButton("开始监听\n(Start Listening...)", this);
+ startServerButton->setFixedSize(190, 70);
+
+ sendAllButton = new QPushButton("一键功能测试", this);
+ sendAllButton->setFixedSize(190, 70);
+ sendAllButton->setEnabled(false);
+
+ statusListWidget = new QListWidget(this);
+ statusListWidget->setMinimumSize(350, 840);
+ statusListWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+ QHBoxLayout* buttonLayout = new QHBoxLayout;
+ buttonLayout->addWidget(startServerButton);
+ buttonLayout->addWidget(sendAllButton);
+ buttonLayout->addStretch();
+
+ QVBoxLayout* leftLayout = new QVBoxLayout;
+ leftLayout->addLayout(buttonLayout);
+ leftLayout->setStretch(0, 1);
+ leftLayout->addWidget(statusListWidget);
+ leftLayout->setStretch(1, 200);
+
+ saveCheckBox = new QCheckBox("", this);
+ saveCheckBox->setChecked(true);
+ selectFileButton = new QPushButton("Save", this);
+ selectFileButton->setFixedSize(45, 28);
+ clearLogButton = new QPushButton("Clear", this);
+ clearLogButton->setFixedSize(55, 28);
+ filePathLineEdit = new QLineEdit(this);
+ filePathLineEdit->setFixedSize(250, 28);
+ filePathLineEdit->setReadOnly(true);
+
+ QHBoxLayout* fileLayout = new QHBoxLayout;
+ fileLayout->addWidget(saveCheckBox);
+ fileLayout->addWidget(selectFileButton);
+ fileLayout->addWidget(filePathLineEdit);
+ fileLayout->addWidget(clearLogButton);
+
+ leftLayout->addLayout(fileLayout);
+ leftLayout->setStretch(2, 1);
+
+ // 读取 JSON 配置文件
+ readJsonConfig();
+
+ QWidget* leftContainer = new QWidget(this);
+ leftContainer->setLayout(leftLayout);
+ leftContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+ // 前板
+ QGroupBox* frontDeviceInfoGroupBox = createFrontDeviceInfoGroupBox();
+ QGroupBox* frontLicenseGroupBox = createLicenseGroupBox();
+
+ QHBoxLayout* frontGroupBoxLayout = new QHBoxLayout;
+ frontGroupBoxLayout->addWidget(frontDeviceInfoGroupBox, 1);
+ frontGroupBoxLayout->addWidget(frontLicenseGroupBox, 1);
+
+ QTabWidget* frontTabWidget = new QTabWidget(this);
+ frontTabWidget->setFixedSize(900, 315);
+ QWidget* frontFunctionTestTab = createFunctionTestTab(frontBoardTest, "frontBoardTest");
+ QWidget* frontFunctionConfigTab = createFunctionConfigTab(frontBoardFuncConfig, "frontBoardFuncConfig");
+ frontTabWidget->addTab(frontFunctionTestTab, "前板测试项");
+ frontTabWidget->addTab(frontFunctionConfigTab, "前板配置项");
+
+ QTabWidget* mainTabWidget = new QTabWidget(this);
+ QWidget* frontDevAreaTab = new QWidget(this);
+ QVBoxLayout* frontDevLayout = new QVBoxLayout(frontDevAreaTab);
+ frontDevLayout->addLayout(frontGroupBoxLayout);
+ frontDevLayout->addWidget(frontTabWidget, 2, Qt::AlignTop | Qt::AlignLeft);
+ mainTabWidget->addTab(frontDevAreaTab, "前 板");
+
+ // 后板
+ QGroupBox* backDeviceInfoGroupBox1 = createBackDeviceInfoGroupBox();
+ QGroupBox* BackConnectServerGroupBox = createBackConnectServerGroupBox();
+
+ QHBoxLayout* backGroupBoxLayout = new QHBoxLayout;
+ backGroupBoxLayout->addWidget(backDeviceInfoGroupBox1, 1);
+ backGroupBoxLayout->addWidget(BackConnectServerGroupBox, 1);
+
+ QTabWidget* backTabWidget = new QTabWidget(this);
+ backTabWidget->setFixedSize(900, 315);
+ QWidget* backFunctionTestTab = createFunctionTestTab(backBoardTest, "backBoardTest");
+ QWidget* backFunctionConfigTab = createFunctionConfigTab(backBoardFuncConfig, "backBoardFuncConfig");
+ backTabWidget->addTab(backFunctionTestTab, "后板测试项");
+ backTabWidget->addTab(backFunctionConfigTab, "后板配置项");
+
+ QWidget* backDevAreaTab = new QWidget(this);
+ QVBoxLayout* backDevLayout = new QVBoxLayout(backDevAreaTab);
+ backDevLayout->addLayout(backGroupBoxLayout);
+ backDevLayout->addWidget(backTabWidget, 2, Qt::AlignTop | Qt::AlignLeft);
+ mainTabWidget->addTab(backDevAreaTab, "后 板");
+
+ // 整机
+ QWidget* allDevAreaTab = new QWidget(this);
+ QVBoxLayout* allDevLayout = new QVBoxLayout(allDevAreaTab);
+ mainTabWidget->addTab(allDevAreaTab, "整 机");
+
+ QTabWidget* tabWidget_media = new QTabWidget(this);
+ QWidget* imageDisplayTab = createImageDisplayTab();
+ QWidget* videoDisplayTab = createVideoDisplayTab();
+ tabWidget_media->addTab(imageDisplayTab, "图像显示区");
+ tabWidget_media->addTab(videoDisplayTab, "视频显示区");
+
+ QVBoxLayout* rightVerticalLayout = new QVBoxLayout;
+ rightVerticalLayout->addWidget(mainTabWidget, 5);
+ rightVerticalLayout->addWidget(tabWidget_media, 4);
+
+ QHBoxLayout* mainLayout = new QHBoxLayout;
+ mainLayout->addWidget(leftContainer, 1, Qt::AlignTop | Qt::AlignLeft);
+ mainLayout->addLayout(rightVerticalLayout, 3);
+
+ setLayout(mainLayout);
+ setWindowTitle("SL100 工厂产测工具 - V0.0.1");
+ resize(1340, 900);
+
+ connect(startServerButton, &QPushButton::clicked, this, &MainWidget::onStartServerClicked);
+ connect(sendAllButton, &QPushButton::clicked, this, &MainWidget::onSendAllClicked);
+ connect(statusListWidget, &QListWidget::itemChanged, this, &MainWidget::scrollToBottom);
+ connect(selectFileButton, &QPushButton::clicked, this, &MainWidget::onSelectFileButtonClicked);
+ connect(clearLogButton, &QPushButton::clicked, this, &MainWidget::onclearLogButtonClicked);
+ connect(saveCheckBox, &QCheckBox::stateChanged, this, &MainWidget::onSaveCheckBoxStateChanged);
+}
+
// 服务器响应
void MainWidget::onHttpRequestFinished(const QJsonObject& response)
{
@@ -546,131 +803,6 @@ void MainWidget::readJsonConfig()
getVideoJson = readJson_getVideo();
}
-// 设置 UI
-void MainWidget::setupUI()
-{
- startServerButton = new QPushButton("开始监听\n(Start Listening...)", this);
- startServerButton->setFixedSize(190, 70);
-
- sendAllButton = new QPushButton("一键功能测试", this);
- sendAllButton->setFixedSize(190, 70);
- sendAllButton->setEnabled(false);
-
- statusListWidget = new QListWidget(this);
- statusListWidget->setMinimumSize(350, 840);
- statusListWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
-
- QHBoxLayout* buttonLayout = new QHBoxLayout;
- buttonLayout->addWidget(startServerButton);
- buttonLayout->addWidget(sendAllButton);
- buttonLayout->addStretch();
-
- QVBoxLayout* leftLayout = new QVBoxLayout;
- leftLayout->addLayout(buttonLayout);
- leftLayout->setStretch(0, 1);
- leftLayout->addWidget(statusListWidget);
- leftLayout->setStretch(1, 200);
-
- saveCheckBox = new QCheckBox("", this);
- saveCheckBox->setChecked(true);
- selectFileButton = new QPushButton("Save", this);
- selectFileButton->setFixedSize(45, 28);
- clearLogButton = new QPushButton("Clear", this);
- clearLogButton->setFixedSize(55, 28);
- filePathLineEdit = new QLineEdit(this);
- filePathLineEdit->setFixedSize(250, 28);
- filePathLineEdit->setReadOnly(true);
-
- QHBoxLayout* fileLayout = new QHBoxLayout;
- fileLayout->addWidget(saveCheckBox);
- fileLayout->addWidget(selectFileButton);
- fileLayout->addWidget(filePathLineEdit);
- fileLayout->addWidget(clearLogButton);
-
- leftLayout->addLayout(fileLayout);
- leftLayout->setStretch(2, 1);
-
- // 读取 JSON 配置文件
- readJsonConfig();
-
- QWidget* leftContainer = new QWidget(this);
- leftContainer->setLayout(leftLayout);
- leftContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
-
- // 前板
- QGroupBox* frontDeviceInfoGroupBox = createFrontDeviceInfoGroupBox();
- QGroupBox* frontLicenseGroupBox = createLicenseGroupBox();
-
- QHBoxLayout* frontGroupBoxLayout = new QHBoxLayout;
- frontGroupBoxLayout->addWidget(frontDeviceInfoGroupBox, 1);
- frontGroupBoxLayout->addWidget(frontLicenseGroupBox, 1);
-
- QTabWidget* frontTabWidget = new QTabWidget(this);
- frontTabWidget->setFixedSize(900, 315);
- QWidget* frontFunctionTestTab = createFunctionTestTab(frontBoardTest, "frontBoardTest");
- QWidget* frontFunctionConfigTab = createFunctionConfigTab(frontBoardFuncConfig, "frontBoardFuncConfig");
- frontTabWidget->addTab(frontFunctionTestTab, "前板测试项");
- frontTabWidget->addTab(frontFunctionConfigTab, "前板配置项");
-
- QTabWidget* mainTabWidget = new QTabWidget(this);
- QWidget* frontDevAreaTab = new QWidget(this);
- QVBoxLayout* frontDevLayout = new QVBoxLayout(frontDevAreaTab);
- frontDevLayout->addLayout(frontGroupBoxLayout);
- frontDevLayout->addWidget(frontTabWidget, 2, Qt::AlignTop | Qt::AlignLeft);
- mainTabWidget->addTab(frontDevAreaTab, "前 板");
-
- // 后板
- QGroupBox* backDeviceInfoGroupBox1 = createBackDeviceInfoGroupBox();
- QGroupBox* BackConnectServerGroupBox = createBackConnectServerGroupBox();
-
- QHBoxLayout* backGroupBoxLayout = new QHBoxLayout;
- backGroupBoxLayout->addWidget(backDeviceInfoGroupBox1, 1);
- backGroupBoxLayout->addWidget(BackConnectServerGroupBox, 1);
-
- QTabWidget* backTabWidget = new QTabWidget(this);
- backTabWidget->setFixedSize(900, 315);
- QWidget* backFunctionTestTab = createFunctionTestTab(backBoardTest, "backBoardTest");
- QWidget* backFunctionConfigTab = createFunctionConfigTab(backBoardFuncConfig, "backBoardFuncConfig");
- backTabWidget->addTab(backFunctionTestTab, "后板测试项");
- backTabWidget->addTab(backFunctionConfigTab, "后板配置项");
-
- QWidget* backDevAreaTab = new QWidget(this);
- QVBoxLayout* backDevLayout = new QVBoxLayout(backDevAreaTab);
- backDevLayout->addLayout(backGroupBoxLayout);
- backDevLayout->addWidget(backTabWidget, 2, Qt::AlignTop | Qt::AlignLeft);
- mainTabWidget->addTab(backDevAreaTab, "后 板");
-
- // 整机
- QWidget* allDevAreaTab = new QWidget(this);
- QVBoxLayout* allDevLayout = new QVBoxLayout(allDevAreaTab);
- mainTabWidget->addTab(allDevAreaTab, "整 机");
-
- QTabWidget* tabWidget_media = new QTabWidget(this);
- QWidget* imageDisplayTab = createImageDisplayTab();
- QWidget* videoDisplayTab = createVideoDisplayTab();
- tabWidget_media->addTab(imageDisplayTab, "图像显示区");
- tabWidget_media->addTab(videoDisplayTab, "视频显示区");
-
- QVBoxLayout* rightVerticalLayout = new QVBoxLayout;
- rightVerticalLayout->addWidget(mainTabWidget, 5);
- rightVerticalLayout->addWidget(tabWidget_media, 4);
-
- QHBoxLayout* mainLayout = new QHBoxLayout;
- mainLayout->addWidget(leftContainer, 1, Qt::AlignTop | Qt::AlignLeft);
- mainLayout->addLayout(rightVerticalLayout, 3);
-
- setLayout(mainLayout);
- setWindowTitle("SL100 工厂产测工具 - V0.0.1");
- resize(1340, 900);
-
- connect(startServerButton, &QPushButton::clicked, this, &MainWidget::onStartServerClicked);
- connect(sendAllButton, &QPushButton::clicked, this, &MainWidget::onSendAllClicked);
- connect(statusListWidget, &QListWidget::itemChanged, this, &MainWidget::scrollToBottom);
- connect(selectFileButton, &QPushButton::clicked, this, &MainWidget::onSelectFileButtonClicked);
- connect(clearLogButton, &QPushButton::clicked, this, &MainWidget::onclearLogButtonClicked);
- connect(saveCheckBox, &QCheckBox::stateChanged, this, &MainWidget::onSaveCheckBoxStateChanged);
-}
-
void MainWidget::onSelectFileButtonClicked()
{
QString filePath = QFileDialog::getSaveFileName(this, tr("选择文件路径"), "", tr("Text Files (*.txt);;All Files (*)"));
@@ -754,75 +886,14 @@ void MainWidget::onDisconnectClient(int clientId)
clientTimers.remove(clientId);
}
handler->deleteLater();
- connectedClientsCount--;
+ connectedClientsCount --;
updateServerButtonText();
-
break;
}
}
-
- // 启动 mDNS 服务广播
- startMdnsService();
-}
-
-// 处理客户端断开连接信号
-void MainWidget::onClientDisconnected(ClientHandler* handler)
-{
- int clientId = handler->getClientId();
- qDebug() << " preVideoClientId :" << handler->preVideoClientId;
- qDebug() << " clientId :" << clientId;
- if (handler->preVideoClientId == clientId) {
- qDebug() << "Current path: " << QDir::currentPath();
- QString filePath = QDir::currentPath() + "/add1.h264";
- if (QFile::exists(filePath)) {
- QFile file(filePath);
- if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { // 使用 Truncate 模式打开文件以清空内容
- qDebug() << "File add1.h264 cleared successfully.";
- }
- else {
- qDebug() << "Failed to clear file add1.h264:" << file.errorString();
- }
- }
- else {
- qDebug() << "File add1.h264 does not exist.";
- }
- }
- if (clientTimers.contains(clientId)) {
- QTimer* timer = clientTimers[clientId];
- timer->stop();
- delete timer;
- clientTimers.remove(clientId);
- }
-
- clients.removeOne(handler);
- /*
- 将 ClientHandler 对象的删除操作放入事件队列中,等待事件循环处理。
- 在事件循环执行时,会安全地删除 ClientHandler 对象,这包括释放其占用的资源和内存
- */
- handler->deleteLater(); // 延迟删除 ClientHandler 对象
-
- // 更新连接数并更新按键文本
- connectedClientsCount--;
- qDebug() << " connectedClientsCount :" << connectedClientsCount;
- if (nextClientId <= 2) nextClientId--;
- deviceConnected = true;
-
- updateServerButtonText();
-}
-
-// 更新按键文本的函数
-void MainWidget::updateServerButtonText()
-{
- if (deviceConnected) {
- deviceConnected = false;
- startServerButton->setText(tr("正在监听(Listening)"));
- if (connectedClientsCount == 0) startMdnsService();
- }
- else if (connectedClientsCount == 0) {
- startServerButton->setText(tr("开始监听\n(Start Listening...)"));
- }
- else {
- startServerButton->setText(tr("正在监听(Listening)\n%1 台设备连接").arg(connectedClientsCount));
+ if (connectedClientsCount == 0) {
+ // 启动 mDNS 服务广播
+ startMdnsService();
}
}
@@ -1026,7 +1097,7 @@ void MainWidget::startMdnsService()
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";
+ QString serviceType = "_myservice._tcp.local";
quint16 port = TCP_CONNECT_PORT;
mServiceProvider->startServiceBroadcast(serviceName, serviceType, port);
@@ -1086,13 +1157,15 @@ void MainWidget::onStartServerClicked()
startServerButton->setText(tr("开始监听\n(Start Listening...)"));
startServerButton->setStyleSheet("");
sendAllButton->setEnabled(false);
-
stopMdnsService();
}
}
void MainWidget::sendDataToClient(int clientId, const QByteArray& data)
{
+ if ((clientId == 0) && (isBackBoardOrAllBoard)) {
+ clientId = isBackBoardOrAllBoard;
+ }
if (clients_1.contains(clientId)) {
ClientHandler* handler = clients_1[clientId];
handler->sendDataToClient(data); // 调用 ClientHandler 中的方法发送数据
@@ -1232,9 +1305,7 @@ void MainWidget::onOpenFocusWindowClicked()
int itemIndex = button->property("getVideoIndex").toInt();
//qDebug() << "New Button clicked with itemIndex:" << itemIndex;
if (itemIndex == 2) {
- // 创建并显示新窗口
- NewButtonDialog dialog(this);
- dialog.exec();
+ emit openFocusWindowRequested(itemIndex); // 发送信号
}
}
}
@@ -1301,7 +1372,7 @@ void MainWidget::onSendBackFuncItemClicked()
QPushButton* button = qobject_cast(sender());
int itemIndex = button->property("backBoardFuncConfig").toInt();
for (ClientHandler* handler : clients) {
- if (handler->getClientId() == handler->controlClientId) {
+ if ((isBackBoardOrAllBoard) || (handler->getClientId() == handler->controlClientId)) {
QString text = backFuncConfigLineEdit->text();
qDebug() << "Text in backFuncConfigLineEdit:" << text;
handler->sendBackFuncItem(itemIndex, text);
@@ -1342,7 +1413,7 @@ void MainWidget::onSendBackItemClicked()
QPushButton* button = qobject_cast(sender());
int itemIndex = button->property("backBoardTest").toInt();
for (ClientHandler* handler : clients) {
- if (handler->getClientId() == handler->controlClientId) {
+ if ((isBackBoardOrAllBoard) || (handler->getClientId() == handler->controlClientId)) {
handler->sendBackItem(itemIndex);
break;
}
diff --git a/FactoryTestTool/SourceCode/Widget/MainWidget.h b/FactoryTestTool/SourceCode/Widget/MainWidget.h
index 970bf71..6329a95 100644
--- a/FactoryTestTool/SourceCode/Widget/MainWidget.h
+++ b/FactoryTestTool/SourceCode/Widget/MainWidget.h
@@ -54,8 +54,16 @@
#include "FocusWindow.h"
+#include "../Network/mdns/qmdnsengine/include/server.h"
+#include "../Network/mdns/qmdnsengine/include/hostname.h"
+#include "../Network/mdns/qmdnsengine/include/provider.h"
+#include "../Network/mdns/qmdnsengine/include/service.h"
+#include "../Network/mdns/qmdnsengine/include/message.h"
+#include "../Network/mdns/qmdnsengine/include/query.h"
+
#define TEST_UDP_BROADCAST 0 // 用于测试 UDP 组播实现 mdns 功能 非标准 mdns
#define MANUAL_UPLOAD_LICENSE 0 // 打开手动上传 License的功能
+#define START_MDNS 1
#define TCP_CONNECT_PORT 12412 // TCP监听的端口
@@ -68,6 +76,9 @@ public:
explicit MainWidget(QWidget* parent = nullptr);
~MainWidget();
+signals:
+ void openFocusWindowRequested(int itemIndex);
+
private slots:
// 发送HTTP请求
//void onSomeButtonClicked();
@@ -178,6 +189,7 @@ private:
int nextClientId; // 新增的客户端编号
int connectedClientsCount = 0; // 连接客户端的数量
int isRequestSuccessful = 0; // GET请求是否成功
+ int isBackBoardOrAllBoard = 0;
bool manualSend; // 判断是否是手动触发的发送
bool deviceConnected = false; // 判断是否有设备连接过
bool isSendingAll; // 一键功能测试 状态
@@ -217,6 +229,7 @@ private:
QTimer* threadStatusTimer; // 检查线程状态的定时器
QTimer* connectionStatusCheckTimer; // 检查连接状态的定时器
+ QMap dataHandlers;
QMap clientThreads;
QMap clientReadTimers;
QMap clients_1;
diff --git a/FactoryTestTool/SourceCode/main.cpp b/FactoryTestTool/SourceCode/main.cpp
index 8650b00..67efc08 100644
--- a/FactoryTestTool/SourceCode/main.cpp
+++ b/FactoryTestTool/SourceCode/main.cpp
@@ -23,7 +23,7 @@ int main(int argc, char* argv[]) {
//closeConsole(); // 调用函数关闭控制台窗口
//FreeConsole(); // 关闭控制台窗口
QApplication app(argc, argv);
-
+ qDebug() << "Current working directory:" << QDir::currentPath();
QIcon appIcon("./app_icon.ico");
app.setWindowIcon(appIcon);
diff --git a/FactoryTestTool/TestLog/20240829_191522.txt b/FactoryTestTool/TestLog/20240829_191522.txt
new file mode 100644
index 0000000..ad7ea84
--- /dev/null
+++ b/FactoryTestTool/TestLog/20240829_191522.txt
@@ -0,0 +1,6 @@
+device ID: 1 - Item 0: ---> NG
+device ID: 1 - Item 0: ---> NG
+device ID: 1 - Item 0: ---> NG
+device ID: 1 - Item 0: ---> NG
+device ID: 1 - Item 0: ---> NG
+device ID:-1 ---> All 5 items test completed !!!
diff --git a/FactoryTestTool/add1.h264 b/FactoryTestTool/add1.h264
index 231a279..e69de29 100644
Binary files a/FactoryTestTool/add1.h264 and b/FactoryTestTool/add1.h264 differ