0

次のコードを実行すると、トレイアプリケーションは画面の中央にAboutWindowQLabelオブジェクトをポップアップ表示できます。ただし、この画面を閉じると、アプリケーション全体がエラーなしでシャットダウンされます(トレイアイコンが消え、コンソールログにエラーはまったく表示されません)。

import sys
from PyQt4 import QtGui, QtCore


class AboutWindow(QtGui.QLabel):

def __init__(self, parent=None):
    QtGui.QLabel.__init__(self, parent=parent)
    self.setText("""
    Huge text goes here
    """)


class SystemTrayIcon(QtGui.QSystemTrayIcon):
    def __init__(self, icon, parent=None):
        QtGui.QSystemTrayIcon.__init__(self, icon, parent)
        menu = QtGui.QMenu(parent)
        self.createMenuActions(menu)
        self.setContextMenu(menu)
        # I've tried using the same parent as QSystemTrayIcon, 
        # but the label is not shown.
        # self.aboutWindow = AboutWindow(parent=parent)
        self.aboutWindow = AboutWindow(parent=None)


    def createMenuActions(self, menu):
        exitAction = QtGui.QAction("Exit", menu)
        configureAppAction = QtGui.QAction("Configure Application", menu)
        aboutAction = QtGui.QAction("About", menu)

        self.connect(configureAppAction, QtCore.SIGNAL('triggered()'), self._configureApp)
        self.connect(aboutAction, QtCore.SIGNAL('triggered()'), self._showAbout)
        self.connect(exitAction, QtCore.SIGNAL('triggered()'), self._exitApp)

        self.addActionsToMenu(menu, configureAppAction, aboutAction, exitAction)

    def addActionsToMenu(self, menu, *args):
        for action in args:
            menu.addAction(action)

    def _configureApp(self): pass

    def _showAbout(self):
        self.aboutWindow.show()

    def _exitApp(self):
        sys.exit(0)

def main():
    app = QtGui.QApplication(sys.argv)
    widget = QtGui.QWidget()
    # I'm passing a widget parent to QSystemTrayIcon as pointed out in:
    # http://stackoverflow.com/questions/893984/pyqt-show-menu-in-a-system-tray-application
    trayIcon = SystemTrayIcon(QtGui.QIcon("icon.xpm"), widget)
    trayIcon.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

コードで指摘されているように、トレイアイコンとAboutWindowオブジェクトに同じ親を設定しようとしましたが、機能しませんでした(ラベルは表示されていません)。QMainWindowのサブクラス化も試しましたが、同じ効果が発生しました。

ウィンドウとアイコンのどちらも同じ親を共有していない場合に、QSystemTrayIconから新しいウィンドウを開くときのデフォルトの動作であるかどうか、およびこの問題の回避策があるかどうかを理解したいと思います。

ありがとう。

4

2 に答える 2

0

さて、私は問題についてあまり明確ではなかったと思いますが、私は簡単な解決策を見つけました。

Qtには、ウィジェットにディスパッチされたcloseイベントをキャプチャするメソッドがあります(http://doc.qt.nokia.com/4.6/qwidget.html#closeEvent)。QWidgetサブクラスで、このメソッドを書き直して、ウィジェットが閉じないようにし(すべてのテストで、アプリケーション全体を閉じる)、非表示にすることができます。以下のコードは、コードを機能させるために変更した内容を示しています。

...

class AboutWindow(QtGui.QLabel):

    def __init__(self, parent=None):
        QtGui.QLabel.__init__(self, parent=parent)
        self.setText("""
        Huge text goes here
        """)

    # Prevent the widget from closing the whole application, only hides it
    def closeEvent(self, event):
        event.ignore()
        self.hide()

...
于 2011-03-17T12:36:00.630 に答える
0

この問題は、「のみ」ウィンドウを閉じると、Qtがアプリケーションを終了したいと誤って判断したために発生します。あなたの(Kaos12)の答えは醜い修正です。時々あなたは本当にものを閉じたいと思うでしょう(それはそれを隠すことと同じではありません)。これを行う適切な方法は、次の行を追加してこの動作を無効にすることです。

app.setQuitOnLastWindowClosed(False)

そのコードの50行目以降(アプリケーションを「作成」した後)。この命令は、すべてのウィンドウが閉じている場合でもアプリケーションを終了しないようにQtに指示します。

于 2013-06-10T21:04:16.853 に答える