CSerialPort教程4.3.x (4) - CSerialPort在QT中的使用

CSerialPort教程4.3.x (4) - CSerialPort在QT中的使用

环境:

复制代码
QT: 5.6.3

前言

CSerialPort项目是一个基于C/C++的轻量级开源跨平台串口类库,可以轻松实现跨平台多操作系统的串口读写,同时还支持C#, Java, Python, Node.js等。

CSerialPort项目的开源协议自 V3.0.0.171216 版本后采用GNU Lesser General Public License v3.0

为了让开发者更好的使用CSerialPort进行开发,特编写基于4.3.x版本的CSerialPort教程系列。

CSerialPort项目地址:

QT完整示例程序地址:

1. 新建QT项目

新建一个QT项目目,解决方案名称为CommQT

【文件】-【新建文件或项目】-【Application(Qt)】-【Qt Widgets Application】-【choose...】-【名称: CommQT】

在CommQT解决方案目录下载CSerialPort源码

复制代码
$ cd CommQT
$ git clone https://github.com/itas109/CSerialPort

目录结构如下:

复制代码
D:/CommQT $ tree
.
+--- CommQT.pro
+--- CSerialPort
|   +--- include
|   |   +--- CSerialPort
|   |   |   +--- SerialPort.h
|   |   |   +--- SerialPortInfo.h
|   +--- src
|   |   +--- SerialPort.cpp
|   |   +--- SerialPortBase.cpp
|   |   +--- SerialPortInfo.cpp
|   |   +--- SerialPortInfoBase.cpp
|   |   +--- SerialPortInfoUnixBase.cpp
|   |   +--- SerialPortInfoWinBase.cpp
|   |   +--- SerialPortUnixBase.cpp
|   |   +--- SerialPortWinBase.cpp
+--- main.cpp
+--- mainwindow.cpp
+--- mainwindow.h
+--- mainwindow.ui

2. CommQT.pro中增加必要的CSerialPort依赖

CommQT.pro中增加CSerialPort依赖

复制代码
#-------------------------------------------------
#
# Project created by QtCreator
#
#-------------------------------------------------

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = CommQT
TEMPLATE = app


SOURCES += main.cpp\
        mainwindow.cpp

HEADERS  += mainwindow.h

FORMS    += mainwindow.ui

# add by itas109
# 1. headers
INCLUDEPATH += "$$PWD/CSerialPort/include"

# 2. sources
SOURCES += $$PWD/CSerialPort/src/SerialPortBase.cpp
SOURCES += $$PWD/CSerialPort/src/SerialPort.cpp
SOURCES += $$PWD/CSerialPort/src/SerialPortInfoBase.cpp
SOURCES += $$PWD/CSerialPort/src/SerialPortInfo.cpp

win32 {
    SOURCES += $$PWD/CSerialPort/src/SerialPortWinBase.cpp
    SOURCES += $$PWD/CSerialPort/src/SerialPortInfoWinBase.cpp
}

unix {
    SOURCES += $$PWD/CSerialPort/src/SerialPortUnixBase.cpp
    SOURCES += $$PWD/CSerialPort/src/SerialPortInfoUnixBase.cpp
}

# 3. add system libs
win32-msvc*:LIBS += advapi32.lib
win32-msvc*:LIBS += setupapi.lib
win32-g++:LIBS += libsetupapi

# 4. define UNICODE
DEFINES += _UNICODE
# end by itas109

3. 在QT中添加CSerialPort代码

3.1 增加CSerialPort的头文件、继承类、接收函数及CSerialPort实例对象

在mainwindow.h文件中

  • 增加CSerialPort的头文件
  • MainWindow类继承CSerialPortListener
  • 增加接收函数onReadEvent(const char *portName, unsigned int readBufferLen)
  • 增加CSerialPort的实例对象
  • 增加QPlainTextEdit控件接收数据

mainwindow.h

复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

// add by itas109
#include <QPlainTextEdit>

#include "CSerialPort/SerialPort.h"
#include "CSerialPort/SerialPortInfo.h"
using namespace itas109;
// end by itas109

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow,public CSerialPortListener // add by itas109
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

    // add by itas109
private:
    void onReadEvent(const char *portName, unsigned int readBufferLen);

signals:
    void emitUpdateReceive(QString str);

private slots:
    void OnUpdateReceive(QString str);

private:
    QPlainTextEdit * p_plainTextEditReceive;
    CSerialPort m_serialPort;
    // end by itas109
};

#endif // MAINWINDOW_H

3.2 增加串口的相关实现代码

