Search code examples
pythonuser-interfacedictionarypyqtsignals-slots

python Connect a slider existing in a dictionary to an entry in a dictionary


I three similar slider/entry combinations that needs to be connected to their respective partners. The problem I'm having is that I can't identify the correct slider/entry when connecting using the valueChanged function.

Here is the code:

        def createwidgets(self):

          self.labeldic1 = {}
          self.labeldic4 = {}
          self.labeldic5 = {}
          self.buttondic1 = {}
          self.buttondic4 = {}
          self.entrydic1 = {}
          self.entrydic2 = {}
          self.sliderdic1 ={}

          for i in range (0,3):
            self.label1 = QLabel('Target IPv6 address', self)
            self.label5 = QLabel('Mb/s', self)
            self.entry1 = QLineEdit(self)

            self.entry2 = QLineEdit(self)
            self.entry2.setMaxLength(2)
            self.entry2.setText("1")

            self.slider1 = QSlider(self)
            self.slider1.setOrientation(Qt.Horizontal)
            self.slider1.setMinimum(1)
            self.slider1.setMaximum(10)
            self.slider1.setSingleStep(1)

            self.labeldic1.update({i:self.label1})
            self.labeldic5.update({i:self.label5})
            self.entrydic1.update({i:self.entry1})
            self.entrydic2.update({i:self.entry2})
            self.sliderdic1.update({i:self.slider1})

          rows = [1,3,5]
          x = 0
          for i in rows:
            self.gLayout.addWidget(self.labeldic1[x],i,0)
            self.gLayout.addWidget(self.labeldic5[x],i+1,3)
            self.gLayout.addWidget(self.entrydic1[x],i,1,1,4)
            self.gLayout.addWidget(self.entrydic2[x],i+1,4)
            self.gLayout.addWidget(self.sliderdic1[x],i+1,1,1,2)
            x += 1

          for i in range(0,3):
            self.sliderdic1[i].valueChanged.connect(lambdai=i:self.slidechanged(i))
            self.entrydic2[i].textChanged.connect(self.textchanged)

        def slidechanged(self, value):
          svalue = str(self.slider1.value()) #This is supposed to be str(self.sliderdic1[x].value())
          self.entry2.setText(svalue) #this is supposed to be self.entrydic2[x].setText(svalue)

        def textchanged(self, value):
          try:
            if int(value) > 0:
                lvalue = int(self.entry2.text()) #This is supposed to be int(self.entrydict2[x].text())
                self.slider1.setValue(lvalue) #This is supposed to be self.sliderdic1[x].setValue(lvalue)
          except:
                self.entry2.setText('1') #This is supposed to be self.entrydic2[x].setText('1')

I should be somehow able to identify self.entry2.setText(svalue) as self.entrydic2[x].setText(svalue), but I don't know how to pass the value to the function

Thank you in advance for any help you can offer


Solution

  • Your code is not far off: you just need a few small refinements.

    The problem with your signal connections is that the signals are sending values which are overwriting your default index argument. So you just need to insert an extra argument in your lambdas/slots, like this:

        for i in range(0,3):
            self.sliderdic1[i].valueChanged.connect(
                lambda value, i=i: self.slidechanged(value, i))
            self.entrydic2[i].textChanged.connect(
                lambda text, i=i: self.textchanged(text, i))
    
    def slidechanged(self, value, index):
        self.entrydic2[index].setText(str(value))
    
    def textchanged(self, value, index):
        try:
            if int(value) > 0:
                self.sliderdic1[index].setValue(int(value))
        except ValueError:
            self.entrydic2[index].setText('1')
    

    (NB: never, ever use a bare except: it makes debugging almost impossible!)