3
votes

I am writing an application using PyQt and Qt StyleSheets, but had some issues with the BoxModel.

I was able to reproduce the problem with this small hierarchy of objects (each with a BoxLayout):

  1. MainWindow (sub-class of QWidget)
  2. QWidget
  3. 2x a QLabel

My stylesheet is very simple:

  • A 1px solid blue border for the labels (3)
  • A 1px solid red border for the widget (2)
  • A 50px margin for the widget (2)

I would expect to see (from top to center of the app):

  • A 50px margin
  • A red border
  • The standard layout spacing/contentmargin
  • A blue border

However, this is not the case. It seems the inner labels are not positioned relative to the contents rect of the widget, but instead to the content rect of the outer window. The blue border of the labels (and their text) actually extends outside the red border of their parent widget.

Screenshot showing the issue

The full code is here:

import sys

from PyQt4 import QtGui

qss_string = """
QWidget#card {
    border: 1px solid red;
    margin: 50px;
}

QLabel {
    border: 1px solid blue;
}
"""

class MainWindow(QtGui.QWidget):
  def __init__(self, parent = None):
    super(MainWindow, self).__init__(parent)

    window_layout = QtGui.QHBoxLayout()

    card = QtGui.QWidget(self)

    widget_layout = QtGui.QVBoxLayout()
    widget_layout.addWidget(QtGui.QLabel("a long testing text which should fit inside a box", card))
    widget_layout.addWidget(QtGui.QLabel("a short text", card))
    card.setLayout(widget_layout)

    card.setObjectName("card")
    window_layout.addWidget(card)

    self.setLayout(window_layout)

    self.setObjectName("window")
    self.setStyleSheet(qss_string)


def main():
  app = QtGui.QApplication(sys.argv)
  main_window = MainWindow()
  main_window.show()
  return app.exec_()


if __name__ == "__main__":
  sys.exit(main())
1

1 Answers

2
votes

Two possible solutions that worked for me (in Pyqt5 however)

  1. Use QFrame instead of QWidget as your container (card)

  2. Name your labels lets say label1 and label2 and then add the following commands

    label1.setStyleSheet("QLabel{margin:50px;margin-bottom:0px;}")
    label2.setStyleSheet("QLabel{margin:50px;margin-top:0px;}")
    

In my opinion the first one is better, the second is just a workaround