diff --git a/SerialForwardingTool/SerialForwardingTool.pro b/SerialForwardingTool/SerialForwardingTool.pro new file mode 100644 index 0000000..b33af5a --- /dev/null +++ b/SerialForwardingTool/SerialForwardingTool.pro @@ -0,0 +1,44 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2019-05-08T09:02:42 +# +#------------------------------------------------- + +QT += core gui +QT += serialport + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = SerialForwardingTool +TEMPLATE = app + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +CONFIG += c++11 + +SOURCES += \ + main.cpp \ + mainwindow.cpp + +HEADERS += \ + mainwindow.h + +FORMS += \ + mainwindow.ui + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +RESOURCES += \ + hres.qrc diff --git a/SerialForwardingTool/SerialForwardingTool.pro.user b/SerialForwardingTool/SerialForwardingTool.pro.user new file mode 100644 index 0000000..7c99409 --- /dev/null +++ b/SerialForwardingTool/SerialForwardingTool.pro.user @@ -0,0 +1,567 @@ + + + + + + EnvironmentId + {2d03fc4c-541a-4fa5-8f5c-ae92a1998dce} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.11.2 MinGW 32bit + Desktop Qt 5.11.2 MinGW 32bit + qt.qt5.5112.win32_mingw53_kit + 0 + 0 + 0 + + E:/C++/Qt/build-SerialForwardingTool-Desktop_Qt_5_11_2_MinGW_32bit-Debug + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + + E:/C++/Qt/build-SerialForwardingTool-Desktop_Qt_5_11_2_MinGW_32bit-Release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + + E:/C++/Qt/build-SerialForwardingTool-Desktop_Qt_5_11_2_MinGW_32bit-Profile + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 3 + + + 0 + 部署 + + ProjectExplorer.BuildSteps.Deploy + + 1 + Deploy Configuration + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + SerialForwardingTool + + Qt4ProjectManager.Qt4RunConfiguration:E:/C++/Qt/SerialForwardingTool/SerialForwardingTool.pro + true + + SerialForwardingTool.pro + + + 3768 + false + true + false + false + true + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.6.2 MinGW 32bit2 + Desktop Qt 5.6.2 MinGW 32bit2 + qt.56.win32_mingw49_kit + 0 + 0 + 0 + + E:/C++/Qt/build-SerialForwardingTool-Desktop_Qt_5_6_2_MinGW_32bit2-Debug + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + + E:/C++/Qt/build-SerialForwardingTool-Desktop_Qt_5_6_2_MinGW_32bit2-Release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + + E:/C++/Qt/build-SerialForwardingTool-Desktop_Qt_5_6_2_MinGW_32bit2-Profile + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + true + false + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 3 + + + 0 + 部署 + + ProjectExplorer.BuildSteps.Deploy + + 1 + Deploy Configuration + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + + + + Custom Executable + + ProjectExplorer.CustomExecutableRunConfiguration + 3768 + false + true + false + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 18 + + + Version + 18 + + diff --git a/SerialForwardingTool/hres.qrc b/SerialForwardingTool/hres.qrc new file mode 100644 index 0000000..badd040 --- /dev/null +++ b/SerialForwardingTool/hres.qrc @@ -0,0 +1,5 @@ + + + res/ico/icon.ico + + diff --git a/SerialForwardingTool/main.cpp b/SerialForwardingTool/main.cpp new file mode 100644 index 0000000..aab39bb --- /dev/null +++ b/SerialForwardingTool/main.cpp @@ -0,0 +1,11 @@ +#include "mainwindow.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.show(); + + return a.exec(); +} diff --git a/SerialForwardingTool/mainwindow.cpp b/SerialForwardingTool/mainwindow.cpp new file mode 100644 index 0000000..90910c2 --- /dev/null +++ b/SerialForwardingTool/mainwindow.cpp @@ -0,0 +1,275 @@ +#include "mainwindow.h" +#include "ui_mainwindow.h" +#include +#include +#include +#include + +MainWindow::MainWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::MainWindow), + m_serialPortA(new QSerialPort), + m_serialPortB(new QSerialPort), + m_isMonitor(false) +{ + ui->setupUi(this); + setWindowIcon(QIcon(":/res/ico/icon.ico")); + setWindowTitle(" 串口转发工具"); + setWindowFlags(windowFlags() & ~Qt::WindowMaximizeButtonHint); + setFixedSize(this->width(), this->height()); + + // 获取本机串口名称 + for (const auto &sp : QSerialPortInfo::availablePorts()) + { + ui->cmbCOMA->addItem(sp.portName()); + ui->cmbCOMB->addItem(sp.portName()); + } + + // 设置波特率选项 + QMetaEnum baudRate = QMetaEnum::fromType(); + for (int i = 0; i < baudRate.keyCount(); ++i) + { + ui->cmbBaudRateA->addItem(baudRate.key(i)); + ui->cmbBaudRateB->addItem(baudRate.key(i)); + } + // 设置默认波特率为9600 + ui->cmbBaudRateA->setCurrentText(baudRate.valueToKey(QSerialPort::BaudRate::Baud9600)); + ui->cmbBaudRateB->setCurrentText(baudRate.valueToKey(QSerialPort::BaudRate::Baud9600)); + + // 设置数据位选项 + QMetaEnum dataBits = QMetaEnum::fromType(); + for (int i = 0; i < dataBits.keyCount(); ++i) + { + ui->cmbDataBitsA->addItem(dataBits.key(i)); + ui->cmbDataBitsB->addItem(dataBits.key(i)); + } + // 设置默认数据为选项为8位 + ui->cmbDataBitsA->setCurrentText(dataBits.valueToKey(QSerialPort::DataBits::Data8)); + ui->cmbDataBitsB->setCurrentText(dataBits.valueToKey(QSerialPort::DataBits::Data8)); + + // 设置校验位选项 + QMetaEnum parity = QMetaEnum::fromType(); + for (int i = 0; i < parity.keyCount(); ++i) + { + ui->cmbParityA->addItem(parity.key(i)); + ui->cmbParityB->addItem(parity.key(i)); + } + + // 设置停止位选项 + QMetaEnum stopBits = QMetaEnum::fromType(); + for (int i = 0; i < stopBits.keyCount(); ++i) + { + ui->cmbStopBitsA->addItem(stopBits.key(i)); + ui->cmbStopBitsB->addItem(stopBits.key(i)); + } + +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +/** + * @brief MainWindow::openSerialPort 根据用户设置打开串口,返回是否打开成功 + * @return 是否打开成功 + */ +bool MainWindow::openSerialPort() +{ + ui->txtOutput->clear(); + if (ui->cmbCOMA->currentText() == ui->cmbCOMB->currentText()) + { + ui->txtOutput->append("不能选择相同的串口!"); + return false; + } + if (ui->cmbCOMA->currentText() == "" || ui->cmbCOMB->currentText() == "") + { + ui->txtOutput->append("不能有串口为空"); + return false; + } + + // 打开串口A + ui->txtOutput->append("正在尝试打开串口A..."); + // 设置串口名 + m_serialPortA->setPortName(ui->cmbCOMA->currentText()); + // 设置波特率 + m_serialPortA->setBaudRate(static_cast(QMetaEnum::fromType().keyToValue(ui->cmbBaudRateA->currentText().toStdString().data()))); + // 设置数据位 + m_serialPortA->setDataBits(static_cast(QMetaEnum::fromType().keyToValue(ui->cmbDataBitsA->currentText().toStdString().data()))); + // 无流控制 + m_serialPortA->setFlowControl(QSerialPort::FlowControl::NoFlowControl); + // 设置校验位 + m_serialPortA->setParity(static_cast(QMetaEnum::fromType().keyToValue(ui->cmbParityA->currentText().toStdString().data()))); + // 设置停止位 + m_serialPortA->setStopBits(static_cast(QMetaEnum::fromType().keyToValue(ui->cmbStopBitsA->currentText().toStdString().data()))); + // 尝试以读写方式打开 + if (!m_serialPortA->open(QIODevice::ReadWrite)) + { + ui->txtOutput->append("串口A打开失败!错误信息:" + m_serialPortA->errorString()); + return false; + } + else + { + ui->txtOutput->append("串口A打开成功!"); + } + + // 打开串口B + ui->txtOutput->append("正在尝试打开串口B..."); + // 设置串口名 + m_serialPortB->setPortName(ui->cmbCOMB->currentText()); + // 设置波特率 + m_serialPortB->setBaudRate(static_cast(QMetaEnum::fromType().keyToValue(ui->cmbBaudRateB->currentText().toStdString().data()))); + // 设置数据位 + m_serialPortB->setDataBits(static_cast(QMetaEnum::fromType().keyToValue(ui->cmbDataBitsB->currentText().toStdString().data()))); + // 无流控制 + m_serialPortB->setFlowControl(QSerialPort::FlowControl::NoFlowControl); + // 设置校验位 + m_serialPortB->setParity(static_cast(QMetaEnum::fromType().keyToValue(ui->cmbParityB->currentText().toStdString().data()))); + // 设置停止位 + m_serialPortB->setStopBits(static_cast(QMetaEnum::fromType().keyToValue(ui->cmbStopBitsB->currentText().toStdString().data()))); + // 尝试以读写方式打开 + if (!m_serialPortB->open(QIODevice::ReadWrite)) + { + ui->txtOutput->append("串口B打开失败!错误信息:" + m_serialPortB->errorString()); + if (m_serialPortA->isOpen()) + { + m_serialPortA->close(); + ui->txtOutput->append("关闭串口A"); + } + return false; + } + else + { + ui->txtOutput->append("串口B打开成功!"); + } + // 连接串口信号槽 + { + // 串口A接收数据信号 + connect(m_serialPortA,SIGNAL(readyRead()),this,SLOT(comAReceiveInfo())); + // 串口B接收数据信号 + connect(m_serialPortB,SIGNAL(readyRead()),this,SLOT(comBReceiveInfo())); + } + return true; +} + +/** + * @brief MainWindow::closeSerialPort 关闭串口 + */ +void MainWindow::closeSerialPort() +{ + // 断开串口信号槽连接 + { + // 串口A接收数据信号 + disconnect(m_serialPortA,SIGNAL(readyRead()),this,SLOT(comAReceiveInfo())); + // 串口B接收数据信号 + disconnect(m_serialPortB,SIGNAL(readyRead()),this,SLOT(comBReceiveInfo())); + } + m_serialPortA->close(); + m_serialPortB->close(); +} + +/** + * @brief MainWindow::on_btnStart_clicked 开始转发按钮点击事件 + */ +void MainWindow::on_btnStart_clicked() +{ + if (ui->btnStart->text() == "开始转发") + { + // 尝试打开串口 + if (this->openSerialPort()) + { + ui->txtOutput->clear(); + ui->txtOutput->append("串口打开成功!开始转发"); + + // 禁用所有选择框 + ui->cmbCOMA->setEnabled(false); + ui->cmbCOMB->setEnabled(false); + ui->cmbBaudRateA->setEnabled(false); + ui->cmbBaudRateB->setEnabled(false); + ui->cmbDataBitsA->setEnabled(false); + ui->cmbDataBitsB->setEnabled(false); + ui->cmbParityA->setEnabled(false); + ui->cmbParityB->setEnabled(false); + ui->cmbStopBitsA->setEnabled(false); + ui->cmbStopBitsB->setEnabled(false); + ui->btnStart->setText("停止转发"); + } + } + else + { + // 关闭串口 + this->closeSerialPort(); + // 禁用所有选择框 + ui->cmbCOMA->setEnabled(true); + ui->cmbCOMB->setEnabled(true); + ui->cmbBaudRateA->setEnabled(true); + ui->cmbBaudRateB->setEnabled(true); + ui->cmbDataBitsA->setEnabled(true); + ui->cmbDataBitsB->setEnabled(true); + ui->cmbParityA->setEnabled(true); + ui->cmbParityB->setEnabled(true); + ui->cmbStopBitsA->setEnabled(true); + ui->cmbStopBitsB->setEnabled(true); + ui->btnStart->setText("开始转发"); + } +} + +/** + * @brief MainWindow::comAReceiveInfo COMA接收消息事件 + */ +void MainWindow::comAReceiveInfo() +{ + if (m_isMonitor) + { + auto data = m_serialPortA->readAll(); + ui->txtOutput->append(data); + // 将A发的转发给B + m_serialPortB->write(data); + } + else + { + m_serialPortB->write(m_serialPortA->readAll()); + } +} + +/** + * @brief MainWindow::comBReceiveInfo COMB接收消息事件 + */ +void MainWindow::comBReceiveInfo() +{ + if (m_isMonitor) + { + auto data = m_serialPortB->readAll(); + ui->txtOutput->append(data); + // 将B发的转发给A + m_serialPortA->write(data); + } + else + { + m_serialPortA->write(m_serialPortB->readAll()); + } +} + +void MainWindow::on_btnClear_clicked() +{ + ui->txtOutput->clear(); +} + +void MainWindow::on_checkBox_stateChanged(int isChecked) +{ + if (isChecked) + { + m_isMonitor = true; + ui->txtOutput->append("开始监听"); + } + else + { + m_isMonitor = false; + ui->txtOutput->append("停止监听"); + } +} + +void MainWindow::closeEvent(QCloseEvent *) +{ + this->closeSerialPort(); +} diff --git a/SerialForwardingTool/mainwindow.h b/SerialForwardingTool/mainwindow.h new file mode 100644 index 0000000..9f77f81 --- /dev/null +++ b/SerialForwardingTool/mainwindow.h @@ -0,0 +1,66 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include + +namespace Ui { +class MainWindow; +} + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow(); +private: + /** + * @brief MainWindow::openSerialPort 根据用户设置打开串口,返回是否打开成功 + * @return 是否打开成功 + */ + bool openSerialPort(); + /** + * @brief MainWindow::closeSerialPort 关闭串口 + */ + void closeSerialPort(); + +private slots: + /** + * @brief MainWindow::on_btnStart_clicked 开始转发按钮点击事件 + */ + void on_btnStart_clicked(); + + /** + * @brief MainWindow::comAReceiveInfo COMA接收消息事件 + */ + void comAReceiveInfo(); + /** + * @brief MainWindow::comBReceiveInfo COMB接收消息事件 + */ + void comBReceiveInfo(); + + void on_btnClear_clicked(); + + void on_checkBox_stateChanged(int); +protected: + void closeEvent(QCloseEvent *); + +private: + Ui::MainWindow *ui; + + /** + * @brief 串口A + */ + QSerialPort *m_serialPortA; + /** + * @brief 串口B + */ + QSerialPort *m_serialPortB; + + bool m_isMonitor; +}; + +#endif // MAINWINDOW_H diff --git a/SerialForwardingTool/mainwindow.ui b/SerialForwardingTool/mainwindow.ui new file mode 100644 index 0000000..b23fcf0 --- /dev/null +++ b/SerialForwardingTool/mainwindow.ui @@ -0,0 +1,269 @@ + + + MainWindow + + + + 0 + 0 + 481 + 442 + + + + MainWindow + + + + + + 10 + 10 + 461 + 421 + + + + + + + QLayout::SetDefaultConstraint + + + + + + 0 + 180 + + + + + 16777215 + 180 + + + + 串口A设置: + + + + + 10 + 30 + 205 + 131 + + + + + + + 串口号: + + + + + + + + + + 波特率: + + + + + + + + + + 奇偶校验: + + + + + + + + + + 数据位: + + + + + + + + + + 停止位: + + + + + + + + + + + + + + + 0 + 180 + + + + + 16777215 + 180 + + + + 串口B设置: + + + + + 10 + 30 + 205 + 131 + + + + + + + 串口号: + + + + + + + + + + 波特率: + + + + + + + + + + 奇偶校验: + + + + + + + + + + 数据位: + + + + + + + + + + 停止位: + + + + + + + + + + + + + + + + 状态: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + 10 + 53 + 441 + 131 + + + + + + + 10 + 40 + 54 + 12 + + + + 输出: + + + + + + 10 + 20 + 201 + 16 + + + + 是否监听消息(可能会影响效率) + + + + + + 400 + 30 + 51 + 23 + + + + 清空 + + + + + + + + 开始转发 + + + + + + + + + + + diff --git a/SerialForwardingTool/res/ico/icon.ico b/SerialForwardingTool/res/ico/icon.ico new file mode 100644 index 0000000..cc8910f Binary files /dev/null and b/SerialForwardingTool/res/ico/icon.ico differ diff --git a/SerialForwardingTool/res/ico/inwinic.ico b/SerialForwardingTool/res/ico/inwinic.ico new file mode 100644 index 0000000..8c72c01 Binary files /dev/null and b/SerialForwardingTool/res/ico/inwinic.ico differ diff --git a/img1.png b/img1.png new file mode 100644 index 0000000..5593e5b Binary files /dev/null and b/img1.png differ diff --git a/img2.png b/img2.png new file mode 100644 index 0000000..a715cf0 Binary files /dev/null and b/img2.png differ