首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PyQt QGridLayout()不当行为

PyQt QGridLayout()不当行为
EN

Stack Overflow用户
提问于 2020-01-27 15:58:29
回答 2查看 617关注 0票数 0

我试图让GUI应用程序正常工作,但不幸的是,单个画布对象的间距并不像预期的那样。我希望有以下布局:

对于Grid布局,我使用以下代码:

代码语言:javascript
复制
# Adapt Widget StyleSheet
self.button_classification.setStyleSheet("font: bold 10pt Consolas; color: #009682")  # #009682 is the KIT-Green
self.button_start.setStyleSheet('font: bold 10pt Consolas; color: #009682; border-style: outset; border-width: 2px; border-radius: 10px; border-color: #646873; padding: 6px')
self.layout4_image_widget.setStyleSheet('background-image: url(Python_logo.png);')

# Define Layouts
self.window = QWidget()
self.layout = QGridLayout()

# Add Widgets to layouts
self.layout.addWidget(self.canvas_left, 0, 0, 5, 5)
self.layout.addWidget(self.canvas_right, 0, 5, 5, 5)
self.layout.addWidget(self.canvas_right_buttom, 8, 7, 3, 3)
self.layout.addWidget(self.canvas_right_top, 5, 7, 3, 3)
self.layout.addWidget(self.canvas_middle_buttom, 8, 3, 3, 4)
self.layout.addWidget(self.canvas_middle_top, 5, 3, 3, 4)
self.layout.addWidget(self.layout4_image_widget, 5, 0, 3, 3)
self.layout.addWidget(self.button_start, 8, 0, 1, 3)
self.layout.addWidget(self.button_classification, 9, 0, 1, 3)
self.layout.addWidget(self.LCD_Number, 10, 0, 1, 3)
self.window.setLayout(self.layout)

但不幸的是,我得到的结果是:

所以中间的5-7行是宽的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-27 21:40:08

对小部件使用列和行跨度并不像您所认为的那样有效。网格布局中的每个“单元”可能有不同的大小,这取决于每个小部件sizeHint和sizePolicy

所有小部件都有一个默认大小策略,这个属性是一个小部件用于告诉容器它在调整大小时的行为方式(如果它展开,有固定的高度/宽度,它可以收缩,等等)。

默认情况下,按钮和复选框具有固定的垂直策略,这意味着它们永远不会增长或收缩。

每个布局都有一个拉伸值,可以为每个“插槽”分配。扩展始终默认为0,这给每个小部件留下了增长或缩小以满足其需要的可能性,但当设置该值时,可用空间由布局中的每个扩展之和计算,然后等分。例如,如果您有一个包含两个小部件的简单布局,第一个和第二个有一个stretch=1,那么可用空间将被除以3 (1 + 2),其中第一个占据三分之一,第二个占三分之二。

对于网格布局,您可以使用setRowStretch()setColumnStretch()来实现您建议的目标,但是这只适用于具有兼容策略(首选或扩展)的小部件,而且在您的示例中,这些按钮的高度是固定的,这是不够的。

有两种可能性,但在这两种情况下,我将使用更简单的布局,因为出于上述原因,不需要使用高计数的行和列,因此可以使用setRowStretch/setColumnStretch

布局只使用4列:

代码语言:javascript
复制
+----+---+---+----+
|        |        |
+----+---+---+----+
|    |       |    |
+----+---+---+----+
|    |       |    |
+----+---+---+----+

第一行有两个具有2列跨度的“单元格”,下面的行将两个中央槽合并为一个具有类似跨度的单个单元格。

1.手动设置这些小部件的策略

在这种情况下,实际上有5行,第1行有rowStretch=5,第2行有3行,剩下的1行。通过手动将垂直大小策略设置为小部件,它们可以增长到它们所占据的行的长度所需的高度。

代码语言:javascript
复制
    # first row, notice the spans
    self.layout.addWidget(self.canvas_left, 0, 0, 1, 2)
    self.layout.addWidget(self.canvas_right, 0, 2, 1, 2)

    # second row, if the span is not specified defaults to (1, 1)
    self.layout.addWidget(self.layout4_image_widget, 1, 0)
    self.layout.addWidget(self.canvas_middle_top, 1, 1, 1, 2)
    self.layout.addWidget(self.canvas_right_top, 1, 3)

    # left widgets for third, fourth and fifth rows
    self.layout.addWidget(self.button_start, 2, 0)
    self.layout.addWidget(self.button_classification, 3, 0)
    self.layout.addWidget(self.LCD_Number, 4, 0)

    # remaining widgets, notice the vertical and horizontal spans
    self.layout.addWidget(self.canvas_right_buttom, 2, 1, 3, 2)
    self.layout.addWidget(self.canvas_middle_buttom, 2, 3, 3, 1)

    # the column stretches set based on the grid given by you
    self.layout.setColumnStretch(0, 3)
    self.layout.setColumnStretch(1, 2)
    self.layout.setColumnStretch(2, 2)
    self.layout.setColumnStretch(3, 3)

    # the row stretches, with the final 3 rows set to 1
    self.layout.setRowStretch(0, 5)
    self.layout.setRowStretch(1, 3)
    self.layout.setRowStretch(2, 1)
    self.layout.setRowStretch(3, 1)
    self.layout.setRowStretch(4, 1)

    # the default policy for both buttons and checkboxes is QSizePolicy.Minimum
    # horizontally, and QSizePolicy.Fixed vertically, let's just change the latter
    self.button_start.setSizePolicy(
        QSizePolicy.Minimum, QSizePolicy.Preferred)
    self.button_classification.setSizePolicy(
        QSizePolicy.Minimum, QSizePolicy.Preferred)

不幸的是,这并不完美:正如您所看到的那样,按钮可能变得太大,复选框中有许多不必要的空白,可以由LCD小部件代替。

2.使用容器部件

在本例中,只有3行,并将一个额外的QWidget用作左下角小部件的容器。

代码语言:javascript
复制
    self.layout.addWidget(self.canvas_left, 0, 0, 1, 2)
    self.layout.addWidget(self.canvas_right, 0, 2, 1, 2)

    self.layout.addWidget(self.layout4_image_widget, 1, 0)
    self.layout.addWidget(self.canvas_middle_top, 1, 1, 1, 2)
    self.layout.addWidget(self.canvas_right_top, 1, 3)

    # create a container widget and add it to the main layout
    self.container = QWidget()
    self.layout.addWidget(self.container, 2, 0)
    containerLayout = QVBoxLayout(self.container)

    # add the widgets to the container
    containerLayout.addWidget(self.button_start)
    containerLayout.addWidget(self.button_classification)
    containerLayout.addWidget(self.LCD_Number)

    # the remaining widgets on the third row
    self.layout.addWidget(self.canvas_right_buttom, 2, 1, 1, 2)
    self.layout.addWidget(self.canvas_middle_buttom, 2, 3)

    self.layout.setColumnStretch(0, 3)
    self.layout.setColumnStretch(1, 2)
    self.layout.setColumnStretch(2, 2)
    self.layout.setColumnStretch(3, 3)

    # there are only 3 rows, the second and third have the same row span
    self.layout.setRowStretch(0, 5)
    self.layout.setRowStretch(1, 3)
    self.layout.setRowStretch(2, 3)

在这种情况下,空间使用更加优化,为那些需要它的小部件( LCD)留出更多的空间。

票数 2
EN

Stack Overflow用户

发布于 2020-01-27 17:10:05

https://doc.qt.io/qtforpython/PySide2/QtWidgets/QGridLayout.html#PySide2.QtWidgets.PySide2.QtWidgets.QGridLayout.setRowStretch

也许这和这个功能有关..。正如他们所说,拉伸因子与行的相对占用空间有关,其默认值为0。您可以尝试将每一行设置为1。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59934650

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档