QT串口助手(三):数据接收
作者:zzssdd2
E-mail:zzssdd2@foxmail.com
一、前言
开发环境:Qt5.12.10 + MinGW
实现的功能
- 串口数据的接收
- ascii字符形式显示与hex字符形式显示
- 时间戳的显示
- 接收数据的统计与显示
- 接收清零
涉及的知识点
QSerialPort
类的使用- 数据格式的转换
QTime
类的使用- 控件
QTextEdit
、QCheckBox
、QPushButton
、QLabel
的使用
二、功能实现
下面开始逐步讲解以上列举的功能实现
2.1、数据读取
在《QT串口助手(二):参数配置》中已经实现了串口参数的配置,参数配置完成后就可以开启串口的数据接收功能了。在QT中的QSerialPort类继承自QIODevice类,所以可以使用QIODevice的readyRead()信号来触发数据的接收,在槽函数中实现数据的读取与处理。信号槽连接如下:
/* 接收数据信号槽 */
connect(serial, &QSerialPort::readyRead, this, &Widget::SerialPortReadyRead_slot);
补充:
[signal]
void QIODevice::readyRead()This signal is emitted once every time new data is available for reading from the device's current read channel. It will only be emitted again once new data is available, such as when a new payload of network data has arrived on your network socket, or when a new block of data has been appended to your device.
readyRead() is not emitted recursively; if you reenter the event loop or call waitForReadyRead() inside a slot connected to the readyRead() signal, the signal will not be reemitted (although waitForReadyRead() may still return true).
Note for developers implementing classes derived from QIODevice: you should always emit readyRead() when new data has arrived (do not emit it only because there's data still to be read in your buffers). Do not emit readyRead() in other conditions.
当有收到新数据信号时,就会执行槽函数里面的数据读取功能:
/*读取串口收到的数据*/
QByteArray bytedata = serial->readAll();
补充:
QByteArray QIODevice::readAll()
Reads all remaining data from the device, and returns it as a byte array.
This function has no way of reporting errors; returning an empty QByteArray can mean either that no data was currently available for reading, or that an error occurred.
2.2、数据转换
若需要将接收到的数据以HEX格式显示,则需要对接收到的数据进行以下处理:
/*将数据转换为hex格式并以空格分隔->去掉头尾空白字符->转换为大写形式*/
framedata = bytedata.toHex(' ').trimmed().toUpper();
补充:
QByteArray QByteArray::toHex(char separator) const
This is an overloaded function.
Returns a hex encoded copy of the byte array. The hex encoding uses the numbers 0-9 and the letters a-f.
If separator is not '\0', the separator character is inserted between the hex bytes.
Example:
QByteArray macAddress = QByteArray::fromHex("123456abcdef");
macAddress.toHex(':'); // returns "12:34:56:ab:cd:ef"
macAddress.toHex(0); // returns "123456abcdef"
This function was introduced in Qt 5.9.
QByteArray QByteArray::trimmed() const
Returns a byte array that has whitespace removed from the start and the end.
Whitespace means any character for which the standard C++
isspace()
function returnstrue
in the C locale. This includes the ASCII characters '\t', '\n', '\v', '\f', '\r', and ' '.Example:
QByteArray ba(" lots\t of\nwhitespace\r\n ");
ba = ba.trimmed();
// ba == "lots\t of\nwhitespace";
Unlike simplified(), trimmed() leaves internal whitespace alone.
QByteArray QByteArray::toUpper() const
Returns an uppercase copy of the byte array. The bytearray is interpreted as a Latin-1 encoded string.
Example:
QByteArray x("Qt by THE QT COMPANY");
QByteArray y = x.toUpper();
// y == "QT BY THE QT COMPANY"
2.3、添加时间戳
有时为了便于观察数据收发时间,需要在数据前插入时间戳显示。使用QTime类中的方法可以获取当前系统的时间(精确到ms),对数据处理如下:
/*在数据前插入时间戳:[时:分:秒:毫秒]:RX -> 数据*/
framedata = QString("[%1]:RX -> %2").arg(QTime::currentTime().toString("HH:mm:ss:zzz")).arg(framedata);
补充:
[static]
QTime QTime::currentTime()Returns the current time as reported by the system clock.
Note that the accuracy depends on the accuracy of the underlying operating system; not all systems provide 1-millisecond accuracy.
Furthermore, currentTime() only increases within each day; it shall drop by 24 hours each time midnight passes; and, beside this, changes in it may not correspond to elapsed time, if a daylight-saving transition intervenes.
2.4、接收计数
使用一个quint32类型数据对每次接收数据长度进行累加,记录接收数据总数,然后将数据更新到ui界面:
dataTotalRx += bytedata.length();
ui->RxCnt_label->setText(QString::number(dataTotalRx));
2.5、数据显示
以上功能完成后将数据显示到接收框中(为了区分不同显示格式,做了不同的颜色显示)。完整的数据接收功能展示如下:
/*
函 数:SerialPortReadyRead_slot
描 述:readyRead()信号对应的数据接收槽函数
输 入:无
输 出:无
*/
void Widget::SerialPortReadyRead_slot()
{
QString framedata;
/*读取串口收到的数据*/
QByteArray bytedata = serial->readAll();
/*数据是否为空*/
if (!bytedata.isEmpty())
{
if(ui->HexDisp_checkBox->isChecked())
{
/*hex显示*/
framedata = bytedata.toHex(' ').trimmed().toUpper();
ui->Receive_TextEdit->setTextColor(QColor(Qt::green));
}
else
{
/*ascii显示*/
framedata = QString(bytedata);
ui->Receive_TextEdit->setTextColor(QColor(Qt::magenta));
}
/*是否显示时间戳*/
if (ui->TimeDisp_checkBox->isChecked())
{
framedata = QString("[%1]:RX -> %2").arg(QTime::currentTime().toString("HH:mm:ss:zzz")).arg(framedata);
ui->Receive_TextEdit->append(framedata);
}
else
{
ui->Receive_TextEdit->insertPlainText(framedata);
}
/*更新接收计数*/
dataTotalRxCnt += bytedata.length();
ui->RxCnt_label->setText(QString::number(dataTotalRxCnt));
}
}
演示效果如下:
补充:
QColor::QColor(Qt::GlobalColor color)
This is an overloaded function.
Constructs a new color with a color value of color.
enum Qt::GlobalColor
Qt's predefined QColor objects:
Constant Value Description Qt::white
3
White (#ffffff) Qt::black
2
Black (#000000) Qt::red
7
Red (#ff0000) Qt::darkRed
13
Dark red (#800000) Qt::green
8
Green (#00ff00) Qt::darkGreen
14
Dark green (#008000) Qt::blue
9
Blue (#0000ff) Qt::darkBlue
15
Dark blue (#000080) Qt::cyan
10
Cyan (#00ffff) Qt::darkCyan
16
Dark cyan (#008080) Qt::magenta
11
Magenta (#ff00ff) Qt::darkMagenta
17
Dark magenta (#800080) Qt::yellow
12
Yellow (#ffff00) Qt::darkYellow
18
Dark yellow (#808000) Qt::gray
5
Gray (#a0a0a4) Qt::darkGray
4
Dark gray (#808080) Qt::lightGray
6
Light gray (#c0c0c0) Qt::transparent
19
a transparent black value (i.e., QColor(0, 0, 0, 0)) Qt::color0
0
0 pixel value (for bitmaps) Qt::color1
1
1 pixel value (for bitmaps)
2.6、清除接收
当清除接收
按键点击后,会清除接收框显示的内容以及接收计数。使用QPushButton的点击信号槽实现如下:
/*
函 数:on_ClearRx_Bt_clicked
描 述:清除接收按键点击信号对应的槽函数
输 入:无
输 出:无
*/
void Widget::on_ClearRx_Bt_clicked()
{
ui->Receive_TextEdit->clear();
ui->RxCnt_label->setText(QString::number(0));
dataTotalRxCnt = 0;
}
三、总结
本篇文章主要是讲述如何对串口数据进行接收和显示。除了上面列出的主要功能外,还需要了解各个控件的操作方法,比如QTextEdit文本的添加、QLabel文本的设置等。还有就是QT中基本的数据类型的数据使用,比如QString、QBytArray等。
QT串口助手(三):数据接收的更多相关文章
- QT串口助手(四):数据发送
作者:zzssdd2 E-mail:zzssdd2@foxmail.com 一.前言 开发环境:Qt5.12.10 + MinGW 实现的功能 串口数据的发送 ascii字符与hex字符的相互转换 自 ...
- QT串口助手(五):文件操作
作者:zzssdd2 E-mail:zzssdd2@foxmail.com 一.前言 开发环境:Qt5.12.10 + MinGW 功能 文件的发送 数据的保存 知识点 QFile类的使用 QTime ...
- QT串口助手(二):参数配置
作者:zzssdd2 E-mail:zzssdd2@foxmail.com 一.前言 主要实现功能 串口参数的配置:波特率.数据位.停止位.校验位 本机串口设备的查询与添加显示 串口设备的手动更新与打 ...
- python串口助手
最近项目中要使用模拟数据源通过向外发送数据,以前都是用C#编写,最近在研究python,所以就用python写了一个串口助手,方便以后的测试. 在电脑上通过虚拟串口助手产生两个虚拟串口,运行编写的串口 ...
- 玩转X-CTR100 | STM32F4 l X-Assistant串口助手控制功能
我造轮子,你造车,创客一起造起来!塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ] X-CTR100控制器配套的X-Assis ...
- 玩转X-CTR100 | X-Assistant串口助手控制功能
更多塔克创新资讯欢迎登陆[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ] X-CTR100控制器配套的X-Assistant串口调试 ...
- 【转】QT 串口QSerialPort + 解决接收数据不完整问题
类:QSerialPort 例程:Examples\Qt-5.9.1\serialport\terminal,该例子完美展示了qt串口收发过程,直接在这上面修改就可以得到自己的串口软件.核心方法 // ...
- STM32移植RT-Thread后的串口在调试助手上出现:(mq != RT_NULL) assert failed at rt_mq_recv:2085和串口只发送数据不能接收数据问题
STM32移植RT-Thread后的串口在调试助手上出现:(mq != RT_NULL) assert failed at rt_mq_recv:2085的问题讨论:http://www.rt-thr ...
- python3 Serial 串口助手的接收读取数据
其实网上已经有许多python语言书写的串口,但大部分都是python2写的,没有找到一个合适的python编写的串口助手,只能自己来写一个串口助手,由于我只需要串口能够接收读取数据就可以了,故而这个 ...
随机推荐
- 为什么Python多线程无法利用多核
1.全局解释锁 如题: Python的多线程为什么不能利用多核处理器? 全局解释器锁(Global Interpreter Lock)是计算机程序设计语言解释器用于同步线程的一种机制,它使得任何时刻仅 ...
- python k-means聚类实例
port sys reload(sys) sys.setdefaultencoding('utf-8') import matplotlib.pyplot as plt import numpy as ...
- Asp.Net Core使用MongoDB
MongoDB 是一个基于分布式且面向文档存储的开源 NoSql数据库系统 MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的.它支持的数据结构 ...
- 记一次Ajax请求MVC调优
问题描述 ASP.NETMVC项目,编辑页面赋值操作,ajax请求很慢. 对同一个控制器有2个请求 一个为获取该表的树形结构数据(绑定下拉框) 一个为获取某实体的单条记录(编辑操作) 排查过程 数据库 ...
- Word2Vec和LDA的区别与联系
Word2vec是目前最常用的词嵌入模型之一.是一种浅层的神经网络模型,他有2种网络结构,分别是CBOW(continues bag of words)和 skip-gram.Word2vec 其实是 ...
- Linux下登录Oracle命令行时删除键^H解决方法
Linux下登录Oracle命令行时删除键^H解决方法 在linux服务器下登录oracle的控制台,如果输入错误,想用删除键删除时却不能删除,输出的是^H的字符. 方法 用如下的命令可以使删除键生效 ...
- 166个最常用的Linux命令,哪些你还不知道?
linux命令是对Linux系统进行管理的命令.对于Linux系统来说,无论是中央处理器.内存.磁盘驱动器.键盘.鼠标,还是用户等都是文件,Linux系统管理的命令是它正常运行的核心. 线上查 ...
- Android驱动入门-在Android系统上运行JAVA程序
在linux上运行java程序,直接用javac编译,再用java运行就行了.但是在Android上,由于虚拟机和pc端的不同,所以操作方法也是不一样的. 如果想在Android上运行Hello wo ...
- stm32之定时器彻底研究
分类: C/C++ 这里介绍两种方式使用stm32的定时器:直接操作寄存器和使用st的官方的库文件. 相比较而言,直接操作定时器比较简洁,对着寄存器看十分明了.而使用库文件有一点晕头转向. (个人观点 ...
- matplotlib中subplots的用法
1.matplotlib中如果只画一张图的话,可以直接用pyplot,一般的做法是: import matplotlib.pyplot as plt plt.figure(figsize=(20,8) ...