个人编写串口助手程序示例

本篇文章为记录下班之后空闲时间,断断续续,参照野火串口助手界面,个人编写的串口助手程序示例。

一、分析程序需要的功能

  1. 串口助手程序,必然需要QSerialPort类,因此需要写个自定义类,来处理对QSerialPort的各种操作。
  2. 点击可用串口下拉框应实时更新当前可用串口,因此需要写个自定义类,继承自QCombobox,获取鼠标左键点击事件,在点击事件中更新可用串口。
  3. 我想将UI界面串口类分离开,因此需要一个自定义线程托管类,通过MoveToThread()将窗口类移到子线程中去,通过信号槽来实现子线程和主线程间的各种通信。
  4. 本示例界面参照的是野火调试助手的串口功能界面,野火调试助手下载链接为:野火调试助手,在实际使用野火调试助手过程中,发现在多项发送功能中,需要实现动态添加界面控件,因此需要写一个自定义类,继承自QTabWidget,通过代码实现动态添加界面控件。

二、具体实现

1 自定义QSerialPort处理类

class MySerialPort : public QObject
{
    Q_OBJECT
public:
    MySerialPort();
    ~MySerialPort();
private:
    /**
      *@name    get_useable_serial_portname
      *@brief   get cur can be used serial portname
      *@param
      *@return  QList<QSerialPortInfo>
      *@note
      *@author  Mydolen
      *@date    2022-12-09
      */
    QList<QSerialPortInfo> get_useable_serial_portname();
    /**
      *@name    open_port
      *@brief   open serial port
      *@param   QString portname,
                quint32 baudrate = QSerialPort::Baud115200,
                QSerialPort::DataBits DataBits = QSerialPort::Data8,
                QSerialPort::Parity Parity = QSerialPort::NoParity,
                QSerialPort::StopBits StopBits = QSerialPort::OneStop,
                QSerialPort::FlowControl FlowControl = QSerialPort::NoFlowControl
      *@return  void
      *@note
      *@author  Mydolen
      *@date    2022-12-09
      */
    void open_port(QString portname,
                   quint32 baudrate = QSerialPort::Baud115200,
                   QSerialPort::DataBits DataBits = QSerialPort::Data8,
                   QSerialPort::Parity Parity = QSerialPort::NoParity,
                   QSerialPort::StopBits StopBits = QSerialPort::OneStop,
                   QSerialPort::FlowControl FlowControl = QSerialPort::NoFlowControl);
    /**
    *@name    close_port
    *@brief   close port
    *@param
    *@return  void
    *@note
    *@author  Mydolen
    *@date    2022-12-12
    */
    void close_port();
    /**
    *@name    read_receive_data
    *@brief   slot of readyread signal
    *@param
    *@return  QSharedPointer<QByteArray>
    *@note
    *@author  Mydolen
    *@date    2022-12-11
    */
    QSharedPointer<QByteArray> read_receive_data();
    /**
    *@name    write_to_serial
    *@brief   write to serial
    *@param   QSharedPointer<QByteArray> data
    *@return  void
    *@note
    *@author  Mydolen
    *@date    2022-12-13
    */
    void write_to_serial(QSharedPointer<QByteArray> data);
private:
    QSerialPort *m_serial;
    QString     cur_portname;
signals:
    void sig_get_serial_portname_list();                                                    //外部获取当前可用串口列表信号
    void sig_open_port(QString portname,
                       quint32 baudrate = QSerialPort::Baud115200,
                       QSerialPort::DataBits DataBits = QSerialPort::Data8,
                       QSerialPort::Parity Parity = QSerialPort::NoParity,
                       QSerialPort::StopBits StopBits = QSerialPort::OneStop,
                       QSerialPort::FlowControl FlowControl = QSerialPort::NoFlowControl);  //外部打开串口信号
    void sig_close_port();                                                                  //外部关闭串口信号
    void sig_write_data(QSharedPointer<QByteArray> data);                                   //外部向串口写数据信号

    void sig_emit_serial_portname_list(QSharedPointer<QList<QSerialPortInfo>> list_pointer);//返回当前可用串口列表
    void sig_emit_read_data(QSharedPointer<QByteArray> data);                               //向外部发送读取到的数据
    void sig_error_occured(QString error_str);                                              //向外部发送错误信息
    void sig_normal_info(QString info);                                                     //向外部发送正常信息
};

2 自定义QComboBox控件

class MyComboBox : public QComboBox
{
    Q_OBJECT
public:
    MyComboBox(QWidget *parent = nullptr);
    ~MyComboBox();
protected:
    virtual void mousePressEvent(QMouseEvent *e);
signals:
    void left_button_clicked();
};

3 自定义线程托管类

class MyHostThread : public QThread
{
    Q_OBJECT
public:
    MyHostThread(QObject *be_hosted);
    ~MyHostThread();
};

4 自定义QTabWidget控件

class MyTabWidget : public QTabWidget
{
    Q_OBJECT
public:
    MyTabWidget(QWidget *parent = nullptr);
private:
    /**
    *@name    init_thread
    *@brief   init thread
    *@param
    *@return  void
    *@note    note
    *@author  Mydolen
    *@date    2022-12-15
    */
    void init_thread();
    /**
    *@name    create_new_input_item
    *@brief   create new input item
    *@param   const int index
    *@return  QGridLayout*
    *@note    note
    *@author  Mydolen
    *@date    2022-12-15
    */
    QHBoxLayout* create_new_input_item(const int index);
    /**
    *@name    create_new_tab_widget_item
    *@brief   create new tab
    *@param   const int index
    *@return  QGridLayout*
    *@note    note
    *@author  Mydolen
    *@date    2022-12-15
    */
    QGridLayout* create_new_tab_widget_item(const int index);
    /**
    *@name    slot_add_new_tab
    *@brief   add new tab to tabwidget
    *@param   const int index
    *@return  void
    *@note    none
    *@author  Mydolen
    *@date    2022-12-15
    */
    void slot_add_new_tab();
    /**
    *@name    slot_delete_one_tab
    *@brief   delete one tab
    *@param
    *@return  void
    *@note    none
    *@author  Mydolen
    *@date    2022-12-15
    */
    void slot_delete_one_tab();
    /**
    *@name    slot_turn_next_tab
    *@brief   turn next or pre tab
    *@param   bool next_or_pre
    *@return  void
    *@note    note
    *@author  Mydolen
    *@date    2022-12-15
    */
    void slot_turn_next_tab(bool next_or_pre);
    /**
    *@name    slot_move_to_home_page
    *@brief   move to home or back page
    *@param   bool home_or_back
    *@return  void
    *@note    note
    *@author  Mydolen
    *@date    2022-12-15
    */
    void slot_move_to_home_page(bool home_or_back);
    /**
    *@name    slot_jump_to_index
    *@brief   jump to index
    *@param   const int index
    *@return  void
    *@note    note
    *@author  Mydolen
    *@date    2022-12-15
    */
    void slot_jump_to_index(const int index);
    /**
    *@name    slot_clear_cur_tab
    *@brief   clear cur tab
    *@param
    *@return  void
    *@note    note
    *@author  Mydolen
    *@date    2022-12-15
    */
    void slot_clear_cur_tab();
    /**
    *@name    slot_receive_button_group_signals_button
    *@brief   receive button group signals
    *@param   QAbstractButton *but
    *@return  void
    *@note    note
    *@author  Mydolen
    *@date    2022-12-15
    */
    void slot_receive_button_group_signals_button(QAbstractButton *button);
private:
    int             m_index;
    QButtonGroup    *m_but_group;
signals:
    void sig_add_new_tab();                         //增加一页控件
    void sig_turn_next_tab(bool next_or_pre);       //前、后一页
    void sig_move_to_home_page(bool home_or_back);  //首页、尾页
    void sig_delete_one_tab();                      //删除一页
    void sig_clear_cur_tab();                       //清空当前页
    void sig_jump_to_index(const int index);        //跳转到某页
    void sig_cur_tab_index(const int index);        //向外部发送当前页序号
    void sig_max_tab_index(const int index);        //向外部发送最大页序号
    void sig_button_clicked(const QString str);     //按钮按下发送对应LineEdit内的输入内容
};

三、界面展示

主界面

三、简要总结

  1. 本示例所应用的技术:
    1. 串口通讯
    2. 多线程
    3. 信号槽
    4. 智能指针
    5. HEX转码
    6. 自定义控件
    7. 动态变更界面控件
  2. 将来需要实现的功能:
    1. 自动发送功能。
    2. 保存到文件功能。
    3. 都不难,只是在写这篇文章的时候还没加上
  3. 本项目编译环境:Qt 6.2.4 Community \ MSVC 2019
  4. 本项目Gitee地址:MyProjectA
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值