Qt串口通信开发之Qt串口通信模块QSerialPort开发完整实例(串口助手开发)

时间:2022-03-19 07:04:01

之前自己写了用于上位机做基本收发的界面,独立出来相当于一个串口助手,先贴图:

Qt串口通信开发之Qt串口通信模块QSerialPort开发完整实例(串口助手开发)

功能作为串口助手来说还算完善,五个发送槽,一个接收槽,可以检测可用串口并加上相关标志,串口设置,记数功能,还有菜单栏上的文件操作和一些选择功能。

下面说一说这个项目:

做这个串口助手分为两步,第一步是设计界面,第二部是功能的代码实现。

一、界面设计

界面设计用Qt Designer,当然用Qt Creator的界面编辑器也可以,只不过感觉Qt Designer更好用一点,因为可以随时运行查看你的界面效果而不用编译整个项目输出一个可执行程序再看看界面效果,这样会影响效率。

界面设计你想界面是什么样就怎么样设计,拉控件,排版,设置大小,修改对象名等等,都在这上面做好,这些用程序写的话会很麻烦,工作量也大。这上面的对象名很重要,因为在后面的代码实现中会用到,这个界面用到的控件还是挺多的,这里也不一个一个讲,我直接贴出来:

Qt串口通信开发之Qt串口通信模块QSerialPort开发完整实例(串口助手开发)

Qt串口通信开发之Qt串口通信模块QSerialPort开发完整实例(串口助手开发)

Qt串口通信开发之Qt串口通信模块QSerialPort开发完整实例(串口助手开发)

Qt串口通信开发之Qt串口通信模块QSerialPort开发完整实例(串口助手开发)

Qt串口通信开发之Qt串口通信模块QSerialPort开发完整实例(串口助手开发)

senderGB_1 - 5都是一样的,改下数就行

Qt串口通信开发之Qt串口通信模块QSerialPort开发完整实例(串口助手开发)

Qt串口通信开发之Qt串口通信模块QSerialPort开发完整实例(串口助手开发)

当然,用你自己喜欢的命名也可以,后面程序改下名字就行。

二、代码实现

先贴代码

basictransceiver.h

  1. #ifndef BASICTRANSCEIVER_H
  2. #define BASICTRANSCEIVER_H
  3.  
  4. #include <QMainWindow>
  5. #include "ui_basictransceiver.h"
  6.  
  7. class QTimer;
  8. class SerialPortSetting;
  9. class QSerialPort;
  10. class QPushButton;
  11.  
  12. class BasicTransceiver : public QMainWindow, public Ui::BasicTransceiver
  13. {
  14. Q_OBJECT
  15.  
  16. public:
  17. explicit BasicTransceiver(QWidget *parent = 0);
  18.  
  19. ~BasicTransceiver();
  20.  
  21. void StringToHex(QString str, QByteArray &senddata);
  22.  
  23. char ConvertHexChar(char ch);
  24.  
  25. void startAutoSend(QPushButton *sendButton);
  26.  
  27. void setConnections();
  28.  
  29. void writeHex(QTextEdit *textEdit);
  30.  
  31. void writeChr(QTextEdit *textEdit);
  32.  
  33. void resetCnt();
  34.  
  35. protected:
  36. void dragEnterEvent(QDragEnterEvent *event);
  37.  
  38. void dropEvent(QDropEvent *event);
  39.  
  40. private slots:
  41. void checkAutoSendCB();
  42.  
  43. void on_cleanButton_clicked();
  44.  
  45. void on_receiveTextBrowser_textChanged();
  46.  
  47. void setBaudRate();
  48.  
  49. void setParity();
  50.  
  51. void setDataBits();
  52.  
  53. void setStopBits();
  54.  
  55. void setFlowCtrl();
  56.  
  57. void on_connectButton_toggled(bool checked);
  58.  
  59. void setComLabel();
  60.  
  61. void setBaudLabel();
  62.  
  63. void writeToBuf();
  64.  
  65. void enabledSendButton();
  66.  
  67. void disabledSendButton();
  68.  
  69. void enabledAutoSend();
  70.  
  71. void disabledAutoButton();
  72.  
  73. void resetAutoSendCB();
  74.  
  75. void readMyCom();
  76.  
  77. void checkAvailablePorts();
  78.  
  79. void on_checkAPButton_clicked();
  80.  
  81. void checkPort();
  82.  
  83. void on_resetCntButton_clicked();
  84.  
  85. void on_exitButton_clicked();
  86.  
  87. bool saveAs();
  88.  
  89. void open();
  90.  
  91. //void about();
  92.  
  93. private:
  94. bool loadFile(const QString &fileName);
  95.  
  96. bool readFile(const QString &fileName);
  97.  
  98. bool saveFile(const QString &fileName);
  99.  
  100. bool writeFile(const QString &fileName);
  101.  
  102. QTimer *Timer_AS;//自动发送定时器
  103. QTimer *Timer_UPDATE;
  104. QTimer *Timer_CP;//定时检测串口是否存在
  105. SerialPortSetting *SPSetting;
  106. QSerialPort *mySerialPort;
  107. QSet<QString> portSet;
  108. QVector<int> iVec;
  109. QString senderFlag;
  110. QString readData;
  111. bool trashFlag = false;
  112. bool portIsOpen = false;
  113. int BaudCnt = 0;
  114. int ParityCnt = 0;
  115. int DataBitsCnt = 0;
  116. int StopBitsCnt = 0;
  117. int FlowCtrlCnt = 0;
  118.  
  119. };
  120.  
  121. #endif // BASICTRANSCEIVER_H

