QT5串口编程
Posted 宁静致远2021
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QT5串口编程相关的知识,希望对你有一定的参考价值。
这里使用了QSerialPort模块提供的两个类:QSerialPort类和QSerialPortInfo类,QSerialPort类提供了对串口的操作,QSerialPortInfo类提供了对串口信息的获取。下面是主要代码,包含了对串口类的简单使用。
1 添加库,添加类
首先,一定要在.pro文件中添加:QT += serialport
首先,QT5是自带QSerialPort这个类的,使用时需要在pro文件里面添加一行:
QT += serialport
然后直接引用头文件就可以了。
#include <QSerialPort> //提供访问串口的功能
#include <QSerialPortInfo> //提供系统中存在的串口的信息
在QT5中,串口通信是借助一个QSerialPort的对象来实现的,在设置QSerialPort对象对串口的名称、波特率、数据位、校验位、停止位等参数后,方能对串口进行读写。下面,总结了一下借助QSerailPort对串口进行设置、打开、读、写和关闭的过程。
2 设置和打开串口
串口初始化如下:
/****************************串口初始化*****************************/
void MainWindow::initPort()
//读取串口信息
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
qDebug()<<"Name:"<<info.portName();
qDebug()<<"Description:"<<info.description();
qDebug()<<"Manufacturer:"<<info.manufacturer();
//这里相当于自动识别串口号之后添加到了cmb,如果要手动选择可以用下面列表的方式添加进去
QSerialPort serial;
serial.setPort(info);
if(serial.open(QIODevice::ReadWrite))
//将串口号添加到cmb
ui->cmbPortName->addItem(info.portName());
//关闭串口等待人为(打开串口按钮)打开
serial.close();
QStringList baudList;//波特率
QStringList parityList;//校验位
QStringList dataBitsList;//数据位
QStringList stopBitsList;//停止位
baudList<<"50"<<"75"<<"100"<<"134"<<"150"<<"200"<<"300"
<<"600"<<"1200"<<"1800"<<"2400"<<"4800"<<"9600"
<<"14400"<<"19200"<<"38400"<<"56000"<<"57600"
<<"76800"<<"115200"<<"128000"<<"256000";
ui->cmbBaudRate->addItems(baudList);
ui->cmbBaudRate->setCurrentIndex(12);
parityList<<"无"<<"奇"<<"偶";
parityList<<"标志";
parityList<<"空格";
ui->cmbParity->addItems(parityList);
ui->cmbParity->setCurrentIndex(0);
dataBitsList<<"5"<<"6"<<"7"<<"8";
ui->cmbDataBits->addItems(dataBitsList);
ui->cmbDataBits->setCurrentIndex(3);
stopBitsList<<"1";
stopBitsList<<"1.5";
stopBitsList<<"2";
ui->cmbStopBits->addItems(stopBitsList);
ui->cmbStopBits->setCurrentIndex(0);
//设置按钮可以被按下
ui->btnOpen->setCheckable(true);
这里通过遍历所有串口将我们需要使用的串口添加到了combox中,如果想要手动选择可以将串口名称通过列表的方式添加到combox中,到使用的时候再选择 。
串口设置如下:
/****************************串口设置******************************/
void MainWindow::on_btnOpen_clicked()
if(ui->btnOpen->text() == "打开串口")
my_serialport = new QSerialPort(this);
//设置串口号
my_serialport->setPortName(ui->cmbPortName->currentText());
//以读写方式打开串口
if(my_serialport->open(QIODevice::ReadWrite))
//设置波特率
my_serialport->setBaudRate(ui->cmbBaudRate->currentText().toInt());
//设置数据位
my_serialport->setDataBits(QSerialPort::Data8);
//设置校验位
my_serialport->setParity(QSerialPort::NoParity);
//设置流控制
my_serialport->setFlowControl(QSerialPort::NoFlowControl);
//设置停止位
my_serialport->setStopBits(QSerialPort::OneStop);
//每秒读一次
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(readComDataSlot()));
timer->start(1000);
setNonSelectable();
else
QMessageBox::about(NULL, "提示", "串口没有打开!");
return;
else
timer->stop();
setSelectable();
my_serialport->close();
#include "widget.h"
#include "ui_widget.h"
#include <QLayout>
#include <QDebug>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
ui->setupUi(this);
m_serialPort = new QSerialPort();
initUI();
m_portNameList = getPortNameList();
m_PortNameComboBox->addItems(m_portNameList);
connect(m_OpenPortButton,&QPushButton::clicked,this,&Widget::openPort);
Widget::~Widget()
if (m_serialPort->isOpen())
m_serialPort->close();
delete m_serialPort;
delete ui;
void Widget::initUI()
this->setWindowTitle("码农小明 test QSerialPort");
m_OpenPortButton = new QPushButton();
m_OpenPortButton->setText("打开串口");
m_PortNameComboBox = new QComboBox();
QHBoxLayout *m_layout = new QHBoxLayout();
m_layout->addWidget(m_PortNameComboBox);
m_layout->addWidget(m_OpenPortButton);
this->setLayout(m_layout);
QStringList Widget::getPortNameList()
QStringList m_serialPortName;
foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
m_serialPortName << info.portName();
qDebug()<<"serialPortName:"<<info.portName();
return m_serialPortName;
void Widget::openPort()
if(m_serialPort->isOpen())//如果串口已经打开了 先给他关闭了
m_serialPort->clear();
m_serialPort->close();
m_serialPort->setPortName(m_PortNameComboBox->currentText());//当前选择的串口名字
if(!m_serialPort->open(QIODevice::ReadWrite))//用ReadWrite 的模式尝试打开串口
qDebug()<<"打开失败!";
return;
qDebug()<<"串口打开成功!";
m_serialPort->setBaudRate(QSerialPort::Baud115200,QSerialPort::AllDirections);//设置波特率和读写方向
m_serialPort->setDataBits(QSerialPort::Data8); //数据位为8位
m_serialPort->setFlowControl(QSerialPort::NoFlowControl);//无流控制
m_serialPort->setParity(QSerialPort::NoParity); //无校验位
m_serialPort->setStopBits(QSerialPort::OneStop); //一位停止位
connect(m_serialPort,SIGNAL(readyRead()),this,SLOT(receiveInfo()));
//接收到单片机发送的数据进行解析
void Widget::receiveInfo()
QByteArray info = m_serialPort->readAll();
qDebug()<<"receive info:"<<info;
3 读取数据
//从接收缓冲区中读取数据
QByteArray buffer = serial.readAll();
串口在收到数据后,会将数据存入接收缓冲区。此时,我们可以通过readAll()函数将接收缓冲区的数据读出来。当串口的接收缓冲区有数据时,QSerilaPort对象会发出一个readyRead()的信号。因此,我们可以编写一个槽函数来读数据,例如:
//连接信号和槽
QObject::connect(&serial, &QSerialPort::readyRead, this, &MainWindow::serialPort_readyRead);
//……
//编写的槽函数
void MainWindow::serialPort_readyRead()
//从接收缓冲区中读取数据
QByteArray buffer = serial.readAll();
//处理数据
//……
这里是对串口的设置,需要先打开串口才能设置串口参数。参数设置好之后就可以通过read()和write()函数进行数据的读写,我这里用的是1秒的定时器来读缓冲区的数据。
数据收发如下:
/****************************数据传输******************************/
void MainWindow::readComDataSlot()
//读取串口数据
QByteArray readComData = my_serialport->readAll();
//将读到的数据显示到数据接收区的te中
if(readComData != NULL)
ui->teReceiveData->append(readComData);
//清除缓冲区
readComData.clear();
void MainWindow::on_btnSend_clicked()
//获取发送区的数据
QString sendData = ui->teSendData->toPlainText();
QByteArray sendData_2 = sendData.toLatin1();
//写入缓冲区
my_serialport->write(sendData_2);
4 发送数据
serial->write(data);
使用write函数便可以把字节数组中的字节发送出去。
//串口接收
void MainWindow::serialPort_readyRead()
//从接收缓冲区中读取数据
QByteArray buffer = serial.readAll();
//从界面中读取以前收到的数据
QString recv = ui->textEdit->toPlainText();
recv += QString(buffer);
//清空以前的显示
ui->textEdit->clear();
//重新显示
ui->textEdit->append(recv);
5 关闭串口
serial->close();
以上是关于QT5串口编程的主要内容,如果未能解决你的问题,请参考以下文章