初学QT 涉及到的功能有
1、使用QT实现串口通信(除了串口号其他参数如波特率全部固定)
2、使用Qt中的定时器
3、访问特定txt文件并读取文件内容通过串口发送
第一次做这样的程序,感觉还是很有收获,记录一下。
成品图 功能很少,非常简陋就是了![在这里插入图片描述](https://img-blog.csdnimg.cn/ec23e1ed298548dbad115bc7c9f87962.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bmz55Sw5paH6ams,size_20,color_FFFFFF,t_70,g_se,x_16)
程序文件结构 ![在这里插入图片描述](https://img-blog.csdnimg.cn/e5a4e20d4c994f99b1b89f2c40220e06.png)
首先看看.pro文件
# .pro文件唯二更改的地方就是这里 加入了serialport
QT += core gui serialport
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
dialog.cpp
HEADERS += \
dialog.h
FORMS += \
dialog.ui
# 加入一个个人程序图标用的
RC_ICONS = WYF.ico
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
再看看 “dialog.h”
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QSerialPort>
#include <QDebug>
#include <QList>
#include <QSerialPortInfo>
#include <QTextCodec>
#include <QTimer>
#include <QFile>
//上面是一些必要的引用
QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }
QT_END_NAMESPACE
class Dialog : public QDialog
{
Q_OBJECT
public:
Dialog(QWidget *parent = nullptr);
~Dialog();
public:
//配置串口
bool getSerialPortConfig(void);
//打开特定txt
void open();
private slots:
//更新串口号
void ShowComNumber();
void on_Send_Button_clicked();
void on_Serial_Button_clicked();
private:
Ui::Dialog *ui;
//实例化两个定时器备用
QTimer *Send_Timer;
QTimer *Com_Timer;
//实例化一个串口对象
QSerialPort mSerialPort;
//一个布尔对象用来判断是否开启了串口
bool mIsOpen;
//这下面本来是用来控制串口号波特率之类的参数的
//后面因为参数基本写死了就没用上,毕竟不是串口助手不需要这么多参数
QString mportName;//串口号
QString mBaudName;//波特率
QString mParity;//校验位
QString mDataBit;//数据位
QString mStopBit;//停止位
QStringList portStringList; //保存当前可用的串口号
};
#endif // DIALOG_H
再来看看 dialog.cpp
内容略长 可以分为 几个部分
1、 初始化定时器扫描串口
ui->setupUi(this);
// 设置两个定时器
Send_Timer = new QTimer(this);
Send_Timer->start(3000);
//将扫描串口这个槽函数和定时器结合
Com_Timer = new QTimer(this);
connect(Com_Timer, SIGNAL(timeout()), this, SLOT(ShowComNumber()));
Com_Timer->start(1000);
//初始化串口状态为关闭
mIsOpen = false;
//实例化串口
//这里我忘了在头文件里面已经实例化过一次了
QSerialPort serial;
//遍历所有可用串口号,本站有许多方法,具体原理可以看QT的文档
foreach(const QSerialPortInfo &serialPortInfo ,QSerialPortInfo::availablePorts())
//遍历之后把串口号加入到这个list
//然后加入到SerialPortBox这个控件中
portStringList += serialPortInfo.portName();
ui->SerialPortBox->addItems(portStringList);
2、配置串口
bool Dialog::getSerialPortConfig(void)
{
//配置串口号
mportName = ui->SerialPortBox->currentText();
mSerialPort.setPortName(mportName);
//波特率直接写死 9600
mSerialPort.setBaudRate(QSerialPort::Baud9600);
//无校验位
mSerialPort.setParity(QSerialPort::NoParity);
//默认数据位8位
mSerialPort.setDataBits(QSerialPort::Data8);
//默认停止位
mSerialPort.setStopBits(QSerialPort::OneStop);
return mSerialPort.open(QSerialPort::ReadWrite);
}
3、打开串口
void Dialog::on_Serial_Button_clicked()
{
if(true == mIsOpen)
{
//串口打开后->执行关闭动作
mSerialPort.close();
ui->Serial_Button->setText("On");
ui->SerialPortBox->setEnabled(true);
ui->Send_Button->setEnabled(false);
qDebug() << "Serial Port Shutted Down"<<endl;
mIsOpen = false;
}
else
{
//当前串口没有打开串口->执行打开串口的动作
if(true == getSerialPortConfig())
{
mIsOpen = true;
qDebug() << mportName << "Serial Port Opened"<<endl;
ui->Serial_Button->setText("Off");
ui->SerialPortBox->setEnabled(false);
ui->Send_Button->setEnabled(true);
}
else
{
mIsOpen = false;
qDebug() << "Serial Port isn't Opened"<<endl;
}
}
}
4、打开txt文件并读取
5、通过串口输出出去
void Dialog::open()
{
QString Head1,Head2,End;
Head1 = "A";
Head2 = "B";
End = "C";
//定义两个帧头一个帧尾
if(true == mIsOpen)
{
//扫描输入到框里的文件
QFile file(ui->Address->toPlainText());
//没打开就在输出一个没打开不然就输出OK
if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug()<<"Can't open the file!"<<endl;
}
else
{
qDebug()<<"OK"<<endl;
}
//然后就是对文件操作,本站大把教程
while(!file.atEnd()) {
QByteArray line = file.readLine();
QString str(line);
qDebug()<< str;
qDebug()<<Head1;
//然后就通过串口输出出去就行了,格式是字符型
mSerialPort.write(Head1.toLocal8Bit());
mSerialPort.write(Head2.toLocal8Bit());
mSerialPort.write(str.toLocal8Bit());
mSerialPort.write(End.toLocal8Bit());
}
}
}
6、持续扫描新串口
这部分代码是在本站找的 代码逻辑和第一步差不多
void Dialog::ShowComNumber()
{
QStringList newPortStringList;
foreach(const QSerialPortInfo &serialPortInfo ,QSerialPortInfo::availablePorts())
newPortStringList += serialPortInfo.portName();
if(newPortStringList.size() != portStringList.size())
{
portStringList = newPortStringList;
ui->SerialPortBox->clear();
ui->SerialPortBox->addItems(portStringList);
}
if(mportName != ui->SerialPortBox->currentText()) //串口突然断开连接了
{
mportName = ui->SerialPortBox->currentText();
if("Off" == ui->Serial_Button->text())
{
on_Serial_Button_clicked();
}
}
}
"dialog.cpp"完整代码如下
#include "dialog.h"
#include "ui_dialog.h"
//打开特定串口并且实时更新串口号
//打开特定地址的txt
//发送txt里的内容
Dialog::Dialog(QWidget *parent)
: QDialog(parent)
, ui(new Ui::Dialog)
{
ui->setupUi(this);
// 设置两个定时器
Send_Timer = new QTimer(this);
Send_Timer->start(3000);
Com_Timer = new QTimer(this);
connect(Com_Timer, SIGNAL(timeout()), this, SLOT(ShowComNumber()));
Com_Timer->start(1000);
//初始化串口状态为关闭
mIsOpen = false;
QSerialPort serial;
foreach(const QSerialPortInfo &serialPortInfo ,QSerialPortInfo::availablePorts())
portStringList += serialPortInfo.portName();
ui->SerialPortBox->addItems(portStringList);
}
Dialog::~Dialog()
{
delete ui;
}
bool Dialog::getSerialPortConfig(void)
{
//配置串口号
mportName = ui->SerialPortBox->currentText();
mSerialPort.setPortName(mportName);
//波特率直接写死 9600
mSerialPort.setBaudRate(QSerialPort::Baud9600);
//无校验位
mSerialPort.setParity(QSerialPort::NoParity);
//默认数据位8位
mSerialPort.setDataBits(QSerialPort::Data8);
//默认停止位
mSerialPort.setStopBits(QSerialPort::OneStop);
return mSerialPort.open(QSerialPort::ReadWrite);
}
void Dialog::open()
{
QString Head1,Head2,End;
Head1 = "A";
Head2 = "B";
End = "C";
if(true == mIsOpen)
{
QFile file(ui->Address->toPlainText());
//QFile file("C:/Users/Normal Guy/Desktop/ABC.txt");
if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug()<<"Can't open the file!"<<endl;
}
else
{
qDebug()<<"OK"<<endl;
}
while(!file.atEnd()) {
QByteArray line = file.readLine();
QString str(line);
qDebug()<< str;
qDebug()<<Head1;
mSerialPort.write(Head1.toLocal8Bit());
mSerialPort.write(Head2.toLocal8Bit());
mSerialPort.write(str.toLocal8Bit());
mSerialPort.write(End.toLocal8Bit());
}
}
}
void Dialog::ShowComNumber()
{
QStringList newPortStringList;
foreach(const QSerialPortInfo &serialPortInfo ,QSerialPortInfo::availablePorts())
newPortStringList += serialPortInfo.portName();
if(newPortStringList.size() != portStringList.size())
{
portStringList = newPortStringList;
ui->SerialPortBox->clear();
ui->SerialPortBox->addItems(portStringList);
}
if(mportName != ui->SerialPortBox->currentText()) //串口突然断开连接了
{
mportName = ui->SerialPortBox->currentText();
if("Off" == ui->Serial_Button->text())
{
on_Serial_Button_clicked();
}
}
}
void Dialog::on_Send_Button_clicked()
{
if(true == mIsOpen)
{
connect(Send_Timer, SIGNAL(timeout()), this, SLOT(open()));
}
else
{
qDebug() << "Serial Port hasn't opened"<<endl;
}
}
void Dialog::on_Serial_Button_clicked()
{
if(true == mIsOpen)
{
//串口打开后->执行关闭动作
mSerialPort.close();
ui->Serial_Button->setText("On");
ui->SerialPortBox->setEnabled(true);
ui->Send_Button->setEnabled(false);
qDebug() << "Serial Port Shutted Down"<<endl;
mIsOpen = false;
}
else
{
//当前串口没有打开串口->执行打开串口的动作
if(true == getSerialPortConfig())
{
mIsOpen = true;
qDebug() << mportName << "Serial Port Opened"<<endl;
ui->Serial_Button->setText("Off");
ui->SerialPortBox->setEnabled(false);
ui->Send_Button->setEnabled(true);
}
else
{
mIsOpen = false;
qDebug() << "Serial Port isn't Opened"<<endl;
}
}
}
具体UI和控件名字