串口调试助手--Qt
程序员文章站
2022-12-21 10:26:59
串口调试助手 该程序使用Qt框架,C ++语言编译而成 项目文件介绍: 该文件中获取串口是通过读取Windows系统下的注册表中的信息得到的, - 使用Qt中的定时器来每个3s读取一次注册表 串口通信方面:通过使用Qt的封装的QSerialPort来实现 main.cpp mainwindow.h ......
串口调试助手----------该程序使用qt框架,c ++语言编译而成
项目文件介绍:
main.cpp 该文件为该程序的入口程序 mainwindow.h 该文件为该程序的主要声明部分 mainwindow.cpp 该文件为该程序的主要定义部分 mainwindow.ui 该文件为该程序的ui界面设计 界面.png 界面的显示效果
该文件中获取串口是通过读取windows系统下的注册表中的信息得到的, - 使用qt中的定时器来每个3s读取一次注册表
串口通信方面:通过使用qt的封装的qserialport来实现
main.cpp
#include "mainwindow.h" #include <qapplication> int main(int argc, char *argv[]) { qapplication a(argc, argv); mainwindow w; w.show(); return a.exec(); }
mainwindow.h
#ifndef mainwindow_h #define mainwindow_h #include <qmainwindow> #include <qserialport> #include <qtimer> namespace ui { class mainwindow; } class mainwindow : public qmainwindow { q_object public: explicit mainwindow(qwidget *parent = nullptr); ~mainwindow(); /* * 功能:获取电脑中串口的端口 * 参数:无 * 返回值:无 */ void get_serial_port(void); /* * 功能:当串口有数据的时候执行 * 参数:无 * 返回值:无 */ void readdata(void); /* * 功能:每个3s执行的任务 * 参数:无 * 返回值:无 */ void mythread(void); private slots: /* * 功能:点击pushbutton按钮功能 * 参数:无 * 返回值:无 */ void on_pushbutton_clicked(); /* * 功能:点击清空按钮功能,清空显示区的显示 * 参数:无 * 返回值:无 */ void on_pushbutton_2_clicked(); void on_pushbutton_3_clicked(); void on_pushbutton_4_clicked(); void on_pushbutton_5_clicked(); private: ui::mainwindow *ui; //串口类指针 qserialport *serial; //时间类指针 qtimer *time; }; #endif // mainwindow_h
mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" #include "windows.h" #include "qvector" #include "qdebug" #include "stdio.h" #include "qmessagebox" #include <stdlib.h> #define max_key_length 255 #define max_value_name 16383 /* * 功能:读取注册表下的子项 * 参数:hkey:注册表的根 * lpsubkey:注册表根下的路径 * retarray:返回要查找的路径下的值的数组 * 返回值:无 */ static void get_regedit(hkey hkey,lpcstr lpsubkey,qvector<qstring> &retarray); mainwindow::mainwindow(qwidget *parent) : qmainwindow(parent), ui(new ui::mainwindow) { ui->setupui(this); //时间类初始化 time = new qtimer(this); connect(time,&qtimer::timeout,this,&mainwindow::mythread); time->start(3000); //状态栏显示 ui->statusbar->showmessage("程序运行中..."); //初始化串口的显示 this->get_serial_port(); qstringlist temp; //波特率的显示 temp << "9600" << "4800" << "19200" << "38400" << "57600" << "115200"; ui->combobox_2->additems(temp); //数据位的显示 temp.clear(); temp << "8" << "5" << "6" << "7"; ui->combobox_3->additems(temp); //奇偶检验位的显示 temp.clear(); temp << "0" << "1" << "2"; ui->combobox_4->additems(temp); //停止位的显示 temp.clear(); temp << "1" << "1.5" << "2"; ui->combobox_5->additems(temp); this->serial = new qserialport(nullptr); } mainwindow::~mainwindow() { delete ui; } /* * 功能:获取电脑中串口的端口 * 参数:无 * 返回值:无 */ void mainwindow::get_serial_port() { qvector<qstring> retarray; ui->combobox->clear(); get_regedit(hkey_local_machine,\ "hardware\\devicemap\\serialcomm",\ retarray); qdebug() << retarray.size(); qvector<qstring>::iterator iter; for (iter=retarray.begin();iter!=retarray.end();iter++) { qdebug() << *iter << "\0"; ui->combobox->additem(*iter); } } /* * 功能:点击pushbutton按钮功能,打开串口 * 参数:无 * 返回值:无 */ void mainwindow::on_pushbutton_clicked() { if(!serial->isopen()) { qdebug() << ui->combobox->currenttext(); //设置串口的端口名称 serial->setportname(ui->combobox->currenttext()); //toint:将字符串转换为数字 //设置串口的波特率 serial->setbaudrate((ui->combobox_2->currenttext()).toint(nullptr,10)); //设置串口的数据位 serial->setdatabits((qserialport::databits((ui->combobox_3->currenttext()).toint(nullptr,10)))); //设置串口的奇偶校验位 serial->setparity(qserialport::parity((ui->combobox_4->currenttext()).toint(nullptr,10))); //设置串口的停止位 serial->setstopbits(qserialport::stopbits((ui->combobox_5->currenttext()).toint(nullptr,10))); //设置串口的流 serial->setflowcontrol(qserialport::noflowcontrol); bool isserial = serial->open(qiodevice::readwrite); if(!isserial) { qdebug() << "串口打开错误!"; return; } //创建一个信号与槽,使得串口有数据可以读取的时候可以执行readdata()函数 connect(serial,&qserialport::readyread,this,&mainwindow::readdata); ui->pushbutton->settext("已启动"); } else { ui->pushbutton->settext("启动"); serial->close(); } } /* * 功能:读取注册表下的子项 * 参数:hkey:注册表的根 * lpsubkey:注册表根下的路径 * retarray:返回要查找的路径下的值的数组 * 返回值:无 */ static void get_regedit(hkey hkey,lpcstr lpsubkey,qvector<qstring> &retarray) { hkey phkey = nullptr; bool issuccess = false; /* * 功能:打开注册表,返回值为是否打开成功 */ issuccess = regopenkeya(hkey,lpsubkey,&phkey); if(issuccess != error_success) { qdebug() << "注册表打开失败!"; return; } qdebug() << "注册表打开成功!"; /* * 功能:读取注册表下的子项 */ dword i =0; lstatus retcode = error_success; char achvalue[max_value_name]; dword cchvalue = max_value_name; byte data[max_value_name]; dword cbdata = max_value_name; do { cchvalue = max_value_name; cbdata = max_value_name; achvalue[0] = '\0'; data[0] = '\0'; qstring temp = ""; retcode = regenumvaluea(phkey, i,achvalue,&cchvalue,nullptr,nullptr,data,&cbdata); if (retcode == error_success && achvalue[0] != '\0') { qdebug() << i++ << achvalue << " "; byte j = 0; while(data[j] != '\0') temp += (char)(data[j++]); qdebug() << temp; retarray.append(temp); } }while(achvalue[0] != '\0'); /* * 功能:关闭注册表,返回值为是否打开成功 */ issuccess = regclosekey(phkey); if(issuccess != error_success) { qdebug() << "注册表关闭失败!"; return; } qdebug() << "注册表关闭成功!"; return; } /* * 功能:点击清空按钮功能,清空显示区的显示 * 参数:无 * 返回值:无 */ void mainwindow::on_pushbutton_2_clicked() { ui->textbrowser->settext(""); } /* * 功能:当串口有数据的时候执行,在显示区域显示 * 串口接受到的值 * 参数:无 * 返回值:无 */ void mainwindow::readdata(void) { //是否选择了该按钮,选择以16进制进行输出 if(ui->radiobutton->ischecked()) { qbytearray temp = serial->readall().tohex(); for(int i = 0;i < temp.length();++i) { //在16进制开始加入"0x" if(i % 2 == 0) ui->textbrowser->insertplaintext("0x"); ui->textbrowser->insertplaintext((qstring)temp.at(i)); //在16进制结束加上空格" " if(i % 2 == 1) ui->textbrowser->insertplaintext(" "); } } //没有选择则按照ascii码输出 else ui->textbrowser->insertplaintext(serial->readall()); ui->textbrowser->movecursor(qtextcursor::end); } /* * 功能:向串口中发送数据 * 参数:无 * 返回值:无 */ void mainwindow::on_pushbutton_3_clicked() { //判断串口是否处于打开状态 if(serial->isopen()) { qbytearray temp = ui->textedit->toplaintext().toutf8(); qdebug() << temp; serial->write(temp); } else { //串口没有连接的时候发送数据就会出错 qmessagebox messagebox(qmessagebox::icon(2),"警告","串口未连接",qmessagebox::yes,nullptr); messagebox.exec(); } } /* * 功能:清空发送区 * 参数:无 * 返回值:无 */ void mainwindow::on_pushbutton_4_clicked() { ui->textedit->clear(); } /* * 功能:退出程序 * 参数:无 * 返回值:无 */ void mainwindow::on_pushbutton_5_clicked() { if(serial->isopen()) serial->close(); this->close(); } /* * 功能:每个3s执行的任务,判断端口和串口是否打开 * 参数:无 * 返回值:无 */ void mainwindow::mythread() { qdebug() << "线程ok "; if(serial->isreadable()) ui->pushbutton->settext("已启动"); else ui->pushbutton->settext("启动"); this->get_serial_port(); }
mainwindow.ui
<?xml version="1.0" encoding="utf-8"?> <ui version="4.0"> <class>mainwindow</class> <widget class="qmainwindow" name="mainwindow"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>768</width> <height>500</height> </rect> </property> <property name="minimumsize"> <size> <width>768</width> <height>500</height> </size> </property> <property name="maximumsize"> <size> <width>768</width> <height>500</height> </size> </property> <property name="windowtitle"> <string>串口助手</string> </property> <widget class="qwidget" name="centralwidget"> <widget class="qpushbutton" name="pushbutton"> <property name="geometry"> <rect> <x>20</x> <y>230</y> <width>93</width> <height>28</height> </rect> </property> <property name="text"> <string>启动</string> </property> </widget> <widget class="qpushbutton" name="pushbutton_2"> <property name="geometry"> <rect> <x>120</x> <y>290</y> <width>93</width> <height>28</height> </rect> </property> <property name="text"> <string>清空显示</string> </property> </widget> <widget class="qcombobox" name="combobox"> <property name="geometry"> <rect> <x>120</x> <y>50</y> <width>87</width> <height>22</height> </rect> </property> </widget> <widget class="qcombobox" name="combobox_2"> <property name="geometry"> <rect> <x>120</x> <y>80</y> <width>87</width> <height>22</height> </rect> </property> </widget> <widget class="qcombobox" name="combobox_3"> <property name="geometry"> <rect> <x>120</x> <y>110</y> <width>87</width> <height>22</height> </rect> </property> </widget> <widget class="qcombobox" name="combobox_4"> <property name="geometry"> <rect> <x>120</x> <y>140</y> <width>87</width> <height>22</height> </rect> </property> </widget> <widget class="qcombobox" name="combobox_5"> <property name="geometry"> <rect> <x>120</x> <y>170</y> <width>87</width> <height>22</height> </rect> </property> </widget> <widget class="qradiobutton" name="radiobutton"> <property name="geometry"> <rect> <x>0</x> <y>295</y> <width>115</width> <height>19</height> </rect> </property> <property name="text"> <string>以16进制输出</string> </property> </widget> <widget class="qpushbutton" name="pushbutton_3"> <property name="geometry"> <rect> <x>120</x> <y>360</y> <width>93</width> <height>28</height> </rect> </property> <property name="text"> <string>发送</string> </property> </widget> <widget class="qgroupbox" name="groupbox"> <property name="geometry"> <rect> <x>230</x> <y>4</y> <width>551</width> <height>331</height> </rect> </property> <property name="title"> <string>接受显示区</string> </property> <widget class="qtextbrowser" name="textbrowser"> <property name="geometry"> <rect> <x>10</x> <y>20</y> <width>521</width> <height>301</height> </rect> </property> </widget> </widget> <widget class="qgroupbox" name="groupbox_2"> <property name="geometry"> <rect> <x>230</x> <y>340</y> <width>541</width> <height>121</height> </rect> </property> <property name="title"> <string>发送显示区</string> </property> <widget class="qtextedit" name="textedit"> <property name="geometry"> <rect> <x>10</x> <y>20</y> <width>521</width> <height>91</height> </rect> </property> </widget> </widget> <widget class="qpushbutton" name="pushbutton_4"> <property name="geometry"> <rect> <x>120</x> <y>400</y> <width>93</width> <height>28</height> </rect> </property> <property name="text"> <string>清空发送</string> </property> </widget> <widget class="qlabel" name="label"> <property name="geometry"> <rect> <x>20</x> <y>50</y> <width>71</width> <height>21</height> </rect> </property> <property name="text"> <string>串口端口</string> </property> </widget> <widget class="qlabel" name="label_2"> <property name="geometry"> <rect> <x>20</x> <y>83</y> <width>80</width> <height>15</height> </rect> </property> <property name="text"> <string>串口波特率</string> </property> </widget> <widget class="qlabel" name="label_3"> <property name="geometry"> <rect> <x>20</x> <y>113</y> <width>80</width> <height>15</height> </rect> </property> <property name="text"> <string>串口数据位</string> </property> </widget> <widget class="qlabel" name="label_4"> <property name="geometry"> <rect> <x>20</x> <y>143</y> <width>80</width> <height>15</height> </rect> </property> <property name="text"> <string>串口校验位</string> </property> </widget> <widget class="qlabel" name="label_5"> <property name="geometry"> <rect> <x>20</x> <y>173</y> <width>80</width> <height>15</height> </rect> </property> <property name="text"> <string>串口停止位</string> </property> </widget> <widget class="qlabel" name="label_6"> <property name="geometry"> <rect> <x>25</x> <y>5</y> <width>191</width> <height>41</height> </rect> </property> <property name="font"> <font> <family>楷体</family> <pointsize>12</pointsize> </font> </property> <property name="text"> <string>欢迎使用调试助手</string> </property> </widget> <widget class="qpushbutton" name="pushbutton_5"> <property name="geometry"> <rect> <x>120</x> <y>230</y> <width>93</width> <height>28</height> </rect> </property> <property name="text"> <string>退出</string> </property> </widget> </widget> <widget class="qstatusbar" name="statusbar"/> <widget class="qmenubar" name="menubar"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>768</width> <height>26</height> </rect> </property> <widget class="qmenu" name="menu"> <property name="title"> <string>菜单</string> </property> <addaction name="separator"/> <addaction name="actiondsa"/> </widget> <widget class="qmenu" name="menu_2"> <property name="title"> <string>帮助</string> </property> </widget> <addaction name="menu"/> <addaction name="menu_2"/> </widget> <widget class="qtoolbar" name="toolbar"> <property name="windowtitle"> <string>toolbar</string> </property> <attribute name="toolbararea"> <enum>toptoolbararea</enum> </attribute> <attribute name="toolbarbreak"> <bool>false</bool> </attribute> </widget> <action name="actiondsa"> <property name="text"> <string>退出</string> </property> </action> </widget> <layoutdefault spacing="6" margin="11"/> <resources/> <connections/> </ui>
界面的实际效果为: