dialog.h:

  1. #ifndef DIALOG_H
  2. #define DIALOG_H
  3.  
  4. #include <QDialog>
  5.  
  6. #include "masterthread.h"
  7. //这里的写法有点。。为什么不直接加头文件
  8. QT_BEGIN_NAMESPACE
  9.  
  10. class QLabel;
  11. class QLineEdit;
  12. class QSpinBox;
  13. class QPushButton;
  14. class QComboBox;
  15.  
  16. QT_END_NAMESPACE
  17.  
  18. class Dialog : public QDialog
  19. {
  20. Q_OBJECT
  21.  
  22. public:
  23. explicit Dialog(QWidget *parent = nullptr);
  24.  
  25. private slots:
  26. void transaction();
  27. void showResponse(const QString &s);
  28. void processError(const QString &s);
  29. void processTimeout(const QString &s);
  30.  
  31. private:
  32. void setControlsEnabled(bool enable);
  33.  
  34. private:
  35. int transactionCount;
  36. QLabel *serialPortLabel;                  //声明了各类控件
  37. QComboBox *serialPortComboBox;
  38. QLabel *waitResponseLabel;
  39. QSpinBox *waitResponseSpinBox;
  40. QLabel *requestLabel;
  41. QLineEdit *requestLineEdit;
  42. QLabel *trafficLabel;
  43. QLabel *statusLabel;
  44. QPushButton *runButton;
  45.  
  46. MasterThread thread;                    //创建了一个线程类
  47. };
  48.  
  49. #endif // DIALOG_H

masterthread.h:

  1. #ifndef MASTERTHREAD_H
  2. #define MASTERTHREAD_H
  3.  
  4. #include <QThread>
  5. #include <QMutex>
  6. #include <QWaitCondition>
  7.  
  8. //! [0]
  9. class MasterThread : public QThread
  10. {
  11. Q_OBJECT
  12.  
  13. public:
  14. explicit MasterThread(QObject *parent = nullptr);
  15. ~MasterThread();
  16.  
  17. void transaction(const QString &portName, int waitTimeout, const QString &request);        //用来传递GUI界面的信息函数
  18. void run() Q_DECL_OVERRIDE;                                         //线程运行函数
  19.  
  20. signals:
  21. void response(const QString &s);                                      //一些信号:响应、错误、时间
  22. void error(const QString &s);
  23. void timeout(const QString &s);
  24.  
  25. private:
  26. QString portName;                                               //需要操作记录的私有变量
  27. QString request;
  28. int waitTimeout;
  29. QMutex mutex; //互斥锁,保护上面的私有变量
  30. QWaitCondition cond; //条件变量,用来同步
  31. bool quit;
  32. };
  33. //! [0]
  34.  
  35. #endif // MASTERTHREAD_H

