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. linux根目录介绍

    1. /bin binary二进制 存放系统许多可执行程序文件 执行的相关指令,例如ls pwd whoami,后台的支持文件目录 2. /sbin super binary超级的二进制 存放系统许多 ...

  2. ubuntu下file_get_contents返回空字符串

    ubuntu下file_get_contents返回空字符串 | 浏览:302 | 更新:2014-03-30 10:11 本文起初面临的问题是PHP中SoapClient不好使,最后file_get ...

  3. 背水一战 Windows 10 (115) - 后台任务: 通过 toast 激活后台任务, 定时激活后台任务

    [源码下载] 背水一战 Windows 10 (115) - 后台任务: 通过 toast 激活后台任务, 定时激活后台任务 作者:webabcd 介绍背水一战 Windows 10 之 后台任务 通 ...

  4. 【高速接口-RapidIO】6、Xilinx RapidIO核仿真与包时序分析

    提示:本文的所有图片如果不清晰,请在浏览器的新建标签中打开或保存到本地打开 一.软件平台与硬件平台 软件平台: 操作系统:Windows 8.1 64-bit 开发套件:Vivado2015.4.2 ...

  5. 2019-4-29 js学习笔记

    js学习笔记一:js数据类型   1:基本数据类型       number类型(整数,小数)      String类型          boolean类型        NaN类型其实是一个nu ...

  6. 手工检测SQL注入漏洞

    SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令,具体来说,它是利用现有应用程序将(恶意的)SQL命令注入到后台数据库引擎执 ...

  7. [Postman]发送第一个请求(1)

    通过API请求,您可以与具有要访问的API端点的服务器联系,并执行某些操作.这些操作是HTTP方法. 最常用的方法是GET,POST,PUT和DELETE.方法的名称是不言自明的.例如,GET使您可以 ...

  8. Kubernetes 新时代的宠儿

    本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. Kuberne ...

  9. MYSQL服务器系统变量

    一:查看服务所有变量 MySQL服务器维护许多配置其操作的系统变量.每个系统变量都有一个默认值.可以使用命令行或选项文件中的选项在服务器启动时设置系统变量.其中大多数都可以在运行时使用动态更改 SET ...

  10. 【spring】aop切面通知,日志处理

    1.spring的切面编程 概念原理可以看这里:http://blog.csdn.net/moreevan/article/details/11977115 2.所需要的jar包 maven引入jar ...