【问题标题】:PyQt4 Minimize to TrayPyQt4 最小化到托盘
【发布时间】:2010-10-19 23:38:33
【问题描述】:

有没有办法在 PyQt4 中最小化托盘?我已经使用过 QSystemTrayIcon 类,但现在我想最小化或“隐藏”我的应用程序窗口,并且只显示托盘图标。

有人做过吗?任何方向将不胜感激。

在 Window XP Pro 上使用 Python 2.5.4 和 PyQt4

【问题讨论】:

    标签: python pyqt4 system-tray minimize


    【解决方案1】:

    一旦您记住实际上无法最小化到system tray,这非常简单。

    相反,你通过这样做来伪造它:

    1. 捕捉窗口上的最小化事件
    2. 在最小化事件处理程序中,创建并显示一个 QSystemTrayIcon
    3. 同样在最小化事件处理程序中,在您的窗口上调用 hide() 或 setVisible(false)
    4. 在系统托盘图标上捕捉单击/双击/菜单项
    5. 在您的系统托盘图标事件处理程序中,在您的窗口上调用 show() 或 setVisible(true),并可选择隐藏您的托盘图标。

    【讨论】:

      【解决方案2】:

      代码有帮助,所以这是我为应用程序编写的内容,除了 closeEvent 而不是最小化事件。

      注意事项:

      “closeEvent(event)”是一个被重写的Qt事件,所以必须放在实现你要隐藏的窗口的类中。

      “okayToClose()”是您可能考虑实现的函数(或您可能想要存储的布尔标志),因为有时您实际上想要退出应用程序而不是最小化到系统托盘。

      还有一个如何再次显示()您的窗口的示例。

      def __init__(self):
        traySignal = "activated(QSystemTrayIcon::ActivationReason)"
        QtCore.QObject.connect(self.trayIcon, QtCore.SIGNAL(traySignal), self.__icon_activated)
      
      def closeEvent(self, event):
        if self.okayToClose(): 
          #user asked for exit
          self.trayIcon.hide()
          event.accept()
        else:
          #"minimize"
          self.hide()
          self.trayIcon.show() #thanks @mojo
          event.ignore()
      
      def __icon_activated(self, reason):
        if reason == QtGui.QSystemTrayIcon.DoubleClick:
          self.show()
      

      【讨论】:

      • #"最小化" self.hide() self.trayIcon.show() event.ignore()
      • 我添加了@mojo 关于如何灵活处理系统托盘图标的建议。原始代码来自托盘图标始终可见的应用程序,self.trayIcon.hide() 是为了使图标在退出后不会停留在系统托盘上(可悲的是典型的 Windows 行为)。请注意,现在用户必须实现 showEvent(event) 方法并调用 self.trayIcon.hide() 才能完成此示例。我应该首先发布一个仅最小化/恢复的示例:)
      【解决方案3】:

      只是添加到 Chris 的示例中:

      在声明信号时使用 Qt 表示法很重要,即

      正确

      self.connect(self.icon, SIGNAL("activated(QSystemTrayIcon::ActivationReason)"), self.iconClicked)
      

      而不是 PyQt 的

      不正确并且不起作用:

      self.connect(self.icon, SIGNAL("activated(QSystemTrayIcon.ActivationReason)"), self.iconClicked)
      

      注意信号字符串中的::。我花了大约三个小时才弄清楚。

      【讨论】:

      • 请用>>“你使用Qt NOTATION的关键”
      • def create_sys_tray(self): self.sysTray = QtGui.QSystemTrayIcon(self) self.sysTray.setIcon(QtGui.QIcon('../images/corp/blip_32.png')) self. sysTray.setVisible(True) self.connect(self.sysTray, QtCore.SIGNAL("activated(QSystemTrayIcon::ActivationReason)"), self.on_sys_tray_activated) self.sysTrayMenu = QtGui.QMenu(self) act = self.sysTrayMenu.addAction ("FOO") def on_sys_tray_activated(self, reason): print "reason-=" , reason
      【解决方案4】:

      这是工作代码..感谢 MatzeCrucial,SIGNAL 让我产生了更多的好奇心.. 但做其他事情。所以你要一个#!时刻:-)

      def create_sys_tray(self):
          self.sysTray = QtGui.QSystemTrayIcon(self)
          self.sysTray.setIcon( QtGui.QIcon('../images/corp/blip_32.png') )
          self.sysTray.setVisible(True)
          self.connect(self.sysTray, QtCore.SIGNAL("activated(QSystemTrayIcon::ActivationReason)"), self.on_sys_tray_activated)
      
          self.sysTrayMenu = QtGui.QMenu(self)
          act = self.sysTrayMenu.addAction("FOO")
      
      def on_sys_tray_activated(self, reason):
          print "reason-=" , reason
      

      【讨论】:

        【解决方案5】:

        这是对 vzades 回复的编辑,但由于多种原因被拒绝。它与他们的代码完全相同,但也会遵守最小化事件(并且在没有语法错误/缺少图标的情况下运行)。

        import sys
        from PyQt4 import QtGui, QtCore
        
        
        class Example(QtGui.QWidget):
            def __init__(self):
                super(Example, self).__init__()
                self.initUI()
        
            def initUI(self):
                style = self.style()
        
                # Set the window and tray icon to something
                icon = style.standardIcon(QtGui.QStyle.SP_MediaSeekForward)
                self.tray_icon = QtGui.QSystemTrayIcon()
                self.tray_icon.setIcon(QtGui.QIcon(icon))
                self.setWindowIcon(QtGui.QIcon(icon))
        
                # Restore the window when the tray icon is double clicked.
                self.tray_icon.activated.connect(self.restore_window)
        
            def event(self, event):
                if (event.type() == QtCore.QEvent.WindowStateChange and 
                        self.isMinimized()):
                    # The window is already minimized at this point.  AFAIK,
                    # there is no hook stop a minimize event. Instead,
                    # removing the Qt.Tool flag should remove the window
                    # from the taskbar.
                    self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.Tool)
                    self.tray_icon.show()
                    return True
                else:
                    return super(Example, self).event(event)
        
            def closeEvent(self, event):
                reply = QtGui.QMessageBox.question(
                    self,
                    'Message',"Are you sure to quit?",
                    QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
                    QtGui.QMessageBox.No)
        
                if reply == QtGui.QMessageBox.Yes:
                    event.accept()
                else:
                    self.tray_icon.show()
                    self.hide()
                    event.ignore()
        
            def restore_window(self, reason):
                if reason == QtGui.QSystemTrayIcon.DoubleClick:
                    self.tray_icon.hide()
                    # self.showNormal will restore the window even if it was
                    # minimized.
                    self.showNormal()
        
        def main():
            app = QtGui.QApplication(sys.argv)
            ex = Example()
            ex.show()
            sys.exit(app.exec_())
        
        
        if __name__ == '__main__':
            main()
        

        【讨论】:

        • 如何让它在启动后只显示托盘图标?如果我将 setWindowFlags 行移动到 initUI(),它没有效果,正常的窗口仍然显示
        【解决方案6】:

        这是处理 PyQt5 托盘图标双击的正确方法。

        def _create_tray(self):
            self.tray_icon = QSystemTrayIcon(self)
            self.tray_icon.activated.connect(self.__icon_activated)
        
        def __icon_activated(self, reason):
            if reason in (QSystemTrayIcon.Trigger, QSystemTrayIcon.DoubleClick):
                pass
        

        【讨论】:

        • 我知道这并不能直接回答这个问题,但是这个问题有很多观点,谷歌的人正在寻找一个更新的答案。
        【解决方案7】:

        这是代码,它确实有助于我向我展示代码

        import sys
        from PyQt4 import QtGui, QtCore
        from PyQt4.QtGui import QDialog, QApplication, QPushButton, QLineEdit, QFormLayout, QSystemTrayIcon
        
        
        class Example(QtGui.QWidget):
        
            def __init__(self):
                super(Example, self).__init__()
                self.initUI()
        
            def initUI(self):
                self.icon = QSystemTrayIcon()
                r = self.icon.isSystemTrayAvailable()
                print r
                self.icon.setIcon(QtGui.QIcon('/home/vzades/Desktop/web.png'))
                self.icon.show()
                # self.icon.setVisible(True)
                self.setGeometry(300, 300, 250, 150)
                self.setWindowIcon(QtGui.QIcon('/home/vzades/Desktop/web.png'))
                self.setWindowTitle('Message box')
                self.show()
                self.icon.activated.connect(self.activate)
                self.show()
        
            def closeEvent(self, event):
        
                reply = QtGui.QMessageBox.question(self, 'Message', "Are you sure to quit?", QtGui.QMessageBox.Yes |
                                                   QtGui.QMessageBox.No, QtGui.QMessageBox.No)
        
                if reply == QtGui.QMessageBox.Yes:
                    event.accept()
                else:
                    self.icon.show()
        
                    self.hide()
        
                    event.ignore()
        
            def activate(self, reason):
                print reason
                if reason == 2:
                    self.show()
        
            def __icon_activated(self, reason):
                if reason == QtGui.QSystemTrayIcon.DoubleClick:
                    self.show()
        
        
        def main():
        
            app = QtGui.QApplication(sys.argv)
            ex = Example()
            sys.exit(app.exec_())
        
        
        if __name__ == '__main__':
            main()
        

        【讨论】:

        • 这段代码看起来很糟糕。它是如何获得选票的,令人无法理解。
        • 我不明白为什么它这么糟糕。可能比问题要求的多一点,解释也很短,但看起来像普通代码。
        猜你喜欢
        • 1970-01-01
        • 2013-04-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-15
        • 1970-01-01
        相关资源
        最近更新 更多