欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

串口调试助手--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来实现

#include "mainwindow.h"
#include <qapplication>

int main(int argc, char *argv[])
{
    qapplication a(argc, argv);
    mainwindow w;
    w.show();

    return a.exec();
}
#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
#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();
}
<?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>

界面的实际效果为:

串口调试助手--Qt