如何在PySide / PyQt中杀死一个纯控制台应用程序?

时间:2014-07-27 17:49:26

标签: python qt pyqt pyside

我正在尝试将(旧式)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作为纯控制台应用程序。但如果有人有兴趣回答这个单独的问题,我可以开始一个单独的问题)。


潜在相关帖子:

1 个答案:

答案 0 :(得分:2)

问题是因为您在致电QCoreApplication.quit()之前致电QCoreApplication.exec_()。对quit的调用未在事件循环中排队,它立即发生。对QCoreApplication.exec_()的调用启动事件循环,该循环仅在事件循环运行时调用QCoreApplication.exit()(或QCoreApplication.quit())时结束。

这在Qt documentation of QCoreApplication中有所解释,但很容易错过。

我想你不需要调用exec_(),因为你没有在当前代码中使用任何事件(大多数事件都与窗口/鼠标/键盘有关,尽管你可能会想到使用未来就像QTimer生成的那样。这真的取决于你将来想要对该程序做什么。 如果你不调用exec_(),那么你的脚本将按照你通常期望的任何Python脚本的方式退出(代码中唯一的阻塞函数是对exec_()的调用,删除它并且没有保留它正在运行。)