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

2023-11-06

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完整示例程序地址:

  • https://github.com/itas109/CSerialPort/tree/master/examples/CommQT
  • https://gitee.com/itas109/CSerialPort/tree/master/examples/CommQT

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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • 无法在 QGLWidget 中设置所需的 OpenGL 版本

    我正在尝试在 Qt 4 8 2 中使用 QGLWidget 我注意到 QGLWidget 创建的默认上下文不显示 OpenGL 3 1 以上的任何输出 Qt wiki 有一个教程 http qt project org wiki How t
  • 如何从浮点数组创建新的 QImage

    我有一个代表图像的浮点数数组 列在前 我想在 QGraphicsSecene 上将图像显示为 QPixmap 为了做到这一点 我尝试使用 QImage 构造函数 QImage const uchar data int width int h
  • 如何为 qmlRegisterSingletonType 实现单例提供程序?

    我想在 QML 中使用 C 类作为 Singleton 实例 并认为我必须使用 qmlRegisterSingletonType 注册它们 此函数需要一个提供已注册 C 类的实例的函数 我在 Windows 上使用最新的 Qt 5 3 1
  • PyQt - 如何从给定的小部件获取顶级父级?

    给定的小部件如何访问它最旧的父级 即顶级小部件 我需要 showMinimized it 现在我正在使用 self parent parent parent showMinimized 但这似乎不是最好的方法 如果它移动了 我需要手动更改父
  • Qt5和QML:如何使用WebEngine Quick Nano浏览器自动输入用户名和密码

    我正在使用编写一个小应用程序Qt and QML使用 Qt 文档中的示例WebEngine Quick Nano 浏览器 https doc snapshots qt io qt5 5 9 qtwebengine webengine qui
  • QML:无法读取未定义的属性“xxx”

    ApplicationWindow id root property string rootName rootName visible true width 800 height 400 title qsTr WatchFace Maker
  • 有没有办法向 QListView 添加部分?

    我正在使用 Qt5 2 和 C 来实现一个应用程序 需要显示一个列表 其中包含类似于下面的示例图像的部分 source ngo hung com http www ngo hung com files images contact list
  • 在 Qt 服务器上验证用户身份

    我正在尝试使用 C QtTcpSocket 为个人项目 多人国际象棋游戏 实现身份验证系统 我的朋友建议了一种验证用户的方法 但我想问是否有更简单或更好的方法 来自 Python 背景 做这个项目主要是为了加深对 C 的理解 我将发布我朋友
  • QComboBox 下拉项边距

    我想设计我的风格QComboBox为下拉项目留出边距 现在是这样的 我想要这样的东西 我尝试过 QComboBox QAbstractItemView item margin 3px 但它不起作用 你能帮我解决这个问题吗 您想在项目之间设置
  • QMutex 是否需要是静态的,以便此类实例的其他线程调用知道暂停其操作?

    从多个线程调用以下附加函数 我不希望数据重写附加 因为计数器尚未增加 除了当前使用 Append 的线程之外 这是否会挂起所有进入的线程 或者其他线程会继续运行而不追加数据吗 互斥锁是否需要是 静态 的 或者每个实例都知道要暂停操作吗 如果
  • 如何在 OS X 上的 Qt 应用程序中设置应用程序图标,足以进行分发?

    跟进这个答案 https stackoverflow com a 20918932 368896 to 这个问题 https stackoverflow com questions 20909341 what is the fastest
  • QStyledItemDelegate 绘制自定义小部件失败

    在我的一个项目中 我使用的是QTableWidget为了显示一些复杂的计算结果 为了提高表格的可读性 我需要在单个表格单元格内显示两个对齐的值 后来我想通过使用颜色或箭头等来进一步自定义小部件 为此我源自QStyledItemDelegat
  • 清除pyqt中布局中的所有小部件

    有没有办法清除 删除 布局中的所有小部件 self plot layout QtGui QGridLayout self plot layout setGeometry QtCore QRect 200 200 200 200 self r
  • QMainWindow 上的 Qt 布局

    我设计了一个QMainWindow with QtCreator s设计师 它由默认的中央小部件 aQWidget 其中包含一个QVBoxLayout以及其中的所有其他小部件 现在我想要的一切就是QVBoxLayout自动占据整个中央小部件
  • 如何在针对 Windows XP 的情况下使用 VS2012 构建 Qt 4/5?

    我正在尝试使用 Visual Studio 2012 构建 Qt 4 8 5 Qt 5 2 1 针对 Windows XP SDK v7 1a 使用 VS2102 编译时 源代码与 SDK v7 1a 存在各种不兼容性 因此无法开箱即用 这
  • Qt中Q_PROPERTY的意义是什么?

    我无法理解 Q PROPERTY 的用法 Q PROPERTY 如何帮助程序具有防御性 它是干什么用的 我看过这个论坛 但确实无法应用 我已经理解了这个例子 但不明白它的用法 这是一个例子 我能从中得到什么 我知道阅读将赋予只读特权 wri
  • Qt中用于线程间通信的类设计

    问题陈述 用相机跟踪物体并相应地移动相机的方位角和仰角 Process 相机获取物体的图像 处理相机的每一帧以查找物体 应该被跟踪 并将每帧中生成的信息传递给机械设备 万向节 以平移和倾斜方式移动摄像机 Design 主 Gui 在一个线程
  • PyQt4 信号和槽

    我正在使用 PyQt4 编写我的第一个 Python 应用程序 我有一个 MainWindow 和一个 Dialog 类 它是 MainWindow 类的一部分 self loginDialog LoginDialog 我使用插槽和信号 这
  • Qt(在 Windows 上)将权限级别设置为“requireAdministrator”

    我正在使用 Qt Creator 并努力制作 exe文件默认以管理员身份运行 在线阅读所有解决方案我试图将这一行放入我的 pro file QMAKE LFLAGS MANIFESTUAC level requireAdministrato
  • 通过单击内部小部件而不是标题栏来移动窗口

    在 Windows 中 当我创建 QMainWindow 时 我可以通过单击标题栏并拖动它来在屏幕上移动它 在我的应用程序中 我使用隐藏了标题栏setWindowFlags Qt CustomizeWindowHint 我正在尝试使用小部件

