Skip to content

Instantly share code, notes, and snippets.

@quasoft
Created October 15, 2016 20:25
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save quasoft/e7e5caa5f9c22b727e9666e4c8b4820d to your computer and use it in GitHub Desktop.
Save quasoft/e7e5caa5f9c22b727e9666e4c8b4820d to your computer and use it in GitHub Desktop.
Example on creating a cross platform system tray application in Python and Qt4
#!/usr/bin/env python3
import sys
from PyQt4 import QtGui
class SystemTrayIcon(QtGui.QSystemTrayIcon):
def __init__(self, icon, parent=None):
self.event_play_click = None
self.event_pause_click = None
self.event_exit_click = None
QtGui.QSystemTrayIcon.__init__(self, icon, parent)
menu = QtGui.QMenu(parent)
self._play_action = menu.addAction("Play", self.on_play_click)
self._pause_action = menu.addAction("Pause", self.on_pause_click)
self._exit_action = menu.addAction("Exit", self.on_exit_click)
self.setContextMenu(menu)
self.activated.connect(self.on_icon_click)
self.show()
def on_play_click(self):
self.fire_play_click()
print("Play clicked")
def on_pause_click(self):
self.fire_pause_click()
print("Pause clicked")
def on_exit_click(self):
self.fire_exit_click()
print("Exit clicked")
exit(0)
def on_icon_click(self, reason):
if reason == QtGui.QSystemTrayIcon.Trigger:
print("Icon clicked, changing icon")
newicon = QtGui.QIcon("blocked.svg")
self.setIcon(newicon)
def fire_play_click(self):
if self.event_play_click:
self.event_play_click(self)
def fire_pause_click(self):
if self.event_pause_click:
self.event_pause_click(self)
def fire_exit_click(self):
if self.event_exit_click:
self.event_exit_click(self)
class SystemTrayApp:
def __init__(self):
self.event_exit_app = None
"""Called when the user clicks the Exit option from the system tray context menu"""
self._app = QtGui.QApplication(sys.argv)
self._widget = QtGui.QWidget()
self._icon = SystemTrayIcon(QtGui.QIcon("ui/playing.svg"), self._widget)
self._icon.event_exit_click = self.on_exit_click
def run(self):
sys.exit(self._app.exec_())
def fire_exit_app(self):
if self.event_exit_app:
self.event_exit_app(self)
def on_exit_click(self, sender):
self.fire_exit_app()
if __name__ == '__main__':
app = SystemTrayApp()
app.run()
@silasrm
Copy link

silasrm commented May 24, 2021

PySide6 version

#!/usr/bin/env python3
import sys
from PySide6.QtGui import QIcon
from PySide6.QtWidgets import QSystemTrayIcon, QApplication, QWidget, QMenu


class SystemTrayIcon(QSystemTrayIcon):
    def __init__(self, icon, parent=None):
        self.event_play_click = None
        self.event_pause_click = None
        self.event_exit_click = None
        self.is_actived = True

        # QSystemTrayIcon.__init__(self, icon, parent)
        # self.tray = QSystemTrayIcon()
        QSystemTrayIcon.__init__(self)
        self.setIcon(icon)

        menu = QMenu(parent)
        self._play_action = menu.addAction("Play", self.on_play_click)
        self._pause_action = menu.addAction("Pause", self.on_pause_click)
        menu.addSeparator()
        self._exit_action = menu.addAction("Exit", self.on_exit_click)

        self.setContextMenu(menu)

        self.activated.connect(self.on_icon_click)
        self.show()

    def on_play_click(self):
        self.fire_play_click()
        self.setIcon(QIcon("playing.svg"))  
        print("Play clicked")

    def on_pause_click(self):
        self.fire_pause_click()
        self.setIcon(QIcon("blocked.svg"))
        print("Pause clicked")

    def on_exit_click(self):
        self.fire_exit_click()
        print("Exit clicked")
        exit(0)

    def on_icon_click(self, reason):
        # if reason == self.DoubleClick:
        #     print("Icon clicked, changing icon")
        #     # newicon = QIcon("blocked.svg")
        #     self.setIcon(QIcon("blocked.svg"))
        if reason == self.Trigger:
            if self.is_actived:
                self.is_actived = False
                print("Is Off")
                self.setIcon(QIcon("blocked.svg"))
            else:
                self.is_actived = True
                print("Is On")
                self.setIcon(QIcon("playing.svg"))

    def fire_play_click(self):
        if self.event_play_click:
            self.event_play_click(self)

    def fire_pause_click(self):
        if self.event_pause_click:
            self.event_pause_click(self)

    def fire_exit_click(self):
        if self.event_exit_click:
            self.event_exit_click(self)


class SystemTrayApp:
    def __init__(self):
        self.event_exit_app = None
        """Called when the user clicks the Exit option from the system tray context menu"""

        self._app = QApplication(sys.argv)
        self._widget = QWidget()
        self._icon = SystemTrayIcon(QIcon("playing.svg"), self._widget)
        self._icon.event_exit_click = self.on_exit_click

    def run(self):
        sys.exit(self._app.exec())

    def fire_exit_app(self):
        if self.event_exit_app:
            self.event_exit_app(self)

    def on_exit_click(self, sender):
        self.fire_exit_app()


if __name__ == '__main__':
    app = SystemTrayApp()
    app.run()

@quasoft
Copy link
Author

quasoft commented Sep 25, 2021

Thank you for sharing!

@volovikariel
Copy link

How would I go about making this non-blocking, so that I can have some logic happening in the background as well?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment