我更喜欢在不考虑图形用户界面的情况下编写我的应用程序。一旦应用程序代码正常工作,我喜欢在它之上粘贴一个GUI层 - 两者之间有一个干净的界面。应用程序线程和Qt线程之间的清晰分离(Python-PyQt)
我首先尝试使GUI从应用程序运行在不同的进程中。但是我很快就后悔了这个实验。在两个流程之间建立通信链接并不是微不足道的。所以我决定现在,多个线程都没问题(尽管Python全局解释器锁使它们在单个内核上运行)。
MainThread完全掌握在Qt GUI中。显然这是标准做法。因此,让我们假设软件的整体结构应该是这样的(注意,qtThread是同义MainThread):
我的应用程序代码在appThread运行 - 干净与GUI分离。但在某个时候,必须有互动。
我已经阅读了很多关于如何组织这个文章的文章,但许多资料相互矛盾。即使官方的Qt应用程序也是错误的(官方文档鼓励将QThread的子类化)。最具启发意义的文章中,我能找到的是这些:
http://ilearnstuff.blogspot.be/2012/08/when-qthread-isnt-thread.html http://ilearnstuff.blogspot.be/2012/09/qthread-best-practices-when-qthread.html
即使考虑所有后,我仍然在怀疑几件事情。
问题1.什么是启动appThread最合适的方法是什么?
什么是启动appThread最合适的方法是什么?纠正我,如果我错了,但我相信,有两种选择:
选择1:启动一个标准的Python线程
Python提供了threading
库,一个可以导入到产生新的线程:
import threading
if __name__ == '__main__':
# 1. Create the qt thread (is MainThread in fact)
qtApp = QApplication(sys.argv)
QApplication.setStyle(QStyleFactory.create('Fusion'))
# 2. Create the appThread
appThread = threading.Thread(name='appThread', target=appThreadFunc, args=(p1,p2,))
appThread.start()
# 3. Start the qt event loop
qtApp.exec_()
print('Exiting program')
这个选择对我来说看起来最清洁。您甚至可以在不考虑GUI的情况下真正编写您的代码appThread代码。毕竟,您使用的是标准Python threading
库。那里没有Qt的东西。
但我找不到有关在appThread和MainThread之间建立通信链接的明确文档。第二个问题更多关于这个问题..
选择2:启动一个线程的QThread
这种选择看起来不那么干净,因为你惹Qt的东西写你的应用程序代码。无论如何,它看起来像一个可行的选择,因为两个线程之间的通信链接 - appThread和MainThread - 可能更好地支持。
有无数的方法来启动QThread线程。官方的Qt文档鼓励子类QThread
并重新实现run()方法。但我读到这种做法其实很糟糕。请参阅我在问题开始时发布的两个链接的更多信息。
问题2.什么是两个线程之间的最佳通信链路?
什么是两个线程之间的最佳通信链路?很明显,这个问题的答案很大程度上取决于问题1中的选择。我可以想象,将标准Python线程链接到GUI与连接QThread非常不同。
我会离开它给你提出建议,但在我的脑海里弹出了几个机制:
- 队列:使用标准的Python队列或Qt的队列?
- 信号/槽机制:...
- 插座:应该工作,但看起来有点笨重
- 管:...
- 临时文件:繁琐
备注:
请提一下,如果你的答案适用于Python 2.x或3.x.另外请记住,在谈论线程,队列等时可能会很快出现混淆。请提及您是否参考标准Python线程或QThread,标准Python队列或QQueue,...
为什么你认为有必要为前端和后端使用单独的线程/进程?后端是否阻止了gui?如果不是,这似乎是一个毫无意义的问题。但即使它阻止了,你提出问题的方式似乎也引发了很多基于意见的答案。 SO是关于*特定的编程问题*,而不是通用的软件设计方法。 – ekhumoro