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

How to kill a pure console application in PySide/PyQt?

我正试图将SummerField关于(旧样式)Pyqt信号/插槽的文章中的代码转换为新样式的Pyside代码。一个例子是纯控制台应用程序,我以前从未使用过它。不幸的是,当我尝试多次运行它时,我被告知上一个应用程序仍在运行。

这是一个简单的应用程序:它基本上允许您设置一个数字,如果该数字是新的,则返回报告:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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应用程序的经验和quit()的文档)。

在zetcode关闭一个窗口示例之后,我尝试用qtApp.instance().quit()替换qtApp.quit(),这产生了相同的非杀戮结果。

那么,我该怎么杀死这东西呢?

一个想法是,我甚至不应该一开始就启动它(正如这里建议的那样)。尽管它是纯控制台应用程序,但SummerField的原始程序使用app=QtGui.QApplication(sys.argv)初始化,并且不包含最后两行。事情好几次了。但是,是否不担心每次运行都会创建一个新的进程,因此他的程序似乎可以在不发出警告的情况下有效地增加进程?(请注意,在实践中,我不认为这发生在我的系统上,因此,由于我不理解的原因,答案似乎是"不")。

使用pyside控制/初始化/终止控制台应用程序的正确方法是什么?

(这暂时忽略了一个问题,为什么会像前面指出的那样,将pyside用于纯Python控制台应用程序呢?但是如果有人有兴趣回答这个单独的问题,我可以为它开始一个单独的问题)。

潜在相关职位:

  • Pyside应用程序未正确关闭


问题是你在打电话给QCoreApplication.exec_()之前先打电话给QCoreApplication.quit()。对quit的调用没有在事件循环中排队,它会立即发生。对QCoreApplication.exec_()的调用启动事件循环,仅在事件循环运行时调用QCoreApplication.exit()QCoreApplication.quit()时结束。

这在QCoreApplication的qt文档中有一些解释,但很容易忽略。

我认为您不需要调用exec_(),因为您在当前代码中没有使用任何事件(大多数事件都与窗口/鼠标/键盘有关,尽管您可能会在将来使用一些事件,如QTimer生成的事件)。这真的取决于你将来想用这个程序做什么。如果您不调用exec_(),那么您的脚本将退出,正如您通常期望的任何python脚本所做的那样(代码中唯一的阻塞函数是对exec_()的调用,删除它,但没有任何东西使其保持运行)。