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. NodeJs在windows上安装配置测试

    Node.js简介简单的说 Node.js 就是运行在服务端的 JavaScript.Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境.Node.js 使用了一个 ...

  2. PSR-PHP开发规范(本文版权归作者:luluyrt@163.com)

    遵循PSR-4的自动加载 一.简介 首先这里要了解PSR,Proposing a Standards Recommendation(提出标准建议)的缩写,就是一种PHP开发规范,让我们研发出来的代码更 ...

  3. 查看 Oracle 数据库锁和解锁的方法

    -- 查看数据库锁明细 select a.sid, b.serial#, b.username, b.osuser, b.machine, b.program, c.object_name,d.spi ...

  4. 《C# 从现象到本质》出版,免费送书10本

    我的第一本书<C# 从现象到本质>已于近日正式在京东和淘宝天猫上开始销售了.至此,我的图书写作和出版活动正式告一段落.图书销售网址见下. 试读样章 京东 天猫 从看书到写书 借着图书出版之 ...

  5. Android开发 - 掌握ConstraintLayout(七)辅助线(Guideline)

    了解过UI设计的同学都知道,在设计的时候,我们经常在界面上拖进一些辅助线来帮我们对齐UI元素,或者方便我们统一的页边距. 在ConstraintLayout的编辑器中,同样也支持这样的功能,我们可以创 ...

  6. 跟繁琐的命令行说拜拜!Gerapy分布式爬虫管理框架来袭!

    背景 用 Python 做过爬虫的小伙伴可能接触过 Scrapy,GitHub:https://github.com/scrapy/scrapy.Scrapy 的确是一个非常强大的爬虫框架,爬取效率高 ...

  7. flash中调用XML遇到的中文显示异常问题

    昨天使用flash调用XML文件进行显示时,出现了中文无法显示的问题,记录一下解决方法: 1.字体设置: 一般flash里的动态文本和嵌入文本都是默认的使用Arial字体,这个字体里可能没有中文,所以 ...

  8. Linux的用户管理(基础篇)

    用户相关 临时切换用户: su 用户名 完全切换用户: su – 用户名 查看当前登入的用户名: whoami 查看当前用户下的一切环境变量: env 登出当前登入的用户: logout 查看系统的用 ...

  9. System.net.mail.smtpException;服务器提交了协议冲突 服务器响应为:

    最近发邮件遇到问题. 主机godaddy 端口 25,80 都可以用 stmp服务器地址:smtpout.secureserver.net 不支持ssl 我就吧 EnableSsl 设置为false了 ...

  10. 如何将云原生工作负载映射到 Kubernetes 中的控制器

    作者:Janakiram MSV 译者:殷龙飞 原文地址:https://thenewstack.io/how-to-map-cloud-native-workloads-to-kubernetes- ...