Qt 6.8版本 自制windows下运行软件<一>——串口调试助手
自制串口调试助手 哔哩哔哩效果展示
一、 说明
本人在读学生,跟随哔哩哔哩网站北京迅为公司的教学视频,进行学习qt,由于视频中的实现过程是利用ui界面的实现,本人在学习过程中,通过完全敲代码的形式,实现同样的功能,并利用网络上其他资源,添加进行去自己所需要的功能。比如本串口调试助手中的编码格式的选择,是我自己加进去的,在此记录一下学习过程。望有缘人发现错误的时候,指点一下,我将更正,我也将十分感激。
二、 准备工具
windows下安装Qt6.8 的版本(当然其他版本也能实现,可能会有一些不兼容)
三、新建工程
完成以后,对工程内的ui部分进行删除
四、删除工程中的多余部分
删除完成以后如下所示:
用 ctrl+s,然后ctrl+r 如果弹出以下窗口,则新建成功
this->setFixedSize(1200,750);
this->setWindowTitle(QString::fromLocal8Bit("自制串口助手-Lihoujun"));
通过上面两行代码实现窗口大小的实现,以及名称的设置。效果如下:
五、 代码实现
我在写代码之前,把名字修改了一下。
mainwindow.cpp代码
#include "mainwindow.h"
QByteArray SerialPortAssistant::utf8ToGbk(const QString &utf8Str) // UTF-8 转 GBK
{
QByteArray utf8Data = utf8Str.toUtf8();
QTextCodec *codec = QTextCodec::codecForName("GBK");
if (codec) {
return codec->fromUnicode(utf8Str);
}
return QByteArray();
}
QString SerialPortAssistant::gbkToUtf8(const QByteArray &gbkData) // GBK 转 UTF-8
{
QTextCodec *codec = QTextCodec::codecForName("GBK");
if (codec) {
QString utf16Str = codec->toUnicode(gbkData); // 转换为 QString
return utf16Str;
}
return QString();
}
void SerialPortAssistant::ReceAreaInit(void)
{
ReceArea = new QPlainTextEdit(this);
ReceArea->setFixedSize(860,400);
ReceArea->move(320,20);
ReceArea->setReadOnly(true);
QPushButton* ReceAreaClear = new QPushButton(QString::fromLocal8Bit("清除接收区"),this);
ReceAreaClear->setFixedSize(150,30);
ReceAreaClear->move(1030,450);
connect(ReceAreaClear,&QPushButton::clicked,[&](){
ReceArea->clear();
});
}
void SerialPortAssistant::SendAreaInit(void)
{
SendArea = new QPlainTextEdit(this);
SendArea->setFixedSize(860,100);
SendArea->move(320,500);
QPushButton* SendAreaClear = new QPushButton(QString::fromLocal8Bit("清除发送区"),this);
SendAreaClear->setFixedSize(150,30);
SendAreaClear->move(1030,630);
connect(SendAreaClear,&QPushButton::clicked,[&](){
SendArea->clear();
});
}
void SerialPortAssistant::ParameterPositonConfig(void)
{
this->COM = new QComboBox(this);
this->bound = new QComboBox(this);
this->databits = new QComboBox(this);
this->stopbits = new QComboBox(this);
this->paritybits = new QComboBox(this);
this->ReceType = new QComboBox(this);
this->SendType = new QComboBox(this);
this->ReceCode = new QComboBox(this);
this->SendCode = new QComboBox(this);
this->NewLine = new QComboBox(this);
this->bound->addItem("115200");
this->bound->addItem("9600");
this->bound->addItem("4800");
this->databits->addItem("8");
this->stopbits->addItem("1");
this->paritybits->addItem("None");
this->paritybits->addItem("1");
this->paritybits->addItem("0");
this->ReceType->addItem(QString::fromLocal8Bit("文本模式"));
this->ReceType->addItem("hex");
this->SendType->addItem(QString::fromLocal8Bit("文本模式"));
this->SendType->addItem("hex");
this->ReceCode->addItem("utf-8");
this->ReceCode->addItem("gbk");
this->SendCode->addItem("utf-8");
this->SendCode->addItem("gbk");
this->NewLine->addItem("yes");
this->NewLine->addItem("no");
QLabel* COMLabel = new QLabel(QString::fromLocal8Bit("串口号:"),this);
QLabel* boundLable = new QLabel(QString::fromLocal8Bit("波特率:"),this);
QLabel* stopbitsLable = new QLabel(QString::fromLocal8Bit("停止位:"),this);
QLabel* databitsLable = new QLabel(QString::fromLocal8Bit("数据位:"),this);
QLabel* paritybitsLable = new QLabel(QString::fromLocal8Bit("校验位:"),this);
QLabel* recetypeLable = new QLabel(QString::fromLocal8Bit("接收格式:"),this);
QLabel* sendtypeLable = new QLabel(QString::fromLocal8Bit("发送格式:"),this);
QLabel* ReceCodeLable = new QLabel(QString::fromLocal8Bit("接收编码:"),this);
QLabel* SendCodeLable = new QLabel(QString::fromLocal8Bit("发送编码:"),this);
QLabel* SendNewLineLable = new QLabel(QString::fromLocal8Bit("发送新行:"),this);
QLabel* pic1Lable = new QLabel(this);
QLabel* pic2Lable = new QLabel(this);
pic1Lable->setPixmap(QPixmap("E:/Qt/Serial/LHJ.png"));
pic2Lable->setPixmap(QPixmap("E:/Qt/Serial/GLUT.jpg"));
pic1Lable->setScaledContents(true);
pic2Lable->setScaledContents(true);
pic1Lable->resize(250,100);
pic2Lable->resize(130,130);
pic1Lable->move(520,620);
pic2Lable->move(90,560);
QVector<QComboBox*>setups;
setups.push_back(COM);
setups.push_back(bound);
setups.push_back(databits);
setups.push_back(stopbits);
setups.push_back(paritybits);
setups.push_back(ReceType);
setups.push_back(SendType);
setups.push_back(ReceCode);
setups.push_back(SendCode);
setups.push_back(NewLine);
QVector<QLabel*>labels;
labels.push_back(COMLabel);
labels.push_back(boundLable);
labels.push_back(databitsLable);
labels.push_back(stopbitsLable);
labels.push_back(paritybitsLable);
labels.push_back(recetypeLable);
labels.push_back(sendtypeLable);
labels.push_back(ReceCodeLable);
labels.push_back(SendCodeLable);
labels.push_back(SendNewLineLable);
for(int i=0;i<setups.size();i++)
{
setups[i]->setFixedSize(200,30);
setups[i]->move(100,20+i*50);
labels[i]->move(30,20+i*50);
}
}
void SerialPortAssistant::ConnectSerial(void)
{
QSerialPort::BaudRate Bound;
QSerialPort::DataBits dataBits;
QSerialPort::StopBits stopBits;
QSerialPort::Parity parityBits;
QString port = COM->currentText();
QString baud = bound->currentText();
QString data = databits->currentText();
QString stop = stopbits->currentText();
QString parity = paritybits->currentText();
QString RxCode = ReceCode->currentText();
QString TxCode = SendCode->currentText();
if(baud == "115200") Bound = QSerialPort::Baud115200;
else if(baud == "9600") Bound = QSerialPort::Baud9600;
else if(baud == "4800") Bound = QSerialPort::Baud4800;
if(data == "8") dataBits = QSerialPort::Data8;
if(stop == "1") stopBits = QSerialPort::OneStop;
if(parity == "None") parityBits = QSerialPort::NoParity;
else if(parity == "0") parityBits = QSerialPort::EvenParity;
else if(parity == "1") parityBits = QSerialPort::OddParity;
SerialPort = new QSerialPort(this);
SerialPort->setBaudRate(Bound);
SerialPort->setDataBits(dataBits);
SerialPort->setStopBits(stopBits);
SerialPort->setParity(parityBits);
SerialPort->setPortName(port);
if(SerialPort->open(QIODevice::ReadWrite) == true)
{
QMessageBox::information(this,"COM","串口打开成功");
connect(SerialPort,&QSerialPort::readyRead,[&](){
auto data = SerialPort->readAll();
if(ReceType->currentText() == "hex")
{
QString Hex = data.toHex(' ');
ReceArea->appendPlainText(Hex);
}
else
{
QString str;
if (ReceCode->currentText() == "gbk")
{
str = gbkToUtf8(data); // 将 GBK 数据转换为 UTF-8
}
else
{
str = QString::fromUtf8(data); // 直接使用 UTF-8
}
ReceArea->appendPlainText(str);
}
});
}
else
{
QMessageBox::critical(this,"COM","串口打开失败");
}
}
void SerialPortAssistant::timerEvent(QTimerEvent* e)
{
QVector<QString>temp;
for(const QSerialPortInfo& info : QSerialPortInfo::availablePorts())
{
temp.push_back(info.portName());
}
std::sort(temp.begin(),temp.end());
if(temp != ports)
{
this->COM->clear();
this->ports = temp;
for(auto& a:ports) this->COM->addItem(a);
}
updateTime(); // 每秒更新时间显示
}
void SerialPortAssistant::TranslationControl(void)
{
SendButton = new QPushButton(QString::fromLocal8Bit("发送"),this);
OpenButton = new QPushButton(QString::fromLocal8Bit("打开串口"),this);
CloseButton = new QPushButton(QString::fromLocal8Bit("关闭串口"),this);
SendButton->setFixedSize(150,30);
OpenButton->setFixedSize(100,30);
CloseButton->setFixedSize(100,30);
SendButton->move(860,630);
OpenButton->move(30,520);
CloseButton->move(180,520);
CloseButton->setDisabled(true);
SendButton->setDisabled(true);
connect(SendButton,&QPushButton::clicked,[&](){
QString data = SendArea->toPlainText();
//qDebug() << data;
if(SendType->currentText() == "hex")
{
QByteArray Arr;
for(int i=0;i<data.size();++i)
{
if(data[i] == ' ') continue;
int num = data.mid(i, 2).toUInt(nullptr,16);
++i;
Arr.append(num);
}
if(NewLine->currentText() == "yes")
{
Arr.append("\r\n");
}
SerialPort->write(Arr);
}
else
{
QByteArray sendData = data.toLocal8Bit();
if (SendCode->currentText() == "gbk")
{
sendData = utf8ToGbk(data); // 将 UTF-8 数据转换为 GBK
}
else
{
sendData = data.toUtf8(); // 直接使用 UTF-8
}
if(NewLine->currentText() == "yes")
{
sendData.append("\r\n");
}
SerialPort->write(sendData);
}
});
connect(CloseButton,&QPushButton::clicked,[&](){
SendButton->setDisabled(true);
OpenButton->setDisabled(false);
CloseButton->setDisabled(true);
SerialPort->close();
});
connect(OpenButton,&QPushButton::clicked,[&](){
//打开串口,进行连接
if(COM->currentText() != "")
{
OpenButton->setDisabled(true);
SendButton->setDisabled(false);
CloseButton->setDisabled(false);
ConnectSerial();
}
else
{
QMessageBox::critical(this,"COM","串口打开失败");
}
});
}
void SerialPortAssistant::updateTime(void)
{
QDateTime currentTime = QDateTime::currentDateTime();
QString timeStr = currentTime.toString("yyyy-MM-dd hh:mm:ss");
timeLabel->setText(timeStr);
}
void SerialPortAssistant::GetSysTime(void)
{
timeLabel = new QLabel(this);
timeLabel->setFixedSize(300, 30);
timeLabel->move(100, 700);
updateTime(); // 初始化显示当前时间
}
SerialPortAssistant::SerialPortAssistant(QWidget *parent) : QMainWindow(parent)
{
this->setFixedSize(1200,750);
this->setWindowTitle(QString::fromLocal8Bit("自制串口助手-Lihoujun"));
ReceAreaInit();
SendAreaInit();
ParameterPositonConfig();
TranslationControl();
GetSysTime();
this->startTimer(1000); //1s的定时器
}
SerialPortAssistant::~SerialPortAssistant()
{
}
mainwindow.h代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPlainTextEdit>
#include <QPushButton>
#include <QComboBox>
#include <QLabel>
#include <QDebug>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QMessageBox>
#include <QDateTime>
#include <QTimer>
//编码格式转换所需头文件
#include <QCoreApplication>
#include <QString>
#include <QByteArray>
#include <QTextCodec>
class SerialPortAssistant:public QMainWindow{
Q_OBJECT
public:
SerialPortAssistant(QWidget *parent = nullptr);
~SerialPortAssistant();
void ReceAreaInit(void);
void SendAreaInit(void);
void ParameterPositonConfig(void);
void TranslationControl(void);
void ConnectSerial(void);
void timerEvent(QTimerEvent* e);
void GetSysTime(void);
void updateTime(void);
QByteArray utf8ToGbk(const QString &utf8Str);
QString gbkToUtf8(const QByteArray &gbkData);
private:
QPlainTextEdit* SendArea;
QPlainTextEdit* ReceArea;
QPushButton* SendButton;
QPushButton* OpenButton; //打开串口
QPushButton* CloseButton; //关闭串口
//QPushButton* SendAreaClear;
//QPushButton* ReceAreaClear;
QComboBox* COM;
QComboBox* bound;
QComboBox* databits;
QComboBox* stopbits;
QComboBox* paritybits;
QComboBox* SendType;
QComboBox* ReceType;
QComboBox* ReceCode; //接收编码
QComboBox* SendCode; //发送编码
QComboBox* NewLine; //发送编码
QSerialPort* SerialPort;
QVector<QString>ports;
QLabel* CurrentTimeLabel;
QLabel *timeLabel; // 用于显示当前时间的标签
};
#endif // MAINWINDOW_H
六、 效果展示
自制串口调试助手 哔哩哔哩效果展示
自制串口调试助手