mainwindow.cpp文件增加

  • MainWindow::MainWindow中增加CSerialPort的测试代码

  • 增加OnReceive函数的实现

    #include "mainwindow.h"
    #include "ui_mainwindow.h"

    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);

    复制代码
      // add by itas109
      p_plainTextEditReceive = NULL;
      p_plainTextEditReceive = new QPlainTextEdit();
      this->setCentralWidget(p_plainTextEditReceive);
    
      std::vector<SerialPortInfo> portNameList = CSerialPortInfo::availablePortInfos();
    
      if (portNameList.size() > 0)
      {
          p_plainTextEditReceive->moveCursor (QTextCursor::End);
          p_plainTextEditReceive->insertPlainText(QString("First avaiable Port: %1\n").arg(portNameList[0].portName));
      }
      else
      {
          p_plainTextEditReceive->moveCursor (QTextCursor::End);
          p_plainTextEditReceive->insertPlainText("No avaiable Port");
          return;
      }
    
      connect(this,&MainWindow::emitUpdateReceive,this,&MainWindow::OnUpdateReceive,Qt::QueuedConnection);
    
      m_serialPort.connectReadEvent(this);
    
      m_serialPort.init(portNameList[0].portName);
    
      m_serialPort.open();
    
      if (m_serialPort.isOpen())
      {
          p_plainTextEditReceive->moveCursor (QTextCursor::End);
          p_plainTextEditReceive->insertPlainText(QString("open %1 success\n").arg(portNameList[0].portName));
    
          m_serialPort.writeData("itas109", 7);
      }
      else
      {
          p_plainTextEditReceive->moveCursor (QTextCursor::End);
          p_plainTextEditReceive->insertPlainText(QString("open %1 failed\n").arg(portNameList[0].portName));
      }
      // end by itas109

    }

    MainWindow::~MainWindow()
    {
    delete ui;

    复制代码
      // add by itas109
      m_serialPort.disconnectReadEvent();
      // end by itas109

    }

    // add by itas109
    void MainWindow::onReadEvent(const char *portName, unsigned int readBufferLen)
    {
    if(readBufferLen > 0)
    {
    char data[1024];
    int recLen = m_serialPort.readData(data,readBufferLen > 1023 ? 1023 : readBufferLen);

    复制代码
          if (recLen > 0)
          {
              data[recLen] = '\0';
    
              emitUpdateReceive(QString::fromLocal8Bit(data,recLen));
          }
      }

    }

    void MainWindow::OnUpdateReceive(QString str)
    {
    p_plainTextEditReceive->moveCursor (QTextCursor::End);
    p_plainTextEditReceive->insertPlainText(str);
    }
    // end by itas109

4. 结果

代码中的COM2对应的串口为RS232环回测试硬件,因此对应的结果为:

程序启动后,初始化并打开串口COM2,接收窗打印open xxx success,发送数据itas09,随后接收窗打印itas09

windows下结果:

复制代码
First avaiable Port: COM1
open COM1 success
itas109

linux下结果:

复制代码
First avaiable Port: /dev/ttyUSB0
open /dev/ttyUSB0 success
itas109

linux下可能遇到权限问题

复制代码
open port error: Unable to open /dev/ttyUSB0: 权限不够

临时解决:

复制代码
$ sudo chmod 777 /dev/ttyUSB0

永久解决(dev为当前用户名):

复制代码
$ sudo usermod -aG dialout dev
$ newgrp dialout # 立即生效

License

License under CC BY-NC-ND 4.0: 署名-非商业使用-禁止演绎


Reference:

  1. https://github.com/itas109/CSerialPort
  2. https://gitee.com/itas109/CSerialPort
  3. https://blog.csdn.net/itas109
相关推荐
漫步企鹅2 天前
【VS Code - Qt】如何基于Docker Linux配置Windows10下的VS Code,开发调试ARM 版的Qt应用程序?
linux·qt·docker·arm·vs code·开发调试
pzzqq2 天前
buildroot编译qt 5.9.8 arm64版本踩坑
开发语言·qt
还债大湿兄2 天前
基于Qt Property Browser的通用属性系统:Any类与向量/颜色属性的完美结合
开发语言·qt
luciferau2 天前
Qt: WA_DontCreateNativeAncestors
qt
钱彬 (Qian Bin)3 天前
AI质检数据准备利器:基于Qt/QML 5.14的图像批量裁剪工具开发实战
qt·自定义·图像·qml·qt quick·裁剪工具
啊森要自信3 天前
【QT】常⽤控件详解(七)容器类控件 GroupBox && TabWidget && 布局管理器 && Spacer
linux·开发语言·c++·qt·adb
郝学胜-神的一滴3 天前
Horse3D引擎研发笔记(一):从使用Qt的OpenGL库绘制三角形开始
c++·qt·3d·unity·图形渲染·unreal engine
啊森要自信3 天前
【QT】常⽤控件详解(六)多元素控件 QListWidget && Table Widget && Tree Widget
c语言·开发语言·c++·qt
ZPC82104 天前
参数服务器 server and client
服务器·qt
牵牛老人4 天前
Qt中的QWebSocket 和 QWebSocketServer详解:从协议说明到实际应用解析
开发语言·qt·网络协议