【问题标题】:PyQt4 - Ambiguity in QLayout SpacingPyQt4 - QLayout 间距中的歧义
【发布时间】:2012-01-25 06:26:21
【问题描述】:

我有一个 QHBoxLayout,我会一一添加小部件。
我通过添加自定义小部件而不是 QLabel(重复)来替代。
QHBoxLayout 归 QGroupBox 所有。

但是,我注意到当布局中添加的小部件很少时,自定义小部件和 QLabel 之间的间距是“不规则的”。

我打算让 QLabels 在自定义小部件之间的间隙中居中,但 QLabels 只会在添加更多小部件时接近中心。

这些屏幕截图显示了这两种情况。
所需的情况(仅在布局中有很多小部件时发生),
以及不受欢迎的情况(当布局中有小部件时发生)。

正如您在底部案例中看到的那样,QLabels 不在自定义小部件之间居中。相反,它们非常靠右!

是什么导致了这种行为??

我相信 QGroupBox 具有居中(水平)对齐方式,并且 QLabel 的固定宽度为 10(对于 '->' QLabel 为 20)像素(以避免难看的重叠)。

任何帮助都将不胜感激!
谢谢!

规格:
python 2.7.1
PyQt4
视窗 7

QHBoxLayout 的实例化是绝对正常的,并且与所有示例类似。
这是填充布局的代码。

for i in range (0,len(Reactants)):

    self.WidgetHouse.Reaction_Element_Layout.addWidget(eval('self.OverallContainer_Reactants.Reactant_'+str(i)))

    # self.WidgetHouse.Reaction_Element_Layout           is the QHBoxLayout
    # self.OverallContainer_Reactants.Reactant_'+str(i)       is a Custom Widget

    if i != (len(Reactants)-1):
        tmp = QtGui.QLabel('+')
        tmp.setFixedWidth(10)
        tmp.setAlignment(QtCore.Qt.AlignCenter)
        self.WidgetHouse.Reaction_Element_Layout.addWidget(tmp)

    else:
        tmp = QtGui.QLabel('->')
        tmp.setFixedWidth(20)
        tmp.setAlignment(QtCore.Qt.AlignCenter)
        self.WidgetHouse.Reaction_Element_Layout.addWidget(tmp)

编辑:

设置 QLabels 的固定宽度 (tmp.setFixedWidth(10)) 是“右锚定”的来源。
但是,不设置固定宽度会导致布局中的 QLabels 和自定义小部件专用的空间相同,从而导致 QLabels 和自定义小部件重叠。

与上面的代码相同,但不包括 'tmp.setFixedWidt(10)'

我能做些什么来防止这种不完全可怕的事情发生?
我可以将标签从前面“向后”移动吗?
(将所有内容添加到布局后,对所有自定义小部件调用 .raise_(​​) 不起作用)

(或者我是否必须根据布局中小部件的数量手动计算标签的适当宽度?太糟糕了!)

另一个编辑:

进展:

我不会更改 QLabel 的最大/最小(或固定)宽度,但我确实将它们的对齐方式设置为居中。
相反,我设置了自定义小部件的最小宽度。
这修复了明显的“重叠”(实际上并非如此)并使标签看起来“更居中”。

但是,如您所见,QLabels 仍然没有完全居中 - 太靠右了。
如果我没有在 QLabels 上设置中心对齐,它们就太左了。

现在可能是什么问题?

(我没有在标签上设置最大宽度)

感谢到目前为止所有的帮助!

