python - 如何在 PySide/PyQt 中终止纯控制台应用程序?

标签 python qt pyqt pyside

我正在尝试从 Summerfield's article 转换代码(旧式)PyQt 信号/槽到新式 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() 的经验)。

遵循Closing a window例如,在 Zetcode 中,我尝试将 qtApp.quit() 替换为 qtApp.instance().quit(),这产生了相同的非终止结果。

那么,我该如何杀死这个东西呢?

一个想法是我一开始就不应该启动它( as suggested here )。尽管它是一个纯控制台应用程序,但 Summerfield 的原始程序使用 app=QtGui.QApplication(sys.argv) 进行初始化,并且不包含最后两行。事情运行良好,多次。但是,是否不担心每次运行都会创建一个新进程,因此他的程序似乎在没有警告的情况下有效地增加了进程? (请注意,在实践中,我认为这不会发生在我的系统上,因此答案似乎是“否”,原因我不明白)。

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

(暂时忽略这个问题,为什么人们会使用 PySide 作为 Python 中的纯控制台应用程序 as has been pointed out previously 。但是如果有人有兴趣回答这个单独的问题,我可以开始一个单独的问题的问题)。


潜在相关帖子:

最佳答案

问题是因为您在调用 QCoreApplication.exec_() 之前调用了 QCoreApplication.quit()。对 quit 的调用不会在事件循环中排队,而是立即发生。对 QCoreApplication.exec_() 的调用启动事件循环,该循环仅在调用 QCoreApplication.exit() (或 QCoreApplication.quit())时结束code>) 是在事件循环运行时生成的。

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

我想您实际上并不需要调用 exec_() 因为您在当前代码中没有使用任何事件(大多数事件与窗口/鼠标/键盘有关,尽管您可能会这样做)可以想象,将来会使用一些类似 QTimer 生成的内容)。这实际上取决于您将来想用该程序做什么。 如果您不调用 exec_(),那么您的脚本将像您通常期望任何 Python 脚本那样退出(代码中唯一的阻塞函数是对 exec_() 的调用,删除它,就没有什么可以让它继续运行。)

关于python - 如何在 PySide/PyQt 中终止纯控制台应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24983783/

相关文章:

python - 如何正确关闭 PyQt 的 QtApplication?

python - 使用列值从 Pandas DataFrame 获取数据

python - pip install MySQL-python,命令 "python setup.py egg_info"失败,错误代码为 1

qt - qt中临时父级和父级之间的区别

qt - 将 QSizeGrip 添加到 QLabel 的角落

C++ QtSoap 不工作: "undefined reference to ` QtSoapHttpTransport::QtSoapHttpTransport(QObject*)`

python - 如何更新 GUI pyqt 内热图的颜色条?

python - 将 DataFrame 的结果输出到 QLabel

python - 如何从 Django 模型更改 sqlite 表列值类型?

Python 模拟错误 : stop called on unstarted patcher