dialog.cpp:

  1. #include "dialog.h"
  2.  
  3. #include <QLabel>
  4. #include <QLineEdit>
  5. #include <QComboBox>
  6. #include <QSpinBox>
  7. #include <QPushButton>
  8. #include <QGridLayout>
  9.  
  10. #include <QtSerialPort/QSerialPortInfo>
  11.  
  12. QT_USE_NAMESPACE
  13.  
  14. Dialog::Dialog(QWidget *parent)
  15. : QDialog(parent)
  16. , transactionCount()
  17. , serialPortLabel(new QLabel(tr("Serial port:")))
  18. , serialPortComboBox(new QComboBox())
  19. , waitResponseLabel(new QLabel(tr("Wait response, msec:")))
  20. , waitResponseSpinBox(new QSpinBox())
  21. , requestLabel(new QLabel(tr("Request:")))
  22. , requestLineEdit(new QLineEdit(tr("Who are you?")))
  23. , trafficLabel(new QLabel(tr("No traffic.")))
  24. , statusLabel(new QLabel(tr("Status: Not running.")))
  25. , runButton(new QPushButton(tr("Start")))
  26. {
  27. const auto infos = QSerialPortInfo::availablePorts();
  28. for (const QSerialPortInfo &info : infos)
  29. serialPortComboBox->addItem(info.portName());
  30.  
  31. waitResponseSpinBox->setRange(, );
  32. waitResponseSpinBox->setValue();
  33.  
  34. auto mainLayout = new QGridLayout;
  35. mainLayout->addWidget(serialPortLabel, , );
  36. mainLayout->addWidget(serialPortComboBox, , );
  37. mainLayout->addWidget(waitResponseLabel, , );
  38. mainLayout->addWidget(waitResponseSpinBox, , );
  39. mainLayout->addWidget(runButton, , , , );
  40. mainLayout->addWidget(requestLabel, , );
  41. mainLayout->addWidget(requestLineEdit, , , , );
  42. mainLayout->addWidget(trafficLabel, , , , );
  43. mainLayout->addWidget(statusLabel, , , , );
  44. setLayout(mainLayout);
  45.  
  46. setWindowTitle(tr("Blocking Master"));
  47. serialPortComboBox->setFocus();
  48.  
  49. connect(runButton, &QPushButton::clicked, this, &Dialog::transaction);
  50. connect(&thread, &MasterThread::response, this, &Dialog::showResponse);
  51. connect(&thread, &MasterThread::error, this, &Dialog::processError);
  52. connect(&thread, &MasterThread::timeout, this, &Dialog::processTimeout);
  53. }
  54.  
  55. void Dialog::transaction()
  56. {
  57. setControlsEnabled(false);
  58. statusLabel->setText(tr("Status: Running, connected to port %1.")
  59. .arg(serialPortComboBox->currentText()));
  60. thread.transaction(serialPortComboBox->currentText(),
  61. waitResponseSpinBox->value(),
  62. requestLineEdit->text());
  63. }
  64.  
  65. void Dialog::showResponse(const QString &s)
  66. {
  67. setControlsEnabled(true);
  68. trafficLabel->setText(tr("Traffic, transaction #%1:"
  69. "\n\r-request: %2"
  70. "\n\r-response: %3")
  71. .arg(++transactionCount).arg(requestLineEdit->text()).arg(s));
  72. }
  73.  
  74. void Dialog::processError(const QString &s)
  75. {
  76. setControlsEnabled(true);
  77. statusLabel->setText(tr("Status: Not running, %1.").arg(s));
  78. trafficLabel->setText(tr("No traffic."));
  79. }
  80.  
  81. void Dialog::processTimeout(const QString &s)
  82. {
  83. setControlsEnabled(true);
  84. statusLabel->setText(tr("Status: Running, %1.").arg(s));
  85. trafficLabel->setText(tr("No traffic."));
  86. }
  87.  
  88. void Dialog::setControlsEnabled(bool enable)
  89. {
  90. runButton->setEnabled(enable);
  91. serialPortComboBox->setEnabled(enable);
  92. waitResponseSpinBox->setEnabled(enable);
  93. requestLineEdit->setEnabled(enable);
  94. }

