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

How to set margin of content of QScrollArea



  • Hi,
    I am struggling to set the margin of the widgets inside a QScrollArea.
    This is what I tried:

    class NodeWidget(QWidget):
        def __init__(self):
            super(NodeWidget, self).__init__()
    
            # UI
            main_layout = QGridLayout()
    
            name_label = QLabel('label 1')
            name_label.setFont(QFont('Poppins', 12))
            package_name_label = QLabel('label 1')
            package_name_label.setFont(QFont('Poppins', 12))
    
            main_layout.addWidget(name_label, 0, 0)
            main_layout.addWidget(package_name_label, 1, 0)
    
            self.setLayout(main_layout)
    
    
            main_layout.setVerticalSpacing(0)
            main_layout.setSpacing(0)
            self.setContentsMargins(-6, -6, -6, -6)
            main_layout.setContentsMargins(-6, -6, -6, -6)
    
            self.setStyleSheet('margin: 0px;')  # doen't work
    
    
    class MyWidget(QScrollArea):
        def __init__(self):
            super(MyWidget, self).__init__()
            self.setWidgetResizable(True)
            self.list_scroll_area_widget = QWidget()
            self.setWidget(self.list_scroll_area_widget)
    
            self.list_layout = QVBoxLayout()
            self.list_layout.setAlignment(Qt.AlignTop)
            self.list_scroll_area_widget.setLayout(self.list_layout)
    
    
            nw1 = NodeWidget()
            self.list_layout.addWidget(nw1)
            nw2 = NodeWidget()
            self.list_layout.addWidget(nw2)
    
            self.setStyleSheet('background-color: #5555aa; border: 1px solid grey;')
    
            self.setContentsMargins(0, 0, 0, 0)  # doesn't work either
    
    

    Result:
    Qt 58.png
    I actually want the space between the label boxes and the border of the scroll area to be smaller.
    How can i do this?
    Thanks for answers!


  • Lifetime Qt Champion

    @Niagarer said in How to set margin of content of QScrollArea:

    self.setContentsMargins(0, 0, 0, 0) # doesn't work either

    Hi
    It has to be on the inner most layout that holds the widgets.



  • @mrjj Hi,
    thank you, that was an improvement.
    I now call

            self.list_layout.setContentsMargins(0, 0, 0, 0)
    

    too.
    Qt 59.png
    But still there is some space I don't get rid of.
    Setting spacing of the list_layout to 0 also has no effect on the space between the two boxes...


  • Lifetime Qt Champion

    @Niagarer
    hi
    I think we still have some ContentsMargins on one of the layouts
    It does look like the default size. on left / right side.

    The space between the two boxes might be normal as it just how the layout divide the space
    even if spacing is set to zero , it will do like this unless you insert a spacer to press them upwards.



  • @mrjj
    Also thought about that but adding a spacer as third item to main_layout has no effect at all on the space between them.
    So it seems like it's just the margin of these NodeWidgets although their margins actually should be 0


  • Lifetime Qt Champion

    @Niagarer
    Im not really sure where space comes from
    but its possible to have ScrollArea margin/borderless

    alt text

    So maybe it does come from the NodeWidgets for some reason
    but you should be able to get rid of it.



  • @mrjj
    Ok. Strange, but thanks for the input I will see if I find what's missing


  • Banned

    Okay went through your code and created a MUC out of it, then I proceeded to muck around with it and this is what I ended up with and I believe this does what you were asking about. Not sure if you really needed the QGridLayout but since from what I could see you were gaining nothing from it I rolled back to something simpler

    from PyQt5.QtCore    import Qt
    from PyQt5.QtGui     import QFont
    from PyQt5.QtWidgets import QApplication, QWidget, QGridLayout, QScrollArea
    from PyQt5.QtWidgets import QVBoxLayout, QLabel
    
    class NewWidget(QWidget):
        def __init__(self, Id):
            QWidget.__init__(self)
            self.Id = Id
    
            MyFont = QFont('Poppins', 12)
    
            self.lblName = QLabel('Name ' + str(self.Id))
            self.lblName.setFont(MyFont)
    
            self.lblPackageName = QLabel('Package ' + str(self.Id))
            self.lblPackageName.setFont(MyFont)
    
            VBox = QVBoxLayout()
            VBox.setSpacing(0)
            VBox.setContentsMargins(0, 0, 0, 0)
    
            VBox.addWidget(self.lblName)
            VBox.addWidget(self.lblPackageName)
    
            self.setLayout(VBox)
    
    class MyScrollArea(QScrollArea):
        def __init__(self):
          # First do not use super( ) unless you are fully aware of what 3 major issues 
          # you must code for in conjunction with using it and the actual rare issue 
          # that it is meant to solve. Note this rare issue is rare and unless you are 
          # doing some complicated inheritance you will most likely never run into that
          # issue -- however the 3 major issues it creates by using it you are much more 
          # likely to run into than the rare issue its meant for
          #
          #  super(MyWidget, self).__init__()
            QScrollArea.__init__(self)
          # Always good to group like things, and put them in a sort of structured order
            self.setWidgetResizable(True)
            self.setStyleSheet('background-color: #5555aa; border: 1px solid grey;')
            self.setContentsMargins(0, 0, 0, 0)  # doesn't work either
    
            nw1 = NewWidget(1)
            nw2 = NewWidget(2)
    
            VBox = QVBoxLayout()
            VBox.setSpacing(0)
            VBox.setAlignment(Qt.AlignTop)
            VBox.setContentsMargins(0, 0, 0, 0)
            VBox.addWidget(nw1)
            VBox.addWidget(nw2)
    
            self.setLayout(VBox)
    
    if __name__ == "__main__":
        MainEventHandler = QApplication([])
    
        application = MyScrollArea()
        application.show()
        
        MainEventHandler.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
    


  • Thank you, you are right, I made a mistake:
    I applied negative content margins on a layout which seems to result in positive minus border:

    Qt 61.png
    left: main_layout.setContentsMargins(6, 6, 6, 6)
    right: main_layout.setContentsMargins(-6, -6, -6, -6)
    I actually could have seen this in @mrjj's post... my bad

    So, all I needed to do is to call

    layout.setSpacing(0)
    layout.setContentMargins(0, 0, 0, 0)
    

    on every layout in the extreme case.

    Qt 62.png

    I still haven't found a way to do all this through a stylesheet for the scrollarea though but at least this is one way of doing it.


  • Banned

    I think there might be a way to do this via a stylesheet. However this would only work if python-qt supports the concept of CSS (aka Cascading Style Sheets) if it does not support this concept then no it will have to be done for each container that you use because each container would have its own Style Sheet associated with it. However again as I said I think it might support this as I think I remember that a container contained within a container adopts its parents style sheet but I could be wrong on this as I have not played around with it too extensively and I am pulling from pure memory which can get a bit jumbled at times with all the languages I have worked with over the years.

    Note I mention all of this to perhaps help you google possible concepts to help ferret out a more conclusive answer


Log in to reply