PyQt4 - QLayout 间距的模糊性

0 投票
2 回答
3896 浏览
提问于 2025-04-17 08:46

我有一个QHBoxLayout,我一个一个地往里面添加小部件。
我交替添加一个自定义小部件和一个QLabel(重复这个过程)。
这个QHBoxLayout是属于一个QGroupBox的。

不过,我注意到当添加的小部件不多时,自定义小部件和QLabel之间的间距是“不规则”的。

我希望QLabel能在自定义小部件之间的空隙中居中,但只有在添加更多小部件时,QLabel才会靠近中心。

这些截图展示了两种情况。
理想的情况(只有在布局中有很多小部件时才会出现),
和不理想的情况(当布局中小部件不多时出现)。

底部情况间距不规则,顶部情况正常。

在底部的情况中,你可以看到QLabel并没有在自定义小部件之间居中。相反,它们偏得很远,靠右边!

是什么导致了这种情况呢?

我认为QGroupBox是水平居中的,而QLabel的宽度是固定的(10像素或20像素用于'->'的QLabel),这样可以避免重叠。

任何帮助都非常感谢!
谢谢!

规格:
python 2.7.1
PyQt4
Windows 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)

编辑:

设置QLabel的固定宽度(tmp.setFixedWidth(10))是导致“右对齐”的原因。
但是,不设置固定宽度会导致布局中QLabel和自定义小部件占用相同的空间,导致QLabel和自定义小部件重叠。

固定宽度标签与布局调节宽度的对比

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

我该怎么做才能避免这种情况,而不是完全糟糕的解决方案?
我可以把标签“往后移”吗?
(在所有自定义小部件添加到布局后调用.raise_()并没有奏效)

(或者我需要根据布局中小部件的数量手动计算标签的适当宽度吗?真糟糕!)

另一个编辑:

进展:

我没有改变QLabel的最大/最小(或固定)宽度,但我把它们的对齐方式设置为居中。
相反,我设置了自定义小部件的最小宽度。
这解决了明显的“重叠”(其实并不是真的重叠),让标签看起来“更居中”。

不过,如你所见,QLabel仍然没有完全居中——偏得太远右边了。
如果我不把QLabel的对齐方式设置为居中,它们又偏得太左了。

现在可能是什么问题呢?

重叠问题解决了,但对齐仍然是个问题

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

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

2 个回答

2

这里有一个简单的示例脚本,它大致模拟了问题中的用户界面,但没有任何布局上的问题:

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_())
0

解决所有问题的方法:

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

这样就能让小部件完美居中,不会出现“重叠”的情况。
:)

谢谢大家的帮助!

撰写回答