masterthread.cpp:

  1. #include "masterthread.h"
  2.  
  3. #include <QtSerialPort/QSerialPort>
  4.  
  5. #include <QTime>
  6.  
  7. QT_USE_NAMESPACE
  8.  
  9. MasterThread::MasterThread(QObject *parent)
  10. : QThread(parent), waitTimeout(), quit(false)
  11. {
  12. }
  13.  
  14. //! [0]
  15. MasterThread::~MasterThread()
  16. {
  17. mutex.lock();
  18. quit = true;
  19. cond.wakeOne();
  20. mutex.unlock();
  21. wait();
  22. }
  23. //! [0]
  24.  
  25. //! [1] //! [2]
  26. void MasterThread::transaction(const QString &portName, int waitTimeout, const QString &request)
  27. {
  28. //! [1]
  29. QMutexLocker locker(&mutex);                            //用QMutexLocker锁住函数内的操作
  30. this->portName = portName;
  31. this->waitTimeout = waitTimeout;
  32. this->request = request;
  33. //! [3]
  34. if (!isRunning())                                  //判断线程是否启动
  35. start();
  36. else
  37. cond.wakeOne();                                 //已经启动则唤醒线程
  38. }
  39. //! [2] //! [3]
  40.  
  41. //! [4]
  42. void MasterThread::run()
  43. {
  44. bool currentPortNameChanged = false;          //临时变量
  45.  
  46. mutex.lock();
  47. //! [4] //! [5]
  48. QString currentPortName;                 //临时变量
  49. if (currentPortName != portName) {
  50. currentPortName = portName;
  51. currentPortNameChanged = true;
  52. }
  53.  
  54. int currentWaitTimeout = waitTimeout;
  55. QString currentRequest = request;
  56. mutex.unlock();                      //到这里把私有信息传递进去了
  57. //! [5] //! [6]
  58. QSerialPort serial;                    //创建了一个串口类
  59.  
  60. while (!quit) {
  61. //![6] //! [7]
  62. if (currentPortNameChanged) {            //如果改了名字
  63. serial.close();
  64. serial.setPortName(currentPortName);      //重新打开
  65.  
  66. if (!serial.open(QIODevice::ReadWrite)) {        //判断是否打开成功
  67. emit error(tr("Can't open %1, error code %2")
  68. .arg(portName).arg(serial.error()));
  69. return;
  70. }
  71. }
  72. //! [7] //! [8]
  73. // write request
  74. QByteArray requestData = currentRequest.toLocal8Bit();      //请求的消息转成byte格式
  75. serial.write(requestData);                      //发送数据
  76. if (serial.waitForBytesWritten(waitTimeout)) {           //等待waitTimeout时间发送数据
  77. //! [8] //! [10]
  78. // read response
  79. if (serial.waitForReadyRead(currentWaitTimeout)) {      //等待waitTimeout时间读取串口数据
  80. QByteArray responseData = serial.readAll();        //将读取数据写到responseData中
  81. while (serial.waitForReadyRead())             //再等10秒
  82. responseData += serial.readAll();            //写进responseData中
  83.  
  84. QString response(responseData);               //这里又转成QString类型了
  85. //! [12]
  86. emit this->response(response);               //发送response信号
  87. //! [10] //! [11] //! [12]
  88. } else {
  89. emit timeout(tr("Wait read response timeout %1")
  90. .arg(QTime::currentTime().toString())); //发送响应延时信号
  91. }
  92. //! [9] //! [11]
  93. } else {
  94. emit timeout(tr("Wait write request timeout %1")
  95. .arg(QTime::currentTime().toString())); //发送写延时信号
  96. }
  97. //! [9] //! [13]
  98. mutex.lock();
  99. cond.wait(&mutex);                           //这里又等待了?怎么唤醒?第二次按按钮时唤醒,这是一个循环。再次点击又运行一次
  100. if (currentPortName != portName) {
  101. currentPortName = portName;
  102. currentPortNameChanged = true;
  103. } else {
  104. currentPortNameChanged = false;
  105. }
  106. currentWaitTimeout = waitTimeout;
  107. currentRequest = request;
  108. mutex.unlock();
  109. }
  110. //! [13]
  111. }

