2

トレイアイコンがあり、閉じるボタンまたはトレイアイコンをクリックするとタスクバーから非表示にできる単純な PyQt アプリケーションがあります。アプリケーションは、トレイ アイコンのコンテキスト メニューから閉じることができます。ユーザーがコンテキスト メニューの [終了] をクリックすると、確認の質問を含むモーダル ウィンドウが表示されます。ユーザーが「はい」をクリックするとアプリケーションが閉じ、「いいえ」をクリックするとアプリケーションは引き続き動作します。

メイン ウィンドウが非表示の場合、ユーザーがモーダル ウィンドウで [いいえ] をクリックしてもアプリケーションは閉じられますが、ウィンドウが非表示でない場合はすべて正常です。これは、モーダル ウィンドウでも発生します。たとえば、何らかの情報が表示されます。QtGui.QMessageBox.question の親パラメーターに「魔法」があると思いますが、それを処理する方法がわかりません。この厄介なバグを修正するのを手伝ってください。

コードは次のとおりです。

import sys
from datetime import datetime
from PyQt4 import QtGui, QtCore


class SampleWindow(QtGui.QWidget):

    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.init_ui()

        self.tray_icon.activated.connect(self.tray_click)
        self.show_window.triggered.connect(self.show_from_tray)
        self.now_button.triggered.connect(self.info)
        self.appexit.triggered.connect(self.app_close)

    def init_ui(self):
        self.setGeometry(300, 300, 250, 150)
        self.setWindowTitle('Message box')
        self.tray_icon = QtGui.QSystemTrayIcon()
        self.tray_icon.setIcon(QtGui.QIcon('clock.ico'))
        self.tray_icon.show()
        self.iconMenu = QtGui.QMenu()
        self.show_window = self.iconMenu.addAction("MyApp")
        self.show_window.setDisabled(True)
        self.iconMenu.addSeparator()
        self.now_button = self.iconMenu.addAction("Now")
        self.appexit = self.iconMenu.addAction("Exit")
        self.tray_icon.setContextMenu(self.iconMenu)

    def info(self):
        now = str(datetime.now())
        QtGui.QMessageBox.information(self, 'Now', now)

    def app_close(self):
        info_msg = "Are you sure to quit?"
        reply = QtGui.QMessageBox.question(self,
                                           'Exit',
                                           info_msg,
                                           QtGui.QMessageBox.Yes,
                                           QtGui.QMessageBox.No)
        if reply == QtGui.QMessageBox.Yes:
            QtGui.QApplication.quit()

    def closeEvent(self, event):
        self.hide_to_tray()
        event.ignore()

    def show_from_tray(self):
        self.setWindowFlags(QtCore.Qt.Window)
        self.showNormal()
        self.activateWindow()
        self.show_window.setDisabled(True)

    def hide_to_tray(self):
        self.setWindowFlags(QtCore.Qt.Tool)
        self.show_window.setDisabled(False)

    def tray_click(self, reason):
        if reason != QtGui.QSystemTrayIcon.Context:
            if self.isHidden():
                self.show_from_tray()
            else:
                self.hide_to_tray()


def main():
    app = QtGui.QApplication(sys.argv)
    sample = SampleWindow()
    sample.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()
4

1 に答える 1