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. 这口号是当年心 ...
随机推荐
- 4412 移植mpu9250尝试
4412的板子IO都是1.8v的.只有I2C6是用了电平转换到了3.3v.所以我准备使用I2C6来驱动mpu9250 一.首先去掉占用的模块 menuconfig中去掉触摸的驱动 Device Dri ...
- JS中关于引用类型数据及函数的参数传递
(JavaScript 中,函数的参数传递方式都是按值传递,没有按引用传递的参数) 一.数据类型 在 javascript 中数据类型可以分为两类: 基本类型值 primitive type,比如Un ...
- [CSP-S模拟测试]:y(DP+bitset)
题目背景 $\frac{1}{4}$遇到了一道水题,叕完全不会做,于是去请教小$D$.小$D$懒得理$\frac{1}{4}$,直接就离开了.于是,$\frac{1}{4}$只好来问你,这道题是这样的 ...
- 搭建本地npm
cnpm install -g sinopia 然后执行sinopia npm set registry [url] npm adduser 然后就可以发布了 使用的时候切换registry就可以 修 ...
- LCA 总结
代码: //RMQ求LCA struct node { int v, w; }; class LCA { private: vector<int>dep, pos, olx, dis; v ...
- Map-Amap:自定义地图
ylbtech-Map-Amap:自定义地图 1.返回顶部 1. http://lbs.amap.com/getting-started/mapstyle 2. 2.返回顶部 1. 自定义地图,地图从 ...
- Skyline(6.x)-Web二次开发-1多窗口对比
一个页面加载多个 TerraExplorer3DWindow 和 SGWorld 等只有第一个能用(即使用 iframe 也是一样) 所以我决定打开两个新页面实现多窗口对比,然后我在<主页面&g ...
- 1.OpenCV数据类型
基础类型 1.模板类cv::Vec<> 固定向量类,维度已知的小型向量——处理效率高 2.cv::Point类(Point2i,Point2f,Point2d;Point3i,Point3 ...
- day64 views文件
from django.shortcuts import HttpResponse, render, redirect from app01 import models # Create your v ...
- python 装饰器 对类和函数的装饰
#装饰器:对类或者函数进行功能的扩展 很多需要缩进的没有进行缩进'''#第一步:基本函数def laxi(): print('拉屎')#调用函数laxi()laxi() print('======= ...