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: