0

I have a form I am working on where all of the initial elements populate correctly but I am now trying to add a gridbox that will eventually populate a list of patterns. As I test I have done the following:

    def show_game_types(self):
        self.game_types = loadJSONFromFile(game_types_file)
        self.setStyleSheet("")
        game_types_page = QVBoxLayout()
        game_types_page.setContentsMargins(30, 30, 30, 10)
        game_types_page.setSpacing(0)
        # creating a group box
        self.gameTypesFormBox = QGroupBox("Game Types")
        self.gameTypesFormBox.setStyleSheet("font-size: 14px; font-weight: bold;")
        regular_font = "font-size: 11px; font-weight: normal;"
        titles_style = "font-size: 12px; font-weight: bold;"

        self.gt_layout = QFormLayout()

        create_new_gt_button = QPushButton("Create New")
        create_new_gt_button.setStyleSheet(regular_font)
        create_new_gt_button.clicked.connect(self.save_new_game_type)

        self.create_new_gt_textbox = QLineEdit()
        self.create_new_gt_textbox.setMinimumWidth(600)
        self.create_new_gt_textbox.setStyleSheet(regular_font)

        add_patterns_label = QLabel("Modify game type patterns")
        add_patterns_label.setStyleSheet(titles_style)
        self.this_gt_combo = QComboBox()
        self.this_gt_combo.setStyleSheet(regular_font)
        self.this_gt_combo.addItem("-- Select game type --")
        self.this_gt_combo.currentTextChanged.connect(self.load_gt_patterns)
        for type in range(len(self.game_types)):
            self.this_gt_combo.addItem(self.game_types[type]["name"])
        
        self.gt_layout.addRow(self.create_new_gt_textbox, create_new_gt_button)
        self.gt_layout.addRow(add_patterns_label)
        self.gt_layout.addRow(self.this_gt_combo)

        self.selected_label = QLabel("")
        self.gt_layout.addRow(self.selected_label)

        # for pattern in selected game patterns populate a grid
        # start with a blank for "new"
        self.grid_widget = QWidget()
        self.pattern_grid = QGridLayout()
        test = Color('red')
        self.pattern_grid.addWidget(test, 0, 0)
        test2 = Color('blue')
        self.pattern_grid.addWidget(test2, 0, 1)

        self.grid_widget.setLayout(self.pattern_grid)
        self.gt_layout.addRow(QLabel("test"), self.grid_widget)

        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Cancel)
        self.buttonBox.rejected.connect(self.showHomePage)

        self.gameTypesFormBox.setLayout(self.gt_layout)
        game_types_page.addWidget(self.gameTypesFormBox)
        game_types_page.addWidget(self.buttonBox)

        widget = QWidget()
        widget.setLayout(game_types_page)
        self.setCentralWidget(widget)

For reference the Color class is

class Color(QWidget):
    def __init__(self, color):
        super(Color, self).__init__()
        self.setAutoFillBackground(True)
        self.color = color

        palette = self.palette()
        palette.setColor(QPalette.Window, QColor(self.color))
        self.setPalette(palette)

When I try running this the label "test" shows up but the grid added to a widget, which is then added does not appear: missing grid in qformlayout

For testing I set the following and the gridlayout does populate the window correctly

self.setCentralWidget(self.grid_widget)

gridLayout works

I am also able to get the gridlayout to show outside the QFormLayout but then it's not within the Form box and floats underneath it.

        game_types_page.addWidget(self.grid_widget)

grid add to entire page

How do I add the QGridLayout to the QFormLayout?

Scott Rowley
  • 486
  • 1
  • 7
  • 30
  • 1
    By default, QWidget does not have any size hint nor a minimum size, meaning that in certain conditions it may have a *null size*. Your layout usage (which is a bit awkward, by the way) prevents those `Color` widgets to properly show because the parent layout management doesn't see a basic minimum size for the item set with `addRow()`. The main culprit is the default behavior of QFormLayout, but since you don't seem to be using it a lot as it's intended, you should consider using QGridLayout instead, or, alternatively, a QVBoxLayout with nested QHBoxLayouts when you need more than one widget. – musicamante Aug 27 '23 at 20:46
  • Thank you @musicamante, I'm just getting started with PyQt5. You say I'm doing the layout a bit awkward, do you have something I could look at that would show a more intelligent use? – Scott Rowley Aug 27 '23 at 20:52
  • QFormLayout is fundamentally the same as a QGridLayout, it just offers a slightly different behavior by also providing convenience functions that are mostly used for *form layouts*, which require logical access to "rows" for input fields. If you *do* need such behavior, then implement `sizeHint()` and `minimumSizeHint()` as per the duplicated question (also have a look at the QSizePolicy docs). For any other situations, do as suggested above. From your code and image, I believe that a nested layout would suffice: a main QVBoxLayout, and if you need more than one widget in a row, add a » – musicamante Aug 27 '23 at 20:56
  • » QHBoxLayout to it (`addLayout(someLayout)`) with those widgets in it. I suggest you to take some time and experiment with layouts using Qt Designer, so that you could better *visually* understand how different layout managers work and eventually decide how to implement them by code. Note that I don't mean that QFormLayout is worthless or using it is wrong. It's just a peculiar layout that is only valid in certain specific case. From my experience, 90% of the times I *thought* I could use it, I ended up by using a different approach at all. Still, there are some cases in which it *is* valid. – musicamante Aug 27 '23 at 20:58

0 Answers0