Implement Popup mapping in QSystemTrayIcon

84 Views Asked by At

I want to implement behaviour of a popup-window exactly like default volume controller in windows 10. One click on icon, window opens or closes; if window is opened, clicking outside it will close the window. How can i implement this?

Before, i found that it is possible for the widget to override the methods for pressing and releasing the mouse keys, but here it was not found, or it was poorly searched. Help me please.

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QGridLayout, \
                            QWidget, QSystemTrayIcon, QStyle, qApp
import PyQt5.QtCore


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setMinimumSize(PyQt5.QtCore.QSize(600, 130))
        self.setMaximumSize(PyQt5.QtCore.QSize(600, 130))

        self.setWindowFlags(PyQt5.QtCore.Qt.Popup)

        screen_geometry = QApplication.desktop().availableGeometry()
        screen_size = (screen_geometry.width(), screen_geometry.height())
        win_size = (self.frameSize().width(), self.frameSize().height())
        x = screen_size[0] - win_size[0]
        y = screen_size[1] - win_size[1]
        self.move(x, y)
        self.setWindowOpacity(0.85)
        self.setWindowTitle("System Tray Application")
        central_widget = QWidget(self)
        self.setCentralWidget(central_widget)

        grid_layout = QGridLayout(central_widget)
        grid_layout.addWidget(QLabel("Application, which can minimize to tray",
                                     self), 0, 0)

        self.tray_icon = QSystemTrayIcon(self)
        self.tray_icon.setIcon(self.
                               style().standardIcon(QStyle.SP_ComputerIcon))
        self.tray_icon.activated.connect(self.trigger)
        self.tray_icon.show()

        self.setGeometry(500, 570, 600, 130)
        self.fl = False

    def trigger(self, reason):
        if reason == QSystemTrayIcon.MiddleClick:
            qApp.quit()
        elif reason == QSystemTrayIcon.Trigger:
            if not self.fl:
                self.show()
            else:
                self.hide()
            self.fl = not self.fl
        elif reason == 1:
            self.fl = False

    # def mouseReleaseEvent(self, event):
    #     self.hide()
    #     self.fl = False


if __name__ == "__main__":
    app = QApplication(sys.argv)
    mw = MainWindow()
    mw.show()
    sys.exit(app.exec())

1

There are 1 best solutions below

0
On BEST ANSWER

If you want to toggle visibility then you must use the setVisible() and isVisible() methods:

import sys

from PyQt5.QtWidgets import (
    QApplication,
    QGridLayout,
    QLabel,
    QMainWindow,
    QStyle,
    QSystemTrayIcon,
    QWidget,
)
from PyQt5.QtCore import Qt, QSize


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setFixedSize(600, 130)

        self.setWindowFlag(Qt.Popup)

        self.setWindowOpacity(0.85)
        self.setWindowTitle("System Tray Application")
        central_widget = QWidget()
        self.setCentralWidget(central_widget)

        grid_layout = QGridLayout(central_widget)
        grid_layout.addWidget(QLabel("Application, which can minimize to tray"), 0, 0)

        self.tray_icon = QSystemTrayIcon(self)
        self.tray_icon.setIcon(self.style().standardIcon(QStyle.SP_ComputerIcon))
        self.tray_icon.activated.connect(self.trigger)
        self.tray_icon.show()

        self.setGeometry(
            QStyle.alignedRect(
                Qt.LeftToRight,
                Qt.AlignBottom | Qt.AlignRight,
                self.window().size(),
                QApplication.desktop().availableGeometry(),
            )
        )

    def trigger(self, reason):
        if reason == QSystemTrayIcon.MiddleClick:
            QApplication.quit()
        elif reason == QSystemTrayIcon.Trigger:
            self.setVisible(not self.isVisible())


if __name__ == "__main__":
    app = QApplication(sys.argv)
    mw = MainWindow()
    mw.show()
    sys.exit(app.exec())