PyQt4 Свернуть в трей
-
09-09-2019 - |
Вопрос
Есть ли способ свернуть в трей в PyQt4?Я уже работал с классом QSystemTrayIcon, но теперь мне хотелось бы свернуть или «скрыть» окно моего приложения и показать только значок на панели задач.
Кто-нибудь сделал это?Любое направление будет оценено по достоинству.
Использование Python 2.5.4 и PyQt4 в Windows XP Pro
Решение
Это довольно просто, если вспомнить, что на самом деле нет способа минимизировать до системный лоток.
Вместо этого вы подделываете это, делая это:
- Перехватите событие сворачивания в вашем окне
- В обработчике событий свертывания создайте и отобразите QSystemTrayIcon.
- Также в обработчике событий минимизации вызовите методide() или setVisible(false) в вашем окне.
- Поймайте щелчок/двойной щелчок/пункт меню на значке на панели задач.
- В обработчике событий значка на панели задач вызовите show() или setVisible(true) в окне и при необходимости скройте значок на панели задач.
Другие советы
Код помогает, поэтому я написал кое-что для приложения, за исключением события 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()
Просто добавлю к примеру Криса:
Это имеет решающее значение что вы используете нотацию Qt при объявлении сигнала, т.е.
правильный:
self.connect(self.icon, SIGNAL("activated(QSystemTrayIcon::ActivationReason)"), self.iconClicked)
а не PyQt
неправильный и не будет работать:
self.connect(self.icon, SIGNAL("activated(QSystemTrayIcon.ActivationReason)"), self.iconClicked)
Обратите внимание ::
в сигнальной строке.Чтобы это понять, мне потребовалось около трех часов.
Вот рабочий код. Спасибо. Маце для Ключевой, СИГНАЛ отнял у меня больше часов любопытства..но занимаюсь другими делами.так что за #!момент :-)
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
Это была редакция ответа Взадес, но она была отклонена по ряду оснований.Он делает то же самое, что и их код, но также подчиняется событию минимизации (и запускается без синтаксических ошибок/отсутствующих значков).
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()
Это правильный способ обработки двойного щелчка по значку на панели задач для 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
Это код, и он помогает, я верю, покажите мне код
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()