QT blockingmaster例子学习的更多相关文章

  1. qt下面例子学习(部分功能)

    from aa import Ui_Formfrom PyQt4.Qt import *from PyQt4.QtCore import *from PyQt4.QtGui import *from ...

  2. (转)Qt Model/View 学习笔记 (七)——Delegate类

    Qt Model/View 学习笔记 (七) Delegate  类 概念 与MVC模式不同,model/view结构没有用于与用户交互的完全独立的组件.一般来讲, view负责把数据展示 给用户,也 ...

  3. (转)Qt Model/View 学习笔记 (五)——View 类

    Qt Model/View 学习笔记 (五) View 类 概念 在model/view架构中,view从model中获得数据项然后显示给用户.数据显示的方式不必与model提供的表示方式相同,可以与 ...

  4. Qt 智能指针学习(7种指针)

    Qt 智能指针学习 转载自:http://blog.csdn.net/dbzhang800/article/details/6403285 从内存泄露开始? 很简单的入门程序,应该比较熟悉吧 ^_^ ...

  5. 数百个 HTML5 例子学习 HT 图形组件 – 3D建模篇

    http://www.hightopo.com/demo/pipeline/index.html <数百个 HTML5 例子学习 HT 图形组件 – WebGL 3D 篇>里提到 HT 很 ...

  6. 数百个 HTML5 例子学习 HT 图形组件 – 3D 建模篇

    http://www.hightopo.com/demo/pipeline/index.html <数百个 HTML5 例子学习 HT 图形组件 – WebGL 3D 篇>里提到 HT 很 ...

  7. 数百个 HTML5 例子学习 HT 图形组件 – WebGL 3D 篇

    <数百个 HTML5 例子学习 HT 图形组件 – 拓扑图篇>一文让读者了解了 HT的 2D 拓扑图组件使用,本文将对 HT 的 3D 功能做个综合性的介绍,以便初学者可快速上手使用 HT ...

  8. 数百个 HTML5 例子学习 HT 图形组件 – 拓扑图篇

    HT 是啥:Everything you need to create cutting-edge 2D and 3D visualization. 这口号是当年心目中的产品方向,接着就朝这个方向慢慢打 ...

  9. HTML5 例子学习 HT 图形组件

    HTML5 例子学习 HT 图形组件 HT 是啥:Everything you need to create cutting-edge 2D and 3D visualization. 这口号是当年心 ...

随机推荐

  1. 【2019 Multi-University Training Contest 3】

    01: 02:https://www.cnblogs.com/myx12345/p/11593829.html 03: 04:https://www.cnblogs.com/myx12345/p/11 ...

  2. 原生 js 实现 vue 的某些功能

    1.数据双向绑定:https://www.cnblogs.com/yuqing-o605/p/6790709.html?utm_source=itdadao&utm_medium=referr ...

  3. LINUX时间服务器搭建

    一. 因 为工作需要,偶需要将搭建一个NTP服务器来进行时间同步的测试,在公司里一直以为非常的难搭建,也是刚刚工作的缘故,就等正导师给帮着弄一台服务器,结 果导师给了我一个系统叫Fedora,让我偶自 ...

  4. [CSP-S模拟测试]:树(树形DP+期望)

    题目描述 梦游中的你来到了一棵$N$个节点的树上.你一共做了$Q$个梦,每个梦需要你从点$u$走到点$v$之后才能苏醒,由于你正在梦游,所以每到一个节点后,你会在它连出去的边中等概率地选择一条走过去, ...

  5. git 小错误

    (一)在本地直接修改文件,提交后出现(master|REBASE 1/2).由于文件冲突所以导致各种报错. 在git pull --rebase origin master后 error: Pulli ...

  6. 建站手册-浏览器信息:Mozilla 项目

    ylbtech-建站手册-浏览器信息:Mozilla 项目 1.返回顶部 1. http://www.w3school.com.cn/browsers/browsers_mozilla.asp 2. ...

  7. MySQL-初始化和自动更新TIMESTAMP和DATETIME

    https://dev.mysql.com/doc/refman/8.0/en/timestamp-initialization.html 例,添加自动更新的保存最后一次修改该条记录的时间戳的字段: ...

  8. HttpCanary——最强Android抓包工具!

    迎使用HttpCanary——最强Android抓包工具! HttpCanary是一款功能强大的HTTP/HTTPS/HTTP2网络包抓取和分析工具,你可以把他看成是移动端的Fiddler或者Char ...

  9. js 使用技巧

    一,获取客户端状态 1.获取cookie function cookieInfo() { setcookie('cookie_test','1'); var cookie_test = getcook ...

  10. spring boot 尚桂谷学习笔记09 数据访问

    springboot 与数据库访问 jdbc, mybatis, spring data jpa,  1.jdbc原生访问 新建项目 使用 springboot 快速构建工具 选中 web 组件 sq ...