导航:首页 > 使用方法 > qthread使用方法

qthread使用方法

发布时间:2022-06-28 17:40:24

① 谁能说一下在Qt中使用多线程有哪些需要注意的事项呢

在Qt中使用多线程,目前就我使用过的有两种,一是子类化QThread,重写run函数,在run函数里实现自己的代码,这一部分代码通常是比较耗时,或者干脆直接阻塞的。比如一个while循环,设置一个标志,判断循环结束。
这样的例子在网上有很多,就不写了。
这样写的话,会有一些东西需要了解。
子类化QThread的方法,只有run函数里面的内容是执行在子线程里的,其他的部分,比如槽函数什么的还是在主线程里执行(假设是在主线程开启的该子线程)。
还有一种方法,是子类化QObject,新建一个线程,然后使用MoveToThread把这个类的对象移到新建的线程中,这种做法使得它所有的槽函数都是执行在新开辟的线程里面。
如果直接(QObject对象).abc()的话,这个成员函数是在主进程内执行,可能会出现"QObject::killTimer: timers
cannot be stopped from another thread"的运行错误。
使用第二种方法的话,貌似会遇到这样的问题:如果在一个槽函数中把子线程阻塞,其他的槽函数无法接受来自主线程

② 请问Qt中使用WinThread通常如何实现线程间通信如传递QByteArray

在Qt里面是QThread吧,如果是多线程要在一个类里面也没啥问题,效率那主要就是考虑你线程干什么工作了,在Qt里面,你可以直接继承QThread类并实现它的run方法就可以了
class Worker_1 : public QThread
{
public:
Worker_1();

~Worker_1();

protected:
virtual void run() { // do somthing }

}
class Work_2 //你同样可以写出Work_2这个类
class WorkManager : QObject
{
Q_OBJECT

//......

public:

void start()

{
w1.start();

w2.start();

}

private:

Worker_1 w1;

Worker_2 w2;

}

// test main function
int main(void)
{
WorkManager wm;
wm.start();
while(1) QThread::sleep(300000);
}

在Qt里面QMutex、QSemphore只可以用来做线程间同步,如果你涉及到多线程共享资源的访问的话
两个线程间传递QByteArray,如果这个QbyteArray非常大的话,你建议你使用共享内存的方式,当然如果情况还好,可以使用Qt的信号与槽机制

③ 用QThread创建的线程如何关闭

QT线程有3个函数可以关闭线程,分别是:
void quit ()
相当于exit(0)。

void exit ( int returnCode = 0 )
调用exit后,thread将退出event loop,并从exec返回,exec的返回值就是returnCode。
通常returnCode=0表示成功,其他值表示失败。

void terminate ()
结束线程,线程是否立即终止取决于操作系统。
线程被终止时,所有等待该线程Finished的线程都将被唤醒。
terminate是否调用取决于setTerminationEnabled ( bool enabled = true )开关。

其中quit与terminate是槽,可以直接用信号连接关闭线程,不过一般不建议使用terminate,还有想关闭线程,最好像下面例子;
直接调用stop接口就行了,线程就会关闭

class Thread : public QThread
{
Q_OBJECT
public:
Thread();

void setMessage(const QString &message);
void stop();

protected:
void run();

private:
QString messageStr;
volatile bool stopped;
};

Thread::Thread()
{
stopped = false;
}
void Thread::run()
{
while (!stopped)
std::cerr << qPrintable(messageStr);
stopped = false;
std::cerr << std::endl;
}
void Thread::stop()
{
stopped = true;
}

④ qthread类中能添加槽函数吗

主线程(信号)QThread(槽)
这是 Qt Manual 和 例子中普遍采用的方法。 但由于manual没说槽函数是在主线程执行的,所以不少人都认为它应该是在次线程执行了。
定义一个 Dummy 类,用来发信号
定义一个 Thread 类,用来接收信号

⑤ 怎样正确的使用QThread类

要实现一个线程很简单,写一个函数,绑定一些数据,如果有必要的话,可以使用 mutex 或者其他方法来保证和线程的安全交互。
无论是 Win32、POSIX 或其他线程,工作原理都基本相同,并相当可靠。至少我敢说比 socket 更容易使用和处理。
简述
worker-object
worker-object
使用 QThread 时,最主要的事情是把它当成一个线程对象的封装。此封装提供了信号、槽和方法,可以轻松地使用 Qt 项目中的线程对象。这说明了子类化 QThread 并实现其 run() 函数是非常错误的。
一个 QThread 应该更像一个普通线程实例:准备一个 QObject 类和所有想要的功能,然后创建一个新的QThread,使用 moveToThread(QThread *) 将 QObject 对象移动至线程中,并调用 QThread 实例的 start() 函数。就这样,再设置适当的信号/槽连接使它正常退出,所有的事情就都做完了。

⑥ 如何使用 qthread run 获取参数

创建qthread的自定义子类QMyThread。QMyThread增加成员来传递参数。
用QMyThread创建线程时,并把参数赋值给QMyThread对象。run的时候,直接从QMyThread对象中获取参数。

⑦ qthread如何启动多个线程

1. 引言

多线程对于需要处理耗时任务的应用很有用,一方面响应用户操作、更新界面显示,另一方面在“后台”进行耗时操作,比如大量运算、复制大文件、网络传输等。
使用Qt框架开发应用程序时,使用QThread类可以方便快捷地创建管理多线程。而多线程之间的通信也可使用Qt特有的“信号-槽”机制实现。
下面的说明以文件复制为例。主线程负责提供交互界面,显示复制进度等;子线程负责复制文件。最后附有可以执行的代码。

2. QThread使用方法1——重写run()函数

第一种使用方法是自己写一个类继承QThread,并重写其run()函数。
大家知道,C/C++程序都是从main()函数开始执行的。main()函数其实就是主进程的入口,main()函数退出了,则主进程退出,整个进程也就结束了。
而对于使用Qthread创建的进程而言,run()函数则是新线程的入口,run()函数退出,意味着线程的终止。复制文件的功能,就是在run()函数中执行的。
下面举个文件复制的例子。自定义一个类,继承自Qthread

CopyFileThread: public QThread
{
Q_OBJECTpublic:
CopyFileThread(QObject * parent = 0);protected: void run(); // 新线程入口// 省略掉一些内容}

在对应的cpp文件中,定义run()

void CopyFileThread::run(){ // 新线程入口
// 初始化和操作放在这里}

将这个类写好之后,在主线程的代码中生成一个CopyFileThread的实例,例如在mainwindow.cpp中写:

// mainwindow.h中CopyFileThread * m_cpyThread;// mainwindow.cpp中m_cpyThread = new CopyFileThread;

在要开始复制的时候,比如按下“复制”按钮后,让这个线程开始执行:

m_cpyThread->start();

注意,使用start()函数来启动子线程,而不是run()。start()会自动调用run()。
线程开始执行后,就进入run()函数,执行复制文件的操作。而此时,主线程的显示和操作都不受影响。
如果需要进行对复制过程中可能发生的事件进行处理,例如界面显示复制进度、出错返回等等,应该从CopyFileThread中发出信号(signal),并事先连接到mainwindow的槽,由这些槽函数来处理事件。

3. QThread使用方法2——moveToThread()

如果不想每执行一种任务就自定义一个新线程,那么可以自定义用于完成任务的类,并让它们继承自QObject。例如,自定义一个FileCopier类,用于复制文件。

class FileCopier : public QObject
{
Q_OBJECTpublic: explicit FileCopier(QObject *parent = 0);public slots: void startCopying(); void cancelCopying();
}

注意这里我们定义了两个槽函数,分别用于复制的开始和取消。
这个类本身的实例化是在主线程中进行的,例如:

// mainwindow.h中private:
FileCopier* m_copier;// mainwindow.cpp中,初始化时
m_copier = new FileCopier;

此时m_copier还是属于主线程的。要将其移动到子线程处理,需要首先声明并实例化一个QThread:

// mainwindow.h中signals: void startCopyRsquested();private:
QThread * m_childThread; // m_copier将被移动到此线程执行// mainwindow.cpp中,初始化时
m_childThread = new QThread; // 子线程,本身不负责复制

然后使用moveToThread()将m_copier移动到新线程。注意moveToThread()是QObject的公有函数,因此用于复制文件的类FileCopier必须继承自QObject。移动之后启动子线程。此时复制还没有开始。

m_copier->moveToThread(m_childThread); // 将实例移动到新的线程,实现多线程运行
m_childThread->start(); // 启动子线程

注意一定要记得启动子线程,否则线程没有运行,m_copier的功能也无法执行。
要开始复制,需要使用信号-槽机制,触发FileCopier的槽函数实现。因此要事先定义信号并连接:

// mainwindow.h中signals: void startCopyRsquested();// mainwindow.cpp中,初始化时// 使用信号-槽机制,发出开始指令
connect(this, SIGNAL(startCopyRsquested()), m_copier, SLOT(startCopying()));

当按下“复制”按钮后,发出信号。

emit startCopyRsquested(); // 发送信号

m_copier在另一个线程接收到信号后,触发槽函数,开始复制文件。

4.常见问题

4.1. 子线程中能不能进行UI操作?

Qt中的UI操作,比如QMainWindow、QWidget之类的创建、操作,只能位于主线程!
这个限制意味着你不能在新的线程中使用QDialog、QMessageBox等。比如在新线程中复制文件出错,想弹出对话框警告?可以,但是必须将错误信息传到主线程,由主线程实现对话框警告。
因此一般思路是,主线程负责提供界面,子线程负责无UI的单一任务,通过“信号-槽”与主线程交互。

4.2. QThread中的哪些代码属于子线程?

QThread,以及继承QThread的类(以下统称QThread),他们的实例都属于新线程吗?答案是:不。
需要注意的是,QThread本身的实例是属于创建该实例的线程的。比如在主线程中创建一个QThread,那么这个QThread实例本身属于主线程。当然,QThread会开辟一个新线程(入口是run()),但是QThread本身并不属于这个新线程。也就是说,QThread本身的成员都不属于新线程,而且在QThread构造函数里通过new得到的实例,也不属于新线程。这一特性意味着,如果要实现多线程操作,那么你希望属于新线程的实例、变量等,应该在run()中进行初始化、实例化等操作。本文给出的例子就是这样操作的。
如果你的多线程程序运行起来,会出现关于thread的报警,思考一下,各种变量、实例是不是放对了位置,是不是真的位于新的线程里。

4.3. 怎么查看是不是真的实现了多线程?

可以打印出当前线程。对于所有继承自QObject的类,例如QMainwindow、QThread,以及自定义的各种类,可以调用QObject::thread()查看当前线程,这个函数返回的是一个QThread的指针。例如用qDebug()打印:
在mainwindow.cpp的某个函数里、QThread的run()函数里、自定义类的某个函数里,写上:

qDebug() << "Current thread:" << thread();

对比不同位置打印的指针,就可以知道它们是不是位于同一个线程了。

5.范例

范例实现了多线程复制文本文件。
提供的范例文件可用QtCreator编译运行。界面如下(不同的操作系统略有不同):

范例中实现了本文介绍的两种方法,同时也给出了单线程复制对比。打钩选择不同的复制方法。可以发现,在使用多线程的时候,界面不会假死,第二根进度条的动画是持续的;而使用单线程复制的时候,“取消”按钮按不动,界面假死,而且第二根进度条的动画也停止了。
由于范例处理的文件很小,为了让复制过程持续较长时间以便使得现象明显,复制文件的时候,每复制一行加入了等待。

范例代码:
https://github.com/Xia-Weiwen/CopyFile

⑧ python pyqt5 qthread有哪些方法

用例子说明吧,常用的不多
PyQt中的线程类 QtCore.QThread ,使用时继承QThread类
启动界面的线程暂称为UI线程。界面执行命令时都在自己的UI线程中。
如果在UI线程中执行网络连接和数据库操作等耗时的操作,界面会被卡住,Windows下有可能会出现“无响应”的警告。
阻塞UI线程会降低用户体验和应用稳定性。因此我们可以把耗时操作放在线程中去执行。
QThread代表一个线程,我们可以复写run函数来执行我们要的操作。
QThread可以使用 QtCore.pyqtSignal 来与界面交互和传输数据。
PyQt4 QThread 代码示例

•Python2.7
# -*- coding: utf-8 -*-
import sys

from PyQt4 import QtCore
from PyQt4.QtCore import QCoreApplication
from PyQt4.QtGui import QWidget, QPushButton, QApplication, QTextBrowser

class TimeThread(QtCore.QThread):
signal_time = QtCore.pyqtSignal(str, int) # 信号

def __init__(self, parent=None):
super(TimeThread, self).__init__(parent)
self.working = True
self.num = 0

def start_timer(self):
self.num = 0
self.start()

def run(self):
while self.working:
print "Working", self.thread()
self.signal_time.emit("Running time:", self.num) # 发送信号
self.num += 1
self.sleep(1)

class TimeDialog(QWidget):
def __init__(self):
super(TimeDialog, self).__init__()
self.timer_tv = QTextBrowser(self)
self.init_ui()
self.timer_t = TimeThread()
self.timer_t.signal_time.connect(self.update_timer_tv)

def init_ui(self):
self.resize(300, 200)
self.setWindowTitle('TimeDialog')
self.timer_tv.setText("Wait")
self.timer_tv.setGeometry(QtCore.QRect(10, 145, 198, 26))
self.timer_tv.move(0, 15)

btn1 = QPushButton('Quit', self)
btn1.setToolTip('Click to quit')
btn1.resize(btn1.sizeHint())
btn1.move(200, 150)
btn1.clicked.connect(QCoreApplication.instance().quit)

start_btn = QPushButton('Start', self)
start_btn.setToolTip("Click to start")
start_btn.move(50, 150)
self.connect(start_btn, QtCore.SIGNAL("clicked()"), self.click_start_btn)

def click_start_btn(self):
self.timer_t.start_timer()

def update_timer_tv(self, text, number):
self.timer_tv.setText(self.tr(text + " " + str(number)))

if __name__ == '__main__':
app = QApplication(sys.argv)
time_dialog = TimeDialog()
time_dialog.show()

sys.exit(app.exec_())

QThread中使用的信号 signal_time = QtCore.pyqtSignal(str, int) 指定了参数str和int
发送信号 self.signal_time.emit("Running time:", self.num)
外部接收信号 self.timer_t.signal_time.connect(self.update_timer_tv)
信号连接到方法 update_timer_tv(self, text, number) ,注意信号与方法的参数要一一对应
使用中我们可以定义多种不同的信号 QtCore.pyqtSignal
启动线程,调用 start()

⑨ QT线程如何使用的

包含QThread头文件
创建一个对象指针 QThread *myThread;
myThread = new QThread;
myThread->start();

同时需要在新建的QThread线程文件中的run函数里面添加你想要用的代码即可。

建议看看QT开发的书,例子很多。也可以看帮主文档的。

阅读全文

与qthread使用方法相关的资料

热点内容
剪辑视频的方法 浏览:592
如何用化学方法鉴别环己烷和苯胺 浏览:539
浙江菜烹饪方法有哪些 浏览:382
星战模拟器怎么找到自己的家正确方法 浏览:766
2020洪灾原因和解决方法 浏览:828
长期失眠睡不着怎么办最好的方法 浏览:109
哪些激励方法可以激励员工 浏览:336
达尔文作用什么方法得出进化论 浏览:632
鼓楼区干货离心机操作方法有哪些 浏览:393
30公分最佳找点方法视频 浏览:285
球圆度的测量方法 浏览:910
机动车牌正确安装方法 浏览:418
防盗门的安装方法 浏览:508
剪映的学习方法在剪映哪里 浏览:724
快速制作葡萄酒的方法步骤 浏览:438
ipad连接pencil方法 浏览:903
鸟笼制作方法视频 浏览:478
用什么好方法提高成绩 浏览:975
古玩铜钱鉴别方法 浏览:145
薪酬设计制作方法和步骤 浏览:503