要实现串口通信,需要知道串口通信需要的信息
主要参数有:波特率、校验位、数据位、停止位、控制流
主要操作有:串口的打开和关闭、刷新设备串口、接发数据、开关显示灯等。
实现效果如图:
界面设计如下:
每个控件类名如下:
led灯是qlable控件,设置它的长宽都是24px,然后鼠标右击,选择“样式表”,在样式表中添加代码。
附赠完整源码
第一步:在头文件中引入 qtserialport 类的两个头文件(必须引入)
// 引入串口通信的两个头文件(第一步)#include // 提供访问串口的功能#include // 提供系统中存在的串口信第二步:在工程文件中添加以下代码
# 引入串口工程类型(第二步)qt += serialport第三步:在头文件中定义全局的串口对象
qserialport *serial; // 定义全局的串口对象(第三步第四步:参数设置,在头文件中定义初始化参数的函数和参数变量名,在.cpp文件中实现函数
public:void serialportinit(); // 串口初始化(参数配置)private:// 参数配置 qstringlist baudlist; //波特率 qstringlist paritylist; //校验位 qstringlist databitslist; //数据位 qstringlist stopbitslist; //停止位 qstringlist flowcontrollist; //控制流// 串口初始化(参数配置)void mainwindow::serialportinit(){ serial = new qserialport; //申请内存,并设置父对象 // 获取计算机中有效的端口号,然后将端口号的名称给端口选择控件 foreach(const qserialportinfo &info,qserialportinfo::availableports()) { serial->setport(info); // 在对象中设置串口 if(serial->open(qiodevice::readwrite)) // 以读写方式打开串口 { ui->portbox->additem(info.portname()); // 添加计算机中的端口 serial->close(); // 关闭 } else { qdebug()
additem(57600); serial->setbaudrate(qserialport::baud57600); ui->baudbox->setdisabled(true); // 校验,校验默认选择无 ui->paritybox->additem(无); serial->setparity(qserialport::noparity); // 数据位,数据位默认选择8位 ui->bitbox->additem(8); serial->setdatabits(qserialport::data8); // 停止位,停止位默认选择1位 ui->stopbox->additem(1); serial->setstopbits(qserialport::onestop); // 控制流,默认选择无 ui->controlbox->additem(无); serial->setflowcontrol(qserialport::noflowcontrol); // 刷新串口 refreshserialport(0); // 信号connect(serial,&qserialport::readyread,this,&mainwindow::datareceived); // 接收数据connect(ui->sendwordorder,&qpushbutton::clicked,this,&mainwindow::datasend); // 发送数据connect(ui->sendbutton,&qpushbutton::clicked,this,&mainwindow::datasend); // 发送数据connect(ui->sendeditbtn1,&qpushbutton::clicked,this,&mainwindow::datasend); // 发送数据connect(ui->sendeditbtn2,&qpushbutton::clicked,this,&mainwindow::datasend); // 发送数据connect(ui->sendeditbtn3,&qpushbutton::clicked,this,&mainwindow::datasend); // 发送数据}第五步:刷新串口,及时更新可用的串口
// 刷新串口void mainwindow::refreshserialport(int index){ qstringlist portnamelist; // 存储所有串口名 if(index != 0) { serial->setportname(ui->portbox->currenttext()); //设置串口号 } else { ui->portbox->clear(); //关闭串口号 ui->portbox->additem(刷新); //添加刷新 foreach(const qserialportinfo &info,qserialportinfo::availableports()) //添加新串口 { portnamelist.append(info.portname()); } ui->portbox->additems(portnamelist); ui->portbox->setcurrentindex(1); // 当前串口号为com1 serial->setportname(ui->portbox->currenttext()); //设置串口号 }}第六步:发送数据和接收数据
// 接收数据,使用read () / readline () / readall ()void mainwindow::datareceived(){ char buf[512] = {0}; // 存储转换类型后的数据 qbytearray data = serial->readall(); // 读取数据 if(!data.isempty()) // 接收到数据 { qstring str = ui->datareceived->toplaintext(); // 返回纯文本 str += tr(data); // 数据是一行一行传送的,要保存所有数据 ui->datareceived->clear(); // 清空之前的数据 ui->datareceived->append(str); // 将数据放入控件中 qdebug() << str info: toplaintext(); // 清除之前的数据,防止追加,因为每次获取的数据不一样 int index = str.indexof(\\r\\n); // 找到,返回索引值,找不到,返回-1 if(index != -1) { snprintf(buf,500,%s, str.left(index + 2).toutf8().data()); // qstring转为char * 类型 qdebug() << buf info: datasend->toplaintext().tolatin1()); // 串口发送数据}第七步:打开串口和关闭串口,当打开串口后,显示绿灯;关闭串口后,显示红灯
// 串口开关void mainwindow::on_openserialbutton_clicked(){ if(serial->isopen()) // 如果串口打开了,先给他关闭 { serial->clear(); serial->close(); // 关闭状态,按钮显示“打开串口” ui->openserialbutton->settext(打开串口); // 关闭状态,允许用户操作 ui->baudbox->setdisabled(false); ui->paritybox->setdisabled(false); ui->bitbox->setdisabled(false); ui->stopbox->setdisabled(false); ui->controlbox->setdisabled(false); // 禁止操作“发送字符操作” ui->sendwordorder->setdisabled(true); ui->sendbutton->setdisabled(true); // 关闭状态,颜色为绿色 ui->openserialbutton->setstylesheet(color: green;); // 关闭,显示灯为红色 led(true); // 清空数据 ui->datareceived->clear(); ui->datasend->clear(); } else // 如果串口关闭了,先给他打开 { //当前选择的串口名字 serial->setportname(ui->portbox->currenttext()); //用readwrite 的模式尝试打开串口,无法收发数据时,发出警告 if(!serial->open(qiodevice::readwrite)) { qmessagebox::warning(this,tr(提示),tr(串口打开失败!),qmessagebox::ok); return; } // 打开状态,按钮显示“关闭串口” ui->openserialbutton->settext(关闭串口); // 打开状态,禁止用户操作 ui->baudbox->setdisabled(true); ui->paritybox->setdisabled(true); ui->bitbox->setdisabled(true); ui->stopbox->setdisabled(true); ui->controlbox->setdisabled(true); // 允许操作“发送字符操作” ui->sendwordorder->setdisabled(false); ui->sendbutton->setdisabled(false); // 打开状态,颜色为红色 ui->openserialbutton->setstylesheet(color: red;); // 打开,显示灯为绿色 led(false); }}// 开关显示灯void mainwindow::led(bool changecolor){ if(changecolor == false) { // 显示绿色 ui->led->setstylesheet(background-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgba(0, 229, 0, 255), stop:1 rgba(255, 255, 255, 255));border-radius:12px;); } else { // 显示红色 ui->led->setstylesheet(background-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgba(255, 0, 0, 255), stop:1 rgba(255, 255, 255, 255));border-radius:12px;); }}第八步:相关槽函数
// 控件中添加 指令“###”void mainwindow::on_sendbutton_clicked(){ on_clearbutton_clicked(); ui->datasend->append(###);}// 清空控件void mainwindow::on_clearbutton_clicked(){ ui->datasend->settext();}// 清空接收到的数据void mainwindow::on_clearshowbutton_clicked(){ ui->datareceived->settext();}// 点击发送后,获取串口信息并展示在接受控件中void mainwindow::on_sendeditbtn1_clicked(){ on_clearbutton_clicked(); qstring edittext = ui->edit1->text(); //获取发送框内容 ui->datasend->settext(edittext); //将文本内容放在发送栏中}void mainwindow::on_sendeditbtn2_clicked(){ on_clearbutton_clicked(); qstring edittext = ui->edit2->text(); //获取发送框内容 // qdebug() << edit1 text: append(edittext); //将文本内容放在发送栏中}void mainwindow::on_sendeditbtn3_clicked(){ on_clearbutton_clicked(); qstring edittext = ui->edit3->text(); //获取发送框内容 // qdebug() << edit1 text: append(edittext); //将文本内容放在发送栏中}void mainwindow::on_sendwordorder_clicked(){ on_sendbutton_clicked();}源码:
工程文件.pro文件源码:
qt += core gui# 引入串口工程类型(第二步)qt += serialportgreaterthan(qt_major_version, 4): qt += widgetsconfig += c++11# the following define makes your compiler emit warnings if you use# any qt feature that has been marked deprecated (the exact warnings# depend on your compiler). please consult the documentation of the# deprecated api in order to know how to port your code away from it.defines += qt_deprecated_warnings# you can also make your code fail to compile if it uses deprecated apis.# in order to do so, uncomment the following line.# you can also select to disable deprecated apis only up to a certain version of qt.#defines += qt_disable_deprecated_before=0x060000 # disables all the apis deprecated before qt 6.0.0sources += \\ main.cpp \\ mainwindow.cppheaders += \\ mainwindow.hforms += \\ mainwindow.ui# default rules for deployment.qnx: target.path = /tmp/$${target}/binelse: unix:!android: target.path = /opt/$${target}/bin!isempty(target.path): installs += target头文件源码:
#ifndef mainwindow_h#define mainwindow_h#include // 引入串口通信的两个头文件(第一步)#include // 提供访问串口的功能#include // 提供系统中存在的串口信息qt_begin_namespacenamespace ui { class mainwindow; }qt_end_namespaceclass mainwindow : public qmainwindow{ q_objectpublic: mainwindow(qwidget *parent = nullptr); ~mainwindow(); // 串口功能 void serialportinit(); // 串口初始化(参数配置) void refreshserialport(int index); // 刷新串口public slots: // 串口槽函数 void datareceived(); // 接收数据private slots: // 串口槽函数 void datasend(); // 发送数据 void on_openserialbutton_clicked(); // 串口开关 void on_sendbutton_clicked(); // 控件中添加 # void on_clearbutton_clicked(); // 清空控件中的所有 # void on_clearshowbutton_clicked(); // 清空接收到的数据 void led(bool changecolor); // 开关显示灯 // 点击发送,接收数据 void on_sendeditbtn1_clicked(); void on_sendeditbtn2_clicked(); void on_sendeditbtn3_clicked(); void on_sendwordorder_clicked();private: ui::mainwindow *ui; // 串口变量 qserialport *serial; // 定义全局的串口对象(第三步) // 参数配置 qstringlist baudlist; //波特率 qstringlist paritylist; //校验位 qstringlist databitslist; //数据位 qstringlist stopbitslist; //停止位 qstringlist flowcontrollist; //控制流};#endif // mainwindow_h.cpp文件源码:
#include mainwindow.h#include ui_mainwindow.h#include #include mainwindow::mainwindow(qwidget *parent) : qmainwindow(parent) , ui(new ui::mainwindow){ ui->setupui(this); serialportinit();}// 串口初始化(参数配置)void mainwindow::serialportinit(){ serial = new qserialport; //申请内存,并设置父对象 // 获取计算机中有效的端口号,然后将端口号的名称给端口选择控件 foreach(const qserialportinfo &info,qserialportinfo::availableports()) { serial->setport(info); // 在对象中设置串口 if(serial->open(qiodevice::readwrite)) // 以读写方式打开串口 { ui->portbox->additem(info.portname()); // 添加计算机中的端口 serial->close(); // 关闭 } else { qdebug() additem(57600); serial->setbaudrate(qserialport::baud57600); ui->baudbox->setdisabled(true); // 校验,校验默认选择无 ui->paritybox->additem(无); serial->setparity(qserialport::noparity); // 数据位,数据位默认选择8位 ui->bitbox->additem(8); serial->setdatabits(qserialport::data8); // 停止位,停止位默认选择1位 ui->stopbox->additem(1); serial->setstopbits(qserialport::onestop); // 控制流,默认选择无 ui->controlbox->additem(无); serial->setflowcontrol(qserialport::noflowcontrol); // 刷新串口 refreshserialport(0); // 信号 connect(serial,&qserialport::readyread,this,&mainwindow::datareceived); // 接收数据 connect(ui->sendwordorder,&qpushbutton::clicked,this,&mainwindow::datasend); // 发送数据 connect(ui->sendbutton,&qpushbutton::clicked,this,&mainwindow::datasend); // 发送数据 connect(ui->sendeditbtn1,&qpushbutton::clicked,this,&mainwindow::datasend); // 发送数据 connect(ui->sendeditbtn2,&qpushbutton::clicked,this,&mainwindow::datasend); // 发送数据 connect(ui->sendeditbtn3,&qpushbutton::clicked,this,&mainwindow::datasend); // 发送数据}// 刷新串口void mainwindow::refreshserialport(int index){ qstringlist portnamelist; // 存储所有串口名 if(index != 0) { serial->setportname(ui->portbox->currenttext()); //设置串口号 } else { ui->portbox->clear(); //关闭串口号 ui->portbox->additem(刷新); //添加刷新 foreach(const qserialportinfo &info,qserialportinfo::availableports()) //添加新串口 { portnamelist.append(info.portname()); } ui->portbox->additems(portnamelist); ui->portbox->setcurrentindex(1); // 当前串口号为com1 serial->setportname(ui->portbox->currenttext()); //设置串口号 }}// 接收数据,使用read () / readline () / readall ()void mainwindow::datareceived(){ char buf[512] = {0}; // 存储转换类型后的数据 qbytearray data = serial->readall(); // 读取数据 if(!data.isempty()) // 接收到数据 { qstring str = ui->datareceived->toplaintext(); // 返回纯文本 str += tr(data); // 数据是一行一行传送的,要保存所有数据 ui->datareceived->clear(); // 清空之前的数据 ui->datareceived->append(str); // 将数据放入控件中 qdebug() << str info: toplaintext(); // 清除之前的数据,防止追加,因为每次获取的数据不一样 int index = str.indexof(\\r\\n); // 找到,返回索引值,找不到,返回-1 if(index != -1) { snprintf(buf,500,%s, str.left(index + 2).toutf8().data()); // qstring转为char * 类型 qdebug() << buf info: datasend->toplaintext().tolatin1()); // 串口发送数据}// 开关显示灯void mainwindow::led(bool changecolor){ if(changecolor == false) { // 显示绿色 ui->led->setstylesheet(background-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgba(0, 229, 0, 255), stop:1 rgba(255, 255, 255, 255));border-radius:12px;); } else { // 显示红色 ui->led->setstylesheet(background-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgba(255, 0, 0, 255), stop:1 rgba(255, 255, 255, 255));border-radius:12px;); }}mainwindow::~mainwindow(){ delete ui;}// 串口开关void mainwindow::on_openserialbutton_clicked(){ if(serial->isopen()) // 如果串口打开了,先给他关闭 { serial->clear(); serial->close(); // 关闭状态,按钮显示“打开串口” ui->openserialbutton->settext(打开串口); // 关闭状态,允许用户操作 ui->baudbox->setdisabled(false); ui->paritybox->setdisabled(false); ui->bitbox->setdisabled(false); ui->stopbox->setdisabled(false); ui->controlbox->setdisabled(false); // 禁止操作“发送字符操作” ui->sendwordorder->setdisabled(true); ui->sendbutton->setdisabled(true); // 关闭状态,颜色为绿色 ui->openserialbutton->setstylesheet(color: green;); // 关闭,显示灯为红色 led(true); // 清空数据 ui->datareceived->clear(); ui->datasend->clear(); } else // 如果串口关闭了,先给他打开 { //当前选择的串口名字 serial->setportname(ui->portbox->currenttext()); //用readwrite 的模式尝试打开串口,无法收发数据时,发出警告 if(!serial->open(qiodevice::readwrite)) { qmessagebox::warning(this,tr(提示),tr(串口打开失败!),qmessagebox::ok); return; } // 打开状态,按钮显示“关闭串口” ui->openserialbutton->settext(关闭串口); // 打开状态,禁止用户操作 ui->baudbox->setdisabled(true); ui->paritybox->setdisabled(true); ui->bitbox->setdisabled(true); ui->stopbox->setdisabled(true); ui->controlbox->setdisabled(true); // 允许操作“发送字符操作” ui->sendwordorder->setdisabled(false); ui->sendbutton->setdisabled(false); // 打开状态,颜色为红色 ui->openserialbutton->setstylesheet(color: red;); // 打开,显示灯为绿色 led(false); }}// 控件中添加 #void mainwindow::on_sendbutton_clicked(){ on_clearbutton_clicked(); ui->datasend->append(###);}// 清空控件void mainwindow::on_clearbutton_clicked(){ ui->datasend->settext();}// 清空接收到的数据void mainwindow::on_clearshowbutton_clicked(){ ui->datareceived->settext();}// 点击发送后,获取串口信息并展示在接受控件中void mainwindow::on_sendeditbtn1_clicked(){ on_clearbutton_clicked(); qstring edittext = ui->edit1->text(); //获取发送框内容 ui->datasend->settext(edittext); //将文本内容放在发送栏中}void mainwindow::on_sendeditbtn2_clicked(){ on_clearbutton_clicked(); qstring edittext = ui->edit2->text(); //获取发送框内容 // qdebug() << edit1 text: append(edittext); //将文本内容放在发送栏中}void mainwindow::on_sendeditbtn3_clicked(){ on_clearbutton_clicked(); qstring edittext = ui->edit3->text(); //获取发送框内容 // qdebug() << edit1 text: append(edittext); //将文本内容放在发送栏中}void mainwindow::on_sendwordorder_clicked(){ on_sendbutton_clicked();}运行后效果:
Android工程师的面试经验分享
Mini LED个股受市场资金青睐
SIMV熔喷无纺布瑕疵检测系统的检测原理说明
vivo将研发最新无线充电技术
基于工业智能网关的汽车充电桩安全监测方案
Qt实现串口通信
小电动机的两个近似公式
在区块链成为基础建设前需要解决什么痛点
全国“携号转网”已近千万人!
智能家居行业四大硬伤发展瓶颈显露?
未来公司获无人驾驶工业车辆ISO 3691-4认证
红米K30S 最大的不足
三星S8国行版手机报价:只售5688元,比iphone7便宜
东芝电子携多款功率器件产品参加PCIM 2014
变压器铁心片剪切误差的产生及消除办法
半导体产业掀起整并风潮,全球前五大半导体供货商的销售额市占率总和
关于无人驾驶技术的简单解析
高速pcb中的过孔设计原则
腾讯人工智能实验室AI Lab主任张潼已经从腾讯离职,或将重返学术界
拒绝视觉漏拍、误拍,“手机玻璃下料”so easy!