basictransceiver.cpp

  1. #include "basictransceiver.h"
  2. #include "serialportsetting.h"
  3. #include "ui_basictransceiver.h"
  4. #include "ui_serialportsetting.h"
  5. #include <QtSerialPort/QSerialPort>
  6. #include <QtSerialPort/QSerialPortInfo>
  7. #include <QDebug>
  8. #include <QMessageBox>
  9. #include <QStatusBar>
  10. #include <QPushButton>
  11. #include <QByteArray>
  12. #include <QDataStream>
  13. #include <QTimer>
  14. #include <QRegExp>
  15. #include <QRegExpValidator>
  16. #include <QFile>
  17. #include <QFileDialog>
  18. #include <QDragEnterEvent>
  19. #include <QDropEvent>
  20. #include <QMimeData>
  21. #include <QAction>
  22.  
  23. BasicTransceiver::BasicTransceiver(QWidget *parent) :
  24. QMainWindow(parent)
  25. {
  26. setupUi(this);
  27. setFixedSize(1074, 627);
  28. receiveTextBrowser->setAcceptDrops(false);//缺省情况下,QTextEdit接受来自其他应用程序拖拽来的文本,把文件名显示出来。
  29. senderTextEdit_1->setAcceptDrops(false);
  30. senderTextEdit_2->setAcceptDrops(false);
  31. senderTextEdit_3->setAcceptDrops(false);
  32. senderTextEdit_4->setAcceptDrops(false);
  33. senderTextEdit_5->setAcceptDrops(false);
  34. setAcceptDrops(true);//通过禁止QTextEdit控件的drop事件,允许主窗口得到drop事件
  35.  
  36. connectButton->setIcon(QIcon(":/images/open.png"));
  37. cleanButton->setIcon(QIcon(":/images/empty_bin.png"));
  38. checkAPButton->setIcon(QIcon(":/images/find.png"));
  39. resetCntButton->setIcon(QIcon(":/images/to_zero.png"));
  40. exitButton->setIcon(QIcon(":/images/exit.png"));
  41. actionWrite_data->setIcon(QIcon(":/images/write.png"));
  42. actionRead_data->setIcon(QIcon(":/images/read.png"));
  43. actionChoose_file->setIcon(QIcon(":/images/select_file.png"));
  44. exitAction->setIcon(QIcon(":/images/exit.png"));
  45. actionAbout->setIcon(QIcon(":/images/about.png"));
  46. sendButton_1->setIcon(QIcon(":/images/send.png"));
  47. sendButton_2->setIcon(QIcon(":/images/send.png"));
  48. sendButton_3->setIcon(QIcon(":/images/send.png"));
  49. sendButton_4->setIcon(QIcon(":/images/send.png"));
  50. sendButton_5->setIcon(QIcon(":/images/send.png"));
  51.  
  52. setConnections();
  53. emit checkAvailablePorts();
  54.  
  55. Timer_CP = new QTimer(this);
  56. Timer_UPDATE = new QTimer(this);
  57. connect(Timer_UPDATE, SIGNAL(timeout()), this, SLOT(repaint()));
  58. Timer_UPDATE->start(2000);
  59. Timer_AS = new QTimer(this);
  60. }
  61.  
  62. BasicTransceiver::~BasicTransceiver()
  63. {
  64.  
  65. }
  66.  
  67. void BasicTransceiver::checkAutoSendCB()
  68. {
  69. QObject *signalSender = sender();
  70. if ( signalSender->objectName() == "autoSendCB_1")
  71. {
  72. if (autoSendCB_1->isChecked())
  73. {
  74. intervalSB_1->setEnabled(false);
  75. autoSendCB_2->setEnabled(false);
  76. autoSendCB_3->setEnabled(false);
  77. autoSendCB_4->setEnabled(false);
  78. autoSendCB_5->setEnabled(false);
  79. startAutoSend(sendButton_1);
  80. } else if (!autoSendCB_1->isChecked()) {
  81. Timer_AS->stop();
  82. Timer_AS->disconnect();
  83. intervalSB_1->setEnabled(true);
  84. autoSendCB_2->setEnabled(true);
  85. autoSendCB_3->setEnabled(true);
  86. autoSendCB_4->setEnabled(true);
  87. autoSendCB_5->setEnabled(true);
  88. enabledSendButton();
  89. }
  90. } else if ( signalSender->objectName() == "autoSendCB_2") {
  91. if (autoSendCB_2->isChecked())
  92. {
  93. intervalSB_2->setEnabled(false);
  94. autoSendCB_1->setEnabled(false);
  95. autoSendCB_3->setEnabled(false);
  96. autoSendCB_4->setEnabled(false);
  97. autoSendCB_5->setEnabled(false);
  98. startAutoSend(sendButton_2);
  99. } else if (!autoSendCB_2->isChecked()) {
  100. Timer_AS->stop();
  101. Timer_AS->disconnect();
  102. intervalSB_2->setEnabled(true);
  103. autoSendCB_1->setEnabled(true);
  104. autoSendCB_3->setEnabled(true);
  105. autoSendCB_4->setEnabled(true);
  106. autoSendCB_5->setEnabled(true);
  107. enabledSendButton();
  108. }
  109. } else if ( signalSender->objectName() == "autoSendCB_3") {
  110. if (autoSendCB_3->isChecked())
  111. {
  112. intervalSB_3->setEnabled(false);
  113. autoSendCB_1->setEnabled(false);
  114. autoSendCB_2->setEnabled(false);
  115. autoSendCB_4->setEnabled(false);
  116. autoSendCB_5->setEnabled(false);
  117. startAutoSend(sendButton_3);
  118. } else if (!autoSendCB_3->isChecked()) {
  119. Timer_AS->stop();
  120. Timer_AS->disconnect();
  121. intervalSB_3->setEnabled(true);
  122. autoSendCB_1->setEnabled(true);
  123. autoSendCB_2->setEnabled(true);
  124. autoSendCB_4->setEnabled(true);
  125. autoSendCB_5->setEnabled(true);
  126. enabledSendButton();
  127. }
  128. } else if ( signalSender->objectName() == "autoSendCB_4") {
  129. if (autoSendCB_4->isChecked())
  130. {
  131. intervalSB_4->setEnabled(false);
  132. autoSendCB_1->setEnabled(false);
  133. autoSendCB_2->setEnabled(false);
  134. autoSendCB_3->setEnabled(false);
  135. autoSendCB_5->setEnabled(false);
  136. startAutoSend(sendButton_4);
  137. } else if (!autoSendCB_4->isChecked()) {
  138. Timer_AS->stop();
  139. Timer_AS->disconnect();
  140. intervalSB_4->setEnabled(true);
  141. autoSendCB_1->setEnabled(true);
  142. autoSendCB_2->setEnabled(true);
  143. autoSendCB_3->setEnabled(true);
  144. autoSendCB_5->setEnabled(true);
  145. enabledSendButton();
  146. }
  147. } else if ( signalSender->objectName() == "autoSendCB_5") {
  148. if (autoSendCB_5->isChecked())
  149. {
  150. intervalSB_5->setEnabled(false);
  151. autoSendCB_1->setEnabled(false);
  152. autoSendCB_2->setEnabled(false);
  153. autoSendCB_3->setEnabled(false);
  154. autoSendCB_4->setEnabled(false);
  155. startAutoSend(sendButton_5);
  156. } else if (!autoSendCB_5->isChecked()) {
  157. Timer_AS->stop();
  158. Timer_AS->disconnect();
  159. intervalSB_5->setEnabled(true);
  160. autoSendCB_1->setEnabled(true);
  161. autoSendCB_2->setEnabled(true);
  162. autoSendCB_3->setEnabled(true);
  163. autoSendCB_4->setEnabled(true);
  164. enabledSendButton();
  165. }
  166. }
  167. }
  168.  
  169. //清除接收区的内容
  170. void BasicTransceiver::on_cleanButton_clicked()
  171. {
  172. if (trashFlag == true) {
  173. receiveTextBrowser->clear();
  174. cleanButton->setIcon(QIcon(":/images/empty_bin.png"));
  175. }
  176. }
  177.  
  178. void BasicTransceiver::on_receiveTextBrowser_textChanged()
  179. {
  180. QString tempStr = receiveTextBrowser->toPlainText();
  181. if (!tempStr.isEmpty()) {
  182. trashFlag = true;
  183. if (autoClean->isChecked()){
  184. if (tempStr.size() >6200 ){
  185. receiveTextBrowser->clear();
  186. cleanButton->setIcon(QIcon(":/images/empty_bin.png"));
  187. }
  188. } else {
  189. cleanButton->setIcon(QIcon(":/images/clean.png"));
  190. }
  191. } else {
  192. trashFlag = false;
  193. cleanButton->setIcon(QIcon(":/images/empty_bin.png"));
  194. }
  195. }
  196.  
  197. void BasicTransceiver::setBaudRate()
  198. {
  199. if (portIsOpen) {
  200. if (BAUDCB->currentText() == "115200")
  201. mySerialPort->setBaudRate(QSerialPort::Baud115200);
  202. else if (BAUDCB->currentText() == "9600")
  203. mySerialPort->setBaudRate(QSerialPort::Baud9600);
  204. else if (BAUDCB->currentText() == "1200")
  205. mySerialPort->setBaudRate(QSerialPort::Baud1200);
  206. else if (BAUDCB->currentText() == "2400")
  207. mySerialPort->setBaudRate(QSerialPort::Baud2400);
  208. else if (BAUDCB->currentText() == "4800")
  209. mySerialPort->setBaudRate(QSerialPort::Baud4800);
  210. else if (BAUDCB->currentText() == "19200")
  211. mySerialPort->setBaudRate(QSerialPort::Baud19200);
  212. else if (BAUDCB->currentText() == "38400")
  213. mySerialPort->setBaudRate(QSerialPort::Baud38400);
  214. else if (BAUDCB->currentText() == "57600")
  215. mySerialPort->setBaudRate(QSerialPort::Baud57600);
  216. emit setBaudLabel();
  217. if (BaudCnt) {
  218. statusBar()->showMessage("BaudRate set successfully", 2000);
  219. }
  220. ++BaudCnt;
  221. }
  222. }
  223.  
  224. void BasicTransceiver::setParity()
  225. {
  226. if (portIsOpen) {
  227. if (ParityCB->currentText() == QString::fromLocal8Bit("无校验"))
  228. mySerialPort->setParity(QSerialPort::NoParity);
  229. else if (ParityCB->currentText() == QString::fromLocal8Bit("奇校验"))
  230. mySerialPort->setParity(QSerialPort::OddParity);
  231. else if (ParityCB->currentText() == QString::fromLocal8Bit("偶校验"))
  232. mySerialPort->setParity(QSerialPort::EvenParity);
  233. if (ParityCnt) {
  234. statusBar()->showMessage("Parity set successfully", 2000);
  235. }
  236. ++ParityCnt;
  237. }
  238. }
  239.  
  240. void BasicTransceiver::setDataBits()
  241. {
  242. if (portIsOpen) {
  243. if (DataBitsCB->currentText() == "8")
  244. mySerialPort->setDataBits(QSerialPort::Data8);
  245. else if (DataBitsCB->currentText() == "7")
  246. mySerialPort->setDataBits(QSerialPort::Data7);
  247. else if (DataBitsCB->currentText() == "6")
  248. mySerialPort->setDataBits(QSerialPort::Data6);
  249. else if (DataBitsCB->currentText() == "5")
  250. mySerialPort->setDataBits(QSerialPort::Data5);
  251. if (DataBitsCnt) {
  252. statusBar()->showMessage("DataBits set successfully", 2000);
  253. }
  254. ++DataBitsCnt;
  255. }
  256. }
  257.  
  258. void BasicTransceiver::setStopBits()
  259. {
  260. if (portIsOpen) {
  261. if (StopBitsCB->currentText() == "1")
  262. mySerialPort->setStopBits(QSerialPort::OneStop);
  263. else if (StopBitsCB->currentText() == "1.5")
  264. mySerialPort->setStopBits(QSerialPort::OneAndHalfStop);
  265. else if (StopBitsCB->currentText() == "2")
  266. mySerialPort->setStopBits(QSerialPort::TwoStop);
  267. if (StopBitsCnt) {
  268. statusBar()->showMessage("StopBits set successfully", 2000);
  269. }
  270. ++StopBitsCnt;
  271. }
  272. }
  273.  
  274. void BasicTransceiver::setFlowCtrl()
  275. {
  276. if (portIsOpen) {
  277. if (FlowCtrlCB->currentText() == "off")
  278. mySerialPort->setFlowControl(QSerialPort::NoFlowControl);
  279. else if (FlowCtrlCB->currentText() == "hardware")
  280. mySerialPort->setFlowControl(QSerialPort::HardwareControl);
  281. else if (FlowCtrlCB->currentText() == "xonxoff")
  282. mySerialPort->setFlowControl(QSerialPort::SoftwareControl);
  283. if (FlowCtrlCnt) {
  284. statusBar()->showMessage("FlowCtrl set successfully", 2000);
  285. }
  286. ++FlowCtrlCnt;
  287. }
  288. }
  289.  
  290. void BasicTransceiver::resetCnt()
  291. {
  292. BaudCnt = 0;
  293. ParityCnt = 0;
  294. DataBitsCnt = 0;
  295. StopBitsCnt = 0;
  296. FlowCtrlCnt = 0;
  297. }
  298.  
  299. //打开和关闭串口
  300. void BasicTransceiver::on_connectButton_toggled(bool checked)
  301. {
  302. if (checked == true) {
  303. mySerialPort = new QSerialPort(this);
  304. QString tempStr = COMCB->currentText();
  305. tempStr.remove(" avail", Qt::CaseSensitive);
  306. mySerialPort->setPortName(tempStr);
  307. if (mySerialPort->open(QIODevice::ReadWrite)) {
  308. portIsOpen = true;
  309. emit setBaudRate();
  310. emit setParity();
  311. emit setDataBits();
  312. emit setStopBits();
  313. emit setFlowCtrl();
  314. statusBar()->showMessage(mySerialPort->portName() + " is opened", 2000);
  315. emit setComLabel();
  316. emit enabledSendButton();
  317. emit enabledAutoSend();
  318. COMCB->setEnabled(false);
  319. connect(Timer_CP, SIGNAL(timeout()), this, SLOT(checkPort()));
  320. Timer_CP->start(1000);
  321. connect(mySerialPort, SIGNAL(readyRead()), this, SLOT(readMyCom()));
  322. connectButton->setText(QString::fromLocal8Bit("关闭连接"));
  323. connectButton->setIcon(QIcon(":/images/close.png"));
  324. } else {
  325. QMessageBox::warning(this,
  326. QString::fromLocal8Bit("串口打开失败"),
  327. QString::fromLocal8Bit("串口不存在或本串口"
  328. "已经被占用,请重试!"),
  329. QMessageBox::Cancel);
  330. connectButton->setChecked(false);
  331. return;
  332. }
  333. } else if (checked == false) {
  334. if (Timer_AS->isActive()) {
  335. Timer_AS->stop();
  336. emit resetAutoSendCB();
  337. }
  338. if (Timer_CP->isActive()) Timer_CP->stop();
  339. Timer_CP->disconnect();
  340. if (mySerialPort->isOpen()) mySerialPort->close();
  341. emit disabledSendButton();
  342. emit disabledAutoButton();
  343. emit setComLabel();
  344. emit setBaudLabel();
  345. resetCnt();
  346. COMCB->setEnabled(true);
  347. connectButton->setText(QString::fromLocal8Bit("打开连接"));
  348. connectButton->setIcon(QIcon(":/images/open.png"));
  349. portIsOpen = false;
  350. }
  351. }
  352.  
  353. //设置显示串口号和波特率的Label
  354. void BasicTransceiver::setComLabel()
  355. {
  356. if (mySerialPort->isOpen()) {
  357. comLabel->setText(QString(mySerialPort->portName()));
  358. } else if (!mySerialPort->isOpen()) {
  359. comLabel->setText(QString::fromLocal8Bit("COM:#"));
  360. }
  361. }
  362.  
  363. void BasicTransceiver::setBaudLabel()
  364. {
  365. if (mySerialPort->isOpen()) {
  366. int i_baud = mySerialPort->baudRate();
  367. QString s_baud;
  368. baudLabel->setText(s_baud.setNum(i_baud));
  369. } else if (!mySerialPort->isOpen()) {
  370. baudLabel->setText(QString::fromLocal8Bit("BAUD:#"));
  371. }
  372. }
  373.  
  374. void BasicTransceiver::writeToBuf()
  375. {
  376. QObject *signalSender = sender();
  377. if (signalSender->objectName() == "sendButton_1") {
  378. if (hexRB_1->isChecked()) {
  379. writeHex(senderTextEdit_1);
  380. } else {
  381. writeChr(senderTextEdit_1);
  382. }
  383. } else if (signalSender->objectName() == "sendButton_2") {
  384. if (hexRB_2->isChecked()) {
  385. writeHex(senderTextEdit_2);
  386. } else {
  387. writeChr(senderTextEdit_2);
  388. }
  389. } else if (signalSender->objectName() == "sendButton_3") {
  390. if (hexRB_3->isChecked()) {
  391. writeHex(senderTextEdit_3);
  392. } else {
  393. writeChr(senderTextEdit_3);
  394. }
  395. } else if (signalSender->objectName() == "sendButton_4") {
  396. if (hexRB_4->isChecked()) {
  397. writeHex(senderTextEdit_4);
  398. } else {
  399. writeChr(senderTextEdit_4);
  400. }
  401. } else if (signalSender->objectName() == "sendButton_5") {
  402. if (hexRB_5->isChecked()) {
  403. writeHex(senderTextEdit_5);
  404. } else {
  405. writeChr(senderTextEdit_5);
  406. }
  407. }
  408. }
  409.  
  410. void BasicTransceiver::writeHex(QTextEdit *textEdit)
  411. {
  412. QString dataStr = textEdit->toPlainText();
  413. //如果发送的数据个数为奇数的,则在前面最后落单的字符前添加一个字符0
  414. if (dataStr.length() % 2){
  415. dataStr.insert(dataStr.length()-1, '0');
  416. }
  417. QByteArray sendData;
  418. StringToHex(dataStr, sendData);
  419. mySerialPort->write(sendData);
  420. RxLCD->display(RxLCD->value() + sendData.size());
  421. }
  422.  
  423. void BasicTransceiver::writeChr(QTextEdit *textEdit)
  424. {
  425. QByteArray sendData = textEdit->toPlainText().toUtf8();
  426. if (!sendData.isEmpty() && !sendData.isNull()) {
  427. mySerialPort->write(sendData);
  428. }
  429. RxLCD->display(RxLCD->value() + sendData.size());
  430. }
  431.  
  432. void BasicTransceiver::StringToHex(QString str, QByteArray &senddata) //字符串转换为十六进制数据0-F
  433. {
  434. int hexdata,lowhexdata;
  435. int hexdatalen = 0;
  436. int len = str.length();
  437. senddata.resize(len / 2);
  438. char lstr,hstr;
  439. for (int i = 0; i < len; ) {
  440. hstr = str[i].toLatin1();
  441. if (hstr == ' ') {
  442. ++i;
  443. continue;
  444. }
  445. ++i;
  446. if (i >= len) break;
  447. lstr = str[i].toLatin1();
  448. hexdata = ConvertHexChar(hstr);
  449. lowhexdata = ConvertHexChar(lstr);
  450. if ((hexdata == 16) || (lowhexdata == 16))
  451. break;
  452. else
  453. hexdata = hexdata*16 + lowhexdata;
  454. ++i;
  455. senddata[hexdatalen] = (char)hexdata;
  456. ++hexdatalen;
  457. }
  458. senddata.resize(hexdatalen);
  459. }
  460.  
  461. char BasicTransceiver::ConvertHexChar(char ch)
  462. {
  463. if ((ch >= '0') && (ch <= '9'))
  464. return ch - 0x30;
  465. else if ((ch >= 'A') && (ch <= 'F'))
  466. return ch - 'A' + 10;
  467. else if ((ch >= 'a') && (ch <= 'f'))
  468. return ch - 'a' + 10;
  469. else return ch - ch;
  470. }
  471.  
  472. void BasicTransceiver::enabledSendButton()
  473. {
  474. sendButton_1->setEnabled(true);
  475. sendButton_2->setEnabled(true);
  476. sendButton_3->setEnabled(true);
  477. sendButton_4->setEnabled(true);
  478. sendButton_5->setEnabled(true);
  479. }
  480.  
  481. void BasicTransceiver::disabledSendButton()
  482. {
  483. sendButton_1->setEnabled(false);
  484. sendButton_2->setEnabled(false);
  485. sendButton_3->setEnabled(false);
  486. sendButton_4->setEnabled(false);
  487. sendButton_5->setEnabled(false);
  488. }
  489.  
  490. void BasicTransceiver::startAutoSend(QPushButton *sendButton)
  491. {
  492. connect(Timer_AS, SIGNAL(timeout()), sendButton, SIGNAL(clicked()));
  493. QString interval;
  494. if (sendButton->objectName() == "sendButton_1") {
  495. disabledSendButton();
  496. Timer_AS->start(intervalSB_1->value());
  497. statusBar()->showMessage(QString::fromLocal8Bit("每 ") + interval.setNum(intervalSB_1->value())+ QString::fromLocal8Bit("ms 自动发送一次") , 2000);
  498. } else if (sendButton->objectName() == "sendButton_2") {
  499. disabledSendButton();
  500. Timer_AS->start(intervalSB_2->value());
  501. statusBar()->showMessage(QString::fromLocal8Bit("每 ") + interval.setNum(intervalSB_2->value())+ QString::fromLocal8Bit("ms 自动发送一次") , 2000);
  502. } else if (sendButton->objectName() == "sendButton_3") {
  503. disabledSendButton();
  504. Timer_AS->start(intervalSB_3->value());
  505. statusBar()->showMessage(QString::fromLocal8Bit("每 ") + interval.setNum(intervalSB_3->value())+ QString::fromLocal8Bit("ms 自动发送一次") , 2000);
  506. } else if (sendButton->objectName() == "sendButton_4") {
  507. disabledSendButton();
  508. Timer_AS->start(intervalSB_4->value());
  509. statusBar()->showMessage(QString::fromLocal8Bit("每 ") + interval.setNum(intervalSB_4->value())+ QString::fromLocal8Bit("ms 自动发送一次") , 2000);
  510. } else if (sendButton->objectName() == "sendButton_5") {
  511. disabledSendButton();
  512. Timer_AS->start(intervalSB_5->value());
  513. statusBar()->showMessage(QString::fromLocal8Bit("每 ") + interval.setNum(intervalSB_5->value())+ QString::fromLocal8Bit("ms 自动发送一次") , 2000);
  514. }
  515. }
  516.  
  517. void BasicTransceiver::setConnections()
  518. {
  519. connect(autoSendCB_1, SIGNAL(stateChanged(int)), this, SLOT(checkAutoSendCB()));
  520. connect(autoSendCB_2, SIGNAL(stateChanged(int)), this, SLOT(checkAutoSendCB()));
  521. connect(autoSendCB_3, SIGNAL(stateChanged(int)), this, SLOT(checkAutoSendCB()));
  522. connect(autoSendCB_4, SIGNAL(stateChanged(int)), this, SLOT(checkAutoSendCB()));
  523. connect(autoSendCB_5, SIGNAL(stateChanged(int)), this, SLOT(checkAutoSendCB()));
  524.  
  525. connect(actionWrite_data, SIGNAL(triggered()), this, SLOT(saveAs()));
  526. connect(actionRead_data, SIGNAL(triggered()), this, SLOT(open()));
  527. connect(actionChoose_file, SIGNAL(triggered()), this, SLOT(open()));
  528. connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
  529. connect(actionAbout, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
  530.  
  531. connect(sendButton_1, SIGNAL(clicked()), this, SLOT(writeToBuf()));
  532. connect(sendButton_2, SIGNAL(clicked()), this, SLOT(writeToBuf()));
  533. connect(sendButton_3, SIGNAL(clicked()), this, SLOT(writeToBuf()));
  534. connect(sendButton_4, SIGNAL(clicked()), this, SLOT(writeToBuf()));
  535. connect(sendButton_5, SIGNAL(clicked()), this, SLOT(writeToBuf()));
  536.  
  537. connect(BAUDCB, SIGNAL(currentIndexChanged(int)), this, SLOT(setBaudRate()));
  538. connect(ParityCB, SIGNAL(currentIndexChanged(int)), this, SLOT(setParity()));
  539. connect(DataBitsCB, SIGNAL(currentIndexChanged(int)), this, SLOT(setDataBits()));
  540. connect(StopBitsCB, SIGNAL(currentIndexChanged(int)), this, SLOT(setStopBits()));
  541. connect(FlowCtrlCB, SIGNAL(currentIndexChanged(int)), this, SLOT(setFlowCtrl()));
  542. }
  543.  
  544. void BasicTransceiver::enabledAutoSend()
  545. {
  546. autoSendCB_1->setEnabled(true);
  547. autoSendCB_2->setEnabled(true);
  548. autoSendCB_3->setEnabled(true);
  549. autoSendCB_4->setEnabled(true);
  550. autoSendCB_5->setEnabled(true);
  551. }
  552.  
  553. void BasicTransceiver::disabledAutoButton()
  554. {
  555. autoSendCB_1->setEnabled(false);
  556. autoSendCB_2->setEnabled(false);
  557. autoSendCB_3->setEnabled(false);
  558. autoSendCB_4->setEnabled(false);
  559. autoSendCB_5->setEnabled(false);
  560. }
  561.  
  562. void BasicTransceiver::resetAutoSendCB()
  563. {
  564. autoSendCB_1->setChecked(false);
  565. autoSendCB_2->setChecked(false);
  566. autoSendCB_3->setChecked(false);
  567. autoSendCB_4->setChecked(false);
  568. autoSendCB_5->setChecked(false);
  569. }
  570.  
  571. void BasicTransceiver::readMyCom()
  572. {
  573. QByteArray temp = mySerialPort->readAll();
  574. QString buf;
  575.  
  576. if (actionAlways_show->isChecked()) {
  577. if(!temp.isEmpty()){
  578. if(chrReceive->isChecked()){
  579. buf = temp;
  580. }else if(hexReceive->isChecked()){
  581. for(int i = 0; i < temp.count(); i++){
  582. QString s;
  583. s.sprintf("0x%02x, ", (unsigned char)temp.at(i));
  584. buf += s;
  585. }
  586. }
  587. receiveTextBrowser->setText(receiveTextBrowser->document()->toPlainText() + buf);
  588. receiveTextBrowser->moveCursor(QTextCursor::End);
  589.  
  590. //ui->statusBar->showMessage(tr("成功读取%1字节数据").arg(temp.size()));
  591. }
  592. }
  593. TxLCD->display(TxLCD->value() + temp.size());
  594. }
  595.  
  596. //检测可用串口并在可用串口号后面加上可用标志
  597. void BasicTransceiver::checkAvailablePorts()
  598. {//找不到存在串口是不会进入到foreach内部的。。。存在不一定可用
  599. foreach ( const QSerialPortInfo &Info, QSerialPortInfo::availablePorts()) {
  600. QSerialPort availablePort;
  601. availablePort.setPortName(Info.portName());
  602. if (availablePort.open(QIODevice::ReadWrite)) {
  603. int index = COMCB->findText(Info.portName());
  604. COMCB->setItemText(index, Info.portName() + " avail");
  605. COMCB->setCurrentIndex(index);
  606. iVec.push_back(index);//将修改了内容的项索引添加到容器中
  607. checkAPButton->setIcon(QIcon(":/images/find_it.png"));
  608. availablePort.close();
  609. }
  610. }
  611. if (iVec.size() == 0) {checkAPButton->setIcon(QIcon(":/images/find.png"));}
  612. QString availPortCnt;
  613. statusBar()->showMessage(availPortCnt.setNum(iVec.size()) + " available ports", 2000);
  614. }
  615. //将选择串口号的checkBox重置并重新检测可用串口
  616. void BasicTransceiver::on_checkAPButton_clicked()
  617. {
  618. if (!iVec.isEmpty()) {
  619. for (int i = 0; i != iVec.size(); ++i) {
  620. QString tempStr;
  621. COMCB->setItemText(iVec[i], QString("COM") +
  622. tempStr.setNum(iVec[i]));
  623. }
  624. COMCB->setCurrentIndex(0);
  625. iVec.clear();
  626. }
  627. emit checkAvailablePorts();
  628. }
  629.  
  630. void BasicTransceiver::checkPort()
  631. {
  632. QSet<QString> portSet;
  633. foreach ( const QSerialPortInfo &Info, QSerialPortInfo::availablePorts()) {
  634. portSet.insert(Info.portName());
  635. }
  636. if (portSet.find(mySerialPort->portName()) == portSet.end()) {
  637. QMessageBox::warning(this,
  638. QString::fromLocal8Bit("Application error"),
  639. QString::fromLocal8Bit("Fail with the following error : \n串口访问失败\n\nPort:%1")
  640. .arg(mySerialPort->portName()),
  641. QMessageBox::Close);
  642. emit on_connectButton_toggled(false);
  643. }
  644. }
  645.  
  646. void BasicTransceiver::on_resetCntButton_clicked()
  647. {
  648. RxLCD->display(0);
  649. TxLCD->display(0);
  650. }
  651.  
  652. void BasicTransceiver::on_exitButton_clicked()
  653. {
  654. qApp->quit();
  655. }
  656. //另存为
  657. bool BasicTransceiver::saveAs()
  658. {
  659. QString fileName = QFileDialog::getSaveFileName(this,
  660. tr("Save Data"), ".",
  661. tr("Text File (*.txt)"));
  662. if (fileName.isEmpty()) {
  663. return false;
  664. }
  665. return saveFile(fileName);
  666. }
  667. //保存文件
  668. bool BasicTransceiver::saveFile(const QString &fileName)
  669. {
  670. if (!writeFile(fileName)) {
  671. statusBar()->showMessage(tr("Saving canceled"), 2000);
  672. return false;
  673. }
  674. statusBar()->showMessage(tr("Data saved"), 2000);
  675. return true;
  676. }
  677.  
  678. bool BasicTransceiver::writeFile(const QString &fileName)
  679. {
  680. QFile file(fileName);
  681. if (!file.open(QIODevice::WriteOnly | QFile::Text)) {
  682. QMessageBox::warning(this, tr("Save Data"),
  683. tr("Cannot write file %1 : \n%2")
  684. .arg(file.fileName())
  685. .arg(file.errorString()));
  686. return false;
  687. }
  688. QTextStream out(&file);
  689. out << receiveTextBrowser->toPlainText();
  690. return true;
  691. }
  692.  
  693. //打开文件的函数
  694. void BasicTransceiver::open()
  695. {
  696. QString fileName = QFileDialog::getOpenFileName(this,
  697. tr("Choose Text File"), ".",
  698. tr("Text File (*.txt)"));
  699. if (!fileName.isEmpty()) {
  700. loadFile(fileName);
  701. }
  702. }
  703. //加载文件
  704. bool BasicTransceiver::loadFile(const QString &fileName)
  705. {
  706. if (!readFile(fileName)) {
  707. statusBar()->showMessage(tr("Loading canceled"), 2000);
  708. return false;
  709. }
  710. statusBar()->showMessage(tr("Data loaded"), 2000);
  711. return true;
  712. }
  713. //读取文件
  714. bool BasicTransceiver::readFile(const QString &fileName)
  715. {
  716. QFile file(fileName);
  717. if (!file.open(QIODevice::ReadOnly)) {
  718. QMessageBox::warning(this, tr("Read failed"),
  719. tr("Cannot read file %1 : \n%2.")
  720. .arg(file.fileName())
  721. .arg(file.errorString()));
  722. return false;
  723. }
  724. QTextStream in(&file);
  725. QObject *signalSender = sender();
  726. if (signalSender->objectName() == "actionRead_data"){
  727. receiveTextBrowser->setText(in.readAll());
  728. } else if (signalSender->objectName() == "actionChoose_file") {
  729. senderTextEdit_1->setText(in.readAll());
  730. }
  731. return true;
  732. }
  733.  
  734. void BasicTransceiver::dragEnterEvent(QDragEnterEvent *event)
  735. {
  736. if (event->mimeData()->hasFormat("text/uri-list"))
  737. event->acceptProposedAction();
  738. }
  739.  
  740. void BasicTransceiver::dropEvent(QDropEvent *event)
  741. {
  742. QList<QUrl> urls = event->mimeData()->urls();
  743. if (urls.isEmpty())
  744. return;
  745. QString fileName = urls.first().toLocalFile();
  746. if (fileName.isEmpty()){
  747. return;
  748. }
  749. loadFile(fileName);
  750. }

程序完全是面向对象的,每个功能都是用相应函数实现的,这也提高了函数的重用性。

本文是一个完整的Qt串口通信模块QSerialPort开发完整实例,感兴趣的可以细细阅读源码内容,更多关于Qt串口通信知识请查看下面的相关链接

原文链接:https://blog.csdn.net/imkelt/article/details/53000523