qextserialport-1.2rc库下载链接: http://www.pudn.com/Download/item/id/2298532.html

1.添加源码到工程

将qextserialport-1.2rc.zip解压,将解压后的src目录拷贝到项目里的子目录SerialSrc下,在项目pro文件中增加下面这行

include(./serialSrc/src/qextserialport.pri)

2.编译时,显示 'DEVICE_NOTIFY_ALL_INTERFACE_CLASSES'未定义

解决:

修改qextserialenumerator_p.h文件,将0x0500修改为0x0501,解决window下编译提示“DEVICE_NOTIFY_ALL_INTERFACE_CLASSES”未定义错误。

3.读取在线串口

包含头文件:

#include "qextserialport.h"

#include "qextserialenumerator.h"

示例:

QList<QextPortInfo> ports = QextSerialEnumerator::getPorts();
//! [1]
qDebug() << "List of ports:";
//! [2]
foreach (QextPortInfo info, ports) {
qDebug() << "port name:" << info.portName; //COMID
qDebug() << "friendly name:" << info.friendName; //名称
qDebug() << "physical name:" << info.physName;
qDebug() << "enumerator name:" << info.enumName;
qDebug() << "vendor ID:" << info.vendorID;
qDebug() << "product ID:" << info.productID;
qDebug() << "===================================";
}

打印:

4.串口库相关使用(参考example示例)

串口有两种模式EventDriven/Polling

EventDriven(事件驱动方式)

使用事件处理串口的读取,一旦有数据到来,就会发出readyRead()信号,我们可以关联该信号来读取串口的数据。在事件驱动的方式下,串口的读写是异步的,调用读写函数会立即返回,它们不会冻结调用线程。

Polling (查询方式)

读写函数是同步执行的,信号不能工作在这种模式下,而且有些功能也无法实现。但是这种模式下的开销较小。我们需要自己建立定时器来读取串口的数据。

在Windows下支持以上两种模式,而在Linux下只支持Polling模式

读取方式

如果想读取一行有效数据时:

 if(port->canReadLine())
{
qDebug()<<port->readLine();
}

如果想读取所有有效数据时:

 if (port->bytesAvailable()) {
qDebug()<<port->readAll();
}

QextSerialPort类

用来描述具体的一个端口,可以通过它的成员函数,来获取/设置该端口的波特率,名称,停止位等,也可以通过该类来打开/关闭某个端口

示例:

port->setPortName("COM1");                // port是个QextSerialPort类对象
port->setBaudRate(BAUD1152000 );
port->setParity(PAR_NONE);
port->setDataBits(DATA_8);
port->setStopBits(StopBitsType);
port->setQueryMode(EventDriven); //设置事件驱动模式 port->setBaudRate((BaudRateType)ui->baudRateBox->itemData(idx).toInt()); port->open(QIODevice::ReadWrite); //打开串口
//进行操作中... ...
port->close(); //关闭串口

QextSerialEnumerator类

用来统计在线串口用的,它有个成员函数getPorts(),其中上面第3节时便用到了.

它有两个信号函数:

deviceDiscovered(const QextPortInfo &info);
//出现有新的串口时,会触发该信号,并将出现的串口信息存到info参数中 deviceRemoved(const QextPortInfo &info);
//当某个串口消失时,会触发该信号,并将消失的串口信息存到info参数中

注意:上面两个信号函数默认是不会触发的,需要调用setUpNotifications()成员函数来开启信号事件触发

5.示例-使用EventDriven事件驱动模式制作串口助手

5.1 效果图-跟下位机通信

和原子的XCOM串口助手做比较

5.2创建UI

5.3 头文件

#ifndef WIDGET_H
#define WIDGET_H
#include <QtGui>
#include "qextserialport.h"
#include "qextserialenumerator.h" namespace Ui {
class Widget;
} class Widget : public QWidget
{
Q_OBJECT QextSerialPort *port; //端口,用来描述具体的一个端口
QextSerialEnumerator *enumerator; //在线串口统计类 protected:
void closeEvent(QCloseEvent *);
void initBtn(); //初始化按钮
void initComboBoxs(); //初始化下拉列表框
void initSerial(); //初始化串口
void Change_btn_isOn(bool ison); public:
explicit Widget(QWidget *parent = );
~Widget(); private slots:
void on_btn_send_clicked(); //发送数据
void on_betn_clear_clicked(); //清除接收数据
void on_btn_switch_clicked(); //串口开关
void onPortAddedOrRemoved(); //刷新串口号
void readLineData(); //读数据
void on_serial_name_currentIndexChanged(int index); private:
Ui::Widget *ui;
};
#endif // WIDGET_H

5.4 源文件

