Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. dynamica buttons in pyqt5
Forum Updated to NodeBB v4.3 + New Features

dynamica buttons in pyqt5

Scheduled Pinned Locked Moved Unsolved General and Desktop
9 Posts 5 Posters 1.9k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    sara12333
    wrote on last edited by
    #1

    How can I handle each button separately? I want to create multiple of buttons based on the worker's names so I did a for loop based on the worker numbers I have on my DB so I have multiple of assign buttons and workers names as labels,when clicking the assign button I want to save the name of the worker in the, but it only save the last value whenever i clicked. connect to function
    here is my code in python :

    ## repeated for every worker
        for i in range(2):
    
            self.Vl_name_location = QtWidgets.QVBoxLayout()
            self.Vl_name_location.setObjectName("Vl_name_location")
            self.worker_name = QtWidgets.QLabel(self.groupBox)
            self.worker_name.setAlignment(QtCore.Qt.AlignCenter)
    
            ## from db
            self.worker_name.setText("worker_name")
            self.worker_name.setObjectName("worker_name")                       
            self.Vl_name_location.addWidget(self.worker_name)
            self.worker_location = QtWidgets.QLabel(self.groupBox)
            self.worker_location.setAlignment(QtCore.Qt.AlignCenter)
            self.worker_location.setObjectName("worker_location")
            # from db
            self.worker_location.setText("Eng,Zone B")
            self.Vl_name_location.addWidget(self.worker_location)
            self.Hl_worker.addLayout(self.Vl_name_location)
            #####
            ### assign button to connect the name of the worker to the image       on the db
            #####
    
            self.assign_button = QtWidgets.QPushButton(self.groupBox)
            self.assign_button.setMinimumSize(QtCore.QSize(50, 25))
              self.assign_button.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
            self.assign_button.setStyleSheet("")
            self.assign_button.setObjectName("assign_button")
            self.assign_button.setText( "Assign" )
            self.assign_button.clicked.connect(lambda: self.assign_button_clicked(self.worker_name.text() ))
            self.Hl_worker.addWidget(self.assign_button)
    
    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi and welcome to devnet,

      You are overwriting your buttons doing it like that. You should store a list of your buttons if you want to access them again.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      S 1 Reply Last reply
      2
      • SGaistS SGaist

        Hi and welcome to devnet,

        You are overwriting your buttons doing it like that. You should store a list of your buttons if you want to access them again.

        S Offline
        S Offline
        sara12333
        wrote on last edited by
        #3

        @SGaist i tried to store all the buttons but still it only save the last value
        here is my code inside a for loop :

        
                    self.assign_button = QtWidgets.QPushButton(self.groupBox)
                    self.assign_button.setMinimumSize(QtCore.QSize(50, 25))
                    self.assign_button.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
                    self.assign_button.setStyleSheet("")
                    self.assign_button.setObjectName("assign_button")
                    self.assign_button.setText("Assign")
                    btns.append(self.assign_button)
                    btns[i].clicked.connect(lambda: self.assign_button_clicked(str(i), 1))
        
        JonBJ 1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          You are still overwriting self.assign_button.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          1
          • S sara12333

            @SGaist i tried to store all the buttons but still it only save the last value
            here is my code inside a for loop :

            
                        self.assign_button = QtWidgets.QPushButton(self.groupBox)
                        self.assign_button.setMinimumSize(QtCore.QSize(50, 25))
                        self.assign_button.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
                        self.assign_button.setStyleSheet("")
                        self.assign_button.setObjectName("assign_button")
                        self.assign_button.setText("Assign")
                        btns.append(self.assign_button)
                        btns[i].clicked.connect(lambda: self.assign_button_clicked(str(i), 1))
            
            JonBJ Online
            JonBJ Online
            JonB
            wrote on last edited by JonB
            #5

            @sara12333
            As @SGaist says. If you are going to going to be creating all those widgets multiple times as per the the for loop, you''re going to want to make all these variables as arrays. So it's not just, say, self.assign_button that needs array-izing, but also, say, self.worker_name, and everything else.

            At least if you want to be able to reference them later on. At the moment what you are doing is creating multiple Qt widgets OK, but you are always storing them into some self.something variable, so that will only ever end up being a reference to the ones you created in the final pass through the loop.

            If you are really going to be creating multiple "groups" of widgets like this, you would probably be best defining a container class when holds (references to) each of the widgets it uses. Then you can create an array (Python list) of each container widget easily, and access widgets via the elements in that array. self.worker_group_of_widgets[i].assign_button, etc.

            S 1 Reply Last reply
            0
            • JonBJ JonB

              @sara12333
              As @SGaist says. If you are going to going to be creating all those widgets multiple times as per the the for loop, you''re going to want to make all these variables as arrays. So it's not just, say, self.assign_button that needs array-izing, but also, say, self.worker_name, and everything else.

              At least if you want to be able to reference them later on. At the moment what you are doing is creating multiple Qt widgets OK, but you are always storing them into some self.something variable, so that will only ever end up being a reference to the ones you created in the final pass through the loop.

              If you are really going to be creating multiple "groups" of widgets like this, you would probably be best defining a container class when holds (references to) each of the widgets it uses. Then you can create an array (Python list) of each container widget easily, and access widgets via the elements in that array. self.worker_group_of_widgets[i].assign_button, etc.

              S Offline
              S Offline
              sara12333
              wrote on last edited by
              #6

              @JonB Thank you for your reply, I hope that I understood that since I'm new in python so here is my code depending on my understanding:

              class worker_group_of_widgets:
              
                  def __init__(self,assign_button=None, groupBox=None,verticalLayout=None,Hl_worker=None,label_img=None,Vl_name_location=None,worker_name=None,worker_location=None):
                      self.assign_button       = assign_button
                      self.groubBox            = groupBox
                      self.Vl_name_location    = Vl_name_location
                      self.verticalLayout      = verticalLayout
                      self.Hl_worker           = Hl_worker
                      self.label_img           = label_img
                      self.worker_name         = worker_name
                      self.worker_location     = worker_location
              
              containter = []
                      ##############
                      ## repeated for every worker
                      for i in range(2):
              
                          containter[i] = worker_group_of_widgets()
                          containter[i].groubBox=QtWidgets.QGroupBox(self.scrollAreaWidgetContents_2)
                             containter[i].assign_button = QtWidgets.QPushButton(containter[i].groubBox)
                          containter[i].assign_button.clicked.connect(lambda: self.assign_button_clicked(str(i)))
              
              

              if the above code is correct i still got IndexError: list assignment index out of range

              jsulmJ JonBJ 2 Replies Last reply
              0
              • S sara12333

                @JonB Thank you for your reply, I hope that I understood that since I'm new in python so here is my code depending on my understanding:

                class worker_group_of_widgets:
                
                    def __init__(self,assign_button=None, groupBox=None,verticalLayout=None,Hl_worker=None,label_img=None,Vl_name_location=None,worker_name=None,worker_location=None):
                        self.assign_button       = assign_button
                        self.groubBox            = groupBox
                        self.Vl_name_location    = Vl_name_location
                        self.verticalLayout      = verticalLayout
                        self.Hl_worker           = Hl_worker
                        self.label_img           = label_img
                        self.worker_name         = worker_name
                        self.worker_location     = worker_location
                
                containter = []
                        ##############
                        ## repeated for every worker
                        for i in range(2):
                
                            containter[i] = worker_group_of_widgets()
                            containter[i].groubBox=QtWidgets.QGroupBox(self.scrollAreaWidgetContents_2)
                               containter[i].assign_button = QtWidgets.QPushButton(containter[i].groubBox)
                            containter[i].assign_button.clicked.connect(lambda: self.assign_button_clicked(str(i)))
                
                

                if the above code is correct i still got IndexError: list assignment index out of range

                jsulmJ Offline
                jsulmJ Offline
                jsulm
                Lifetime Qt Champion
                wrote on last edited by
                #7

                @sara12333 said in dynamica buttons in pyqt5:

                IndexError: list assignment index out of range

                Of course - you do not append to the list.

                containter.append( worker_group_of_widgets())
                

                https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                1
                • S sara12333

                  @JonB Thank you for your reply, I hope that I understood that since I'm new in python so here is my code depending on my understanding:

                  class worker_group_of_widgets:
                  
                      def __init__(self,assign_button=None, groupBox=None,verticalLayout=None,Hl_worker=None,label_img=None,Vl_name_location=None,worker_name=None,worker_location=None):
                          self.assign_button       = assign_button
                          self.groubBox            = groupBox
                          self.Vl_name_location    = Vl_name_location
                          self.verticalLayout      = verticalLayout
                          self.Hl_worker           = Hl_worker
                          self.label_img           = label_img
                          self.worker_name         = worker_name
                          self.worker_location     = worker_location
                  
                  containter = []
                          ##############
                          ## repeated for every worker
                          for i in range(2):
                  
                              containter[i] = worker_group_of_widgets()
                              containter[i].groubBox=QtWidgets.QGroupBox(self.scrollAreaWidgetContents_2)
                                 containter[i].assign_button = QtWidgets.QPushButton(containter[i].groubBox)
                              containter[i].assign_button.clicked.connect(lambda: self.assign_button_clicked(str(i)))
                  
                  

                  if the above code is correct i still got IndexError: list assignment index out of range

                  JonBJ Online
                  JonBJ Online
                  JonB
                  wrote on last edited by JonB
                  #8

                  @sara12333
                  In addition to @jsulm's post.

                  I'm not sure, but i think your new way omits some of the widget creation you had before you introduced the class-container?

                  In any case, here is how I would do it. I am not going to write the whole thing for you, but I would have something like the following. Note that while I am at it I am making the class for this "user info" stuff its own QWidget. So:

                  class WorkerInfo(QWidget):
                    def __init__(self, parent: QWidget=None):
                      super().__init__(parent)
                  
                      # here all/most of the stuff from your original loop
                      self.Vl_name_location = QtWidgets.QVBoxLayout()
                      ...
                      self.assign_button = QtWidgets.QPushButton(self.groupBox)
                      ...
                  
                  
                  # now your loop in outside world, e.g. in your `QMainWindow`
                  self.all_workers = []
                  for i in range(2):
                    worker = WorkerInfo(self)
                    self.all_workers.push(worker)
                    self.all_workers[i].assign_button.clicked.connect(lambda i: self.assign_button_clicked(str(i)))
                  

                  BTW, I think your current lambda: self.assign_button_clicked(str(i)) will not do as you intend. I think you will find that the i is always 1 (or even 2) when the slot is called, i.e. the value from the last iteration through your for loop. Note how I have passed i as a parameter to the lambda to avoid this. Mine is totally untested, you will have to do so! :)

                  (I may have misunderstood where you want each assign_button = QtWidgets.QPushButton(self.groupBox) to appear, If that is not inside the "group-widget" you are creating for each worker then move it outside, as appropriate. Actually I may be wrong anyway, I think you do create them inside each worker group widget.)

                  1 Reply Last reply
                  1
                  • G Offline
                    G Offline
                    GEngines
                    wrote on last edited by GEngines
                    #9

                    Hi, I randomly came across this post, Wrote a quick script, Hope it helps

                    Script :

                    import sys
                    from PyQt5 import QtWidgets
                    from functools import partial
                    
                    
                    class UI(QtWidgets.QMainWindow):
                        def __init__(self):
                            QtWidgets.QMainWindow.__init__(self)
                            self.init_ui()
                            self.populate_buttons()
                    
                        def init_ui(self):
                            self.setFixedSize(300, 500)
                            central_wid = QtWidgets.QWidget(self)
                            self.setCentralWidget(central_wid)
                            self.main_layout = QtWidgets.QVBoxLayout(self)
                            central_wid.setLayout(self.main_layout)
                    
                        def populate_buttons(self):
                            for i in range(10):
                                a = AdvancedButton("Test Button", i)
                                a.clicked.connect(partial(self.button_click_function, a.value))
                                self.main_layout.addWidget(a)
                    
                        def button_click_function(self, _val):
                            print("Button Value : ", _val)
                    
                    
                    class AdvancedButton(QtWidgets.QPushButton):
                        def __init__(self, button_name, value):
                            QtWidgets.QPushButton.__init__(self, button_name)
                            self.name = button_name
                            self.value = value
                    
                    
                    app = QtWidgets.QApplication(sys.argv)
                    ex = UI()
                    ex.show()
                    sys.exit(app.exec_())
                    

                    UI and Output :
                    c1b8e5e0-aa2b-4547-a4f3-b46c2422d205-image.png

                    As already mentioned by another member, Depending on the need, you might want to store the buttons to a list./array

                    ( replied as it's still listed as unsolved)

                    Bharath

                    1 Reply Last reply
                    1

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved