qt QThread
QThread类提供了一个平台无关的方式来管理线程。
一个QThread对象在程序控制中管理一个线程。线程在run()中开始执行。默认情况下,run()通过调用exec()启动事件循环并在线程里运行一个Qt的事件循环。
可以使用worker-object通过QObject::moveToThread将它们移动到线程。
class Worker : public QObject
{
Q_OBJECT
public slots:
void doWork(const QString ¶meter) {
// ...
emit resultReady(result);
}
signals:
void resultReady(const QString &result);
};
class Controller : public QObject
{
Q_OBJECT
QThread workerThread;
public:
Controller() {
Worker *worker = new Worker;
worker->moveToThread(&workerThread);
connect(workerThread, &QThread::finished, worker, &QObject::deleteLater);
connect(this, &Controller::operate, worker, &Worker::doWork);
connect(worker, &Worker::resultReady, this, &Controller::handleResults);
workerThread.start();
}
~Controller() {
workerThread.quit();
workerThread.wait();
}
public slots:
void handleResults(const QString &);
signals:
void operate(const QString &);
};
Worker槽中的代码将在一个单独的线程中执行,然而,可以将(来自任何对象、在任何线程中)任何信号与该槽自由地连接,在不同的线程里连接信号和槽也是安全的,这要归功于一个叫排队的连接机制(queued connections)。
另一种使代码运行在一个单独的线程中的方法,是子类化QThread中并重新实现的run()。
例如:
class WorkerThread : public QThread
{
Q_OBJECT
void run() Q_DECL_OVERRIDE {
QString result;
emit resultReady(result);
}
signals:
void resultReady(const QString &s);
};
void MyObject::startWorkInAThread()
{
WorkerThread *workerThread = new WorkerThread(this);
connect(workerThread, &WorkerThread::resultReady, this, &MyObject::handleResults);
connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater);
workerThread->start();
}
上面的例子中,在run()返回后线程就会退出,在线程中将不会有任何的事件循环运行除非调用exec()。
注意一个线程实例位于实例化它的旧线程中,而非调用run()的新线程中,这意味着所有线程的排队槽将在旧线程中执行。因此,开发人员希望在新线程调用槽必须使用worker-object方法,新槽不应直接在子类化QThread中来实现。
当子类化QThread时,请记住,构造函数在旧线程中执行,然而run()在新线程中执行。如果一个成员变量的访问来自两个函数,然后从两个不同的线程访问变量,需要检查这样做是否安全。
注:用在不同的线程中的对象进行交互时必须小心。详见同步线程(Synchronizing Threads)。
管理线程
QThread会通知你触发了一个信号当线程started()和finished()时,或者使用isFinished()和isRunning()来查询线程的状态。
可以通过调用exit()或quit()来停止线程。在极端情况下,你可能要强行terminate()一个执行线程。但是,这样做是危险的。请阅读文档查看terminate()和setTerminationEnabled()的详细信息。
从Qt4.8起,可以释放运行刚刚结束的线程对象,通过连接finished()信号到QObject::deleteLater()。
使用wait()来阻塞调用的线程,直到其他线程执行完毕(或者直到指定的时间过去)。
QThread中还提供了静态的、平台独立的休眠功能:sleep()、msleep()、usleep()允许秒,毫秒和微秒来区分,这些函数在Qt5.0中被设为public。
注意:一般情况下,wait()和sleep()函数应该不需要,因为Qt是一个事件驱动型框架。而不是wait(),关心监听信号finished()。取代sleep(),可以考虑使用QTimer。
静态函数currentThreadId()和currentThread()返回标识当前正在执行的线程。前者返回该线程的平台特定的ID,后者返回一个线程指针。
要设置线程的名称,可以在启动线程之前调用setObjectName()。如果不调用setObjectName(),线程的名称将是线程对象的运行时类型(上例中“WorkerThread”,因为这是QThread子类的类名)。请注意,基于Windows的构建版本目前不可用。
qt QThread的更多相关文章
- Qt - QThread(翻译帮助文档)
QThread Class 详细描述 QThread 类提供一个平台无关的方法来管理线程. 一个QThread对象管理一个程序中的控制线程.QThread在run()中开始执行任务.默认地,run() ...
- Qt QThread 线程创建,线程同步,线程通信 实例
1. 继承QThread, 实现run()方法, 即可创建线程. 2. 实例1 代码 myThread.h #ifndef MYTHREAD_H #define MYTHREAD_H #includ ...
- Qt QThread必须要了解的几个函数
概述 如果想对Qt中的QThread有个更加深刻的了解,必须要知道这几个重要的函数,现在就一一介绍下. 函数介绍 属性 返回值 函数体 功能 static QThread * QThread::cur ...
- Qt QThread 多线程使用
一.继承QThread 使用方法 1.创建个继承QThread的类. #ifndef MYTHREAD_H #define MYTHREAD_H #include <QObject> #i ...
- Qt QThread两种方式的使用:1-继承QThread重写run函数; 2- 继承QObject并moveToThread && 消息和槽在线程和依附线程间的传递
2019年08月18日起笔 方式一:继承QThread重写run函数 MyThread.h ----------------------------------- ... class MyThread ...
- QThread多线程编程经典案例分析
传统的图形界面应用程序都只有一个线程执行,并且一次执行一个操作.如果用户调用一个比较耗时的操作,就会冻结界面响应. 一个解决方法是按照事件处理的思路: 调用 Void QApplication::pr ...
- pyqt5-多线程QThread类
要实现多线程,我们要先继承QThread类并重新实现其中的run()函数,也就是说把耗时的操作放入run()函数中 import sys from PyQt5.QtCore import Qt, QT ...
- 【PyQt5 学习记录】004:简单QThread笔记
在文本编辑框中每隔几秒添加一行文本,代码如下: #!/usr/bin/python3 # -*- coding:utf-8 -*- import sys from PyQt5.QtWidgets im ...
- QThread多线程编程经典案例分析(三种方法,解释了为什么使用moveToThread的根本原因,即为了避免调用QThread::exec() )
传统的图形界面应用程序都只有一个线程执行,并且一次执行一个操作.如果用户调用一个比较耗时的操作,就会冻结界面响应. 一个解决方法是按照事件处理的思路: 调用 Void QApplication::pr ...
随机推荐
- ABAP Code Inspector那些隐藏的功能,您都知道吗?
最近有粉丝在后台给我留言,说新知识太多,"学不动了".所谓温故而知新,今天我们就来重温下ABAP里的Code Inspector的用法. 2015年6月,我在SAP社区上写了一篇博 ...
- Linux之python3编译安装
一,前言 centos7默认是装有python的,咱们先看一下 [root@glh ~ 20:18:03]#python Python 2.7.5 (default, Jul 13 2018, 13: ...
- jquery中的ajax方法(备忘)
参考:https://www.cnblogs.com/tylerdonet/p/3520862.html w3school:http://www.w3school.com.cn/jquery/ajax ...
- 【DELL存储】EMC会议 超融合+存储
场景:盐城工厂 IT人数 4个人 机房200台 主要以虚拟化为主 实体机 PG ORACAL MYSQL dell产品线 提供整体方案 架构 针对整车厂 :传统+超融合 1. 介绍产品 1.1 超融 ...
- 一个s的力量——http与https
我们网络上有很多资源,那么我们怎么来访问呢?就拿一个小例子来说,我们都会用百度来搜索东西,就会在地址栏中输入这样的地址http://www.baidu.com这种访问方式就是通过URL来实现的,那么什 ...
- DT7.0主动推送当天高质量图片数据到熊掌号展现
<?php /* 百度当天主动推送熊掌功能 作者:68喜科技 用于:DT7.0 功能模块:优质内容推送熊掌*出图内容当天推送 */ //引入全局变量函数 defined('IN_DESTOON' ...
- 03 Spring对Bean的管理
Spring创建bean的三种方式 1.第一种方式:使用默认构造函数创建 bean.xml <?xml version="1.0" encoding="UTF-8& ...
- JSOI2012 玄武密码 和 HDU2222 Keywords Search
玄武密码 给若干模式串和一个文本串.求每个模式串在文本串上能匹配的最大前缀长度. N<=10^7,M<=10^5,每一段文字的长度<=100. jklover的题解 将模式串建成一个 ...
- jquerymobile tap事件被触发两次
首先介绍一下这个问题出现的背景:我在写网站时想要一套代码兼容手机端和pc端,所以用了jquery和jquery mobile,点击事件用的jquerymobile tap事件,但是在移动端测试时出现点 ...
- LOJ2823 三个朋友 ——查询字串的哈希值
概念 查询字串的hash值 我们所说的哈希通常都是进制哈希,因为它具有一些很方便的性质,例如,具有和前缀和类似的性质. 假设一个字符串的前缀哈希值记为 $h[i]$,进制为 $base$,那么显然 $ ...