#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
setWindowTitle(("简易串口工具"));
ui->recvEdit->setReadOnly(true);
initBtn();
initComboBoxs();
initSerial();
qApp->setStyleSheet("QComboBox::item{text-align: center; }");
} void Widget::initBtn() //初始化按钮
{
Change_btn_isOn(false);
} void Widget::initComboBoxs() //初始化下拉列表框
{
BaudRateType RateTypes[]={
BAUD1200,BAUD2400 ,BAUD4800,BAUD9600 ,
BAUD14400,BAUD19200,BAUD38400,BAUD56000,
BAUD57600,BAUD115200,BAUD128000, BAUD256000};
DataBitsType BitsTypes[]={DATA_5,DATA_6, DATA_7, DATA_8};
for(int i=;i<;i++)
{
ui->serial_baud->addItem(QString("%1").arg((int)RateTypes[i]),RateTypes[i]);
} for(int i=;i<;i++)
{
ui->serial_data->addItem(QString("%1").arg((int)BitsTypes[i]),BitsTypes[i]);
} ui->serial_parity->addItem("无",PAR_NONE);
ui->serial_parity->addItem("奇校验",PAR_ODD);
ui->serial_parity->addItem("偶校验",PAR_EVEN); ui->serial_stop->addItem("",STOP_1);
ui->serial_stop->addItem("1.5",STOP_1_5);
ui->serial_stop->addItem("",STOP_2);
} void Widget::initSerial() //初始化串口
{
onPortAddedOrRemoved();
enumerator = new QextSerialEnumerator();
enumerator->setUpNotifications(); connect(enumerator, SIGNAL(deviceDiscovered(QextPortInfo)),this, SLOT(onPortAddedOrRemoved())); //发现有串口
connect(enumerator, SIGNAL(deviceRemoved(QextPortInfo)), this, SLOT(onPortAddedOrRemoved())); //发现没有串口了 port = new QextSerialPort(QextSerialPort::EventDriven,this);
connect(port, SIGNAL(readyRead()), this,SLOT(readLineData())); //连接信号
} void Widget::on_btn_send_clicked() //发送数据
{
if (port->isOpen() && !ui->sendEdit->toPlainText().isEmpty())
{
QString data = ui->sendEdit->toPlainText();
data+="\r\n";
        port->write( data.toLocal8Bit());
      }
} void Widget::on_betn_clear_clicked()//清除接收数据
{
ui->recvEdit->clear();
} void Widget::on_btn_switch_clicked()//串口开关
{if(!port->isOpen()) //当前未打开
{
Change_btn_isOn(true);
port->setPortName(ui->serial_name->itemData(ui->serial_name->currentIndex()).toString());
port->setBaudRate((BaudRateType)ui->serial_baud->itemData(ui->serial_baud->currentIndex()).toInt());
port->setDataBits((DataBitsType)ui->serial_data->itemData(ui->serial_data->currentIndex()).toInt());
port->setParity((ParityType)ui->serial_parity->itemData(ui->serial_parity->currentIndex()).toInt());
port->setStopBits((StopBitsType)ui->serial_stop->itemData(ui->serial_stop->currentIndex()).toInt());
port->open(QIODevice::ReadWrite);
}
else
{
Change_btn_isOn(false);
port->close();
}
} void Widget::closeEvent(QCloseEvent *)
{
if(port->isOpen())
port->close();
} void Widget::readLineData() //读数据
{
while(port->canReadLine()) {
ui->recvEdit->moveCursor(QTextCursor::End);
ui->recvEdit->insertPlainText(QString::fromLocal8Bit(port->readLine()));
}
} void Widget::onPortAddedOrRemoved() //刷新串口号
{
QString current = ui->serial_name->currentText();
ui->serial_name->blockSignals(true); //阻塞信号
ui->serial_name->clear(); foreach (QextPortInfo info, QextSerialEnumerator::getPorts())
{
QString friendname = info.friendName;
int end=friendname.lastIndexOf(" ");
if(end!=-)
{
ui->serial_name->addItem(QString("%1:%2").arg(info.portName).arg(info.friendName.left(end)),info.portName);
}
else
{
ui->serial_name->addItem(QString("%1:%2").arg(info.portName).arg(info.friendName),info.portName);
}
} ui->serial_name->setCurrentIndex(ui->serial_name->findText(current));
if(ui->serial_name->currentIndex()==-)
ui->serial_name->setCurrentIndex();
ui->serial_name->blockSignals(false); //关闭阻塞
} void Widget::Change_btn_isOn(bool ison)
{
if(!ison)
{
ui->btn_switch->setStyleSheet("color:blue;border: 1px solid blue");
ui->btn_switch->setText("打开串口");
}
else
{
ui->btn_switch->setStyleSheet("color:red;border: 1px solid red");
ui->btn_switch->setText("关闭串口");
}
} Widget::~Widget()
{
delete ui;
} void Widget::on_serial_name_currentIndexChanged(int index)
{
if (port->isOpen()) { //如果是开启的,则关闭串口
port->close();
Change_btn_isOn(false);
}
}

 

