简体   繁体   中英

Pythonic way to assign multiple slider callbacks (PyQt)?

I'm looking for a more pythonic way to connect callback functions to multiple sliders on a PyQt based GUI that I am writing. There has to be a better way to do this! On a related note, is there a way to use dictionaries to iteratively call methods on objects? Say if I want to iteratively get the value of each slider? Thanks in advance.

Code that I want to condense (and pythonify!):

    self.ui.seg1Slider.valueChanged.connect(lambda value,segment='1': self.sliderMoved(value,segment))
    self.ui.seg2Slider.valueChanged.connect(lambda value,segment='2': self.sliderMoved(value,segment))
    self.ui.seg3Slider.valueChanged.connect(lambda value,segment='3': self.sliderMoved(value,segment))
    self.ui.seg4Slider.valueChanged.connect(lambda value,segment='4': self.sliderMoved(value,segment))
    self.ui.seg5Slider.valueChanged.connect(lambda value,segment='5': self.sliderMoved(value,segment))
    self.ui.seg6Slider.valueChanged.connect(lambda value,segment='6': self.sliderMoved(value,segment))
    self.ui.seg7Slider.valueChanged.connect(lambda value,segment='7': self.sliderMoved(value,segment))
    self.ui.seg8Slider.valueChanged.connect(lambda value,segment='8': self.sliderMoved(value,segment))
    self.ui.seg10Slider.valueChanged.connect(lambda value,segment='10': self.sliderMoved(value,segment))
    self.ui.seg11Slider.valueChanged.connect(lambda value,segment='11': self.sliderMoved(value,segment))
    self.ui.seg12Slider.valueChanged.connect(lambda value,segment='12': self.sliderMoved(value,segment))
    self.ui.seg13Slider.valueChanged.connect(lambda value,segment='13': self.sliderMoved(value,segment))
    self.ui.seg14Slider.valueChanged.connect(lambda value,segment='14': self.sliderMoved(value,segment))
    self.ui.seg15Slider.valueChanged.connect(lambda value,segment='15': self.sliderMoved(value,segment))
    self.ui.seg17Slider.valueChanged.connect(lambda value,segment='17': self.sliderMoved(value,segment))
    self.ui.seg18Slider.valueChanged.connect(lambda value,segment='18': self.sliderMoved(value,segment))
    self.ui.seg19Slider.valueChanged.connect(lambda value,segment='19': self.sliderMoved(value,segment))
    self.ui.seg20Slider.valueChanged.connect(lambda value,segment='20': self.sliderMoved(value,segment))
    self.ui.seg21Slider.valueChanged.connect(lambda value,segment='21': self.sliderMoved(value,segment))
    self.ui.seg22Slider.valueChanged.connect(lambda value,segment='22': self.sliderMoved(value,segment))
    self.ui.seg23Slider.valueChanged.connect(lambda value,segment='23': self.sliderMoved(value,segment))
    self.ui.seg24Slider.valueChanged.connect(lambda value,segment='24': self.sliderMoved(value,segment))
    self.ui.seg25Slider.valueChanged.connect(lambda value,segment='25': self.sliderMoved(value,segment))
    self.ui.seg26Slider.valueChanged.connect(lambda value,segment='26': self.sliderMoved(value,segment))
    self.ui.seg27Slider.valueChanged.connect(lambda value,segment='27': self.sliderMoved(value,segment))
    self.ui.seg28Slider.valueChanged.connect(lambda value,segment='28': self.sliderMoved(value,segment))
    self.ui.seg29Slider.valueChanged.connect(lambda value,segment='29': self.sliderMoved(value,segment))
    self.ui.seg30Slider.valueChanged.connect(lambda value,segment='30': self.sliderMoved(value,segment))
    self.ui.seg31Slider.valueChanged.connect(lambda value,segment='31': self.sliderMoved(value,segment))
    self.ui.seg32Slider.valueChanged.connect(lambda value,segment='32': self.sliderMoved(value,segment))

A loop with getattr will work, but it seems you don't have a complete range of numbers to work with (9 and 16 are missing), so you need to take account of that as well:

for segment in range(1, 33):
    if segment == 9 or segment == 16:
        continue
    slider = getattr(self.ui, 'seg%dSlider' % segment)
    slider.valueChanged.connect(
        lambda value, segment=str(segment): self.sliderMoved(value, segment))

However, a somewhat cleaner solution may be possible, since it looks like you are using Qt Designer to create the GUI. This means that the sliders will all get object names that match their attribute names. If you also make sure that all the sliders are put inside a container widget, you will then be able to do something like this:

for slider in self.ui.sliderContainer.findChildren(QtGui.QSlider):
    segment = slider.objectName()[3:][:-6]
    slider.valueChanged.connect(
        lambda value, segment=segment: self.sliderMoved(value, segment))

This is much more robust than the previous solution, because as long as you use the same naming format, you can safely add or remove sliders in Qt Designer without needing to update this code as well.

(PS: It's also possible to find children with object-names that match a given QRegExp ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM