首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当展开布局时,不能使间隔器占据小部件之间的空白

当展开布局时,不能使间隔器占据小部件之间的空白
EN

Stack Overflow用户
提问于 2021-08-07 12:22:45
回答 2查看 357关注 0票数 0

我最近从PyQt5开始,现在正在尝试为一个应用程序编写一个接口。

我想有一个边栏与不同的工具,基本上是一个I/O面板在窗口底部。

这个I/O面板应该只包含2个QPushButtons - Ok and Cancel

当我改变应用程序窗口的大小时,右边的按钮(确定)应该停留在右下角,而左边的按钮(取消)在左下角,右边(但不是在下面)侧边栏。为了实现这一点,我在按钮之间添加了一个水平间隔。

然而,两个按钮始终保持在窗口的右下角.我使用过一些QSizePolicy参数,但它似乎什么也没做。唯一能得到我想要的东西的方法是将构造函数中的水平间隔宽度设置为非零值,但是我对这个解决方案并不满意。为了得到我想要的东西,我应该在下面的代码中修改什么?

代码语言:javascript
复制
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *

class Sidebar(QWidget):
    def __init__(self, parent=None):
        super().__init__()
        layout = QVBoxLayout()
        layout.addWidget(QPushButton(maximumWidth = 200, minimumHeight = 50))
        layout.addWidget(QPushButton(maximumWidth = 200, minimumHeight = 50))
        layout.addWidget(QPushButton(maximumWidth = 200, minimumHeight = 50))
        layout.addWidget(QPushButton(maximumWidth = 200, minimumHeight = 50))
        layout.addWidget(QPushButton(maximumWidth = 200, minimumHeight = 50))
        layout.addWidget(QPushButton(maximumWidth = 200, minimumHeight = 50))
        layout.addItem(QSpacerItem(200, 0, QSizePolicy.Maximum, QSizePolicy.Expanding))
        
        self.setLayout(layout)

        self.setMaximumWidth(200)
        sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Expanding)
        self.setSizePolicy(sizePolicy)
        layout.setSpacing(0)
        layout.setContentsMargins(0, 0, 0, 0)

class IOPanel(QWidget):
    def __init__(self, parent=None):
        super().__init__()
        layout = QHBoxLayout()
        layout.addWidget(QPushButton("Cancel", maximumWidth = 100, maximumHeight = 30), 0, Qt.AlignLeft)
        layout.addItem(QSpacerItem(0, 30, QSizePolicy.Expanding, QSizePolicy.Maximum))
        layout.addWidget(QPushButton("Ok", maximumWidth = 100, minimumHeight = 30), 0, Qt.AlignRight)
        
        self.setLayout(layout)

        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum)
        self.setSizePolicy(sizePolicy)

class Canvas(QWidget):
    def __init__(self, parent=None):
        super().__init__()
        layout = QVBoxLayout()
        panel = IOPanel()
        layout.addWidget(QWidget(), 0, Qt.AlignTop)
        layout.addWidget(panel, 0, Qt.AlignBottom)

        self.setLayout(layout)

        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.setSizePolicy(sizePolicy)

class Interface(QWidget):
    def __init__(self, parent=None):
        super().__init__()
        layout = QHBoxLayout()
        layout.addWidget(Sidebar(), 0, Qt.AlignLeft)
        layout.addWidget(Canvas(), 0, Qt.AlignRight)
        layout.setContentsMargins(0, 0, 0, 0)

        self.setLayout(layout)
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.setSizePolicy(sizePolicy)

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__()
        interface = Interface()
        self.setCentralWidget(interface)
    
def main():
    import sys
    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-08-07 14:03:41

您可以在您的接口小部件中将布局设置为QGridLayout。您可以使用行数和列数来适应您的设置/目标。

代码语言:javascript
复制
....
class Canvas(QWidget):
    def __init__(self, parent=None):
        super().__init__()
        layout = QVBoxLayout()
        #panel = IOPanel() # Remove IOPanel from Canvas widget add it to Main Interface
        layout.addWidget(QWidget(), 0, Qt.AlignTop)
        #layout.addWidget(panel, 0, Qt.AlignBottom)

        self.setLayout(layout)

        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.setSizePolicy(sizePolicy)

class Interface(QWidget):
    def __init__(self, parent=None):
        super().__init__()
        layout = QGridLayout()
        layout.addWidget(Sidebar(), 0, 0, 4, 1)
        layout.addWidget(Canvas(), 0, 1, 3, 3)
        layout.addWidget(IOPanel(), 3, 1, 3, 3)
        layout.setContentsMargins(0, 0, 0, 0)

        self.setLayout(layout)
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.setSizePolicy(sizePolicy)
票数 0
EN

Stack Overflow用户

发布于 2021-08-07 23:13:16

问题不在于布局的设置方式,而是由于使用了addWidget()的对齐参数:

对齐是由对齐指定的。默认的对齐是0,这意味着小部件填充整个单元格

这意味着指定对齐将不会使小部件填充整个单元,而是只填充其首选大小(sizeHint()返回的大小)。此外,由于您已经在侧栏中添加了一个间隔,并且按钮将位于画布垂直布局的底部,因此无论如何指定对齐都是不必要的。

因此,解决方案很简单:从addWidget()中删除所有不需要的参数(包括扩展,它已经默认为0):

代码语言:javascript
复制
class Interface(QWidget):
    def __init__(self, parent=None):
        # ...
        layout.addWidget(Sidebar())
        layout.addWidget(Canvas())

请注意,您可能也希望对addWidget()中的所有Canvas进行同样的操作。

其他考虑因素:

只要添加的布局允许,pointless;

  • boxed

  • QPushButton就会尝试展开;由于您已经为面板设置了最大宽度,因此也为按钮设置了

  • 布局,因此布局已经为间隔器(addStretch()addSpacing())提供了方便的函数,后者在内部自行创建QSpacerItems :您可以在需要在大小策略中设置高级方面的IOPanel;
  • unless按钮之间使用layout.addStretch(),因此在创建新对象方面没有任何用处:您可以直接使用self.setSizePolicy(, )
  • 多个级别的小部件及其布局增加了对象之间的页边距(这就是为什么IO按钮周围有大量空间),除非对所有涉及的布局显式删除页边距;除非您选择网格布局,否则考虑使用较少的容器小部件并使用addLayout()嵌套布局;另一个选项是覆盖QStyle的pixelMetric并为所有PM_Layout*Margin度量返回0,但除非显式设置,否则将所有布局边距默认为0;除非显式设置,否则
  • 面板的大部分与大小相关的代码集都是一个小块;考虑使用更简单的概念并避免不必要的调用:移除间隔项并添加一个扩展,使用样式表min-size属性并正确实现sizeHint();如您所见,生成的代码更简洁,更易于阅读:

代码语言:javascript
复制
class Sidebar(QWidget):
    def __init__(self, parent=None):
        super().__init__()

        layout = QVBoxLayout(self)
        layout.setSpacing(0)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(QPushButton())
        layout.addWidget(QPushButton())
        layout.addWidget(QPushButton())
        layout.addWidget(QPushButton())
        layout.addWidget(QPushButton())
        layout.addWidget(QPushButton())
        layout.addStretch()

        self.setStyleSheet('''
            Sidebar > QPushButton { min-height: 50; }
        ''')
        self.setMaximumWidth(200)

    def sizeHint(self):
        return QSize(self.maximumWidth(), super().sizeHint().height())
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68692333

复制
相关文章

相似问题

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