34.QT-制作串口助手(并动态检测在线串口,附带源码)的更多相关文章

  1. Atitit 图像清晰度 模糊度 检测 识别 评价算法 源码实现attilax总结

    Atitit 图像清晰度 模糊度 检测 识别 评价算法 源码实现attilax总结 1.1. 原理,主要使用像素模糊后的差别会变小1 1.2. 具体流程1 1.3. 提升性能 可以使用采样法即可..1 ...

  2. iOS 指南针的制作 附带源码

    iOS  指南针的制作  附带源码 代码下载地址: http://vdisk.weibo.com/s/HK4yE   http://pan.baidu.com/share/link?shareid=7 ...

  3. [数据结构1.2-线性表] 动态数组ArrayList(.NET源码学习)

    [数据结构1.2-线性表] 动态数组ArrayList(.NET源码学习) 在C#中,存在常见的九种集合类型:动态数组ArrayList.列表List.排序列表SortedList.哈希表HashTa ...

  4. 串口助手下载-带时间戳的串口助手-极简串口助手-V1.1 自动保存配置参数 能显示收发时间方便调试

    1.串口助手下载 2.带时间戳的串口助手,每次收发指令带上了时间戳,方便调试 3.极简串口助手 4.简单易用 高速稳定 5.每次修改的参数都能自动保存,免去了重复配置的工作 下载地址:http://w ...

  5. 福利!Python制作动态字符画(附源码)

    字符画,一种由字母.标点.汉字或其他字符组成的图画.简单的字符画是利用字符的形状代替图画的线条来构成简单的人物.事物等形象,它一般由人工制作而成:复杂的字符画通常利用占用不同数量像素的字符代替图画上不 ...

  6. 使用 SVG 制作单选和多选框动画【附源码】

    通过 JavaScript 实现 SVG 路径动画,我们可以做很多花哨的东西.今天我们要为您介绍一些复选框和单选按钮效果.实现的主要思路是隐藏原生的输入框,使用伪元素创造更具吸引力的样式,输入框被选中 ...

  7. Qt一步一步实现插件调用(附源码)

    最近手里几个项目都采用插件的方式进行开发工作,这里记录一下实现方法,给需要的同学一个参考, 在linux系统和window系统都能成功编译通过,不废话直接步骤 第一步:建立插件原型 新建一个Qt项目, ...

  8. Qt一步一步实现插件通信(附源码)

      前一章已经实现了主程序调用加载插件功能,这一章描述主程序和插件间通信功能 说道Qt的通信必须要了解信号和槽的机制原理,这里不做论述,不清楚的同学去看看信号和槽机制 不废话直接上步骤,在上一章的基础 ...

  9. java动态代理基本原理及proxy源码分析一

    本系列文章主要是博主在学习spring aop的过程中了解到其使用了java动态代理,本着究根问底的态度,于是对java动态代理的本质原理做了一些研究,于是便有了这个系列的文章 为了尽快进入正题,这里 ...

随机推荐

  1. Python之路【第三篇】编码

    Python代码——>字节码——>机器码——>计算机 Windows: cmd ==> python 文件路径 cmd ==>python >> 输入命令 L ...

  2. Hystrix 熔断机制

    熔断机制相当于电路的跳闸功能,即在一定时间内,错误比例达到一定数目时业务从原来流程转移到另外的流程处理.在一段时间后,恢复到原业务逻辑. 测试代码如下 /** * @author zimu * @de ...

  3. MySQL注入技巧性研究

    0x00 前言 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品.MySQL 是最流行的关系型数据库管理系统之一,本人最近针对MySQL注入做了 ...

  4. eclipse使用和快捷键

    一.快捷键 - ctrl + shift + o 导包 - ctrl + shift + t 快速查找某个类 - 先按ctrl + 2 ,再点L, 创建变量并命名 - ctrl + o , 在当前类中 ...

  5. 吴恩达机器学习笔记1-单变量线性回归(Linear Regression with One Variable)

    在监督学习中我们有一个数据集,这个数据集被称训练集.

  6. 第55节:Java当中的IO流-时间api(下)-上

    Java当中的IO流(下)-上 日期和时间 日期类:java.util.Date 系统时间: long time = System.currentTimeMillis(); public class ...

  7. npm安装webpack失败(mac和window都可能会遇到这样的情况,以下问题主要以mac为例)

     问题描述:我想查看一下webpack的版本,于是输入了命令webpack -v, 结果如下图所示: 注:这里提示我们要安装webpack-cli,是因为到了webpack4, webpack 已经将 ...

  8. idea中如何将单个java类导出为jar包文件?

    idea作为一个java开发的便利IDE工具,个人是比较喜欢的,今天来探索个小功能:  导出单个类文件为jar包! 偶有这种需求,就是某个类文件独立存在,但是需要将其导出为jar,供别人临时使用,或者 ...

  9. 10 种保护 Spring Boot 应用的绝佳方法

    原文:developer.okta.com/blog/2018/07/30/10-ways-to-secure-spring-boot 译文:www.jdon.com/49653 Spring Boo ...

  10. JVM学习(一)、垃圾收集器简介

    一.垃圾收集算法 (1)标记-清除算法:最基础的收集算法“标记--清除”(Mark-sweep)算法,算法分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的 ...