首页 > 解决方案 > 拉伸布局时,无法使间隔符占据小部件之间的空白空间

问题描述

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

我想在窗口底部有一个带有不同工具的侧边栏和一个 I/O 面板。

此 I/O 面板应仅包含 2 个QPushButtons- Ok and Cancel

当我更改应用程序窗口的大小时,右键(确定)应该留在右下角,而左按钮(取消) - 在左下角,紧挨着(但不是下面)侧边栏。为此,我在按钮之间添加了一个水平间隔。

但是,这两个按钮始终保留在窗口的右下角。我玩过一些QSizePolicy参数,但它似乎没有做任何事情。我能够得到我想要的唯一方法是将构造函数中的水平间隔宽度设置为非零值,但我对这个解决方案不满意。我应该在下面的代码中更改什么以获得我想要的?

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

标签: pythonpyqt5

解决方案


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

....
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)

推荐阅读