Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Remove Space between 2 Pushbuttons



  • I want to show 10 PushButtons one below the other, without any space just touching each other How do I do this?



  • @ArunBm
    Use a QVBoxLayout, and presumably call setSpacing(0), https://doc.qt.io/qt-5/qboxlayout.html#setSpacing.


  • Banned

    This depends on how you want them displayed. Here is a MUC demonstrating keeping buttons contained. Note if I were implementing this in a program I would sub-class a Widget to contain the 4 lines of each buttons definition and then simply instantiate that class rather than repeat the code numerous times as I have done below

    from PyQt5.QtWidgets import QApplication, QDialog, QHBoxLayout, QVBoxLayout, QPushButton
    
    class MyWindow(QDialog):
        def __init__(self):
            QDialog.__init__(self)
            
            self.setWindowTitle('Togetherness')
            self.resize(200, 400)
    
            self.btnPush0 = QPushButton('Push 0')
          # This keeps the button from filling the window Horizontally
            HBox0 = QHBoxLayout()
            HBox0.addWidget(self.btnPush0)
            HBox0.addStretch(1)
    
            self.btnPush1 = QPushButton('Push 1')
            HBox1 = QHBoxLayout()
            HBox1.addWidget(self.btnPush1)
            HBox1.addStretch(1)
    
            self.btnPush2 = QPushButton('Push 2')
            HBox2 = QHBoxLayout()
            HBox2.addWidget(self.btnPush2)
            HBox2.addStretch(1)
    
            self.btnPush3 = QPushButton('Push 3')
            HBox3 = QHBoxLayout()
            HBox3.addWidget(self.btnPush3)
            HBox3.addStretch(1)
    
            self.btnPush4 = QPushButton('Push 4')
            HBox4 = QHBoxLayout()
            HBox4.addWidget(self.btnPush4)
            HBox4.addStretch(1)
    
            self.btnPush5 = QPushButton('Push 5')
            HBox5 = QHBoxLayout()
            HBox5.addWidget(self.btnPush5)
            HBox5.addStretch(1)
    
            self.btnPush6 = QPushButton('Push 6')
            HBox6 = QHBoxLayout()
            HBox6.addWidget(self.btnPush6)
            HBox6.addStretch(1)
    
            self.btnPush7 = QPushButton('Push 7')
            HBox7 = QHBoxLayout()
            HBox7.addWidget(self.btnPush7)
            HBox7.addStretch(1)
    
            self.btnPush8 = QPushButton('Push 8')
            HBox8 = QHBoxLayout()
            HBox8.addWidget(self.btnPush8)
            HBox8.addStretch(1)
    
            self.btnPush9 = QPushButton('Push 9')
            HBox9 = QHBoxLayout()
            HBox9.addWidget(self.btnPush9)
            HBox9.addStretch(1)
    
            VBox = QVBoxLayout()
            VBox.addLayout(HBox0)
            VBox.addLayout(HBox1)
            VBox.addLayout(HBox2)
            VBox.addLayout(HBox3)
            VBox.addLayout(HBox4)
            VBox.addLayout(HBox5)
            VBox.addLayout(HBox6)
            VBox.addLayout(HBox7)
            VBox.addLayout(HBox8)
            VBox.addLayout(HBox9)
          # These two in tandem handle keeping the buttons together Vertically
            VBox.setSpacing(0)  # No Spacing
            VBox.addStretch(1)  # No Expanding when the window expands
           
            self.setLayout(VBox)
    
    if __name__ == '__main__':
        MainEvtThred = QApplication([])
        
        MainApp = MyWindow()
        MainApp.show()
    
        MainEvtThred .exec()
    
      # If anyone wants more extensive free help I run an online lab-like classroom-like 
      # message server feel free and drop by you will not be able to post until I clear 
      # you as a student as this prevents spammers so if interested here is the invite
      # https://discord.gg/3D8huKC
    


  • @Denni-0 Excellant !!! Thanks


  • Lifetime Qt Champion

    Here is a version using less layouts for the same effect:

    import sys
    
    from PyQt5.QtWidgets import QApplication, QDialog, QHBoxLayout, QVBoxLayout, QPushButton
    
    class MyWindow(QDialog):
        def __init__(self):
            QDialog.__init__(self)
    
            self.setWindowTitle('Togetherness')
            self.resize(200, 400)
    
            vertical_layout = QVBoxLayout()
            vertical_layout.setSpacing(0)  # No Spacing
            vertical_layout.setContentsMargins(0, 0, 0, 0)
    
            for index in range(10):
                button = QPushButton(f"Push {index}")
                vertical_layout.addWidget(button)
    
            vertical_layout.addStretch(1)  # No Expanding when the window expands
    
            horizontal_layout = QHBoxLayout(self)
            horizontal_layout.addLayout(vertical_layout)
            horizontal_layout.addStretch(1)
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
    
        MainApp = MyWindow()
        MainApp.show()
    
        sys.exit(app.exec_())
    


  • @SGaist
    Nice & simple, uses just QVboxLayout + setSpacing() (+ setContentsMargins()) as suggested :)


  • Banned

    @SGaist okay and my version could have been condensed and be more proper by sub-classing the QPushbutton since all of them have the same additional features -- and this is why I did it the more verbose way and commented that it could be sub-classed but I thought the OP might enjoy learning the how to's rather than giving him the entire fish -- aka here is a fishing pole, the bait and there is good place to fish -- go fish


  • Lifetime Qt Champion

    @Denni-0 I fail to see why QPushButton should be subclassed.

    As for the fish, I am all for people learning to do things by themselves. However using one layout per button is not the right technique to learn in the use case of the OP.

    The right tool for the right fish.


  • Banned

    Well @SGaist it kind of depends on what you plan to do. If you do not really need a handle to those buttons it could be done like this (see below). Or perhaps you want to put all these very similar buttons into an dictionary or list the sub-class helps facilitates doing this. Basically the rule is if you are going to repeat a bit of code more than once maybe you ought to encapsulate and reference that and definitely if you are repeating it more than twice and that is what a sub-classing a modified series of buttons does encapsulates the changes and you just call it once for each instance you need.

    from PyQt5.QtWidgets import QApplication, QDialog, QHBoxLayout, QVBoxLayout, QPushButton
    
    class MyBttn(QPushButton):
        def __init__(self, parent, Id, BtnName):
            QPushButton.__init__(self)
            self.Parent = parent
            self.Id = Id
    
            self.btnPush = QPushButton(BtnName)
            self.clicked.connect(self.MeBenClicked)
    
            HBox = QHBoxLayout()
            HBox.addWidget(self.btnPush)
            HBox.addStretch(1)
    
            self.setLayout(VBox)
    
        def MeBenClicked(self):
            self.Parent.BtnClicked(self.Id)
    
    
    class MyWindow(QDialog):
        def __init__(self):
            QDialog.__init__(self)
            
            self.setWindowTitle('Togetherness')
            self.resize(200, 400)
    
            VBox = QVBoxLayout()
            VBox.addWidget(MyBttn(self, 0, 'Push 0'))
            VBox.addWidget(MyBttn(self, 1, 'Push 1'))
            VBox.addWidget(MyBttn(self, 2, 'Push 2'))
            VBox.addWidget(MyBttn(self, 3, 'Push 3'))
            VBox.addWidget(MyBttn(self, 4, 'Push 4'))
            VBox.addWidget(MyBttn(self, 5, 'Push 5'))
            VBox.addWidget(MyBttn(self, 6, 'Push 6'))
            VBox.addWidget(MyBttn(self, 7, 'Push 7'))
            VBox.addWidget(MyBttn(self, 8, 'Push 8'))
            VBox.addWidget(MyBttn(self, 9, 'Push 9'))
          # These two in tandem handle keeping the buttons together Vertically
            VBox.setSpacing(0)  # No Spacing
            VBox.addStretch(1)  # No Expanding when the window expands
    
            self.setLayout(VBox)
    
        def BtnClicked(self, BtnId):
            print('Button Clicked ',BtnId) 
    
    if __name__ == '__main__':
        MainEvtThred = QApplication([])
        
        MainApp = MyWindow()
        MainApp.show()
    
        MainEvtThred .exec()
    
      # If anyone wants more extensive free help I run an online lab-like classroom-like 
      # message server feel free and drop by you will not be able to post until I clear 
      # you as a student as this prevents spammers so if interested here is the invite
      # https://discord.gg/3D8huKC
    

    But ultimately how it is actually done is dependent upon the programmer as there is always more than one way to do something with quality and often one of these quality ways versus another makes little difference just a matter of preference and style. So the above is what I meant by one ought to sub-class the button -- which I think could even be used in your version with the For Loop assuming the Id and the Name can be rendered that way


  • Lifetime Qt Champion

    @Denni-0 said in Remove Space between 2 Pushbuttons:

    class MyBttn(QPushButton):
    def init(self, parent, Id, BtnName):
    QPushButton.init(self)
    self.Parent = parent
    self.Id = Id

        self.btnPush = QPushButton(BtnName)
        self.clicked.connect(self.MeBenClicked)
    
        HBox = QHBoxLayout()
        HBox.addWidget(self.btnPush)
        HBox.addStretch(1)
    
        self.setLayout(VBox)
    
    def MeBenClicked(self):
        self.Parent.BtnClicked(self.Id)
    

    Why are you subleasing QPushButton and creating a QPushButton within it ?
    Your MeBenClicked button violates encapsulation. If you really want to transmit that Id value, create a custom signal in your subclass and emit it when the button clicked. Connect that signal in your MyWindow class. It's not the role of the button to manage what its parent does with the signal.


  • Banned

    Yep it does and sometimes for somethings I do just that -- violate the encapsulation rule -- because like everything there are exceptions to every rule -- is it bad not really due to how its being used -- is it good not really because there are reasons for those rules. Again it all boils down to preference and style -- you can nit-pick over the rules -- or you can use them as guide posts -- but either way you have to understand the whys of those rules in order to make the call -- and I understand the whys

    You do realize there are Classes that require you to create certain methods when you create them -- this is sort along that theme because in this case its not a stand alone class to begin with -- if I were designing a stand alone class that needs to get imported into other applications I would go so far as making my internal signal/slot emit another signal but in this case its not necessary and adds a layer of unnecessary complexity --- K.I.S.S. is my primary rule


  • Lifetime Qt Champion

    Tight coupling is not K.I.S.S.


Log in to reply