gpt4 book ai didi

python - PyQt、QThread、GIL、图形用户界面

转载 作者:行者123 更新时间:2023-11-28 18:41:18 25 4
gpt4 key购买 nike

我有用 Python 编写的 GUI 和程序逻辑。我经常通过调用 urllib.requests(等等)从 Web 请求信息,这会在 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() 按顺序调用,但我想同时执行它们。

最佳答案

我认为您对装饰器的使用过于复杂。您可以使用大约 3-4 行设置代码轻松地将代码包装在新线程中。另外我认为你不应该直接从另一个线程调用你完成的插槽。您应该使用连接的信号来激活它。

import sys
from time import sleep
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *

class Signals(QObject):
update = pyqtSignal(int)
enable_button = pyqtSignal(bool)

class Window(QWidget):
def __init__(self, *args, **kwargs):
QWidget.__init__(self, *args, **kwargs)

self.button = QPushButton("Run", self)
self.button.clicked.connect(self.onButton)

self.progress = QProgressBar(self)
self.progress.setTextVisible(False)

self.layout = QVBoxLayout()
self.layout.setContentsMargins(5, 5, 5, 5)
self.layout.addWidget(self.button)
self.layout.addWidget(self.progress)
self.layout.addStretch()

self.worker_thread = QThread()
self.worker_thread.run = self.worker
self.worker_thread.should_close = False

self.signals = Signals()
self.signals.update.connect(self.progress.setValue)
self.signals.enable_button.connect(self.button.setEnabled)

self.setLayout(self.layout)
self.show()
self.resize(self.size().width(), 0)

# Override
def closeEvent(self, e):
self.worker_thread.should_close = True
self.worker_thread.wait()

@pyqtSlot()
def onButton(self):
self.button.setDisabled(True)
self.worker_thread.start()

# Worker thread, no direct GUI updates!
def worker(self):
for i in range(101):
if self.worker_thread.should_close:
break
self.signals.update.emit(i)
sleep(0.1)
self.signals.enable_button.emit(True)

app = QApplication(sys.argv)
win = Window()
sys.exit(app.exec_())

关于python - PyQt、QThread、GIL、图形用户界面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25722838/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com