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 ожидает только показать меню в трее.

Другие вопросы по тегам