Moving child widgets between QTabWidgets?

Matic Kukovec kukovecmatic at hotmail.com
Wed Jan 18 13:48:58 GMT 2023


Hi Maurizio,

You are correct, I apologize for the mistakes.
I managed to get a self-contained example which throws the same error as my development code:

    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    from PyQt5.QtWidgets import *

    class MyWindow(QMainWindow):
        def __init__(self):
            super().__init__()
            splitter = QSplitter(self)
            self.setCentralWidget(splitter)

            # Frame & frame
            frame = QFrame(self)
            splitter.addWidget(frame)
            layout = QVBoxLayout()
            frame.setLayout(layout)

            # Button
            button = QPushButton("Switch")
            button.clicked.connect(self.switch)
            layout.addWidget(button)

            # Tab widget
            tab_widget = QTabWidget()
            layout.addWidget(tab_widget)
            self.tab_widget = tab_widget

            # Red
            w = QWidget(tab_widget)
            w.setStyleSheet("background: red;")
            tab_widget.addTab(w, "Red")

            # Green
            w = QWidget(tab_widget)
            w.setStyleSheet("background: green;")
            tab_widget.addTab(w, "Green")

            # TreeView
            tv = QTreeView(tab_widget)
            tv.horizontalScrollbarAction(1)
            tv.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)
            tree_model = QStandardItemModel()
            tree_model.setHorizontalHeaderLabels(["TREE EXPLORER"])
            tv.header().hide()
            tv.setModel(tree_model)
            for i in range(100):
                item = QStandardItem("ITEM {}".format(i))

            tv.setUniformRowHeights(True)

            tab_widget.addTab(tv, "TreeView")

        def switch(self, *args):
            widgets = []
            old_tab_widget = self.tab_widget
            for i in reversed(range(old_tab_widget.count())):
                widgets.append((old_tab_widget.widget(i), old_tab_widget.tabText(i)))
                old_tab_widget.removeTab(i)

            for i in reversed(range(self.centralWidget().count())):
                self.centralWidget().widget(i).setParent(None)
            old_tab_widget = None
            self.tab_widget = None

            new_tab_widget = QTabWidget()
            for widget, tab_text in widgets:
                new_tab_widget.addTab(widget, tab_text) # <- ERROR THROWN HERE

            self.centralWidget().addWidget(new_tab_widget)
            self.tab_widget = new_tab_widget


    if __name__ == '__main__':
        import sys

        app = QApplication(sys.argv)
        w = MyWindow()

        w.resize(640, 480)
        w.show()

        sys.exit(app.exec_())

Matic

________________________________
From: Maurizio Berti <maurizio.berti at gmail.com>
Sent: Tuesday, January 17, 2023 10:25 PM
To: Matic Kukovec <kukovecmatic at hotmail.com>
Cc: PyQt at riverbankcomputing.com <pyqt at riverbankcomputing.com>
Subject: Re: Moving child widgets between QTabWidgets?

If it throws that error, it's because the widgets (or their parent) have been deleted.
Unfortunately, your code is insufficient to actually understand where the issue is, and, by the way, it also has important issues: first of all the second for loop is wrong (new_tab_widget is a widget, so that will throw an exception), and using removeTab with the number of a counter is wrong, as you'll always get even numbered items, if you want to remove all widgets, always use removeTab(0).
I suggest you to provide a valid minimal reproducible example.

Maurizio

Il giorno mar 17 gen 2023 alle ore 14:11 Matic Kukovec <kukovecmatic at hotmail.com<mailto:kukovecmatic at hotmail.com>> ha scritto:
HI,

What is the PyQt idiomatic way of moving a widget from one QTabWidget to another?
I have tried this:

widgets = []
for i in range(old_tab_widget.count()):
    widgets.append((old_tab_widget.widget(i), old_tab_widget.tabText(i)))
    old_tab_widget.removeTab(i)

for widget, tab_text in new_tab_widget:
    new_tab_widget.addTab(widget, tab_text)

but this throws errors for example for QTreeView widgets like this:
...
    new_tab_widget.addTab(widget, tab_text)
RuntimeError: wrapped C/C++ object of type TreeExplorer has been deleted
(TreeExplorer is my subclassed QTreeView)

Thanks
Matic


--
È difficile avere una convinzione precisa quando si parla delle ragioni del cuore. - "Sostiene Pereira", Antonio Tabucchi
http://www.jidesk.net
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20230118/0cab9d8c/attachment-0001.htm>


More information about the PyQt mailing list