dialog.h:

#ifndef DIALOG_H
#define DIALOG_H #include <QDialog> #include "masterthread.h"
//这里的写法有点。。为什么不直接加头文件
QT_BEGIN_NAMESPACE class QLabel;
class QLineEdit;
class QSpinBox;
class QPushButton;
class QComboBox; QT_END_NAMESPACE class Dialog : public QDialog
{
Q_OBJECT public:
explicit Dialog(QWidget *parent = nullptr); private slots:
void transaction();
void showResponse(const QString &s);
void processError(const QString &s);
void processTimeout(const QString &s); private:
void setControlsEnabled(bool enable); private:
int transactionCount;
QLabel *serialPortLabel;                  //声明了各类控件
QComboBox *serialPortComboBox;
QLabel *waitResponseLabel;
QSpinBox *waitResponseSpinBox;
QLabel *requestLabel;
QLineEdit *requestLineEdit;
QLabel *trafficLabel;
QLabel *statusLabel;
QPushButton *runButton; MasterThread thread;                    //创建了一个线程类
}; #endif // DIALOG_H

masterthread.h:

#ifndef MASTERTHREAD_H
#define MASTERTHREAD_H #include <QThread>
#include <QMutex>
#include <QWaitCondition> //! [0]
class MasterThread : public QThread
{
Q_OBJECT public:
explicit MasterThread(QObject *parent = nullptr);
~MasterThread(); void transaction(const QString &portName, int waitTimeout, const QString &request);        //用来传递GUI界面的信息函数
void run() Q_DECL_OVERRIDE;                                         //线程运行函数 signals:
void response(const QString &s);                                      //一些信号:响应、错误、时间
void error(const QString &s);
void timeout(const QString &s); private:
QString portName;                                               //需要操作记录的私有变量
QString request;
int waitTimeout;
QMutex mutex; //互斥锁,保护上面的私有变量
QWaitCondition cond; //条件变量,用来同步
bool quit;
};
//! [0] #endif // MASTERTHREAD_H

dialog.cpp:

#include "dialog.h"

#include <QLabel>
#include <QLineEdit>
#include <QComboBox>
#include <QSpinBox>
#include <QPushButton>
#include <QGridLayout> #include <QtSerialPort/QSerialPortInfo> QT_USE_NAMESPACE Dialog::Dialog(QWidget *parent)
: QDialog(parent)
, transactionCount()
, serialPortLabel(new QLabel(tr("Serial port:")))
, serialPortComboBox(new QComboBox())
, waitResponseLabel(new QLabel(tr("Wait response, msec:")))
, waitResponseSpinBox(new QSpinBox())
, requestLabel(new QLabel(tr("Request:")))
, requestLineEdit(new QLineEdit(tr("Who are you?")))
, trafficLabel(new QLabel(tr("No traffic.")))
, statusLabel(new QLabel(tr("Status: Not running.")))
, runButton(new QPushButton(tr("Start")))
{
const auto infos = QSerialPortInfo::availablePorts();
for (const QSerialPortInfo &info : infos)
serialPortComboBox->addItem(info.portName()); waitResponseSpinBox->setRange(, );
waitResponseSpinBox->setValue(); auto mainLayout = new QGridLayout;
mainLayout->addWidget(serialPortLabel, , );
mainLayout->addWidget(serialPortComboBox, , );
mainLayout->addWidget(waitResponseLabel, , );
mainLayout->addWidget(waitResponseSpinBox, , );
mainLayout->addWidget(runButton, , , , );
mainLayout->addWidget(requestLabel, , );
mainLayout->addWidget(requestLineEdit, , , , );
mainLayout->addWidget(trafficLabel, , , , );
mainLayout->addWidget(statusLabel, , , , );
setLayout(mainLayout); setWindowTitle(tr("Blocking Master"));
serialPortComboBox->setFocus(); connect(runButton, &QPushButton::clicked, this, &Dialog::transaction);
connect(&thread, &MasterThread::response, this, &Dialog::showResponse);
connect(&thread, &MasterThread::error, this, &Dialog::processError);
connect(&thread, &MasterThread::timeout, this, &Dialog::processTimeout);
} void Dialog::transaction()
{
setControlsEnabled(false);
statusLabel->setText(tr("Status: Running, connected to port %1.")
.arg(serialPortComboBox->currentText()));
thread.transaction(serialPortComboBox->currentText(),
waitResponseSpinBox->value(),
requestLineEdit->text());
} void Dialog::showResponse(const QString &s)
{
setControlsEnabled(true);
trafficLabel->setText(tr("Traffic, transaction #%1:"
"\n\r-request: %2"
"\n\r-response: %3")
.arg(++transactionCount).arg(requestLineEdit->text()).arg(s));
} void Dialog::processError(const QString &s)
{
setControlsEnabled(true);
statusLabel->setText(tr("Status: Not running, %1.").arg(s));
trafficLabel->setText(tr("No traffic."));
} void Dialog::processTimeout(const QString &s)
{
setControlsEnabled(true);
statusLabel->setText(tr("Status: Running, %1.").arg(s));
trafficLabel->setText(tr("No traffic."));
} void Dialog::setControlsEnabled(bool enable)
{
runButton->setEnabled(enable);
serialPortComboBox->setEnabled(enable);
waitResponseSpinBox->setEnabled(enable);
requestLineEdit->setEnabled(enable);
}

masterthread.cpp:

#include "masterthread.h"

#include <QtSerialPort/QSerialPort>

#include <QTime>

QT_USE_NAMESPACE

