From fdc93e494e9ecd863b1f4e5a02a8b197a0a8de46 Mon Sep 17 00:00:00 2001 From: 168492376 <168492376@qq.com> Date: Mon, 13 Jan 2025 23:00:58 +0800 Subject: [PATCH] first version --- .gitmodules | 3 + 3rdparty/CSerialPort | 1 + images/left_arrow_gray.png | Bin 0 -> 660 bytes images/left_arrow_green.png | Bin 0 -> 677 bytes images/right_arrow_gray.png | Bin 0 -> 673 bytes images/right_arrow_green.png | Bin 0 -> 659 bytes img.qrc | 8 + logo.ico | Bin 0 -> 1342 bytes main.cpp | 13 ++ mainwindow.cpp | 22 +++ mainwindow.h | 26 ++++ mainwindow.ui | 42 ++++++ serialConfigWidget.cpp | 169 +++++++++++++++++++++ serialConfigWidget.h | 41 +++++ serialConfigWidget.ui | 284 +++++++++++++++++++++++++++++++++++ serialTransferTool.pro | 39 +++++ 16 files changed, 648 insertions(+) create mode 100644 .gitmodules create mode 160000 3rdparty/CSerialPort create mode 100644 images/left_arrow_gray.png create mode 100644 images/left_arrow_green.png create mode 100644 images/right_arrow_gray.png create mode 100644 images/right_arrow_green.png create mode 100644 img.qrc create mode 100644 logo.ico create mode 100644 main.cpp create mode 100644 mainwindow.cpp create mode 100644 mainwindow.h create mode 100644 mainwindow.ui create mode 100644 serialConfigWidget.cpp create mode 100644 serialConfigWidget.h create mode 100644 serialConfigWidget.ui create mode 100644 serialTransferTool.pro diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..49e6a9b --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "3rdparty/CSerialPort"] + path = 3rdparty/CSerialPort + url = https://github.com/itas109/CSerialPort.git diff --git a/3rdparty/CSerialPort b/3rdparty/CSerialPort new file mode 160000 index 0000000..c3928be --- /dev/null +++ b/3rdparty/CSerialPort @@ -0,0 +1 @@ +Subproject commit c3928be6d674bd3bb6df2c81b2486bcd4b82304b diff --git a/images/left_arrow_gray.png b/images/left_arrow_gray.png new file mode 100644 index 0000000000000000000000000000000000000000..a3fd9a432dd849daf305c835f9b36bb9e02238e7 GIT binary patch literal 660 zcmeAS@N?(olHy`uVBq!ia0vp^CxF<7gAGV3M}M6Nq!^2X+?^QKos)S9a~60+7BevL9R^{>#$+}%gHjb^Mqz=yFZ8;UlXH^i-{1Xv|FQ2e7ycT_YyKS=Q=~# z6S{>JE=^i#%rBLIG6kI{9d`8`Ru-CKDDEK-lKJn$dMRBdZr<~~b#^(1!X6zK#~y!t zo?}*BrktQG@aRCm6?P{XiAk>6n5Q-hux|+v2Qr02LCip5AX8Zs#FVlT zc+`;A%;qF>A#VdvhZv6#N8y342S7O;PAMRBRsx901rl9#k6Do~;@WG$9K}ZhlTSXm ztJ@g1?DEU*Xt6J19xE&w^mN3!t+(sE_@jO8Wl5C+-;qU^9aQ)%KlNA$bf05V;E{uu6swbr zhwod5O**rM*@J?$1v;Jov6LuJ=vm!(Vq(gX#*k39O*eDGit^@5H$I8sad~7R!&hw1 z|9pHtqleFj@=J{pA$gyfRw@fD gU}|I#?{&L>|JU9_)tcx30#g!$r>mdKI;Vst0E)W)-2eap literal 0 HcmV?d00001 diff --git a/images/left_arrow_green.png b/images/left_arrow_green.png new file mode 100644 index 0000000000000000000000000000000000000000..43ef9b982d218440498ddf0839db349a5e76dacc GIT binary patch literal 677 zcmeAS@N?(olHy`uVBq!ia0vp^CxF<7gAGV3M}M6Nq!^2X+?^QKos)S9a~60+7BevL9R^{>DlxQpbznj&`>y`{d zYsiihj2S_X%|cXEeS5-jMQSkz$hvZ;u3f|4KO$z%GGxmzmA%WQW`XYPOh)6{zN zR{67QY_}bcoYu=QWp;~pgAfaoivWj!qk@CWL&d+ZzE59lz;dV3+%l#uah<@4bBDF> zU23x4{dn%~&o6I2I$QBRddJk{Zr1Bbg&d6s*6y-s(G`mck}==BUjOhGA#IL3nNsZn z95FZJ^Ow&$rpUr%E^_>9jwSzPHx3rPB}ae)pMxF?Fg0f8J_3@FR#unP_!I?ZEV0mA zmfmgP>!x7v{PB|?!QzD+^OqbJX$>sXG8fh6IP=1aFOjv8bM@E56>lyiYJ~~##Ki;c zPq^@_$C-nr`D(dLPz77%-yh%1cp6pgH~$t-yfIrXzT}mcqQHXQ$??ml*Z%)-{C|)0 zjiiObVnF*Hv%^57_B0S_^crZCLT9^0i^B#}eUP!*^MI~%Ouh#qmE}Ncbk~E_oGO-a zQdsfC7U<+DN`3n|Sfo21%QHDL7K#XR6dl>v>F}Y&;*=mqhjNp{9OXU>ra~Y44IgZO z7YZ!fD^Ud0+V}G4?pb=zceO>&m8t^r&wUl`Yz10-p;9FbXxG8X>y$Q%0E4e6S9zlt zkmd?f-Y5a2&2pqWuL9KttjbgYJ9+6Yk2S{?S(;X?@~{C0YE#sC<&Q$`AO0(3_@r+y o+41r4m%r)!Ko>Jibz5v-biai~?5VZ`FljM(y85}Sb4q9e0OIEdNB{r; literal 0 HcmV?d00001 diff --git a/images/right_arrow_gray.png b/images/right_arrow_gray.png new file mode 100644 index 0000000000000000000000000000000000000000..ecc1b9cf76b7d03df226be0e160d4b7900fb4879 GIT binary patch literal 673 zcmeAS@N?(olHy`uVBq!ia0vp^CxF<7gAGV3M}M6Nq!^2X+?^QKos)S9a~60+7BevL9R^{>L;Z z1|jPfHia$1uM7-jC)@~isB(39!=2Hd3U#k%Qc&W){y=RPd>k#077Z;#vJ z`wy>)dh6_%F5WJ{5u@GZ%)yeU*>^STtF}I$qQH(XqV6-EDGBUYoZq8W$kBK}^ytPI zz4?c>h%_GP-31b8RRfWGmVwAEA1nUcGXZLwvDD((=bzp)%$yVqG(9I>-v*MEk(Hh4 zxBRt1ZmUB=*P|Wwo9?kS9^lD6mV8W+g-KYXz3v?E|0U(+6SqMaa6akW2pF!%iK7!PHRrUh?+-h@Nk)7H9n9oTq4M^u0vV6vB82%prg3z;Gvf#RXmsdzL)|%`~1tpSRFC{ zU2V~UUoCsC#S0K4Io64=#VPhFF2fd+*X$#=F}wESmx)V12Z_5S<&lT;$3`+<(tI3UD*!c^i9 ZYh7vTKgGw!pMlAW!PC{xWt~$(69Ddt2}=L~ literal 0 HcmV?d00001 diff --git a/images/right_arrow_green.png b/images/right_arrow_green.png new file mode 100644 index 0000000000000000000000000000000000000000..bbf0672dc99b8710410cb99742d240304585ef01 GIT binary patch literal 659 zcmeAS@N?(olHy`uVBq!ia0vp^CxF<7gAGV3M}M6Nq!^2X+?^QKos)S9a~60+7BevL9R^{>af@Kc7tm4s(?#snU8Gj|KAU?cHSPp?P=J{ zWtq1aC#+4kXH4nPn((k_$_>Q;50l22Gm}4_ee~^V=EeP+`x|-}aU3~f=zHJ)%#XsG z`_+X+mfB6YY9XWK7`Tf0WY=LuA(4e<6G{s$T$+4C*n(8}+C4V(?Q%GEoPrxjdF zykz($Ds<0s*wzVD`e(V)1gl2{9W1Mx_?Mgm8qz3SqTmZs+LOSXX~dU4sm|or-wFCB z9BPgfUa_sHzAHQDmZp+ujKUGd`Au9c77wBg8U@&I3AiX6Y24Pq-(qn=?IK7(%}n4? z1B()~BAj$H#< zV{%&yC|@=e=+Yw#f)oxv)c`R{6x8^NIWv|wWG!VfT(6?ccVx*2-(8%C*T|J|tqA?4 zHrGO6b+0yueYkrL*LtA4Z#-pll5sdEc6yHavX{>{&SeVx_-}rRLda5muErSx92?jg e8FpIDjh~aXqfTOBWehMOF?hQAxvX + + images/right_arrow_green.png + images/left_arrow_green.png + images/right_arrow_gray.png + images/left_arrow_gray.png + + diff --git a/logo.ico b/logo.ico new file mode 100644 index 0000000000000000000000000000000000000000..fa2f84d4a81c9f425eacb0d3ce3296624a6be89b GIT binary patch literal 1342 zcmZQzU<5)CU}R8W&|qa?5CgJ11N_{1xum#&OkPh9mmrWV2y?IjshFY_X&_#HkzWYo z`9bw_oj*}vMqir>HC;8li@7iFKm#oPRJWte35shc6> z*PQzL=ab`E6do?!&(YvsFW3;pbU{~uL9n4^`hO*cgUkjx50W1fC83h>x1sEfAnZkjL4k5;JX*NLy7X|@F2bKm_r3;-59Ss}}933!9#rQCP zSKZ4tB_#$W1ttZi1`Y;G<$%13S1W)lC58?L1ty1m9B*VqBRni0x-hsnusE=QDTQxefh2C>M9f-GYI+3F$Ics8xLECj^O_`x5yZ)51ch5GUr45F(i#_?z9 zGcoR8mMKY4J_D>9hJ_w}Tx|%Cxti>|fblJ0lfoyPdCGG-28c zNBPJ)#dZfy8B+wp>+PAJnp=2ABFe-+ReCMw5iDTLA&Fbe{Y`FScHCe zlE;#IunK)>dw=)*-N%JCQ){hz(l=lEUHJ0UEc=(s>)#aanRU~?Orkwg_h^FE$NuT} z7|ni1@SNHi{PpDjike&2Gt%bwJ5 zG<~~?jKSvL>)XoNmu)wc(b+sFoDt~HIrGD z@m{zw?H%U>S;oye@Bi)=UoaDxsLyPQ|JL1bvsUiw>ixBWMv< z1_@KUi_#lHiBUPZXF6-^;S9mfu?h9iOn#epYe82y+KqX0t^C;Ps?8Zy{eeaQlldA$?X7pqe3oA%s=N_92H;Mxu(o#{QiO; z7-8&!1)rQBU1zZ?uQt5@r#Vc?AeMKJF-!Z$H*O0q6!9#JSJrZ@h^yT4y@MY!=}fq% XU%II!c~PwOUXY}xtDnm{r-UW|(Kh)* literal 0 HcmV?d00001 diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..d871ca9 --- /dev/null +++ b/main.cpp @@ -0,0 +1,13 @@ + +#include "mainwindow.h" + +#include + + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.show(); + return a.exec(); +} diff --git a/mainwindow.cpp b/mainwindow.cpp new file mode 100644 index 0000000..b38b9ce --- /dev/null +++ b/mainwindow.cpp @@ -0,0 +1,22 @@ + +#include "mainwindow.h" +#include "ui_mainwindow.h" +#include "serialConfigWidget.h" + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) +{ + ui->setupUi(this); + this->setWindowTitle("串口转发工具V1.0"); + + QWidget *wdg = new SerialConfigWidget(); + ui->verticalLayout->addWidget(wdg); +} + +MainWindow::~MainWindow() +{ + delete ui; +} + + diff --git a/mainwindow.h b/mainwindow.h new file mode 100644 index 0000000..1cafe77 --- /dev/null +++ b/mainwindow.h @@ -0,0 +1,26 @@ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include + + + +QT_BEGIN_NAMESPACE +namespace Ui { class MainWindow; } +QT_END_NAMESPACE + +class MainWindow : public QMainWindow + +{ + Q_OBJECT + +public: + MainWindow(QWidget *parent = nullptr); + ~MainWindow(); + +private: + Ui::MainWindow *ui; +}; + +#endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui new file mode 100644 index 0000000..71b774f --- /dev/null +++ b/mainwindow.ui @@ -0,0 +1,42 @@ + + + MainWindow + + + + 0 + 0 + 555 + 500 + + + + MainWindow + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + diff --git a/serialConfigWidget.cpp b/serialConfigWidget.cpp new file mode 100644 index 0000000..46bc72f --- /dev/null +++ b/serialConfigWidget.cpp @@ -0,0 +1,169 @@ +#include "serialConfigWidget.h" +#include "ui_serialConfigWidget.h" +#include +#include +#include +#include +#include +#include + +SerialConfigWidget::SerialConfigWidget(QWidget *parent) : + QWidget(parent), + ui(new Ui::SerialConfigWidget) +{ + ui->setupUi(this); + m_SerialPort1.connectReadEvent(this); + m_SerialPort2.connectReadEvent(this); + refreshCom(); + connect(this,SIGNAL(displayTextSignal(QString)),this,SLOT(displayText(QString)),Qt::QueuedConnection); +} + +SerialConfigWidget::~SerialConfigWidget() +{ + delete ui; +} + +void SerialConfigWidget::refreshCom() +{ + QString currentTxt1 = ui->cmbCom1->currentText(); + QString currentTxt2 = ui->cmbCom2->currentText(); + QStringList nameList; + foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts()) + { + nameList.append(info.portName()); + } + std::sort(nameList.begin(), nameList.end(), [&](QString &s1, QString &s2){ + if(s1.size()==s2.size()){ + return s1cmbCom1->clear(); + ui->cmbCom1->addItems(nameList); + if(!currentTxt1.isEmpty()){ + ui->cmbCom1->setCurrentText(currentTxt1); + } + + ui->cmbCom2->clear(); + ui->cmbCom2->addItems(nameList); + if(!currentTxt2.isEmpty()){ + ui->cmbCom2->setCurrentText(currentTxt2); + } +} + +void SerialConfigWidget::on_toolBtnRefresh_clicked() +{ + refreshCom(); +} + + +void SerialConfigWidget::on_toolBtnOk_clicked() +{ + if(ui->toolBtnOk->isChecked()){ + QString portName1 = ui->cmbCom1->currentText(); + QString baud1 = ui->cmbBaud1->currentText(); + + m_SerialPort1.init(portName1.toStdString().c_str(),baud1.toInt(), + itas109::Parity::ParityNone,itas109::DataBits::DataBits8, + itas109::StopBits::StopOne); + m_SerialPort1.setReadIntervalTimeout(readIntervalTimeoutMS); + if(!m_SerialPort1.open()){ + QMessageBox::warning(NULL,tr("警告"),portName1 + tr("打开错误") + QString("\n\ncode: %1\nmessage: %2").arg( + m_SerialPort1.getLastError()).arg(m_SerialPort1.getLastErrorMsg())); + ui->toolBtnOk->setChecked(false); + return ; + } + + QString portName2 = ui->cmbCom2->currentText(); + QString baud2 = ui->cmbBaud2->currentText(); + + m_SerialPort2.init(portName2.toStdString().c_str(),baud2.toInt(), + itas109::Parity::ParityNone,itas109::DataBits::DataBits8, + itas109::StopBits::StopOne); + m_SerialPort2.setReadIntervalTimeout(readIntervalTimeoutMS); + if(!m_SerialPort2.open()){ + QMessageBox::warning(NULL,tr("警告"),portName2 + tr("打开错误") + QString("\n\ncode: %1\nmessage: %2").arg( + m_SerialPort2.getLastError()).arg(m_SerialPort2.getLastErrorMsg())); + m_SerialPort1.close(); + ui->toolBtnOk->setChecked(false); + return ; + } + + ui->toolBtnOk->setStyleSheet("color:green"); + ui->cmbCom1->setDisabled(true); + ui->cmbBaud1->setDisabled(true); + ui->cmbCom2->setDisabled(true); + ui->cmbBaud2->setDisabled(true); + ui->toolBtnRefresh->setDisabled(true); + ui->toolBtnOk->setChecked(true); + }else{ + m_SerialPort1.close(); + m_SerialPort2.close(); + ui->toolBtnOk->setStyleSheet("color:balck"); + ui->cmbCom1->setEnabled(true); + ui->cmbBaud1->setEnabled(true); + ui->cmbCom2->setEnabled(true); + ui->cmbBaud2->setEnabled(true); + ui->toolBtnRefresh->setEnabled(true); + ui->toolBtnOk->setChecked(false); + } + +} + +void SerialConfigWidget::displayText(const QString &txt) +{ + ui->plainTextEdit->appendPlainText(txt.trimmed()); +} + +void SerialConfigWidget::onReadEvent(const char *portName, unsigned int readBufferLen) +{ + QMutexLocker locker(&mtx); + if(portName && std::strcmp(portName,m_SerialPort1.getPortName())==0){ + int recLen = 0; + char * str = NULL; + str = new char[readBufferLen]; + if(str){ + recLen = m_SerialPort1.readData(str, readBufferLen); + } + + if(str && recLen > 0) + { + // TODO: 中文需要由两个字符拼接,否则显示为空"" + //QString m_str = QString::fromLocal8Bit(str,recLen); + //emitUpdateReceive(m_str); + m_SerialPort2.writeData(str,recLen); + QString txt = QString("%1:%2").arg(QString::fromLocal8Bit(portName,std::strlen(portName))).arg(QString::fromLocal8Bit(str,recLen)); + emit displayTextSignal(txt); + } + + if(str) + { + delete[] str; + str = NULL; + } + }else if(portName && std::strcmp(portName,m_SerialPort2.getPortName())==0){ + int recLen = 0; + char * str = NULL; + str = new char[readBufferLen]; + if(str){ + recLen = m_SerialPort2.readData(str, readBufferLen); + } + + if(str && recLen > 0) + { + // TODO: 中文需要由两个字符拼接,否则显示为空"" + //QString m_str = QString::fromLocal8Bit(str,recLen); + //emitUpdateReceive(m_str); + m_SerialPort1.writeData(str,recLen); + QString txt = QString("%1:%2").arg(QString::fromLocal8Bit(portName,std::strlen(portName))).arg(QString::fromLocal8Bit(str,recLen)); + emit displayTextSignal(txt); + } + + if(str) + { + delete[] str; + str = NULL; + } + } +} + diff --git a/serialConfigWidget.h b/serialConfigWidget.h new file mode 100644 index 0000000..7e92db3 --- /dev/null +++ b/serialConfigWidget.h @@ -0,0 +1,41 @@ +#ifndef SERIALCONFIGWIDGET_H +#define SERIALCONFIGWIDGET_H + +#include +#include +#include "CSerialPort/SerialPort.h" + +using namespace itas109; + +namespace Ui { +class SerialConfigWidget; +} + +class SerialConfigWidget : public QWidget ,public CSerialPortListener +{ + Q_OBJECT + +public: + explicit SerialConfigWidget(QWidget *parent = nullptr); + ~SerialConfigWidget(); + +signals: + void displayTextSignal(const QString &txt); + +private slots: + void on_toolBtnRefresh_clicked(); + void on_toolBtnOk_clicked(); + void displayText(const QString &txt); + +private slots: + void onReadEvent(const char *portName, unsigned int readBufferLen) override; + +private: + Ui::SerialConfigWidget *ui; + CSerialPort m_SerialPort1,m_SerialPort2; + int readIntervalTimeoutMS = 50; + QMutex mtx; + void refreshCom(); +}; + +#endif // SERIALCONFIGWIDGET_H diff --git a/serialConfigWidget.ui b/serialConfigWidget.ui new file mode 100644 index 0000000..3b5bc7f --- /dev/null +++ b/serialConfigWidget.ui @@ -0,0 +1,284 @@ + + + SerialConfigWidget + + + + 0 + 0 + 702 + 374 + + + + + 0 + 0 + + + + Form + + + + 4 + + + 4 + + + 4 + + + 4 + + + 0 + + + + + QGroupBox{border:none} + + + + + + true + + + + + + 串口号: + + + + + + + + + + 波特率: + + + + + + + true + + + + 115200 + + + + + 230400 + + + + + 460800 + + + + + 921600 + + + + + + + + + + + QGroupBox{border:none} + + + + + + true + + + + + + 串口号: + + + + + + + + + + 波特率: + + + + + + + true + + + + 115200 + + + + + 230400 + + + + + 460800 + + + + + 921600 + + + + + + + + + + + QGroupBox{border:none} + + + + + + + + + 刷新 + + + + + + + 确定 + + + true + + + false + + + + + + + + + + QGroupBox{border:none} + + + + + + false + + + + 0 + + + + + + 0 + 0 + + + + + 40 + 12 + + + + + 40 + 12 + + + + false + + + + + + :/images/images/left_arrow_gray.png + + + true + + + + + + + + 0 + 0 + + + + + 40 + 12 + + + + + 40 + 12 + + + + + + + :/images/images/right_arrow_gray.png + + + true + + + + + + + + + + 10000 + + + + + + + + + + diff --git a/serialTransferTool.pro b/serialTransferTool.pro new file mode 100644 index 0000000..63f8011 --- /dev/null +++ b/serialTransferTool.pro @@ -0,0 +1,39 @@ +QT += core gui serialport + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++17 + +# You can make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +msvc{ + QMAKE_CFLAGS += /utf-8 + QMAKE_CXXFLAGS += /utf-8 +} + +include($$PWD/3rdparty/CSerialPort/examples/CommQT/commqt.pri) + +SOURCES += \ + main.cpp \ + mainwindow.cpp \ + serialConfigWidget.cpp + +HEADERS += \ + mainwindow.h \ + serialConfigWidget.h + +FORMS += \ + mainwindow.ui \ + serialConfigWidget.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 += \ + img.qrc + +RC_ICONS = logo.ico