0

I'm having trouble changing the parent of the widgets added directly to a frame on PyQt5

I have a grid of frames positioned in another frame without layout, this is because I need a free positioning mechanism instead of the girdLayout.

This is my process:

  1. on a For Loop I Create multiple ClusterFrames and setParent(gridFrameContainer)
  2. Create the widgets, buttons and labels for each ClusterFrame

Everything works ok, all the ClusterFrames are displayed, resized and repositioned when I use ClusterFrame[i].setGeometry

The problem is when I need to remove a ClusterFrame[i] from the frame, as you might know, it's very hard to delete a widget if I don't have a layout.

I've tried ClusterFrame[i].close(), ClusterFrame[i].deletelater del(ClusterFrame[i])...

Since nothing has worked for me, what I do is:

  1. Create a topFrame
  2. Create a stacked Layout for topFrame
  3. Create gridFrameContainer
  4. Add gridFrameContainer to stacked Layout
  5. on a For Loop I Create multiple ClusterFrames and setParent(gridFrameContainer)
  6. Create the widgets, buttons and labels for each ClusterFrame

Here works ok, no problems here.

When I want to change the quantity of ClusterFrames

  1. On a For Loop I change the parent of each ClusterFrames as ClusterFrames[i].setParent(None or MainWindow)
  2. On the StackedLayout I delete the current gridFrameContainer
  3. On the StackedLayout I add a NewGridFrameContainer
  4. On a For Loop I change the parent of each ClusterFrames as ClusterFrames[i].setParent(NewGridFrameContainer)

But they're not displayed anymore.

It seems like I can only set the Parent once, is that right? if so, the I need to delete each ClusterFrame and create it again?

When I create the widgets of ClusterFrames, I set the parent only of the frame, but never of each widget of the cluster like buttons, labels, I suppose that they belongs to the ClusterFrame parent right?

If I change the parent of the frame ClusterFrame, should I change the parent of his widgets?

Thanks

Here's an example: (Press the button to change the parent)

import sys
from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow
from PyQt5 import QtWidgets
class MainWindow(QMainWindow):

    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        self.setWindowTitle("My Awesome App")
        self.showMaximized()
        self.stackedFrames = QtWidgets.QFrame()
        self.stacked_frames_layout = QtWidgets.QStackedLayout()
        self.clustersFrame = QtWidgets.QFrame()  # Disposable each time I need to delete clusters
        other_frame = QtWidgets.QFrame()  # I have multiple frames for other purposes
        and_other_frame = QtWidgets.QFrame()  # I have multiple frames for other purposes

        self.stacked_frames_layout.addWidget(self.clustersFrame)
        self.stacked_frames_layout.addWidget(other_frame)
        self.stacked_frames_layout.addWidget(and_other_frame)

        self.stackedFrames.setLayout(self.stacked_frames_layout)

        # Create 10 clusters
        self.clusters = []
        for i in range(10):
            cluster = QtWidgets.QFrame()
            cluster.setParent(self.clustersFrame)
            layout = QtWidgets.QVBoxLayout()
            label = QLabel("Cluster {}".format(i))
            layout.addWidget(label)
            cluster.setLayout(layout)
            self.clusters.append(cluster)

        # Set Geometry
        size = 100
        for i, cluster in enumerate(self.clusters):
            cluster.setGeometry(i * size + 10, 0, size, size)

        # Main frame
        button_to_test = QtWidgets.QPushButton()
        button_to_test.setText('Change grid')
        button_to_test.clicked.connect(self.change_quantity)

        layout = QtWidgets.QVBoxLayout()
        layout.addWidget(self.stackedFrames)
        layout.addWidget(button_to_test)

        mainFrame = QtWidgets.QFrame()
        mainFrame.setLayout(layout)
        self.setCentralWidget(mainFrame)

    def change_quantity(self):
        self.stacked_frames_layout.removeWidget(self.clustersFrame)
        self.clustersFrame = QtWidgets.QFrame()
        self.stacked_frames_layout.insertWidget(0, self.clustersFrame)
        self.stacked_frames_layout.setCurrentIndex(0)

        size = 110
        self.clusters = self.clusters[:8]
        for i, cluster in enumerate(self.clusters):
            cluster.setParent(self.clustersFrame)
            cluster.setGeometry(i * size + 10, 0, size, size)
app = QApplication(sys.argv)

window = MainWindow()

window.show()

app.exec_()
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
EinSoldiatGott
  • 63
  • 1
  • 11

0 Answers0