Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Problems with QMenu and QSystemTrayIcon
Qt 6.11 is out! See what's new in the release blog

Problems with QMenu and QSystemTrayIcon

Scheduled Pinned Locked Moved Unsolved Qt for Python
7 Posts 3 Posters 2.4k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Mizmas
    wrote on last edited by Mizmas
    #1

    Hi, I'm trying to add a QMenu to the applications tray icon, and am experiencing a few problems.

    Problem #1: The system tray closes when I hover outside the menu of the my app

    Normal:
    alt text
    Mine:
    alt text

    Problem #2: I'm trying to style the menu with a stylesheet, but there's some weird behaviour.

    For example, the I increased the border-radius to show that the background color overflows outside of its border.
    I also can't seem to decrease the size of the QIcon in the stylesheet.
    Screenshot_7.png

    This is how I make the tray and menu:

            # Create tray and set icon
            self.tray = QSystemTrayIcon(self)
            self.tray.setIcon(QIcon(":/Icons/master.png"))
    
            # Add a context menu to the tray icon
            self.tray_menu = QMenu()
    
            # Create quit action
            quit_action = QAction(QIcon(":/Icons/exit.png"), "Quit", self)
            quit_action.triggered.connect(sys.exit)
            self.tray_menu.addAction(quit_action)
    
            # Add menu to tray
            self.tray.setContextMenu(self.tray_menu)
    
            # Connect the tray icon activation event
            self.tray.activated.connect(self.tray_icon_clicked)
    

    And then set the stylesheet:

            # Apply stylesheet to tray menu
            self.tray_menu.setStyleSheet("""
                QMenu {
                    background-color: #1e1e29;
                    color: white;
                    font: 8pt "Heebo SemiBold";
                    border: 2px solid #107672;
                    border-radius: 10px;
                }
    
                QMenu::item {
                    padding: 2px;
                    padding-left: 10px;
                }
    
                QMenu::item:selected {
                    background-color: #343446;
                }
    
                QMenu::icon {
                    padding: 10px;  # Didn't work
                    height: 2px;    # Didn't work
                }
            """)
    
    1 Reply Last reply
    0
    • M Offline
      M Offline
      Mizmas
      wrote on last edited by
      #2
      This post is deleted!
      1 Reply Last reply
      0
      • M Offline
        M Offline
        Mizmas
        wrote on last edited by
        #3

        I seem to have fixed the overflow issue with:

        self.tray_menu.setWindowFlags(self.tray_menu.windowFlags() | Qt.WindowType.FramelessWindowHint)
        self.tray_menu.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
        
        1 Reply Last reply
        0
        • crimson1023C Offline
          crimson1023C Offline
          crimson1023
          wrote on last edited by
          #4

          Hi, you can use property-iconSize in qss to change the icon size.

          1 Reply Last reply
          1
          • Axel SpoerlA Offline
            Axel SpoerlA Offline
            Axel Spoerl
            Moderators
            wrote on last edited by
            #5

            I'm a C++er, not a Pythonologist;
            But I have a hinge that qApp->setQuitOnLastWindowClosed(false); is what would solve the C++ version of your issue.

            Software Engineer
            The Qt Company, Oslo

            M 1 Reply Last reply
            0
            • Axel SpoerlA Axel Spoerl

              I'm a C++er, not a Pythonologist;
              But I have a hinge that qApp->setQuitOnLastWindowClosed(false); is what would solve the C++ version of your issue.

              M Offline
              M Offline
              Mizmas
              wrote on last edited by
              #6

              @Axel-Spoerl Didn't work :P

                  my_app.setQuitOnLastWindowClosed(False)
              
              1 Reply Last reply
              0
              • M Offline
                M Offline
                Mizmas
                wrote on last edited by
                #7

                Here's an example I've made that anyone can run, you will need to replace self.path_to_tray_image to a path of an image in order for it to actually appear in the system tray.

                self.path_to_tray_image = "C:/Users/username/Downloads/image.png"
                
                import sys
                from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton, QSystemTrayIcon, QMenu
                from PyQt6.QtCore import QPoint
                from PyQt6.QtGui import QIcon, QAction, QCursor
                
                
                class TrayApplication(QMainWindow):
                    def __init__(self):
                        
                        # replace to your tray image
                        self.path_to_tray_image = "C:/Users/username/Downloads/image.png"
                
                        super().__init__()
                        self.setWindowTitle("Tray Example")
                        self.setGeometry(100, 100, 400, 300)
                
                        # Create a button to minimize to tray
                        self.minimize_button = QPushButton("Minimize to Tray", self)
                        self.minimize_button.setGeometry(150, 120, 100, 40)
                        self.minimize_button.clicked.connect(self.minimize_to_tray)
                
                        # Set up the system tray icon
                        self.tray_icon = QSystemTrayIcon(self)
                        self.tray_icon.setIcon(QIcon(self.path_to_tray_image))  # Replace with your icon file
                
                        # Add a context menu to the tray icon
                        self.tray_menu = QMenu()
                
                        quit_action = QAction(QIcon(":/path_to_exit_action_image"), "Quit", self)  # Replace with your icon file
                        quit_action.triggered.connect(self.close_application)
                        self.tray_menu.addAction(quit_action)
                
                        # Connect the tray icon activation event
                        self.tray_icon.activated.connect(self.tray_icon_clicked)
                
                    def minimize_to_tray(self):
                        self.hide()
                        self.tray_icon.show()
                
                    def restore_from_tray(self):
                        self.show()
                        self.tray_icon.hide()
                
                    def tray_icon_clicked(self, reason):
                        # Left click
                        if reason == QSystemTrayIcon.ActivationReason.Trigger:
                            self.restore_from_tray()
                
                        # Right click
                        elif reason == QSystemTrayIcon.ActivationReason.Context:
                            # Get the current cursor position
                            cursor_pos = QCursor.pos()
                
                            # Calculate the menu position: align bottom-right corner of the menu to the cursor
                            menu_width = self.tray_menu.sizeHint().width()
                            menu_height = self.tray_menu.sizeHint().height()
                            pos = QPoint(cursor_pos.x() - menu_width, cursor_pos.y() - menu_height)
                
                            # Show the menu at the calculated position
                            self.tray_menu.popup(pos)
                
                    def close_application(self):
                        self.tray_icon.hide()
                        self.close()
                
                
                if __name__ == "__main__":
                    app = QApplication(sys.argv)
                
                    window = TrayApplication()
                    window.show()
                
                    sys.exit(app.exec())
                
                
                1 Reply Last reply
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved