- class QThread#
-
摘要#
方法#
def
__init__()
def
exec()
def
exec_()
def
isFinished()
def
isRunning()
def
loopLevel()
def
priority()
定义
stackSize()
定义
wait()
虚方法#
定义
run()
槽#
定义
exit()
定义
quit()
定义
start()
定义
terminate()
信号#
定义
finished()
定义
started()
静态函数#
注意
本文档可能包含从C++自动翻译到Python的代码片段。我们始终欢迎对片段翻译的贡献。如果您发现翻译中的问题,也可以通过在https:/bugreports.qt.io/projects/PYSIDE创建工单的方式告知我们。
详细描述#
警告
本节包含了自动从C++转换为Python的代码片段,可能包含错误。
一个
QThread
对象管理程序中的一个线程控制。QThread从run()
开始执行。默认情况下,run()
通过调用exec()
启动事件循环,并在线程内运行Qt事件循环。您可以通过使用
moveToThread()
将工作对象移动到线程中来使用它们。class Worker(QObject): Q_OBJECT # public slots def doWork(parameter): result = QString() /* ... here is the expensive or blocking operation ... */ resultReady.emit(result) # signals def resultReady(result): class Controller(QObject): Q_OBJECT workerThread = QThread() # public Controller() { worker = Worker() worker.moveToThread(workerThread) workerThread.finished.connect(worker.deleteLater) self.operate.connect(worker.doWork) worker.resultReady.connect(self.handleResults) workerThread.start() ~Controller() { workerThread.quit() workerThread.wait() # public slots def handleResults(): # signals def operate():
工件的槽中的代码将在一个单独的线程中执行。然而,您可以将工件的槽连接到任何对象的任何信号中,在任意的线程中。由于存在一种称为
queued connections
的机制,因此在不同线程之间连接信号和槽是安全的。使代码在单独的线程中运行的另一种方式是,通过继承
QThread
并重写run()
来实现。例如class WorkerThread(QThread): Q_OBJECT def run(): result = QString() /* ... here is the expensive or blocking operation ... */ resultReady.emit(result) # signals def resultReady(s): def startWorkInAThread(self): workerThread = WorkerThread(self) workerThread.resultReady.connect(self.handleResults) workerThread.finished.connect(workerThread.deleteLater) workerThread.start()
在这个例子中,线程将在run函数返回后退出。除非您调用
exec()
,否则线程中不会运行任何事件循环。重要的是要记住,
QThread
实例lives in
创建它的旧线程中,而不是在调用run()
的新线程中。这意味着所有QThread
的队列槽和invoked methods
都将在这个旧线程中执行。因此,希望在新线程中调用槽的开发者必须使用工作对象方法;不应直接在工作对象继承的子类中实现新槽。与排队槽位或调用的方法不同,直接在
QThread
对象上调用的方法将在调用方法的线程中执行。当继承QThread
时,请注意构造函数在旧线程中执行,而run()
在新的线程中执行。如果从这两个函数中访问成员变量,则变量将在两个不同的线程中访问。请检查这样做是否安全。注意
在跨不同线程交互对象时必须小心。一般来说,函数只能从创建
QThread
对象的线程本身调用(例如:setPriority()
),除非文档说明其他情况。请参阅同步线程的详细信息。管理线程#
QThread
将通过信号通知您线程何时started()
和finished()
,或者您可以使用isFinished()
和isRunning()
来查询线程的状态。您可以通过调用
exit()
或quit()
来停止线程。在极端情况下,您可能想强迫terminate()
正在执行的线程。但是,这样做是危险的,不推荐。请阅读terminate()
和setTerminationEnabled()
的文档,获取详细信息。当一个线程结束时,您通常希望释放在该线程中存在的对象。为此,将
finished()
信号连接到deleteLater()
。使用
wait()
来阻塞调用线程,直到另一个线程完成执行(或者直到经过指定的时间)。QThread
还提供静态、平台无关的睡眠函数:sleep()
,msleep()
,以及usleep()
分别提供一秒钟、毫秒和微秒的分辨率。注意
wait()
和sleep()
函数通常是不必要的,因为 Qt 是一个事件驱动的框架。代替wait()
,可以考虑监听finished()
信号。代替sleep()
函数,考虑使用QTimer
.currentThreadId()
和currentThread()
静态函数返回当前正在执行的线程的标识符。前者返回线程的平台特定 ID;后者返回一个QThread
指针。为了选择您的线程将被赋予的名称(例如,在 Linux 中由命令
ps -L
识别),您可以在启动线程之前调用setObjectName()
。如果您不调用setObjectName()
,您的线程名称将是线程对象的运行时类型的类名(例如,在 Mandelbrot 示例中的"RenderThread"
,因为这是QThread
子类的名称)。注意,这目前在 Windows 的发行版构建中不可用。另请参阅
QThreadStorage
Mandelbrot Producer and Consumer using Semaphores Producer and Consumer using Wait Conditions- class Priority#
此枚举类型指示操作系统应如何调度新创建的线程。
常量
描述
QThread.IdlePriority
仅在没有任何其他线程运行时才会调度。
QThread LowestPriority
调度频率低于LowPriority。
QThread LowPriority
调度频率低于NormalPriority。
QThread NormalPriority
操作系统的默认优先级。
QThread HighPriority
调度频率高于NormalPriority。
QThread HighestPriority
调度频率高于HighPriority。
QThread TimeCriticalPriority
尽可能频繁地调度。
QThread InheritPriority
使用创建线程相同的优先级。这是默认设置。
构建一个新的
QThread
以管理一个新的线程。父对象将拥有QThread
的所有权。线程不会开始执行,直到调用start()
。另请参阅
返回一个指向当前正在执行线程的
QThread
的指针。- eventDispatcher()#
- 返回类型:
返回指向线程事件调度程序的指针。如果线程没有事件调度程序,此函数返回
None
。另请参阅
- exec()#
- 返回类型:
int
进入事件循环并等待直到调用
exit()
,返回传递给exit()
的值。调用quit()
时,返回的值是 0。此函数应在
run()
内部调用。调用此函数是开始事件处理所必需的。- exec_()#
- 返回类型:
int
- exit([retcode=0])#
- 参数:
retcode – int
通知线程的事件循环以退出的形式结束。
在调用此函数后,线程离开事件循环并从对
exec()
的调用中返回。该exec()
函数返回returnCode
。按照惯例,返回码为 0 表示成功,任何非零值都表示错误。
注意,与同名的 C 库函数不同,此函数 确实 返回给调用者 – 停止的是事件处理。
在再次调用
exec()
之前,将不会在此线程中再开始任何 QEventLoops。如果exec()
中的事件循环没有运行,下一个对exec()
的调用也将立即返回。另请参阅
- finished()#
此信号在相关的线程在执行完毕之前发出。
在此信号发出时,事件循环已停止运行。线程不会处理更多事件,除非是延迟删除事件。可以将此信号连接到
deleteLater()
,以释放该线程中的对象。- 静态 idealThreadCount()#
- 返回类型:
int
返回此进程能够并行运行的理想线程数。这是通过查询此进程可用的逻辑处理器数量(如果此操作系统支持)或系统逻辑处理器的总数来实现的。如果无法确定这两个值中的任何一个,则该函数返回 1。
注意
在支持将线程的亲和力设置为所有逻辑处理器子集的操作系统上,此函数返回的值可能在线程之间以及随时间变化。
注意
在支持CPU热插拔和热拔插的操作系统上,此函数返回的值也可能会随时间改变(并且请注意,CPU可以通过软件进行打开和关闭,而无需进行物理或硬件上的更改)。
- isFinished()#
- 返回类型:
bool
如果线程已完成则返回
true
;否则返回false
。另请参阅
- isInterruptionRequested()#
- 返回类型:
bool
如果应停止在此线程上运行的任务,则返回 true。可以通过
requestInterruption()
请求中断。此函数可用于使长时间运行的任务干净地可中断。不建议在长时间运行的函数中频繁检查此函数返回的值,但对于这种情况是有好处的。请注意,不要过度调用它,以保持开销低。
void long_task() { forever { if ( QThread::currentThread()->isInterruptionRequested() ) { return; } } }
- isRunning()#
- 返回类型:
bool
如果线程正在运行则返回
true
;否则返回false
。另请参阅
- loopLevel()#
- 返回类型:
int
返回线程当前的事件循环级别。
注意
这只能在线程内部调用,即它当前是当前线程时。
- static msleep(arg__1)#
- 参数:
arg__1 – int
这是一个重载函数,相当于调用
QThread::sleep(std::chrono::milliseconds{msecs});
注意
该函数不保证准确性。在负载较高的情况下,应用程序的休眠时间可能超过
msecs
。某些操作系统可能将msecs
四舍五入到 10 毫秒或 15 毫秒。返回运行线程的优先级。如果线程未运行,则此函数返回
InheritPriority
。另请参阅
- quit()#
将线程的事件循环退出并返回代码0(成功)。等同于调用
exit
(0)。如果线程没有事件循环,此函数不执行任何操作。
另请参阅
- requestInterruption()#
请求中断线程。该请求是建议性的,由在线程上运行的代码决定是否以及如何对此类请求做出反应。此函数不会停止线程上运行的任何事件循环,也不会以任何方式终止它。
- run()#
线程的起点。在调用
start()
后,新创建的线程将调用此函数。默认实现只是调用exec()
。您可以通过重新实现此函数来简化高级线程管理。从该方法返回将结束线程的执行。
- setEventDispatcher(eventDispatcher)#
- 参数:
eventDispatcher -
QAbstractEventDispatcher
为线程设置事件派送器为
eventDispatcher
。只有当线程尚未安装事件派送器时,才能进行此操作。当实例化
QCoreApplication
时,为主线程自动创建事件派送器,并在start()
中为辅助线程创建。此方法将获取对对象的拥有权。
另请参阅
这个函数将该运行的线程的优先级设置为
priority
。如果线程没有运行,此函数将不执行任何操作并立即返回。使用start()
以特定优先级启动线程。priority
参数可以是QThread::Priority
枚举中的任何值,但不能是InheritPriority
。priority
参数的影响取决于操作系统的调度策略。特别是,在不支持线程优先级的系统上(如Linux,更多信息请参见 http://linux.die.net/man/2/sched_setscheduler)将忽略priority
。另请参阅
- setStackSize(stackSize)#
- 参数:
stackSize – int
将线程的最大堆栈大小设置为
stackSize
。如果stackSize
大于零,则最大堆栈大小设置为stackSize
字节,否则由操作系统自动确定最大堆栈大小。- static setTerminationEnabled([enabled=true])#
- 参数:
enabled – bool
根据
enabled
参数启用或禁用当前线程的终止。线程必须由QThread
启动。如果
enabled
为 false,则禁用终止。对terminate()
的将来调用将立即返回,不产生任何效果。相反,终止将被延迟,直到启用终止。当
enabled
设置为 true 时,终止功能被启用。未来对terminate()
的调用将正常终止线程。如果终止已被推迟(即terminate()
被调用时终止被禁用),此函数将立即终止调用线程。请注意,在这种情况下此函数不会返回。另请参阅
- 静态 sleep(arg__1)#
- 参数:
arg__1 – int
强制当前线程休眠
secs
秒。这是一个重载函数,相当于调用
- stackSize()#
- 返回类型:
int
返回线程的最大栈大小(如果使用
setStackSize()
设置),否则返回零。另请参阅
通过调用
run()
开始线程的执行。操作系统将根据priority
参数调度线程。如果线程已经在运行,此函数将不做任何事情。priority
参数的效果取决于操作系统的调度策略。特别是,在不支持线程优先级的系统(如 Linux,更多信息请参阅 sched_setscheduler 文档)上,将忽略priority
。另请参阅
- started()#
当关联的线程开始执行且在调用
run()
函数之前发射此信号。另请参阅
- terminate()#
终止线程的执行。线程是否立即终止取决于操作系统的调度策略。请在
terminate()
之后使用wait()
,以确保。当线程终止时,所有等待该线程结束的线程都将被唤醒。
警告
此功能非常危险,不建议使用。线程可能在代码路径的任何点被终止。线程可能在修改数据时被终止。没有机会让线程自行清理,解锁任何持有的互斥锁等。简而言之,仅当绝对必要时才使用此函数。
可以通过调用
setTerminationEnabled()
来显式启用或禁用终止。当禁用终止时调用此函数会导致终止被推迟,直到重新启用终止。有关更多信息,请参阅setTerminationEnabled()
的文档。- 静态 usleep(arg__1)#
- 参数:
arg__1 – int
这是一个重载函数,相当于调用
QThread::sleep(std::chrono::microseconds{secs});
注意
此函数不保证准确性。在负载较高的条件下,应用程序可能睡眠时间超过
usecs
。某些操作系统可能将usecs
四舍五入到10毫秒或15毫秒;在Windows上,它将被四舍五入到1毫秒的整数倍。另请参阅
sleep()
msleep()
- wait([deadline=QDeadlineTimer(QDeadlineTimer.Forever)])#
- 参数:
超时时间 –
QDeadlineTimer
- 返回类型:
bool
阻塞线程,直到满足以下任一条件
与该
QThread
对象关联的线程已结束执行(即当它从run()
返回)。如果线程已结束,此函数将返回true。如果线程尚未启动,它也将返回true。达到超时时间。如果达到超时,此函数将返回false。
将超时计时器设置为
QDeadlineTimer::Forever
(默认)将永远不会超时:在这种情况下,仅在线程从run()
返回或线程尚未启动时,函数才返回。这提供了与POSIX
pthread_join()
函数类似的功能。另请参阅
- wait(时间)
- 参数:
时间 – int
- 返回类型:
bool
这是一个重载函数。
时间
是等待的毫秒数。如果时间
是 ULONG_MAX,则等待永远不会超时。- 静态yieldCurrentThread()#
如果存在可运行线程,则将当前线程的执行权让给其他可运行线程。请注意,操作系统决定切换到哪个线程。