随机推荐

  • Spring复习笔记

    1 Spring 1 1 简介 优点 Spring是一个轻量级控制反转 IoC 和面向切面 AOP 的容器 轻量级 低侵入 松耦合 框架粘合剂 更容易整合其他框架 支持事务处理 官网 https spring io projects spr
  • 不怕死就上这些网站

    1 hxxp www dj3344 com 打开后 重启时你的主页就变成它的 并通过QQ向他人传播 现在正飙行 奇坏无比 2 hxxp www qq168 net 打开后 重启时你的主页就变成它的 并通过QQ向他人传播 而且传波病毒 还狠些
  • 我的GIT练习Four

    目录 前言 GIT安装教程 Git作者 GIT优点 GIT缺点 为什么要使用 Git GIT练习Four C1 初始化项目 C2 设计项目首页 C3 设计登录页面 C4 实现登录功能 C5 设计后台页面 C6 设计注册页面 C7 实现注册功
  • 拼搏百天!上月喜获阿里内推,交叉面把面试官面傻眼了

    阿里内推一面 项目 1 面试官让我描述一个自己印象最深的项目 手画设计图 2 针对项目中的技术进行发问 比如 架构设计 部署图 模块之间的通信等 3 因为我描述项目存储数据比较多 让我重新设计数据库的表 怎么设计 后面都是针对项目技术的问题
  • iOS 蓝牙扫描枪扫描内容不正确

    背景 在移动设备上 使用蓝牙扫描枪 相当于接入了一下外接键盘 我们的客户使用我们的App 并连接蓝牙扫码枪 将扫描的内容传输到我们的App中 App再做出对应的响应 举个例子 较为常见的应用场景就是 拣货员拿着扫码枪 扫描产品上的UPC码
  • HttpClient的ssl方式发送请求

    最近因为项目需要 需要以rest方式和第三方平台交互 由于需要ssl方式连接 所以记录一下 maven依赖如下
  • openssl做HMAC实例(C++)

    1 HMAC简介 1 MAC Message Authentication Code 消息认证码算法 可以将其认为是含有秘钥的散列 Hash 函数算法 即兼容了MD和SHA算法 并在此基础上加上了秘钥 因此MAC算法也经常被称作HMAC算法
  • 常见的WRF运行错误

    转载至 https wk atmchem github io 2021 06 03 WRFbugandSolutions WPS Errors Ungrib exe Segmentation Fault Parsed 29 entries
  • sql server判断两个字符串是否相等(区分大小写)

    步骤 一 新增测试数据 新建测试表 create table testTable1 str1 varchar 100 str2 varchar 100 新增测试数据 如下图 二 两字符串进行比较 当直接使用 号进行判断时 是无法区分大小写的
  • 深度学习速学上手小项目

    demo仓库和视频演示 银色子弹zg的个人空间 银色子弹zg个人主页 哔哩哔哩视频 卷积网路CNN分类的模型一般使用包括alexnet DenseNet DLA GoogleNet Mobilenet ResNet ResNeXt Shuf
  • AIX下使用ASM

    metalink note 282036 1 IBM Software Requirements and PTFs for AIX 5 3 support of Oracle Database 10g Release 2 10 2 0 1
  • Anaconda 的Jupyter Notebook更换默认浏览器

    因为之前装的Anaconda默认使用的是系统自带的Edge浏览器 对的 就是这个玩意 然后自己近期一直用的win11 前几个版本还没什么太大问题 但是在20号左右系统自动更新了一下 对的就是这个 然后Microsoft Edge浏览器直接打
  • LUA中的and与or

    LUA中的and与or 2013 01 04 14 51 14074人阅读 评论 2 收藏 举报 分类 Lua 44 逻辑运算符认为false和nil是假 false 其他为真 0也是true and的优先级比or高 其它语言中的and表示
  • 小程序的数据驱动和Vue的双向绑定有何异同

    引言 在现代应用程序开发中 数据驱动和双向绑定是两个非常重要的概念 它们能够提供更好的用户体验和开发效率 本文将探讨小程序的数据驱动和Vue的双向绑定 并通过代码实例来说明它们的异同 让我们一起来了解吧 小程序的数据驱动 小程序是一种轻量级
  • Java初阶——练习题

    import java util Random import java util Scanner public class java 11 1 public static void main String args int ret numb
  • 模板的特化(具体化)

    模板的特化 具体化 重点注意 1 类模板和函数模板都可以被全特化 2 类模板能偏特化 不能被重载 3 函数模板可以实现重载 不能被偏特化 4 类模板调用优先级 全特化类 gt 偏特化类 gt 主版本模板类 6 函数模板同时存在具体化模板 函
  • ZYNQ中FreeRTOS中使用定时器

    使用普通的Timer中断方式时 Timer中断可以正常运行 但是UDP通信进程无法启动 其中TimerIntrHandler是中断服务程序 打印程序运行时间与从BRAM中读取的数据 void SetupInterruptSystem XSc
  • JetBrains各版本全家桶工具 编程开发全套永久软件!IDE也能免费用

    程序员每次换新电脑装IDE总是少不了的 但是奈何激活码难找 功夫不负有心人终于让我找到了激活方法 而且是可以永久激活的 更赞的是操作简单 无需注册机也无需修改文件和host 而且支持2018 2019 2020全版本的全家桶软件 之前也激活
  • shell 多线程介绍与举例

    在Shell脚本中实现多线程通常可以使用以下几种方式 后台执行 在Shell脚本中 你可以使用 符号将某个命令放在后台执行 这样可以同时执行多个命令 达到多线程的效果 例如 bin bash command1 command2 comman
  • CSerialPort教程4.3.x (4) - CSerialPort在QT中的使用

    CSerialPort教程4 3 x 4 CSerialPort在QT中的使用 环境 QT 5 6 3 前言 CSerialPort项目是一个基于C C 的轻量级开源跨平台串口类库 可以轻松实现跨平台多操作系统的串口读写 同时还支持C Ja