1

我正在(试图)制作一个驻留在系统托盘中的小程序,并检查 Twitch 频道列表以查看它们是否每隔一段时间在线。

我目前正在做 GUI(在 PyQt4 中),但它无缘无故退出。

到目前为止,这是我的代码:

import sys
from PyQt4 import QtGui
from PyQt4 import QtCore

class TwitchWatchTray(QtGui.QSystemTrayIcon):
    def __init__(self, icon, parent=None):
        super(TwitchWatchTray, self).__init__(icon, parent)

        self.menu = QtGui.QMenu(parent)
        settings_action = self.menu.addAction("Settings")
        settings_action.triggered.connect(self.open_settings)

        self.menu.addSeparator()

        exit_action = self.menu.addAction("Exit")
        exit_action.triggered.connect(QtCore.QCoreApplication.instance().quit)

        self.setContextMenu(self.menu)
        self.show()

    def open_settings(self):
        settings = SettingsDialog()
        settings.show()

class SettingsDialog(QtGui.QWidget):
    def __init__(self):
        super(SettingsDialog, self).__init__()

        self.resize(300, 300)
        self.setWindowTitle('TwitchWatch Settings')
        vbox = QtGui.QHBoxLayout()

        self.channels_list = QtGui.QListView(self)
        vbox.addWidget(self.channels_list)

        self.add_box = QtGui.QLineEdit(self)
        vbox.addWidget(self.add_box)

        self.setLayout(vbox)
        self.show()

def main():

    app = QtGui.QApplication(sys.argv)
    widget = QtGui.QWidget()
    tw = TwitchWatchTray(QtGui.QIcon("icon.png"), widget)

    app.exec_()
    print("Done!")

if __name__ == '__main__':
    main()

当我右键单击托盘图标并单击“设置”时,它会闪烁一个白色框(我的对话框),然后立即退出并打印“完成!”。

为什么会这样,我该如何解决?

4

1 回答 1

3

打开设置对话框后代码立即退出的原因有两个。

第一个问题是你的open_settings方法:

    def open_settings(self):
        settings = SettingsDialog()
        settings.show()

这将创建一个对话框并使其可见。 show()显示窗口后立即返回;它不会等待窗口关闭。该settings变量在方法结束时超出范围,这会导致您的引用计数SettingsDialog降至零,因此有资格进行垃圾回收。当 Python 删除SettingsDialog对象时,PyQt 将删除底层 C++ 对象,这就是导致对话框再次关闭的原因。

我建议让您的设置对话框子类QDialog而不是QWidget(毕竟它是一个对话框)。而不是打电话settings.show(),你可以打电话settings.exec_()settings.exec_() 确实等待对话框在返回之前关闭。它还返回QDialog.AcceptedQDialog.Rejected取决于用户是单击确定还是取消。我还建议摆脱对构造函数中的self.show()调用SettingsDialog

第二个问题是您QApplication设置为在最后一个窗口关闭时退出。这是默认行为,这是许多应用程序需要的,但不是您的。即使您的对话框保持打开并且您可以关闭它,您也不希望您的应用程序在关闭设置对话框后立即退出。打电话app.setQuitOnLastWindowClosed(False)解决这个问题。

于 2013-09-25T19:39:45.023 回答