0

I have widget with some labels placed grid-like. Code:

    def init_drawers(self):
        self.drawers_widget = QWidget(self)

        width, height = self.get_drawers_size() # ex.: 12, 8
        self.drawers_widget.setGeometry(100, 0, width * 32, height * 32)

        for h in range(height):
            for w in range(width):
                drawer_uid = f"{h}_{w}"

                label = QLabel(self.drawers_widget)
                label.setGeometry(w * 32, h * 32, 32, 32)
                label.mousePressEvent = self.get_generic_clicker(drawer_uid)
                self.bindings[drawer_uid] = (h, w) # {}

                self.drawers[drawer_uid] = label # {}

        self.render_all()

render_all just iterates over self.drawers and sets 32x32 pixmaps for them, so in result I get big image with clickable fields that change their pixmap on click.

At first everything works fine, but then I need to change layout to, for example, 9*9. I tried to delete labels:

if self.drawers:
    for k in self.drawers:
         self.drawers[k].close() # or .deleteLater()
    self.drawers.clear()
    self.bindings.clear()

And call init_drawers again (drawers_widget init was out of that function). Main widget resized, but no labels seen - and also they're not responding to clicks. While using .destroy() instead - click events print new ids, but pixmaps do not update. Also tried to delete drawers_widget too and create it again - same result.

UPD: I get no errors in console.

  • do you get error when you run it in console? always put FULL error message (starting at word "Traceback") in question (not in comments) as text (not screenshot, not link to external portal). There are other useful information in the full error/traceback. – furas Oct 02 '22 at 11:28
  • @furas no, console is clean. Added this note to question. – faintReflection Oct 02 '22 at 12:03
  • Widgets must be explicitly shown if created as children *after* the parent has been already shown. Obviously, if you properly use [layout managers](//doc.qt.io/qt-5/layout.html), that is implicit. – musicamante Oct 02 '22 at 12:45

1 Answers1

0

Well, I still don't get why newly created labels with QWidget parent are not displayed, but for my case I've made workaround using @musicamante suggestion

    def init_drawers(self):
        self.draw_widget = QWidget(self)
        self.draw_grid = QGridLayout(self.draw_widget)
        self.draw_grid.setSpacing(0)
        self.draw_grid.setContentsMargins(0, 0, 0, 0)

        self.setup_drawers()

    def setup_drawers(self):
        # cleanup
        if self.draw_grid.count():
            for i in reversed(range(self.draw_grid.count())):
                self.draw_grid.itemAt(i).widget().setParent(None)

        width, height = self.get_drawers_size()
        self.draw_widget.setGeometry(100, 0, width * 32, height * 32)

        for h in range(height):
            for w in range(width):

                label = QLabel()
                label.setFixedSize(32, 32)
                self.draw_grid.addWidget(label, h, w)

        self.render_all()

Calling setup_drawers later does just what I need. Cleanup method is from this answer and I'm not sure that this is safe, but if I change it to .deleteLater() then after second reload app crashes with
Process finished with exit code -1073740791 (0xC0000409) (no traceback or something)