PyQt4 - неоднозначность в интервале QLayout

У меня есть QHBoxLayout, в который я добавляю виджеты один за другим.
Я чередую, добавляя пользовательский виджет, а не QLabel (повторяющийся).
QHBoxLayout принадлежит QGroupBox.

Однако я заметил, что расстояние между Custom Widget и QLabel является «нерегулярным», когда в макет добавлено несколько виджетов.

Я предполагаю, что QLabels будет центрироваться в промежутке между пользовательскими виджетами, но QLabels приближаются к центру только по мере добавления новых виджетов.

На этих снимках экрана показаны два случая.
Желаемый случай (только при большом количестве виджетов в макете),
и нежелательный случай (возникающий, когда в макете есть маленькие виджеты).

Нерегулярный интервал в нижнем регистре, тонкий в верхнем.

Как вы можете видеть в нижнем регистре, метки QLabel не расположены по центру между пользовательскими виджетами. Вместо этого они очень далеко вправо!

Что вызывает такое поведение ??

Я считаю, что QGroupBox имеет центрированное (горизонтальное) выравнивание, а QLabels имеют фиксированную ширину 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)

РЕДАКТИРОВАТЬ:

Установка фиксированной ширины QLabels (tmp.setFixedWidth (10)) является источником «правильной привязки».
Однако не установка фиксированной ширины приводит к тому, что одно и то же пространство выделяется для QLabels и Custom Widgets в макете , что приводит к перекрытию QLabels и Custom Widgets.

Ярлыки фиксированной ширины против модулированной ширины макета

Идентично приведенному выше коду, исключая tmp.setFixedWidt (10)

Что я могу сделать, чтобы предотвратить это, что не совсем ужасно?
Могу ли я переместить метки «назад» спереди?
(Вызов .raise_ () для всех настраиваемых виджетов после того, как все было добавлено в макет, не Работа)

(Или мне придется делать что-то вроде ручного расчета подходящей ширины меток в зависимости от количества виджетов в макете? Фу!)

ДРУГОЕ ИЗМЕНЕНИЕ:

Прогресс:

Я не меняю максимальную / минимальную (или фиксированную) ширину QLabels, но я устанавливаю их выравнивание по центру.
Вместо этого я устанавливаю минимальную ширину настраиваемого виджета.
Это устраняет очевидное «перекрытие» '(что на самом деле было не так) и делает ярлыки более центрированными.

Однако, как вы можете видеть, QLabels все еще не идеально отцентрованы - слишком далеко вправо.
Если я не установлю выравнивание по центру на QLabels, они будут слишком далеко влево.

В чем может быть проблема сейчас ??

Перекрытие решено, проблема с привязкой все еще существует

(Я не устанавливаю максимальную ширину на этикетках)

Спасибо за помощь, ребята!


person Anti Earth    schedule 21.12.2011    source источник
comment
Есть свойство, называемое чем-то вроде expanding, которое управляет изменением размера. Возможно, вы захотите поиграть с ним в Qt Designer.   -  person Thomas K    schedule 21.12.2011
comment
Я не понимаю, что это значит. Это QProperty или свойство определенного виджета (например, макета или QLabel?)?   -  person Anti Earth    schedule 21.12.2011
comment
Это свойство ваших виджетов - я полагаю, как ярлыков, так и ваших пользовательских виджетов. Ах да, это называется sizePolicy - моя ошибка.   -  person Thomas K    schedule 21.12.2011
comment
Должно быть, в вашем объяснении чего-то не хватает, потому что я не могу воспроизвести это ни в Linux, ни в Windows. Второе изображение не имеет смысла на основе кода, который вы показали, потому что виджеты должны просто автоматически изменять свой размер, чтобы заполнить доступное пространство. Не должно быть необходимости фиксировать ширину меток или изменять политику размера любого из виджетов. Я предполагаю, что с правой стороны пользовательских виджетов есть лишний разделитель.   -  person ekhumoro    schedule 21.12.2011
comment
Никаких проставок нет! :( Мне пришлось исправить ширину меток, потому что, если я этого не сделаю, когда макет станет довольно заполненным, QLabels начнут перекрывать пользовательские виджеты (ни с чем, поскольку геометрия QLabel больше текста? ).   -  person Anti Earth    schedule 22.12.2011
comment
@AntiEarth. Я добавил ответ, который показывает один из возможных способов размещения виджетов без каких-либо проблем, которые вы описываете. Итак, какие существенные различия между моим скриптом и вашим реальным дизайном пользовательского интерфейса?   -  person ekhumoro    schedule 22.12.2011


Ответы (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_())
person ekhumoro    schedule 22.12.2011
comment
Разница в кодах (которая на самом деле вызывает эту ошибку) заключается в том, что я установил фиксированную ширину на своих QLabels (как ускользнул ekhumoro). Это причина странного «закрепления с правой стороны». Однако отсутствие фиксированной ширины приводит к собственным проблемам (перекрытию). Я выложу картинку и отредактирую ОП. - person Anti Earth; 24.12.2011
comment
Я заметил, что вы дважды установили выравнивание метки. Один раз в подклассе и еще раз в супер. Повлияет ли это на перекрытие? - person Anti Earth; 24.12.2011
comment
@AntiEarth. В моем примере, если классу Label присвоена фиксированная ширина, он просто добавляет некоторый дополнительный интервал; нет перекрытия или каких-либо других неожиданных эффектов. Боюсь, что совсем не понимаю вашего второго комментария: выравнивание не выставлено дважды, и нет вызова super. Вы путаете метку в классе Widget с классом Label? Что касается опубликованных вами новых изображений: это полезно, но я думаю, что единственный практический способ решить эту проблему - опубликовать код (или файл ui), демонстрирующий проблему (ы). - person ekhumoro; 24.12.2011
comment
Извините, я перепутал ярлыки. Я снова отредактировал OP с прогрессом. - person Anti Earth; 25.12.2011

Решение всех проблем:

Задайте настраиваемым виджетам фиксированную ширину.

Результат - идеально центрированные виджеты без "перекрытия".
:)

Спасибо за всю помощь, ребята!

person Anti Earth    schedule 26.12.2011
comment
Или просто задайте им максимальную ширину, как я сделал в моем примере скрипта ;-) - person ekhumoro; 26.12.2011