Compare commits

...

2 Commits

7 changed files with 338 additions and 35 deletions

View File

@ -2,9 +2,9 @@
| 更新时间 | 更新内容 |
| ---------- | ------------------------------------------------------------ |
| 2024-09-09 | 1. 调整线程的创建形式,将线程从类中移动到主线程中<br>2. 优化部分控件的显示细节 |
| 2024-09-06 | 1. 完成界面的基本绘制<br>2. 完成部分ui线程和工作线程的分离<br> |
| | |
| | |

View File

@ -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<QPushButton *>(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<QPushButton *>(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);
}
}

View File

@ -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<QPushButton *>(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<QPushButton *>(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<QPushButton *>(sender());
qDebug() << "<<<-----" << btn->objectName() << "Clicked ----->>>";
if (btn == ui->pushButton_refresh_1)
{
SerialPortInfoRefresh(SERIAL_1);
}
else if (btn == ui->pushButton_refresh_2)
{
SerialPortInfoRefresh(SERIAL_2);
}
}

View File

@ -4,7 +4,7 @@
#include <QMainWindow>
#include <QDebug>
#include <QSerialPortInfo>
#include <QThread>
#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

View File

@ -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();
}

View File

@ -3,10 +3,10 @@
#include <QObject>
#include <QDebug>
#include <QThread>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QTimer>
#include <QThread>
//==========================================================================<typedef>
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

0
_src/css/QPushButton.css Normal file
View File