【发布时间】:2017-06-24 11:33:59
【问题描述】:
我有用 Python 编写的 GUI 和程序逻辑。我经常通过调用urllib.requests(等等)从网络请求信息,当GUI 无响应但此调用使用QThread 包装时,这会导致问题。我认为这是因为GIL。但是当我可以在 PyQt 应用程序中使用 QThread 时,如果我不能使代码异步工作,那么在 PyQt 中使用它有什么用呢?
--代码--
qtthreaddecorator.py:
from PyQt4 import QtCore
class Worker(QtCore.QThread):
def __init__(self, thread_name, finished_slot, function, *args, **kwargs):
QtCore.QThread.__init__(self)
self._thread_name = thread_name
self._function = function
self._args = args
self._kwargs = kwargs
self._finished_slot = finished_slot
def run(self):
self._function(*self._args, **self._kwargs)
self._finished_slot()
return
def qt_thread_decorator(slot):
def decorator(function):
def wrapper(*args, **kwargs):
worker = Worker(function.__name__, slot, function, *args, **kwargs)
worker.start()
return
return wrapper
return decorator
以及我使用它的地方:
import qtthreaddecorator
class MainWindow(QtGui.QMainWindow, form_class):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
self.setupUi(self)
self.init()
def init(self):
@qtthreaddecorator.qt_thread_decorator(self._fill_servers)
def _get_servers():
self._get_my_servers()
@qtthreaddecorator.qt_thread_decorator(self._fill_user_info)
def _get_user_info():
self._get_user_info()
_get_servers()
_get_user_info()
在我的例子中,_get_servers() 和 _get_user_info() 按顺序调用,但我想同时执行它们。
【问题讨论】:
-
你是否正确启动线程,例如使用
worker_thread.start()?因为如果您执行worker_thread.run(),它将运行。只是不在另一个线程中。 -
正是worker_thread.start()。等等,我要发布代码。
-
装饰器的有趣使用...您介意创建一个可运行的小示例,按钮在另一个线程中运行一些睡眠吗?或者我可以用一个工作线程示例来回答你的问题,但我不确定它是否会按照书面形式回答你的问题。
-
我同意@Fenikso,绝对是装饰器的有趣用途。我认为您的问题可能源于
wrapper没有返回工作人员,因此它不存在于该函数之外。 -
仅仅从
wrapper返回是不够的。最终,您需要工作人员存在于您正在装饰的功能之外,否则当这些功能返回时,您最终会遇到同样的问题。我认为您使用装饰器使事情变得过于复杂。