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. 这口号是当年心 ...
随机推荐
- 【HDU6609】Find the answer【线段树】
题目大意:给你一个序列,对于每个i,你可以选择1~i-1中任意多的数并将它删去,剩余的数(包括i)∑≤m,问对于每个i最少删几个数可以达到要求 题解: 考虑朴素的思想,对于每个i,我只需要删去最大的若 ...
- Linux Bash Shell快速入门 (三)
forfor 循环结构与 C 语言中有所不同,在 BASH 中 for 循环的基本结构是: for $var in dostatmentsdone 其中 $var 是循环控制变量, 是 $var 需要 ...
- soj#552 449E Jzzhu and Squares
分析 https://www.cnblogs.com/Memory-of-winter/p/11209128.html 代码 #include<bits/stdc++.h> using n ...
- 【ngx-ueditor】百度编辑器按下Shift键不触发contentChange事件
背景:基于Angular 6,引入ngx-ueditor 发现现象:如果以Shift键+任意键结尾,则ngModel会丢失包含shift键的字符 例如:输入“ABC+AB++++”,则ngModel中 ...
- JS-for..of
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/for...of 刚刚上网上看到<V8 ...
- Could not resolve placeholder'XXX' in string value "XXXX"
练习SSM项目的demo中遇到一个问题,我在applicationContext.xml中使用了<context:property-placeholder location="clas ...
- PHP+JS的信息提示弹窗
基于PHP函数的Msg信息提示框 1.可以设置弹出信息,跳转地址,跳转的时间,跳转的信息标题提示: 2.代码实例: <?php function ShowMsg($msg, $gourl,$ti ...
- electron测试TCP通信
这几天学习了一下Elctron,对于这个应用有了一点简单的认识,将这个过程记录一下. 首先,electron会加载main.js,在这里将整个程序启动,相当于其他程序的main函数了. 我是基于ele ...
- jQuery设置checkbox 为选中状态
1设置第一个checkbox 为选中值$('input:checkbox:first').attr("checked",'checked');或者$('input:checkbox ...
- python学习笔记之数据类型、字符编码、文件处理
1.数据类型 1.数字(int,float) 整形(int):定义 age=20 #本质age=int(20) 浮点类型:salary=3000.3 #本质salary=float(3000.3) ...