Qt 转发两串口数据(二桌面程序版)
Posted 福州-司马懿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt 转发两串口数据(二桌面程序版)相关的知识,希望对你有一定的参考价值。
需求
两串口设置统一,均如下图:
项目实战(桌面程序版,这里采用的是动态布局)
项目的pro文件
在项目的pro文件中添加
QT += serialport
forwardobj.h
#ifndef FORWARDOBJ_H
#define FORWARDOBJ_H
#include <QObject>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
/** 波特率:位/秒(B) */
const QSerialPort::BaudRate BAUND_RATE = QSerialPort::Baud115200;
/** 数据位(D) */
const QSerialPort::DataBits DATA_BITS = QSerialPort::Data8;
/** 奇偶校验(P) */
const QSerialPort::Parity PARITY = QSerialPort::NoParity;
/** 停止位(S) */
const QSerialPort::StopBits STOP_BITS = QSerialPort::OneStop;
/** 流控制(F) */
const QSerialPort::FlowControl FLOW_CONTROL = QSerialPort::NoFlowControl;
class ForwardObj : public QObject
Q_OBJECT
public:
explicit ForwardObj(QObject *parent = 0);
~ForwardObj();
/** @brief 获取可用端口数目 */
static int getAvaliablePortsCount();
/** @brief 获取可用的端口名称 */
static QStringList getAvaliablePortNames();
/** @brief 获取可用端口详细信息 */
static QString getAvailablePorts();
/** @brief 打开串口并设置相应的参数 */
bool openPort(const QString &portName1, const QString &portName2);
/** @brief 连接两串口,用于转发 */
void connectDoublePort();
/** @brief 关闭串口 */
void close();
signals:
void log(QString str);
public slots:
void port1ReadyRead();
void port2ReadyRead();
private:
QSerialPort serialPort1;
QSerialPort serialPort2;
/** @brief 打开串口并设置相应的参数 */
bool openPort(QSerialPort &serialPort, const QString &portName);
/** @brief 转发收到的数据 */
void forward(QSerialPort &fromPort, QSerialPort &toPort);
;
#endif // FORWARDOBJ_H
logcontrol.h
#ifndef LOGCONTROL_H
#define LOGCONTROL_H
#include <QStringList>
/** 最大条目数 */
const int MAX_ITEMS_SIZE = 500;
class LogControl : public QStringList
public:
LogControl();
void append(QString str);
QString toString();
;
#endif // LOGCONTROL_H
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QTextBrowser>
#include <QLabel>
#include <QComboBox>
#include <QPushButton>
#include "forwardobj.h"
#include "logcontrol.h"
class MainWindow : public QMainWindow
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void onRefreshBtnClick();
void onOpenSerialPortBtnClick();
void onClearBtnClick();
void onLog(QString str);
private:
QComboBox *serialPortCb1;
QComboBox *serialPortCb2;
QTextBrowser *textBrowser;
ForwardObj *forwardObj;
LogControl logControl;
;
#endif // MAINWINDOW_H
forwardobj.cpp
#include "forwardobj.h"
ForwardObj::ForwardObj(QObject *parent) : QObject(parent)
ForwardObj::~ForwardObj()
close();
int ForwardObj::getAvaliablePortsCount()
int count = 0;
QList<QSerialPortInfo> ports = QSerialPortInfo::availablePorts();
if(!ports.isEmpty())
count = ports.count();
return count;
QStringList ForwardObj::getAvaliablePortNames()
QStringList serialPortNameList;
foreach(QSerialPortInfo info, QSerialPortInfo::availablePorts())
serialPortNameList.append(info.portName());
return serialPortNameList;
QString ForwardObj::getAvailablePorts()
QString str;
QList<QSerialPortInfo> portInfoList = QSerialPortInfo::availablePorts();
if(portInfoList.isEmpty())
str.append("Not found any avaliable serial ports");
return str;
str.append(QString("Found %1 avaliable serial ports\\n\\n").arg(portInfoList.size()));
foreach(QSerialPortInfo info, portInfoList)
str.append(QString("Name : %1\\n").arg(info.portName()));
str.append(QString("Description : %1\\n").arg(info.description()));
str.append(QString("Manufacturer: %1\\n").arg(info.manufacturer()));
str.append(QString("serialNumber: %1\\n").arg(info.serialNumber()));
str.append("\\n");
return str;
bool ForwardObj::openPort(const QString &portName1, const QString &portName2)
bool ret;
ret = openPort(serialPort1, portName1);
if(ret)
ret = openPort(serialPort2, portName2);
if(!ret)
close();
return ret;
void ForwardObj::connectDoublePort()
connect(&serialPort1, SIGNAL(readyRead()), this, SLOT(port1ReadyRead()));
connect(&serialPort2, SIGNAL(readyRead()), this, SLOT(port2ReadyRead()));
void ForwardObj::close()
disconnect(&serialPort1, SIGNAL(readyRead()), this, SLOT(port1ReadyRead()));
disconnect(&serialPort2, SIGNAL(readyRead()), this, SLOT(port2ReadyRead()));
if(serialPort1.isOpen())
QString str(serialPort1.portName());
str.append(" has closed");
serialPort1.close();
emit log(str);
if(serialPort2.isOpen())
QString str(serialPort1.portName());
str.append(" has closed");
serialPort2.close();
emit log(str);
void ForwardObj::port1ReadyRead()
forward(serialPort1, serialPort2);
void ForwardObj::port2ReadyRead()
forward(serialPort2, serialPort1);
bool ForwardObj::openPort(QSerialPort &serialPort, const QString &portName)
foreach (const QSerialPortInfo info, QSerialPortInfo::availablePorts())
if(QString::compare(info.portName(), portName, Qt::CaseInsensitive) == 0)
serialPort.setPort(info);
//打开串口后才能进行余下设置
bool ret = serialPort.open(QIODevice::ReadWrite);
if(ret)
serialPort.setBaudRate(BAUND_RATE);
serialPort.setDataBits(DATA_BITS);
serialPort.setParity(PARITY);
serialPort.setStopBits(STOP_BITS);
serialPort.setFlowControl(FLOW_CONTROL);
serialPort.clearError();
//The serial port has to be open before trying to clear any buffered data; otherwise returns false and sets the NotOpenError error code.
serialPort.clear();
if(ret)
emit log("Open serial port " + info.portName() + " succ");
else
emit log("Open serial port " + info.portName() + " fail(" + serialPort.error() + ", " + serialPort.errorString() + ")");
return ret;
emit log("serial port \\""+ portName +"\\" not found");
return false;
void ForwardObj::forward(QSerialPort &fromPort, QSerialPort &toPort)
QByteArray buffer = fromPort.readAll();
emit log("Read from " + fromPort.portName() + ", data : \\n\\t" + buffer.toHex());
qint64 len = toPort.write(buffer);
if(len == -1)
emit log("Forward to " + toPort.portName() + " fail, error occur: \\n\\t" + toPort.errorString());
else
emit log("Forward to " + toPort.portName() + " succ");
logcontrol.cpp
#include "logcontrol.h"
LogControl::LogControl() : QStringList()
void LogControl::append(QString str)
while(size() >= MAX_ITEMS_SIZE)
removeAt(0);
QStringList::append(str);
QString LogControl::toString()
return join('\\n');
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
mainwindow.cpp
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
//Qt中父亲被删除的时候会自动销毁他的孩子。所以如果New出来的并且没有父亲,那么则需要手动删除它。
QWidget *containerWidget = new QWidget(this);
QVBoxLayout *vboxLayout = new QVBoxLayout(this);
QWidget *topWidget = new QWidget(this);
QHBoxLayout *hboxLayout = new QHBoxLayout(this);
QLabel *serialPortLabel = new QLabel("Select two serial port: ", this);
serialPortCb1 = new QComboBox(this);
serialPortCb2 = new QComboBox(this);
QPushButton *refreshBtn = new QPushButton("Refresh", this);
QPushButton *openSerialPortBtn = new QPushButton("Connect", this);
QPushButton *clearBtn = new QPushButton("Clear", this);
textBrowser = new QTextBrowser(this);
this->setCentralWidget(containerWidget);
containerWidget->setLayout(vboxLayout);
vboxLayout->addWidget(topWidget);
topWidget->setLayout(hboxLayout);
hboxLayout->addWidget(serialPortLabel, 0);
hboxLayout->addWidget(serialPortCb1, 1);
hboxLayout->addWidget(serialPortCb2, 1);
hboxLayout->addWidget(refreshBtn, 1);
hboxLayout->addWidget(openSerialPortBtn, 1);
hboxLayout->addWidget(clearBtn, 1);
vboxLayout->addWidget(textBrowser);
forwardObj = new ForwardObj();
connect(refreshBtn, SIGNAL(clicked()), this, SLOT(onRefreshBtnClick()));
connect(openSerialPortBtn, SIGNAL(clicked()), this, SLOT(onOpenSerialPortBtnClick()));
connect(clearBtn, SIGNAL(clicked()), this, SLOT(onClearBtnClick()));
connect(forwardObj, SIGNAL(log(QString)), this, SLOT(onLog(QString)));
onRefreshBtnClick();
MainWindow::~MainWindow()
forwardObj->close();
delete forwardObj;
void MainWindow::onRefreshBtnClick()
onLog(ForwardObj::getAvailablePorts());
QStringList serialPortNameList = ForwardObj::getAvaliablePortNames();
if(serialPortNameList.size() < 2)
onLog("The count of serial ports cannot be smaller than two");
return;
serialPortCb1->clear();
serialPortCb2->clear();
serialPortCb1->addItems(serialPortNameList);
serialPortCb2->addItems(serialPortNameList);
serialPortCb1->setCurrentIndex(0);
serialPortCb2->setCurrentIndex(1);
void MainWindow::onOpenSerialPortBtnClick()
forwardObj->close();
QString serialPortName1 = serialPortCb1->currentText();
QString serialPortName2 = serialPortCb2->currentText();
bool ret = forwardObj->openPort(serialPortName1, serialPortName2);
if(ret)
onLog("two serial port open succ, start forward...");
forwardObj->connectDoublePort();
else
onLog("open fail, please try to reopen");
void MainWindow::onClearBtnClick()
logControl.clear();
textBrowser->clear();
void MainWindow::onLog(QString str)
logControl.append(str);
textBrowser->setText(logControl.toString());
textBrowser->moveCursor(QTextCursor::End);
最后生成的可执行文件需要引用的DLL
- libgcc_s_dw2-1.dll
- libstdc++-6.dll
- libwinpthread-1.dll
- Qt5Core.dll
- Qt5SerialPort.dll
- Qt5Gui.dll
- Qt5Widgets.dll
- platforms(C:\\Qt\\5.7\\mingw53_32\\plugins\\platforms)
以上是关于Qt 转发两串口数据(二桌面程序版)的主要内容,如果未能解决你的问题,请参考以下文章