首页 > 解决方案 > 如何将单列 QVBoxLayout 修改为多列?

问题描述

我有一列自动生成的按钮,如果有太多,可以挤压窗口中的 UI 元素。因此,我想通过以下方式自动将单列按钮(名义上在QVBoxLayout称为内部的按钮)self.main_layout转换为多列事件:

我的尝试只是导致按钮停留在单列中,但现在甚至不调整大小以填充QSplitter它们占据的框架:

app = QApplication(sys.argv)
window = TestCase()
app.exec_()

class TestCase(QMainWindow):
    def __init__(self):
        super().__init__()
        test = QWidget()
        self.layout = QVBoxLayout()
        test.setLayout(self.layout)
        for i in range(10):
            temp_btn = QPushButton(str(i))
            temp_btn.pressed.connect(self.multi_col)
            self.layout.addWidget(temp_btn)
        self.setCentralWidget(test)

    @pyqtSlot()
    def multi_col(self):
        cols = [QVBoxLayout(), QVBoxLayout()]
        while self.layout.count():
            child = self.layout.takeAt(0)
            if child.widget():
                self.layout.removeItem(child)
                cols[0].addItem(child)
                cols[1], cols[0] = cols[0], cols[1]
        self.layout = QHBoxLayout()
        self.layout.addLayout(cols[0])
        self.layout.addLayout(cols[1])

我在这里做错了什么明显的事情吗?

标签: pythonpyqtautoresizeqvboxlayoutqboxlayout

解决方案


将另一个对象分配给存储另一个布局引用的变量,替换 QWidget 的布局并不是那么简单。在几行代码中,您正在执行以下操作:

self.layout = Foo()
widget.setLayout(self.layout)
self.layout = Bar()

对象与变量不同,对象本身是执行动作的实体,而变量只是存储对象引用的地方。例如,对象可以是人和变量我们的名字,所以如果他们改变我们的名字并不意味着他们改变了我们作为一个人。

解决方案是使用 sip.delete 删除 QLayout,然后设置新布局:

import sys

from PyQt5.QtCore import pyqtSlot
from PyQt5.QtWidgets import (
    QApplication,
    QHBoxLayout,
    QMainWindow,
    QPushButton,
    QVBoxLayout,
    QWidget,
)
import sip


class TestCase(QMainWindow):
    def __init__(self):
        super().__init__()
        test = QWidget()
        self.setCentralWidget(test)

        layout = QVBoxLayout(test)
        for i in range(10):
            temp_btn = QPushButton(str(i))
            temp_btn.pressed.connect(self.multi_col)
            layout.addWidget(temp_btn)

    @pyqtSlot()
    def multi_col(self):
        cols = [QVBoxLayout(), QVBoxLayout()]
        old_layout = self.centralWidget().layout()

        while old_layout.count():
            child = old_layout.takeAt(0)
            widget = child.widget()
            if widget is not None:
                old_layout.removeItem(child)
                cols[0].addWidget(widget)
                cols[1], cols[0] = cols[0], cols[1]
        sip.delete(old_layout)
        lay = QHBoxLayout(self.centralWidget())
        lay.addLayout(cols[0])
        lay.addLayout(cols[1])


def main():
    app = QApplication(sys.argv)
    window = TestCase()
    window.show()
    app.exec_()


if __name__ == "__main__":
    main()

推荐阅读