QT blockingmaster例子学习
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例子学习的更多相关文章
- qt下面例子学习(部分功能)
from aa import Ui_Formfrom PyQt4.Qt import *from PyQt4.QtCore import *from PyQt4.QtGui import *from ...
- (转)Qt Model/View 学习笔记 (七)——Delegate类
Qt Model/View 学习笔记 (七) Delegate 类 概念 与MVC模式不同,model/view结构没有用于与用户交互的完全独立的组件.一般来讲, view负责把数据展示 给用户,也 ...
- (转)Qt Model/View 学习笔记 (五)——View 类
Qt Model/View 学习笔记 (五) View 类 概念 在model/view架构中,view从model中获得数据项然后显示给用户.数据显示的方式不必与model提供的表示方式相同,可以与 ...
- Qt 智能指针学习(7种指针)
Qt 智能指针学习 转载自:http://blog.csdn.net/dbzhang800/article/details/6403285 从内存泄露开始? 很简单的入门程序,应该比较熟悉吧 ^_^ ...
- 数百个 HTML5 例子学习 HT 图形组件 – 3D建模篇
http://www.hightopo.com/demo/pipeline/index.html <数百个 HTML5 例子学习 HT 图形组件 – WebGL 3D 篇>里提到 HT 很 ...
- 数百个 HTML5 例子学习 HT 图形组件 – 3D 建模篇
http://www.hightopo.com/demo/pipeline/index.html <数百个 HTML5 例子学习 HT 图形组件 – WebGL 3D 篇>里提到 HT 很 ...
- 数百个 HTML5 例子学习 HT 图形组件 – WebGL 3D 篇
<数百个 HTML5 例子学习 HT 图形组件 – 拓扑图篇>一文让读者了解了 HT的 2D 拓扑图组件使用,本文将对 HT 的 3D 功能做个综合性的介绍,以便初学者可快速上手使用 HT ...
- 数百个 HTML5 例子学习 HT 图形组件 – 拓扑图篇
HT 是啥:Everything you need to create cutting-edge 2D and 3D visualization. 这口号是当年心目中的产品方向,接着就朝这个方向慢慢打 ...
- HTML5 例子学习 HT 图形组件
HTML5 例子学习 HT 图形组件 HT 是啥:Everything you need to create cutting-edge 2D and 3D visualization. 这口号是当年心 ...
随机推荐
- 安装并配置前端自动化工具-gulp
由于现在前端自动化已经很有必要了,所以我今天死皮烂脸的找了2位前端大咖帮助我安装和配置gulp,讲真,这一步步弄下来直到安装配置成功,到现在还是迷迷糊糊,不过我还是把这些步骤给记录下来,以防下次不记得 ...
- 【LeetCode 96】不同的二叉搜索树
题目链接 [题解] 我们可以枚举这棵树的根节点在i处. 现在问题就变成. 1..i-1这i-1个节点组成的树和i+1..n这n-i个节点组成的树的个数的问题了. 假设他们俩的结果分别是cnt1和cnt ...
- GIT安装包备用地址
如果官网下载被禁止,可在下面这个地址下载,速度飞快 http://www.wmzhe.com/soft-38801.html#download
- Android实战技巧:Dialog (转)
转:http://blog.csdn.net/hitlion2008/article/details/7567549#t0 Dialog是任何系统都必须有的一个控件,作为辅助窗口,用于显示一些消息,或 ...
- 请教怎么查询ORACLE的历史操作记录!
请问如何查询ORACLE的历史操作记录!!!!!我用的是linux oracle 11g r2,想查一下前几天的数据库的历史操作记录,例如对表的insert,delete,update等等的操作记录, ...
- php面试专题---5、流程控制考点
php面试专题---5.流程控制考点 一.总结 一句话总结: 看代码不要先看函数里面的内容,要用的时候再去看:注意静态,注意变量作用域,php中的内置函数需要去归类总结,就是太容易忘记了 1.写出如下 ...
- appium常见问题10_MAC_终端输入aapt指令报错提示"command not found"
问题: MAC终端使用aapt指令"aapt dump badging xxx/xxx/xxx.apk"查看apk包名和activity时报错提示"command not ...
- Html5 学习笔记 【PC固定布局】 实战7 机票预订页面
最终实际效果: HTML代码: <!DOCTYPE html> <html lang="zh-cn"> <head> <meta char ...
- 2015年6月发布了ECMAScript6版本
2015年6月 node.js.npm | cnpm.cli angular2.x.react.js.Vue.js
- 在C#后台使用MD5值对文件进行加
首先说一下MD5值的概念和来源.MD5的全称是Message-Digest Algorithm 5,在90年代初由MIT的计算机科学实验室和RSA Data Security Inc发明,经MD2.M ...