我正在尝试将(旧式)PyQt信号/插槽上的Summerfield's article代码转换为新式PySide代码。一个例子是一个纯控制台应用程序,我以前从未使用过它。不幸的是,当我尝试多次运行时,我被告知前一个应用程序仍在运行。
这是一个简单的应用程序:它基本上允许您设置一个数字,并报告该数字是否是新的:
from PySide import QtCore
import sys
class TaxRate(QtCore.QObject):
rateChangedSig=QtCore.Signal(float)
def __init__(self):
QtCore.QObject.__init__(self)
self.rate = 17.5
def getRate(self):
return self.rate
def setRate(self, newRate):
if newRate != self.rate:
self.rate = newRate
self.rateChangedSig.emit(self.rate) #was self.emit(SIGNAL("rateChanged"), self.rate)
@QtCore.Slot() #technically not really needed
def rateChangedSlot(value):
print("Tax rate changed to {0:.2f} %".format(value))
if __name__=="__main__":
qtApp = QtCore.QCoreApplication(sys.argv) #origional had QtGui.QApplication, but there is no GUI
vat = TaxRate()
vat.rateChangedSig.connect(rateChangedSlot) #was vat.connect(vat, SIGNAL("rateChanged"), rateChanged)
vat.setRate(8.5) # A change will occur (new rate is different)
qtApp.quit()
sys.exit(qtApp.exec_())
总的来说,它按预期工作,除了最后两行不会杀死进程。当我尝试运行程序两次时,第二次我的IDE(Spyder)总是告诉我它已经在一个单独的进程中运行。如果我尝试从命令行运行它,窗口就会挂起。
奇怪的是,当我注释掉最后两行时,我没有得到这个警告。这与我的预期相反(基于之前PySide GUI应用程序和the documentation for quit()的经验)。
在Zetcode上的Closing a window示例后,我尝试将qtApp.quit()
替换为qtApp.instance().quit()
,这会产生相同的非杀戮结果。
那么,我该怎么杀这个东西?
一个想法是我不应该首先开始它(as suggested here)。即使它是一个纯粹的控制台应用程序,Summerfield的原始程序初始化为app=QtGui.QApplication(sys.argv)
,它不包含最后两行。事情很好,多次。但是,是不是每次运行都会创建一个新进程,所以他的程序似乎在没有警告的情况下有效地增加了进程? (注意在实践中我不认为这是在我的系统上发生的,所以答案似乎是'不',原因我不明白。)
使用PySide控制/初始化/杀死控制台应用程序的正确方法是什么?
(暂时忽略了这个问题,为什么人们会在Python as has been pointed out previously中使用PySide作为纯控制台应用程序。但如果有人有兴趣回答这个单独的问题,我可以开始一个单独的问题)。
潜在相关帖子:
答案 0 :(得分:2)
问题是因为您在致电QCoreApplication.quit()
之前致电QCoreApplication.exec_()
。对quit
的调用未在事件循环中排队,它立即发生。对QCoreApplication.exec_()
的调用启动事件循环,该循环仅在事件循环运行时调用QCoreApplication.exit()
(或QCoreApplication.quit()
)时结束。
这在Qt documentation of QCoreApplication
中有所解释,但很容易错过。
我想你不需要调用exec_()
,因为你没有在当前代码中使用任何事件(大多数事件都与窗口/鼠标/键盘有关,尽管你可能会想到使用未来就像QTimer
生成的那样。这真的取决于你将来想要对该程序做什么。
如果你不调用exec_()
,那么你的脚本将按照你通常期望的任何Python脚本的方式退出(代码中唯一的阻塞函数是对exec_()
的调用,删除它并且没有保留它正在运行。)