PyQT5 QSystemTrayIcon активированный сигнал не работает
Я пытаюсь напечатать текст, когда в программе PyQT5 нажата иконка в системном трее. Я попытался подключить активированный сигнал PyQT5 QSystemTrayIcon (излучаемый при нажатии значка в системном трее) к пользовательскому методу, но метод не вызывается. Вот простой пример:
import sys
from PyQt5.QtWidgets import QSystemTrayIcon, QApplication
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot
@pyqtSlot()
def action(signal):
print('test1')
app = QApplication(sys.argv)
icon = QSystemTrayIcon(QIcon('any_icon.png'), app)
icon.show()
icon.activated.connect(action)
#icon.activated['QSystemTrayIcon::ActivationReason'].connect(action)
#icon.pyqtConfigure(activated=action)
print(icon.receivers(icon.activated)) # to check if is connected
sys.exit(app.exec_())
В качестве примера можно привести 3 способа подключения сигнала к слоту (два из них прокомментированы). Я пробовал как с использованием метода с и без декоратора @pyqtSlot(). Соединение не вызывает ошибок. Даже печать приемников сигнала говорит, что это связано с 1 слотом. Тем не менее, он ничего не делает при нажатии на значок systray.
Вопрос: соединение сигнала неправильное, или сигнал вообще не излучается?
Система: Ubuntu 16.04, PyQT5.8. Однако он должен работать и на других системах, так как PyQT является мультиплатформенным. PS: Я прочитал официальную документацию по сигналу / слоту PyQT5 и много связанных вопросов по переполнению стека, но не нашел такой же проблемы. Самый близкий, я думаю, может быть связан с C++, но не применим к python. Любые советы будут по достоинству оценены. Большое спасибо! Редактировать: исправлены опечатки в тексте
2 ответа
Основываясь на ответах @Murdo и @eyllanesc, я протестировал пример кода на нескольких системах. Чистая установка только с Python 3.5 и pip3 install pyqt5
, Сигнал активированного значка в системном трее:
Не работает:
- Ubuntu 16.04 - Unity, PyQt 5.8 и PyQt 5.5.1
- Ubuntu 16.10 - Unity, PyQt 5.8 и PyQt 5.7
За работой:
- Ubuntu 16.04 - Gnome, PyQt 5.8
- Arch Linux - Gnome, PyQt 5.8
- Kubuntu 16.10, KDE, PyQt 5.7
- Xubuntu - Openbox с использованием Stalonetray
Кажется, что пример кода правильный, и в PyQT есть ошибка с использованием Unity - QSystemTrayIcon
не отправляет activated
сигнал при нажатии на значок в системном трее. Я сообщу об ошибке на следующей неделе на берегу реки.
РЕШЕНИЕ QSystemTrayIcon
сигнал активации (нажатие) можно обойти, назначив QMenu
на значок в системном трее и обнаружения QMenu().aboutToShow
сигнал вместо. Таким образом, при нажатии на иконку в трее, сигнал aboutToShow
отправляется, затем отображается меню. Это не совсем тот же результат, но, похоже, нет другого способа обнаружить активацию иконки в системном трее в Unity. Спасибо @Murdo за идею. Простой пример кода:
import sys
from PyQt5.QtWidgets import QApplication, QSystemTrayIcon, QMenu
from PyQt5.QtGui import QIcon
def action():
print('System tray icon clicked.')
app = QApplication(sys.argv)
icon = QSystemTrayIcon(QIcon('any_icon.png'), parent=app)
icon.show()
menu = QMenu(parent=None)
menu.aboutToShow.connect(action)
icon.setContextMenu(menu)
sys.exit(app.exec_())
Ваш пример прекрасно работает в Xubuntu под openbox с помощью stalonetray. Однако в самом Xubuntu это не сработало! Но когда я добавил что-то вроде:
mNu = QMenu()
test = QAction('Test',mNu)
test.triggered.connect(action)
icon.setContextMenu(mNu)
это работало в xubuntu. Мне кажется, что как-то Ubuntu ожидает только показать меню в трее.