嵌套布局... 绘制为堆叠而非分层

1 投票
1 回答
622 浏览
提问于 2025-04-18 17:41

好的……我有点搞不明白。我想创建一个对话框,这个对话框里面有一个GridLayout,里面放了一些复选框(CheckBox),然后在下面有一个接受(Accept)和关闭(Close)的按钮,这些按钮放在一个HBoxLayout里。但是用我下面的代码,结果我只看到GridLayoutHBoxLayout的上面。为什么会这样呢?我该怎么调整对话框的宽度,让它和GridLayout一样宽呢?

class CheckerDialog(QtGui.QDialog) :

    def __init__(self, parent, headers) :
        super(CheckerDialog, self).__init__(parent)

        checksLayout = QtGui.QGridLayout()
        self.cbList = []
        i  = 0
        for y in range(13):
            for x in range (9):
                if i == len(headers) : break
                cb = QtGui.QCheckBox(headers[i], self)
                cb.move(OFFSET_X + SPACER_X*x, OFFSET_Y + SPACER_Y*y)
                self.cbList.append(cb)
                i += 1

        buttonLayout = QtGui.QHBoxLayout()
        applyButton = QtGui.QPushButton("Apply")
        closeButton = QtGui.QPushButton("Close")
        buttonLayout.addWidget(applyButton)        
        buttonLayout.addWidget(closeButton)
        self.connect(applyButton, QtCore.SIGNAL('clicked()'), self._apply)
        self.connect(closeButton, QtCore.SIGNAL('clicked()'), self.close)

        checkerLayout = QtGui.QVBoxLayout()
        checkerLayout.addLayout(buttonLayout)
        checkerLayout.addLayout(checksLayout)

1 个回答

0
  1. HBoxLayout 是在 GridLayout 之上,而不是在下面。

没错,这个顺序在你的代码中是很重要的。代码的顺序会影响最终的效果。

    checkerLayout.addLayout(buttonLayout) # <- TOP
    checkerLayout.addLayout(checksLayout) # <- BOTTOM

如果你想按照指定的索引来放置控件,可以使用 QBoxLayout.insertLayout (self, int index, QLayout layout, int stretch = 0) 这个方法。

    checkerLayout.insertLayout(1, buttonLayout) # <- BOTTOM
    checkerLayout.insertLayout(0, checksLayout) # <- TOP

  1. 而且,GridLayout 的大小并不会控制整体布局的大小。

没错,这一点在你的代码中也很重要。因为你并没有把复选框放在 QGridLayout 中。你只是设置了根布局的几何形状,而不是 QGridLayout。请使用 QGridLayout.addWidget (self, QWidget, int row, int column, Qt.Alignment alignment = 0) 来按照指定的索引 (x, y) 添加控件。

这里有个简单的例子:

import sys
from PyQt4 import QtGui

class QCheckerDialog (QtGui.QDialog):
    def __init__ (self, parent = None) :
        super(QCheckerDialog, self).__init__(parent)

        checkBoxQGridLayout = QtGui.QGridLayout()
        for y in range(13):
            for x in range(9):
                currentQCheckBox = QtGui.QCheckBox('%d, %d' % (x, y))
                currentQCheckBox.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum))
                checkBoxQGridLayout.addWidget(currentQCheckBox, x, y)

        buttonQHBoxLayout  = QtGui.QHBoxLayout()
        applyQPushButton = QtGui.QPushButton('Apply')
        closeQPushButton = QtGui.QPushButton('Close')
        buttonQHBoxLayout.addWidget(applyQPushButton)        
        buttonQHBoxLayout.addWidget(closeQPushButton)

        allQVBoxLayout = QtGui.QVBoxLayout()
        allQVBoxLayout.insertLayout(1, buttonQHBoxLayout)
        allQVBoxLayout.insertLayout(0, checkBoxQGridLayout)
        self.setLayout(allQVBoxLayout)

myQApplication = QtGui.QApplication(sys.argv)
myQQCheckerDialog = QCheckerDialog()
myQQCheckerDialog.show()
sys.exit(myQApplication.exec_())

另外,你可以参考以下链接:

QBoxLayout.insertLayout (self, int index, QLayout layout, int stretch = 0) 参考文档

QGridLayout.addWidget (self, QWidget, int row, int column, Qt.Alignment alignment = 0) 参考文档

撰写回答