1

I want to create a callback for a slider. But since the slider I made is part of a groupbox function. I am not sure how I can connect it:

def createExampleGroup(self, name, interval, steps, min, max):
    groupBox = QGroupBox(name)
    slider = QSlider(Qt.Horizontal)
    slider.setFocusPolicy(Qt.StrongFocus)
    slider.setTickPosition(QSlider.TicksBothSides)
    slider.setMinimum(min)
    slider.setMaximum(max)
    slider.setTickInterval(interval)
    slider.setSingleStep(steps)
    vbox = QVBoxLayout()
    vbox.addWidget(slider)
    # vbox.addStretch(1)
    groupBox.setLayout(vbox)
    return groupBox

def valueChange(self):
    print ("Update Slider")

self.aGroup = self.createExampleGroup("SliderA",10,10,10,100)
self.bGroup = self.createExampleGroup("SliderB",10,10,10,100)

So I am not sure how I can access the slider in each group and connect them to valueChange. And also let valueChange() do different update based on which slider it is. I tried self.aGroup.findChild(QSlider) but it returns an address so I don't know how to use it. The reason I use group is that I may add other widgets in.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
J_yang
  • 2,672
  • 8
  • 32
  • 61

2 Answers2

1

There is several options available to you. You can simply return several widgets from your function:

def create_example_group(...) # python naming convention!
    ...
    return group_box, slider

 self.a_group, a_slider = self.create_example_group(...)
 a_slider.changeValue.connect(...)

Alternative you could give slider a unique name and use findChildren or similar methods on your group-widget to find the widget.

deets
  • 6,285
  • 29
  • 28
1

What findChild returns is the QSlider object, and you are probably printing it getting something similar to:

<PyQt5.QtWidgets.QSlider object at 0x7f6c521dedc8>

that's only what returns __str__, you can find more information in How to print objects of class using print()?.

So I could use that object

slider = self.aGroup.findChild(QSlider)
slider.valueChanged.connect(self.valueChange)

Although that option can be a little dirty, a better option from the design point of view is to create a class that inherits from QGroupBox and that shares the signal:

class MyGroupBox(QGroupBox):
    valueChanged = pyqtSignal(int)

    def __init__(self, name, interval, steps, min, max):
        super(MyGroupBox, self).__init__(name)
        slider = QSlider(Qt.Horizontal)
        slider.setFocusPolicy(Qt.StrongFocus)
        slider.setTickPosition(QSlider.TicksBothSides)
        slider.setMinimum(min)
        slider.setMaximum(max)
        slider.setTickInterval(interval)
        slider.setSingleStep(steps)
        slider.valueChanged.connect(self.valueChanged)
        vbox = QVBoxLayout()
        vbox.addWidget(slider)
        # vbox.addStretch(1)
        self.setLayout(vbox)

Then you can use it in the following way:

self.aGroup = MyGroupBox("SliderA",10,10,10,100)
self.bGroup = MyGroupBox("SliderB",10,10,10,100)
self.aGroup.valueChanged.connect(self.valueChange)

The above gives an identity since it is a class that manifests certain properties by abstracting the internal elements.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • Hi, thanks. This worked!. Regarding a new class method, what if I add a pushbutton or radioButton to the group. Then how do I separate valueChanged between slider or radioButton. Thanks – J_yang Nov 06 '18 at 16:31
  • it's simple create another signal, by example: `radioButtonSignal = pyqtSignal(bool)` then `your_radiobutton.toggled.connect(self.radioButtonSignal)` --> `self.aGroup.radioButtonSignal.connect(some_slot)` – eyllanesc Nov 06 '18 at 16:34
  • hmm. Maybe radio group is not a good example cost the data type is different. What if another slider then. Then they will be have int type... Although for my current application, this case won't happen. – J_yang Nov 06 '18 at 16:37
  • @JiajunYang the same, create another signal: `anotherSignal = pyqtSignal(int)` then `your_another_slider.valueChanged.connect(self.anotherSignal)` --> `self.aGroup.anotherSignal.connect(some_slot)` – eyllanesc Nov 06 '18 at 16:39
  • Worked perfectly. I think I lack the knowledge on pyqtSignal. So I should take a look into it. But thank you very much. – J_yang Nov 06 '18 at 16:48