Pyside2:QSplitter replaceWidget 未按预期工作

Pyside2: QSplitter replaceWidget not working as expected

我有一个 QSplitter,里面有两个小部件,我想更换其中一个:

import sys
from PySide2.QtWidgets import (QMainWindow, QApplication, 
    QVBoxLayout, QWidget, QSplitter, QTextEdit, QLabel)


class Example(QWidget):  
    def __init__(self):
        super().__init__()

        splitter = QSplitter()
        splitter.insertWidget(0, QLabel('test'))
        splitter.insertWidget(1, QTextEdit())

        print(splitter.count())  # prints 2
        splitter.replaceWidget(1, QLabel('something else'))
        print(splitter.count())  # prints 1

        self.layout = QVBoxLayout(self)
        self.layout.addWidget(splitter)


if __name__ == "__main__":
    app = QApplication()

    main = Example()
    main.show()

    sys.exit(app.exec_())

我对 replaceWidget 的理解是,它将用提供的小部件替换拆分器中索引 X 上的现有小部件。在上面的示例中,索引 0 上有一个 QLabel('test'),索引 1 上有一个 QTextEdit().

尝试替换索引 1 上的小部件后,我希望它是 QLabel('something else')。但似乎索引 1 上的小部件只是从查看替换操作前后的 count() 的输出中删除。

有人能看到这个问题吗?

这似乎是由 PySide2 中的错误引起的。调用 replaceWidget() 后计数应该是 2,但它是 1.

根据 docs for replaceWidget, the splitter should take ownership of the new widget and reparent it. But PySide seems to lose track of it somehow - so presumably it just gets garbage-collected. The same code run in PyQt5 works as expected, although the inserted widget still won't show up (because reparenting will always make a widget invisble)。解决这些问题的方法是确保小部件在将其插入拆分器之前具有父级,然后在其上调用 show()

    label = QLabel('something else', self)

    print(splitter.count())
    splitter.replaceWidget(1, label)
    print(splitter.count())

    label.show()

这对我来说在 PySide2 (5.15.2) 和 PyQt5 (5.15.2) 中都能正常工作。