编程语言
首页 > 编程语言> > python-模拟用户单击QSystemTrayIcon

python-模拟用户单击QSystemTrayIcon

作者:互联网

即使正在执行激活的插槽,菜单仍不会显示.我通过手动单击托盘图标和模拟单击来跟踪,并通过相同的执行逻辑进行跟踪.

目前我有

class MyClass(QObject):
   def __init__():
       self._testSignal.connect(self._test_show)
       self.myTrayIcon.activated.connect(lambda reason: self._update_menu_and_show(reason))

   def show():
       self._testSignal.emit()

   @pyqtSlot()
   def _test_show():
       self._trayIcon.activated.emit(QtWidgets.QSystemTrayIcon.Trigger)

   @QtCore.pyqtSlot()
   def _update_menu_and_show(reason):
       if reason in (QtWidgets.QSystemTrayIcon.Trigger):
        mySystemTrayIcon._update_menu()

...
class MySystemTrayIcon(QSystemTrayIcon):

   def _update_menu(self):
      # logic to populate menu
      self.setContextMenu(menu)
...
MyClass().show()

解决方法:

这是我弹出与托盘图标关联的上下文菜单的方式

class MyClass(QObject):
   def __init__():
       self._testSignal.connect(self._test_show)
       self.myTrayIcon.activated.connect(lambda reason: self._update_menu_and_show(reason))

   def show():
       self._testSignal.emit()

   @pyqtSlot()
   def _test_show():
       self._trayIcon.activated.emit(QSystemTrayIcon.Context)

   @QtCore.pyqtSlot()
   def _update_menu_and_show(reason):
       if reason in (QSystemTrayIcon.Trigger, QSystemTrayIcon.Context):
           mySystemTrayIcon._update_menu()
           # Trigger means user initiated, Context used for simulated
           # if simulated seems like we have to tell the window to explicitly show

           if reason == QSystemTrayIcon.Context:
               mySystemTrayIcon.contextMenu().setWindowFlags(QtCore.Qt.WindowStaysOnTopHint|QtCore.Qt.FramelessWindowHint)
               pos = mySystemTrayIcon.geometry().bottomLeft()
               mySystemTrayIcon.contextMenu().move(pos)
               mySystemTrayIcon.contextMenu().show()

...
class MySystemTrayIcon(QSystemTrayIcon):

   def _update_menu(self):
      # logic to populate menu
      self.setContextMenu(menu)
...
MyClass().show()

似乎您必须在上下文菜单上设置WindowStaysOnTopHint才能显示它.
此解决方案特定于mac,因为它假定任务栏位于顶部.

副作用是,即使用户单击其他位置,上下文菜单也始终位于顶部.我在上下文菜单上放置了一个事件过滤器,它注册的唯一有用的事件是QEvent.Leave.

标签:python,qt,pyqt,trayicon
来源: https://codeday.me/bug/20191012/1902857.html