python - Python PyQt 将后端与 GUI 分开
问题描述
我希望我的 Python 后端不必等待我的 PyQt GUI 来绘制(很多)东西。在 PyQt 中是否有比下面的代码示例更好/正确的方法?是否有必要使用线程导入或者 PyQt 有自己更好的方法?
import time
from threading import Thread
class Backend(Thread):
def __init__(self):
super().__init__()
def run(self):
for i in range(20):
print("Backend heavy work")
time.sleep(4)
class GUI(Thread):
def __init__(self):
super().__init__()
def run(self):
for i in range(20):
print("GUI drawing stuff")
time.sleep(0.5)
if __name__ == '__main__':
thread_backend = Backend()
thread_gui = GUI()
thread_backend.start()
thread_gui.start()
我尝试使用 Qtimer 进行操作,但没有成功。谢谢!
解决方案
您不能从 Qt 循环之外更新 UI。您可以做的是使用 qt 信号连接到为您完成工作的方法。举个例子
class GUI(QtCore.QObject): # must be a class that inherits QObject to use signals, I believe
drawSignal = QtCore.pyqtSignal(int)
def __init__(self):
super().__init__()
self.drawSignal.connect(self._drawStuff) # The underscore thing is a little hacky, but sort of pythonic I think, and makes the API clean.
self.drawStuff = self.drawSignal.emit
def _drawStuff(self, i):
# do whatever you want to the gui here
pass
class GUILoop(Thread):
def __init__(self, gui):
super().__init__()
self.gui = gui
def run(self):
for i in range(20):
self.gui.drawStuff(i)
time.sleep(0.5)
if __name__ == '__main__':
gui = GUI()
thread_backend = Backend()
thread_gui = GUILoop(gui)
thread_backend.start()
thread_gui.start()
这可能看起来有点奇怪,但它非常适合 Qt 和 Python 的优势。将信号添加到QMainWindow
已经是QObject
.
推荐阅读
- c# - 我正在尝试使用 html 提交按钮运行 asp.net 方法,但该方法无法运行?
- python - 按下特定键时增加值,然后在表格中记录值
- python - 在 Python 中以另一个变量的值为条件创建一个变量
- java - Java方法不会执行多次
- javascript - 你能写两次'for'吗?
- java - 无法创建 tempDir。java.io.tmpdir 设置为 /tmp
- java - 向服务器 HPSM9.41 webtier 推荐的 Tomcat 的 Java 堆大小
- javascript - 在 JavaScript 中过滤对象数组?
- c++ - 运算符不匹配*=
- java - 为什么 JUnit 5 Suite 注释 @SelectClasses 和 @IncludeClassNamePatterns 无法找到不以“Tests”或“Test”结尾的测试?