From 481918ea8bbdc379276605c23a87871138ab19b0 Mon Sep 17 00:00:00 2001 From: mhvhm <1308784381@qq.com> Date: Mon, 9 Sep 2024 11:54:10 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=E7=BA=BF=E7=A8=8B=E7=9A=84?= =?UTF-8?q?=E5=88=9B=E5=BB=BA=E6=A8=A1=E5=BC=8F=EF=BC=8C=E5=9C=A8=E4=B8=BB?= =?UTF-8?q?=E7=BA=BF=E7=A8=8B=E4=B8=AD=E5=88=9B=E5=BB=BA=E5=AD=90=E7=BA=BF?= =?UTF-8?q?=E7=A8=8B=EF=BC=8C=E8=80=8C=E4=B8=8D=E6=98=AF=E5=9C=A8=E7=B1=BB?= =?UTF-8?q?=E4=B8=AD=E8=BF=9B=E8=A1=8C=E5=88=9B=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- SerialSynTool/SerialSynTool.pro.user | 2 +- SerialSynTool/mainwindow.cpp | 86 ++++++++-- SerialSynTool/mainwindow.cpp.autosave | 228 ++++++++++++++++++++++++++ SerialSynTool/mainwindow.h | 7 +- SerialSynTool/serialport.cpp | 36 ++-- SerialSynTool/serialport.h | 14 +- _src/css/QPushButton.css | 0 8 files changed, 339 insertions(+), 36 deletions(-) create mode 100644 SerialSynTool/mainwindow.cpp.autosave create mode 100644 _src/css/QPushButton.css diff --git a/README.md b/README.md index 420602e..9eeda5b 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ | 更新时间 | 更新内容 | | ---------- | ------------------------------------------------------------ | +| 2024-09-09 | 1. 调整线程的创建形式,将线程从类中移动到主线程中
2. 优化部分控件的显示细节 | | 2024-09-06 | 1. 完成界面的基本绘制
2. 完成部分ui线程和工作线程的分离
| | | | -| | | diff --git a/SerialSynTool/SerialSynTool.pro.user b/SerialSynTool/SerialSynTool.pro.user index 6f939c9..522445a 100644 --- a/SerialSynTool/SerialSynTool.pro.user +++ b/SerialSynTool/SerialSynTool.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/SerialSynTool/mainwindow.cpp b/SerialSynTool/mainwindow.cpp index 312ef9d..ce51040 100644 --- a/SerialSynTool/mainwindow.cpp +++ b/SerialSynTool/mainwindow.cpp @@ -9,9 +9,15 @@ MainWindow::MainWindow(QWidget *parent) ui->setupUi(this); serial = new SerialPort[SERIAL_NUM]; + thread = new QThread[SERIAL_NUM]; UI_Init(); // 控件初始化 Singel_Init(); // 槽和信号的绑定 + + serial[SERIAL_1].moveToThread(&thread[SERIAL_1]); + serial[SERIAL_2].moveToThread(&thread[SERIAL_2]); + + qDebug() << "主线程ID:" << QThread::currentThreadId(); } MainWindow::~MainWindow() @@ -34,6 +40,9 @@ void MainWindow::UI_Init(void) // 表格表头 ui->tableWidget->setColumnCount(3); // 设置3列 ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); // 自适应列宽 + + ui->pushButton_stop_1->setEnabled(false); + ui->pushButton_stop_2->setEnabled(false); } /* @brief: 串口端口信息刷新 @@ -102,16 +111,15 @@ void MainWindow::SerialPortInfoRefresh(uint8_t serialIdx) */ void MainWindow::Singel_Init(void) { - connect(ui->pushButton_start_1, &QPushButton::clicked, this, PushButton_start_clicked_Callback); // 开始按键点击事件绑定 - connect(ui->pushButton_start_2, &QPushButton::clicked, this, PushButton_start_clicked_Callback); // 开始按键点击事件绑定 - connect(ui->pushButton_stop_1, &QPushButton::clicked, this, PushButton_stop_clicked_Callback); // 结束按键点击事件绑定 - connect(ui->pushButton_stop_2, &QPushButton::clicked, this, PushButton_stop_clicked_Callback); // 结束按键点击事件绑定 + connect(ui->pushButton_start_1, &QPushButton::clicked, this, &MainWindow::PushButton_start_clicked_Callback); // 开始按键点击事件绑定 + connect(ui->pushButton_start_2, &QPushButton::clicked, this, &MainWindow::PushButton_start_clicked_Callback); // 开始按键点击事件绑定 + connect(ui->pushButton_stop_1, &QPushButton::clicked, this, &MainWindow::PushButton_stop_clicked_Callback); // 结束按键点击事件绑定 + connect(ui->pushButton_stop_2, &QPushButton::clicked, this, &MainWindow::PushButton_stop_clicked_Callback); // 结束按键点击事件绑定 - connect(ui->pushButton_refresh_1, &QPushButton::clicked, this, PushButton_refresh_clicked_Callback); // 刷新按键点击事件绑定 - connect(ui->pushButton_refresh_2, &QPushButton::clicked, this, PushButton_refresh_clicked_Callback); // 刷新按键点击事件绑定 + connect(ui->pushButton_refresh_1, &QPushButton::clicked, this, &MainWindow::PushButton_refresh_clicked_Callback); // 刷新按键点击事件绑定 + connect(ui->pushButton_refresh_2, &QPushButton::clicked, this, &MainWindow::PushButton_refresh_clicked_Callback); // 刷新按键点击事件绑定 - connect(this, &MainWindow::Signal_Serial_Open, &serial[SERIAL_1], &SerialPort::SerialPort_OpenSerial_Callback); - connect(this, &MainWindow::Signal_Serial_Open, &serial[SERIAL_2], &SerialPort::SerialPort_OpenSerial_Callback); + connect(this, &MainWindow::Signal_Serial_Open, serial, &SerialPort::SerialPort_OpenSerial_Callback, Qt::DirectConnection); // 允许槽函数被新的槽函数打断 } /* @brief: 开启串口按键点击事件槽函数 @@ -123,22 +131,57 @@ void MainWindow::PushButton_start_clicked_Callback(void) QPushButton* btn = qobject_cast(sender()); qDebug() << "<<<-----" << btn->objectName() << "Clicked ----->>>"; - SERIAL_INFO info = {0}; + SERIAL_INFO info; if (btn == ui->pushButton_start_1) { info.portName = ui->comboBox_port_1->currentText().split('-').at(0); // 获取端口号 info.bandrate = ui->comboBox_band_1->currentText().toUInt(nullptr, 10); info.timeOutCnt = ui->lineEdit_timeout_1->text().toUInt(nullptr, 10); + + emit Signal_Serial_Open(&serial[SERIAL_1], &info); // 发送信号 + + if (!thread[SERIAL_1].isRunning()) + { + thread[SERIAL_1].start(); + qDebug() << "线程开始运行"; + } + + if (serial[SERIAL_1].serial->isOpen()) + { + ui->pushButton_stop_1->setEnabled(true); + ui->pushButton_start_1->setEnabled(false); + } + else + { + ui->pushButton_stop_1->setEnabled(false); + ui->pushButton_start_1->setEnabled(true); + } } else if (btn == ui->pushButton_start_2) { info.portName = ui->comboBox_port_2->currentText().split('-').at(0); info.bandrate = ui->comboBox_band_2->currentText().toInt(nullptr, 10); info.timeOutCnt = ui->lineEdit_timeout_2->text().toUInt(nullptr, 10); - } - qDebug() << info.portName << info.bandrate << info.timeOutCnt; - emit Signal_Serial_Open(&info); // 发送信号 + emit Signal_Serial_Open(&serial[SERIAL_2], &info); // 发送信号 + + if (!thread[SERIAL_2].isRunning()) + { + thread[SERIAL_2].start(); + qDebug() << "线程开始运行"; + } + + if (serial[SERIAL_2].serial->isOpen()) + { + ui->pushButton_stop_2->setEnabled(true); + ui->pushButton_start_2->setEnabled(false); + } + else + { + ui->pushButton_stop_2->setEnabled(false); + ui->pushButton_start_2->setEnabled(true); + } + } } /* @brief: 关闭串口按键点击事件槽函数 @@ -149,6 +192,21 @@ void MainWindow::PushButton_stop_clicked_Callback(void) { QPushButton* btn = qobject_cast(sender()); qDebug() << "<<<-----" << btn->objectName() << "Clicked ----->>>"; + + if (btn == ui->pushButton_stop_1) + { + ui->pushButton_start_1->setEnabled(true); + ui->pushButton_stop_1->setEnabled(false); + + thread[SERIAL_1].quit(); + } + else if (btn == ui->pushButton_stop_2) + { + ui->pushButton_start_2->setEnabled(true); + ui->pushButton_stop_2->setEnabled(false); + + thread[SERIAL_2].quit(); + } } /* @brief: 刷新键点击事件槽函数 @@ -161,10 +219,10 @@ void MainWindow::PushButton_refresh_clicked_Callback(void) qDebug() << "<<<-----" << btn->objectName() << "Clicked ----->>>"; if (btn == ui->pushButton_refresh_1) { - SerialPortInfoRefresh(1); + SerialPortInfoRefresh(SERIAL_1); } else if (btn == ui->pushButton_refresh_2) { - SerialPortInfoRefresh(2); + SerialPortInfoRefresh(SERIAL_2); } } diff --git a/SerialSynTool/mainwindow.cpp.autosave b/SerialSynTool/mainwindow.cpp.autosave new file mode 100644 index 0000000..ce51040 --- /dev/null +++ b/SerialSynTool/mainwindow.cpp.autosave @@ -0,0 +1,228 @@ +#include "mainwindow.h" +#include "ui_mainwindow.h" + + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) +{ + ui->setupUi(this); + + serial = new SerialPort[SERIAL_NUM]; + thread = new QThread[SERIAL_NUM]; + + UI_Init(); // 控件初始化 + Singel_Init(); // 槽和信号的绑定 + + serial[SERIAL_1].moveToThread(&thread[SERIAL_1]); + serial[SERIAL_2].moveToThread(&thread[SERIAL_2]); + + qDebug() << "主线程ID:" << QThread::currentThreadId(); +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +/* @brief: UI控件初始化 + * @para: void + * @return: void + */ +void MainWindow::UI_Init(void) +{ + // 串口端口数据刷新 + for (uint8_t i = 0; i < SERIAL_NUM; i++) + { + SerialPortInfoRefresh(i); + } + + // 表格表头 + ui->tableWidget->setColumnCount(3); // 设置3列 + ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); // 自适应列宽 + + ui->pushButton_stop_1->setEnabled(false); + ui->pushButton_stop_2->setEnabled(false); +} + +/* @brief: 串口端口信息刷新 + * @para: [uint8_t] serialIdx:串口序号 + * @return: + */ +void MainWindow::SerialPortInfoRefresh(uint8_t serialIdx) +{ + QFont font; + + // 清除上一次显示 + if (serialIdx == SERIAL_1) + { + ui->comboBox_port_1->clear(); + } + else if (serialIdx == SERIAL_2) + { + ui->comboBox_port_2->clear(); + } + + foreach (const QSerialPortInfo info, QSerialPortInfo::availablePorts()) + { + switch(serialIdx) + { + case SERIAL_1: + { + if (info.isNull()) + { + font = ui->comboBox_port_1->font(); + font.setStrikeOut(true); + } + else + { + font = ui->comboBox_port_1->font(); + font.setStrikeOut(false); + } + ui->comboBox_port_1->setFont(font); + ui->comboBox_port_1->addItem(info.portName() + "-" + info.description()); + }break; + case SERIAL_2: + { + if (info.isNull()) + { + font = ui->comboBox_port_2->font(); + font.setStrikeOut(true); + } + else + { + font = ui->comboBox_port_2->font(); + font.setStrikeOut(false); + } + ui->comboBox_port_2->setFont(font); + ui->comboBox_port_2->addItem(info.portName() + "-" + info.description()); + }break; + default: + { + }break; + } + } +} + +//==========================================================================<槽函数> +/* @brief: 槽与信号的绑定 + * @para: + * @return: + */ +void MainWindow::Singel_Init(void) +{ + connect(ui->pushButton_start_1, &QPushButton::clicked, this, &MainWindow::PushButton_start_clicked_Callback); // 开始按键点击事件绑定 + connect(ui->pushButton_start_2, &QPushButton::clicked, this, &MainWindow::PushButton_start_clicked_Callback); // 开始按键点击事件绑定 + connect(ui->pushButton_stop_1, &QPushButton::clicked, this, &MainWindow::PushButton_stop_clicked_Callback); // 结束按键点击事件绑定 + connect(ui->pushButton_stop_2, &QPushButton::clicked, this, &MainWindow::PushButton_stop_clicked_Callback); // 结束按键点击事件绑定 + + connect(ui->pushButton_refresh_1, &QPushButton::clicked, this, &MainWindow::PushButton_refresh_clicked_Callback); // 刷新按键点击事件绑定 + connect(ui->pushButton_refresh_2, &QPushButton::clicked, this, &MainWindow::PushButton_refresh_clicked_Callback); // 刷新按键点击事件绑定 + + connect(this, &MainWindow::Signal_Serial_Open, serial, &SerialPort::SerialPort_OpenSerial_Callback, Qt::DirectConnection); // 允许槽函数被新的槽函数打断 +} + +/* @brief: 开启串口按键点击事件槽函数 + * @para: + * @return: + */ +void MainWindow::PushButton_start_clicked_Callback(void) +{ + QPushButton* btn = qobject_cast(sender()); + qDebug() << "<<<-----" << btn->objectName() << "Clicked ----->>>"; + + SERIAL_INFO info; + if (btn == ui->pushButton_start_1) + { + info.portName = ui->comboBox_port_1->currentText().split('-').at(0); // 获取端口号 + info.bandrate = ui->comboBox_band_1->currentText().toUInt(nullptr, 10); + info.timeOutCnt = ui->lineEdit_timeout_1->text().toUInt(nullptr, 10); + + emit Signal_Serial_Open(&serial[SERIAL_1], &info); // 发送信号 + + if (!thread[SERIAL_1].isRunning()) + { + thread[SERIAL_1].start(); + qDebug() << "线程开始运行"; + } + + if (serial[SERIAL_1].serial->isOpen()) + { + ui->pushButton_stop_1->setEnabled(true); + ui->pushButton_start_1->setEnabled(false); + } + else + { + ui->pushButton_stop_1->setEnabled(false); + ui->pushButton_start_1->setEnabled(true); + } + } + else if (btn == ui->pushButton_start_2) + { + info.portName = ui->comboBox_port_2->currentText().split('-').at(0); + info.bandrate = ui->comboBox_band_2->currentText().toInt(nullptr, 10); + info.timeOutCnt = ui->lineEdit_timeout_2->text().toUInt(nullptr, 10); + + emit Signal_Serial_Open(&serial[SERIAL_2], &info); // 发送信号 + + if (!thread[SERIAL_2].isRunning()) + { + thread[SERIAL_2].start(); + qDebug() << "线程开始运行"; + } + + if (serial[SERIAL_2].serial->isOpen()) + { + ui->pushButton_stop_2->setEnabled(true); + ui->pushButton_start_2->setEnabled(false); + } + else + { + ui->pushButton_stop_2->setEnabled(false); + ui->pushButton_start_2->setEnabled(true); + } + } +} + +/* @brief: 关闭串口按键点击事件槽函数 + * @para: + * @return: + */ +void MainWindow::PushButton_stop_clicked_Callback(void) +{ + QPushButton* btn = qobject_cast(sender()); + qDebug() << "<<<-----" << btn->objectName() << "Clicked ----->>>"; + + if (btn == ui->pushButton_stop_1) + { + ui->pushButton_start_1->setEnabled(true); + ui->pushButton_stop_1->setEnabled(false); + + thread[SERIAL_1].quit(); + } + else if (btn == ui->pushButton_stop_2) + { + ui->pushButton_start_2->setEnabled(true); + ui->pushButton_stop_2->setEnabled(false); + + thread[SERIAL_2].quit(); + } +} + +/* @brief: 刷新键点击事件槽函数 + * @para: + * @return: + */ +void MainWindow::PushButton_refresh_clicked_Callback(void) +{ + QPushButton* btn = qobject_cast(sender()); + qDebug() << "<<<-----" << btn->objectName() << "Clicked ----->>>"; + if (btn == ui->pushButton_refresh_1) + { + SerialPortInfoRefresh(SERIAL_1); + } + else if (btn == ui->pushButton_refresh_2) + { + SerialPortInfoRefresh(SERIAL_2); + } +} diff --git a/SerialSynTool/mainwindow.h b/SerialSynTool/mainwindow.h index fe2f8e0..00c7790 100644 --- a/SerialSynTool/mainwindow.h +++ b/SerialSynTool/mainwindow.h @@ -4,7 +4,7 @@ #include #include #include - +#include #include "serialport.h" QT_BEGIN_NAMESPACE @@ -30,11 +30,12 @@ private slots: // 槽函数 void PushButton_refresh_clicked_Callback(void); // 刷新按键点击事件绑定 signals: // 信号 - void Signal_Serial_Open(SERIAL_INFO* info); // 开启串口信号 - void Signal_Serial_Close(void); // 关闭串口信号 + void Signal_Serial_Open(SerialPort*, SERIAL_INFO*); // 开启串口信号 + void Signal_Serial_Close(SerialPort*); // 关闭串口信号 private: Ui::MainWindow *ui; SerialPort *serial; + QThread* thread; }; #endif // MAINWINDOW_H diff --git a/SerialSynTool/serialport.cpp b/SerialSynTool/serialport.cpp index 650747a..7fe332b 100644 --- a/SerialSynTool/serialport.cpp +++ b/SerialSynTool/serialport.cpp @@ -6,8 +6,10 @@ */ SerialPort::SerialPort(QObject *parent) : QObject(parent) { - thread = new QThread(); // 创建线程句柄 serial = new QSerialPort(); // 创建串口句柄 + recvFrameTimer = new QTimer(); + + connect(recvFrameTimer, &QTimer::timeout, this, &SerialPort::SerialPort_FrameRecvTimeOut_Callback); } /* @brief: 析构函数 @@ -24,23 +26,33 @@ SerialPort::~SerialPort() * @para: * @return: */ -void SerialPort::SerialPort_OpenSerial_Callback(SERIAL_INFO* info) +void SerialPort::SerialPort_OpenSerial_Callback(SerialPort* pserialport, SERIAL_INFO* info) { - qDebug() << "<<<-----Serial Opened Succssfully ----->>>"; - serial->setPortName(info->portName); - serial->setBaudRate(info->bandrate); - serial->setDataBits(QSerialPort::Data8); - serial->setStopBits(QSerialPort::OneStop); // 以为停止位 - serial->setParity(QSerialPort::NoParity); // 无奇偶校验 - serial->setFlowControl(QSerialPort::NoFlowControl); // 硬件控制 + pserialport->serial->setPortName(info->portName); + pserialport->serial->setBaudRate(info->bandrate); + pserialport->serial->setDataBits(QSerialPort::Data8); + pserialport->serial->setStopBits(QSerialPort::OneStop); // 1位停止位 + pserialport->serial->setParity(QSerialPort::NoParity); // 无奇偶校验 + pserialport->serial->setFlowControl(QSerialPort::NoFlowControl); - if(serial->open(QIODevice::ReadWrite)) + qDebug() << info->portName << info->bandrate << info->timeOutCnt; + + if(pserialport->serial->open(QIODevice::ReadWrite)) { - serial->moveToThread(thread); // 加入线程 - qDebug() << "<<<----- 串口打开成功,线程ID:" << serial->thread() << " ----->>>";; // 获取线程id + pserialport->recvFrameTimer->start(1000); + qDebug() << "串口打开成功"; } else { qDebug() << "串口打开失败"; } } + +/* @brief: 串口接收一帧定时器超时时间到槽函数回调 + * @para: + * @return: + */ +void SerialPort::SerialPort_FrameRecvTimeOut_Callback(void) +{ + qDebug() << QThread::currentThreadId(); +} diff --git a/SerialSynTool/serialport.h b/SerialSynTool/serialport.h index 14fcb32..72ac0e5 100644 --- a/SerialSynTool/serialport.h +++ b/SerialSynTool/serialport.h @@ -3,10 +3,10 @@ #include #include - -#include #include #include +#include +#include //========================================================================== typedef enum @@ -35,11 +35,15 @@ public: signals: public slots: // 槽函数 - void SerialPort_OpenSerial_Callback(SERIAL_INFO* info); + void SerialPort_OpenSerial_Callback(SerialPort* serial, SERIAL_INFO* info); + + void SerialPort_FrameRecvTimeOut_Callback(void); + +public: + QSerialPort* serial; private: - QThread* thread; - QSerialPort* serial; + QTimer* recvFrameTimer; // 接收一帧数据定时器 }; #endif // SERIALPORT_H diff --git a/_src/css/QPushButton.css b/_src/css/QPushButton.css new file mode 100644 index 0000000..e69de29