MasterThread::MasterThread(QObject *parent)
: QThread(parent), waitTimeout(), quit(false)
{
} //! [0]
MasterThread::~MasterThread()
{
mutex.lock();
quit = true;
cond.wakeOne();
mutex.unlock();
wait();
}
//! [0] //! [1] //! [2]
void MasterThread::transaction(const QString &portName, int waitTimeout, const QString &request)
{
//! [1]
QMutexLocker locker(&mutex);                            //用QMutexLocker锁住函数内的操作
this->portName = portName;
this->waitTimeout = waitTimeout;
this->request = request;
//! [3]
if (!isRunning())                                  //判断线程是否启动
start();
else
cond.wakeOne();                                 //已经启动则唤醒线程
}
//! [2] //! [3] //! [4]
void MasterThread::run()
{
bool currentPortNameChanged = false;          //临时变量 mutex.lock();
//! [4] //! [5]
QString currentPortName;                 //临时变量
if (currentPortName != portName) {
currentPortName = portName;
currentPortNameChanged = true;
} int currentWaitTimeout = waitTimeout;
QString currentRequest = request;
mutex.unlock();                      //到这里把私有信息传递进去了
//! [5] //! [6]
QSerialPort serial;                    //创建了一个串口类 while (!quit) {
//![6] //! [7]
if (currentPortNameChanged) {            //如果改了名字
serial.close();
serial.setPortName(currentPortName);      //重新打开 if (!serial.open(QIODevice::ReadWrite)) {        //判断是否打开成功
emit error(tr("Can't open %1, error code %2")
.arg(portName).arg(serial.error()));
return;
}
}
//! [7] //! [8]
// write request
QByteArray requestData = currentRequest.toLocal8Bit();      //请求的消息转成byte格式
serial.write(requestData);                      //发送数据
if (serial.waitForBytesWritten(waitTimeout)) {           //等待waitTimeout时间发送数据
//! [8] //! [10]
// read response
if (serial.waitForReadyRead(currentWaitTimeout)) {      //等待waitTimeout时间读取串口数据
QByteArray responseData = serial.readAll();        //将读取数据写到responseData中
while (serial.waitForReadyRead())             //再等10秒
responseData += serial.readAll();            //写进responseData中 QString response(responseData);               //这里又转成QString类型了
//! [12]
emit this->response(response);               //发送response信号
//! [10] //! [11] //! [12]
} else {
emit timeout(tr("Wait read response timeout %1")
.arg(QTime::currentTime().toString())); //发送响应延时信号
}
//! [9] //! [11]
} else {
emit timeout(tr("Wait write request timeout %1")
.arg(QTime::currentTime().toString())); //发送写延时信号
}
//! [9] //! [13]
mutex.lock();
cond.wait(&mutex);                           //这里又等待了?怎么唤醒?第二次按按钮时唤醒,这是一个循环。再次点击又运行一次
if (currentPortName != portName) {
currentPortName = portName;
currentPortNameChanged = true;
} else {
currentPortNameChanged = false;
}
currentWaitTimeout = waitTimeout;
currentRequest = request;
mutex.unlock();
}
//! [13]
}

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. 替换OSD操作的优化与分析

    http://www.zphj1987.com/2016/09/19/%E6%9B%BF%E6%8D%A2OSD%E6%93%8D%E4%BD%9C%E7%9A%84%E4%BC%98%E5%8C%9 ...

  2. 如何隐藏一个让人很难发现的bug?

    程序员的日常三件事:写bug.改bug.背锅.连程序员都自我调侃道,为什么每天都在加班?因为我的眼里常含bug. 那么如何写出一个让(坑)人(王)很(之)难(王)发现的bug呢? - 1 - 新手开发 ...

  3. C#读取csv、xls、sql数据库的实现

    using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Secu ...

  4. appium 安装

    1.npm安装: cmd——cnpm install -g appium 卸载: cmd——npm uninstall -g appium 2.下载安装包安装: Appium server: 1. A ...

  5. [CSP-S模拟测试]:chemistry(期望DP+组合数学)

    题目传送门(内部题27) 输入格式 第一行有$4$个整数$n,k,p,q$.第二行有$n$个整数$a_i$.接下来有$n-1$行,每行有两个整数$u,v$,表示$u$与$v$之间通过化学单键连接. 输 ...

  6. mysql的windows客户端链接远程全套案例

    我是linux 的服务器,navicat12的客户端, 开始链接的时候需要开服务器上得对外爆漏端口 3306,方法: 添加指定需要开放的端口: firewall-cmd --add-port=/tcp ...

  7. MAC使用命令行打包出ipa包-通过xcodeproj

    参考 : https://www.jianshu.com/p/32af2f71b4e5--老了,里面的一些命令现在都没有了,但可以借鉴思路 https://www.jianshu.com/p/004c ...

  8. 【原创】复制知乎“禁止转载”的内容做笔记 - 基于oncopy监听器的简单解决方案

    原理:移除所有oncopy的监听器. 使用: 新建书签,地址设为: javascript: getEventListeners(document).copy.forEach(({listener}) ...

  9. Npm使用遇到的问题解决

    0.运行项目: 1)git clone 项目 2)项目根目录执行npm install安装依赖 3)执行npm run dev启动 1.安装cnpm: npm install -g cnpm --re ...

  10. rabbitmq-5-案例2-简单的案例+exchange

    Exchange交换机: sendMessage端,发送消息到Exchage1.2, 然后交换机通过路由键,将消息转发给队列queue中,最后客户端从队列中获取消息 交换属性: name:名称 typ ...