1. 简介
我正在使用 Python 3.7 中的 PyQt5
开发一个多线程应用程序,其中我依赖于 QThread
。
假设我有一个派生自 QObject
的类。在该类中,我定义了一个带有 @pyqtSlot
注释的函数:
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import threading
...
class Worker(QObject):
def __init__(self):
super().__init__()
return
@pyqtSlot()
def some_function(self):
...
return
在其他一些代码中,我实例化了
Worker()
并将其移动到一个新的线程中,例如:my_thread = QThread()
my_worker = Worker()
my_worker.moveToThread(my_thread)
my_thread.start()
QTimer.singleShot(100, my_worker.some_function)
return
some_function()
现在应该在my_thread
中运行。原因是:
- 我已经将
Worker()
对象推送到my_thread
中。 - 当命令
my_thread
开始时,实际上在该线程中创建了一个新的Qt事件循环。my_worker
对象驻留在此事件循环中。所有其插槽都可以接收事件,在此事件循环中执行。 some_function()
被适当地注释为@pyqtSlot()
。单次计时器挂钩到此插槽并触发事件。由于my_thread
中的Qt事件循环,插槽实际上在其中执行其代码。
2. 我的问题
我的问题是关于嵌套函数(也称“内部函数”)。请考虑以下内容:
class Worker(QObject):
def __init__(self):
super().__init__()
return
def some_function(self):
...
@pyqtSlot()
def some_inner_function():
...
return
return
正如你所看到的,some_inner_function()
被注释为 @pyqtSlot
。它的代码是否也会在 Worker()
对象所在的线程中运行?
3. 附注:如何钩住内部函数
你可能会想知道如何钩住内部函数。好吧,请考虑以下内容:
class Worker(QObject):
def __init__(self):
super().__init__()
return
def some_function(self):
@pyqtSlot()
def some_inner_function():
# Will this code run in `my_thread`?
...
return
# some_function() will run in the main thread if
# it is called directly from the main thread.
QTimer.singleShot(100, some_inner_function)
return
如果您直接从主线程调用
some_function()
,它将(不幸地)在主线程中运行。如果没有正确使用信号槽机制,您将无法切换线程。
some_function()
内部的单次定时器钩住了some_inner_function()
并触发。假设Worker()
对象已分配给my_thread
,那么内部函数是否会在my_thread
中执行?
PyQt
问题:https://dev59.com/pLPma4cB1Zd3GeqPxuFI? - K.Mulier