0

Actually, my question is the same as this question but the answer didn't help too much, tried the same but didn't work. I want to make a slider works in the tray but what I got is a blank field only.

Is it possible to accomplish this in PyQt5? I tried a lot of things but couldn't find a solution. If it is not possible in PyQt5 then which else library can I use for this?

system tray shows blank instead of slider

My code:

from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import (
    QSlider,
    QHBoxLayout,
    QLabel,
    QApplication,
    QWidgetAction,
)
from PyQt5.QtCore import Qt


def change_sound(value):
    print(value)


class SliderWidgetAction(QFrame):
    pass


class SliderAction(QWidgetAction):
    def __init__(self, label="", parent=None):
        QWidgetAction.__init__(self, parent)

        self._widget = SliderWidgetAction(parent)
        self._label = QLabel(label, self._widget)

        self._slider = QSlider(Qt.Horizontal, self._widget)
        self._slider.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        self.value_changed = self._slider.valueChanged

    def widget(self):
        return self._widget

    def label(self):
        return self._label

    def slider(self):
        return self._slider

    def createWidget(self, menu):
        """
        This method is called by the QWidgetAction base class.
        """
        actionWidget = self.widget()
        actionLayout = QHBoxLayout(actionWidget)
        actionLayout.setContentsMargins(0, 0, 0, 0)
        actionLayout.addWidget(self.label())
        actionLayout.addWidget(self.slider())
        actionWidget.setLayout(actionLayout)
        return actionWidget


app = QApplication([])
app.setQuitOnLastWindowClosed(False)

icon = QIcon("icon.png")

tray = QSystemTrayIcon()
tray.setIcon(icon)
tray.setVisible(True)

menu = QMenu()

action = SliderAction("Test", menu)


action.slider().setMinimum(10)
action.slider().setMaximum(100)
action.slider().setValue(90)
action.slider().valueChanged.connect(change_sound)
label_widget = QLabel("Hello World")
action.setDefaultWidget(label_widget)

menu.addAction(action)

tray.setContextMenu(menu)

app.exec_()
user70
  • 597
  • 2
  • 7
  • 24
  • Your code is unclear. First of all, `createWidget()` should not be called explicitly, as it's called internally (as also written in your comment). Then, as the documentation about [`setDefaultWidget()`](https://doc.qt.io/qt-5/qwidgetaction.html#setDefaultWidget) says: "Unless createWidget() is reimplemented by a subclass to return a new widget the default widget is used when a container widget requests a widget through requestWidget().", so why are you creating a widget by overriding `createWidget()` and then also try to set another widget with `setDefaultWidget()`? Which one do you want? – musicamante Mar 06 '22 at 23:46
  • Also, `createWidget()` should not try to create a new widget with existing ones that are probably already in use somewhere else: a widget can only exist in one place, while `self.widget()` always returns the same widgets while trying to add them to a new layout, which is wrong for two reasons: 1. widgets are like physical objects: they can only exist in one place; 2. once a layout is set on a widget, you cannot set another one for it - but in this case it's still completely useless, as all widgets are always the same. – musicamante Mar 06 '22 at 23:50
  • @musicamante I deleted `createWidget( )` call line, I forgot it there after I finished the tests, thank you for the remark. The problem remains the same. – user70 Mar 07 '22 at 06:33
  • then please [edit] your post and update it with the actual code. – musicamante Mar 08 '22 at 03:47

0 Answers0