【问题讨论】:

  • 有一个类似于expanding 的属性来控制调整大小的行为。您可能想围绕它玩一下 Qt 设计师。
  • 我不确定这意味着什么。它是 QProperty,还是特定 Widget 的属性(即:布局还是 QLabel?)?
  • 这是您的小部件的属性 - 我希望标签和您的自定义小部件。哦,它叫sizePolicy——我的错。
  • 您的解释中一定缺少某些内容,因为我无法在 Linux 或 Windows 上重现这一点。根据您显示的代码,第二张图片没有意义,因为小部件应该自动调整大小以填充可用空间。无需固定标签的宽度,或更改任何小部件的大小策略。我最好的猜测是自定义小部件的右侧有一个多余的间隔项。
  • 没有任何间隔项目! :( 我不得不修复标签的宽度,因为如果我不这样做,当布局变得非常填充时,QLabels 开始与自定义小部件重叠(什么都没有,因为 QLabel 的几何形状大于文本? )。

标签: python layout pyqt pyqt4 spacing


【解决方案1】:

这是一个简单的示例脚本,它是问题中 UI 的合理近似值,但没有任何布局问题:

from PyQt4 import QtGui, QtCore

class Window(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.groupBox = QtGui.QGroupBox(self)
        hbox = QtGui.QHBoxLayout(self.groupBox)
        length = 3
        for index in range(length):
            hbox.addWidget(Widget(u'H\u2082O', self))
            if index < length - 1:
                hbox.addWidget(Label(u'+', self))
            else:
                hbox.addWidget(Label(u'\u2192', self))
        hbox.addWidget(Widget(u'4 H\u2082O', self))
        hbox.addWidget(Label(u'+', self))
        hbox.addWidget(Widget(u'H\u2084O\u2082', self))
        vbox = QtGui.QVBoxLayout(self)
        vbox.addWidget(self.groupBox)
        vbox.addStretch()

class Label(QtGui.QLabel):
    def __init__(self, label, parent=None):
        QtGui.QLabel.__init__(self, label, parent)
        self.setAlignment(QtCore.Qt.AlignCenter)

class Widget(QtGui.QWidget):
    def __init__(self, label, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.setMaximumWidth(100)
        layout = QtGui.QGridLayout(self)
        self.label = QtGui.QLabel(label, self)
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        layout.addWidget(self.label, 0, 0, 1, 2)
        self.lineEdit = QtGui.QLineEdit(self)
        layout.addWidget(self.lineEdit, 1, 0, 1, 2)
        self.toolButton = QtGui.QToolButton(self)
        layout.addWidget(self.toolButton, 2, 0, 1, 1)
        self.comboBox = QtGui.QComboBox(self)
        layout.addWidget(self.comboBox, 2, 1, 1, 1)

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

【讨论】:

  • 代码中的差异(实际上是导致此错误的原因)是我在我的 QLabels 上设置了固定宽度(正如 ekhumoro 所避免的那样)。这就是奇怪的“右侧锚定”的原因。但是,不设置固定宽度会导致其自身的问题(重叠)。我会发布一张图片并编辑 OP。
  • 我注意到您设置了两次标签的对齐方式。一次在子类中,再次在超类中。这会影响重叠吗?
  • @AntiEarth。在我的例子中,如果Label 类被赋予一个固定的宽度,它只是增加了一些额外的间距;没有重叠或任何其他意想不到的效果。恐怕我根本不明白你的第二条评论:对齐没有设置两次,也没有调用super。您是否将Widget 类中的标签与Label 类混淆了?至于您发布的新图片:这很有帮助,但我认为解决此问题的唯一实用方法是发布一些演示问题的代码(或ui 文件)。
  • 抱歉,我混淆了标签。我再次编辑了 OP,但仍有进展。
【解决方案2】:

解决所有问题:

给自定义小部件一个固定的宽度。

结果是完全居中,而不是“重叠”小部件。
:)

感谢大家的帮助!

【讨论】:

  • 或者只给它们一个最大宽度,就像我在示例脚本中所做的那样;-)
猜你喜欢
  • 1970-01-01
  • 2015-07-14
  • 2011-09-17
  • 2015-11-04
  • 2016-04-19
  • 2012-11-02
  • 2023-04-06
  • 2021-12-24
  • 2016-02-10
相关资源
最近更新 更多