如何对齐几个HBoxLayouts中包含的小部件?

时间:2017-01-19 00:09:09

标签: python python-3.x pyqt pyqt5

让我们考虑一下这个小片段:

import sys

from PyQt5 import QtWidgets
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QStandardItem
from PyQt5.QtGui import QStandardItemModel
from PyQt5.QtWidgets import QHBoxLayout
from PyQt5.QtWidgets import QLabel
from PyQt5.QtWidgets import QLineEdit
from PyQt5.QtWidgets import QTreeView
from PyQt5.QtWidgets import QWidget


class PropertiesWidget(QTreeView):

    def __init__(self, columns, *args, **kwargs):
        super(PropertiesWidget, self).__init__(*args, **kwargs)

        self.model = QStandardItemModel(self)
        self.setModel(self.model)
        self.model.setColumnCount(columns)
        self.model.setHeaderData(0, Qt.Horizontal, "Property")
        self.model.setHeaderData(1, Qt.Horizontal, "Value")
        self.setFocusPolicy(Qt.NoFocus)
        self.last_item = 0
        self.last_item = QStandardItem()
        self.parameters = {}

    def begin_group(self, name, key):
        root = QStandardItem(name)
        root.setEditable(False)
        if not key:
            root.setData(key)
        self.model.appendRow([root])
        self.last_item = root

    def end_group(self):
        if (self.last_item and self.last_item.parent()):
            self.last_item = self.last_item.parent()

    def append_row(self, text, widget):
        if not self.last_item:
            return

        if text in self.parameters:
            raise Exception("Not allowed duplicate keys {0}".format(text))

        item = self.last_item
        child = QStandardItem(text)
        child2 = QStandardItem()
        child.setEditable(False)
        item.appendRow([child, child2])
        if widget:
            self.setIndexWidget(child2.index(), widget)

        self.expand(child.index().parent())

    def add_vec2(self, key, value):
        x = QLineEdit(value, self)
        y = QLineEdit(value, self)

        lbl = QLabel('')
        lbl.setMinimumWidth(0)
        lbl2 = QLabel('')
        lbl2.setMinimumWidth(0)

        layout = QHBoxLayout(self)
        layout.addWidget(x, stretch=1)
        layout.addWidget(y, stretch=1)
        layout.addWidget(lbl, stretch=1)
        layout.addWidget(lbl2, stretch=1)
        layout.setContentsMargins(0, 0, 0, 0)

        widget = QWidget(self)
        widget.setLayout(layout)

        setattr(widget, "operator_key", key)
        self.append_row(key, widget)

    def add_vec3(self, key, value):
        x = QLineEdit(value, self)
        y = QLineEdit(value, self)
        z = QLineEdit(value, self)

        lbl = QLabel('')
        lbl.setMinimumWidth(0)

        layout = QHBoxLayout(self)
        layout.addWidget(x, stretch=1)
        layout.addWidget(y, stretch=1)
        layout.addWidget(z, stretch=1)
        layout.addWidget(lbl, stretch=1)
        layout.setContentsMargins(0, 0, 0, 0)

        widget = QWidget(self)
        widget.setLayout(layout)

        setattr(widget, "operator_key", key)
        self.append_row(key, widget)

    def add_vec4(self, key, value):
        x = QLineEdit(value, self)
        y = QLineEdit(value, self)
        z = QLineEdit(value, self)
        w = QLineEdit(value, self)

        layout = QHBoxLayout(self)
        layout.addWidget(x, stretch=1)
        layout.addWidget(y, stretch=1)
        layout.addWidget(z, stretch=1)
        layout.addWidget(w, stretch=1)
        layout.setContentsMargins(0, 0, 0, 0)

        widget = QWidget(self)
        widget.setLayout(layout)

        setattr(widget, "operator_key", key)
        self.append_row(key, widget)


def main():
    app = QtWidgets.QApplication(sys.argv)
    ex = PropertiesWidget(2)
    ex.begin_group("foo", "foo")
    ex.add_vec2("vec2", "vec2_value")
    ex.add_vec3("vec3", "vec3_value")
    ex.add_vec4("vec4", "vec4_value")
    ex.end_group()

    ex.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

如果我运行它并扩展小部件,我们会看到所有的线条在每一行都正确对齐:

enter image description here

但是,如果我缩小它,小部件将不同的大小,如下:

enter image description here

我如何保证无论您如何调整窗口小部件的大小,所有 lineedits都具有相同的大小并且它们将相互对齐?我已经尝试过使用setMinimumWidth(100),但不会这样做。

3 个答案:

答案 0 :(得分:2)

来自#pyqt(freenode)频道的

@Avaris 给了我正在寻找的解决方案,主要技巧是在QLineEdits上正确使用QSizePolicy并清空QLabel,类似这样{{1}会做的伎俩。对于一个完整的工作示例,这里有一个小片段:

setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Expanding)

答案 1 :(得分:-1)

Actualy你的布局没有相同数量的项目。这就是为什么。每一行""你必须拥有相同的长度但具有不同数量的物品。所以当你把它做得更小时,空间会被里面的物品分开。

为了快速解决方法,您可以尝试添加"隐形"像布局的垫片之类的项目,因此每行中的项目总和可以相同

答案 2 :(得分:-3)

您可以使用Tkinter来执行此操作。它更简单,并将保持一切与其网格功能一致! (只需确保为每个盒子设置x偏移!)

Import tkinter

root = tk.Tk() # Some versions of python throw tantrums when you don't do this
root.geometry(...) #Like so: root.geometry("400x400")
#to make this easy I'll only do one box.
"""
The grid feature of tkinter allows you to grid-align boxes to a page.
By just simply asking if root.geometry is less than ... then realign to a new grid.
"""
Entry = tkinter.Entry(root, background = "...") #Use Entry.get() feature to gather what's been written as a value called ans if u want to do this.
#More entries down here.....
Entry.grid(row = 2, column = 2) #Edit row and column for where to grid it.
root.mainloop() # Required by tkinter in order to run.