Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PyQt - Reducing margins and spacing in widget *expands* layout

Consider the case of a QMainWindow with a QWidget as central widget. This widget has a QHBoxLayout. I add two other widgets to it, each with a QVBoxLayout.

I now want to bring the Widgets inside QVBoxLayout closer to each other. The attempt is to use .setMargin(0), .setSpacing(0) and .setContentsMargins(0,0,0,0) for this purpose.

However the result is that their separation is actually increased instead of decreased - as can be seen in the picture (where Gain is the widget where I set the margins and spacings to zero).

enter image description here

The code to reproduce this issue is appended below. (And the same actually happens when using a QGridLayout.)

Here is the question on two different complexity levels:

(a) Since the only difference between the two widgets is that one has the margins and spacings set to zero, one of the used method calls must have done something else to the layout or widget-properties. Which other property is changed by setting any of .setMargin(0), .setSpacing(0) and setContentsMargins(0,0,0,0) ?

(b) How do I make the spacing between the text label and the combobox in this example smaller?


from PyQt4 import QtGui
import sys

class LabeledComboBox(QtGui.QWidget):
    def __init__(self, text="", items=[], parent=None):
        super(LabeledComboBox, self).__init__(parent)
        self.parent = parent
        self.widgetlayout = QtGui.QVBoxLayout(self)
        self.widgetlayout.addWidget(QtGui.QLabel(text))
        self.Combo = QtGui.QComboBox()
        self.Combo.addItems(items)
        self.widgetlayout.addWidget(self.Combo)
        self.parent.mylayout.addWidget(self)

    def printParams(self):
        # print some margin/spacing parameters for testing
        m = self.widgetlayout.margin()
        s = self.widgetlayout.spacing()
        cm = self.widgetlayout.getContentsMargins()
        print "margin: {m}, spacing: {s}, ContentsMargin: {cm}".format(m=m, s=s, cm=cm)

class App(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(App, self).__init__(parent)
        self.mainbox = QtGui.QWidget()
        self.mylayout = QtGui.QHBoxLayout()
        self.mainbox.setLayout(self.mylayout)
        self.setCentralWidget(self.mainbox)

        self.GainWidget = LabeledComboBox("Gain", ['low', 'medium', 'high'],  self)
        self.RevolutionsWidget = LabeledComboBox("Revolutions", ['100', '200', '400'],  self)


        self.GainWidget.printParams()
        # this outputs: margin: 9, spacing: 6, ContentsMargin: (9, 9, 9, 9)
        # now I set everything to zero 
        self.GainWidget.widgetlayout.setMargin(0)
        self.GainWidget.widgetlayout.setSpacing(0)
        self.GainWidget.widgetlayout.setContentsMargins(0,0,0,0)
        # check
        self.GainWidget.printParams()
        # margin: 0, spacing: 0, ContentsMargin: (0, 0, 0, 0)


if __name__=='__main__':
    app = QtGui.QApplication(sys.argv)
    thisapp = App()
    thisapp.show()
    sys.exit(app.exec_())
like image 763
ImportanceOfBeingErnest Avatar asked Oct 07 '16 12:10

ImportanceOfBeingErnest


2 Answers

Firstly: setMargin is an obsolete method which has beed superseded by setContentsMargins, so you can ignore it.

Secondly: the increase in separation is caused by setting the margins to zero. The two vertical layouts are in the same horizontal layout, so they will necessarily have the same height. But the left-hand layout has no margins, so it has more space available to stretch out in. If both vertical layouts have the same settings, their child widgets can be squeezed closer together by resizing the window.

So you need to use setSpacing on both layouts to change the spacing.

like image 125
ekhumoro Avatar answered Nov 15 '22 18:11

ekhumoro


In the latest PyQt 5.10 setContentsMargins method is working well. You may create a layout for your widget and then apply its margins.

widget.layout.setContentsMargins(0,0,0,0)

like image 29
Pixsa Avatar answered Nov 15 '22 20:11

Pixsa