我最近从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()发布于 2021-08-07 14:03:41
您可以在您的接口小部件中将布局设置为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)发布于 2021-08-07 23:13:16
问题不在于布局的设置方式,而是由于使用了addWidget()的对齐参数:
对齐是由对齐指定的。默认的对齐是0,这意味着小部件填充整个单元格。
这意味着指定对齐将不会使小部件填充整个单元,而是只填充其首选大小(sizeHint()返回的大小)。此外,由于您已经在侧栏中添加了一个间隔,并且按钮将位于画布垂直布局的底部,因此无论如何指定对齐都是不必要的。
因此,解决方案很简单:从addWidget()中删除所有不需要的参数(包括扩展,它已经默认为0):
class Interface(QWidget):
def __init__(self, parent=None):
# ...
layout.addWidget(Sidebar())
layout.addWidget(Canvas())请注意,您可能也希望对addWidget()中的所有Canvas进行同样的操作。
其他考虑因素:
只要添加的布局允许,pointless;
addStretch()和addSpacing())提供了方便的函数,后者在内部自行创建QSpacerItems :您可以在需要在大小策略中设置高级方面的IOPanel;layout.addStretch(),因此在创建新对象方面没有任何用处:您可以直接使用self.setSizePolicy(, );addLayout()嵌套布局;另一个选项是覆盖QStyle的pixelMetric并为所有PM_Layout*Margin度量返回0,但除非显式设置,否则将所有布局边距默认为0;除非显式设置,否则min-size属性并正确实现sizeHint();如您所见,生成的代码更简洁,更易于阅读: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())https://stackoverflow.com/questions/68692333
复制相似问题