PyQt5 快速入门(五)PyQt5 布局管理
一, GUI 布局管理简介
PyQt5 中进行界面布局管理的方法主要由两种, 一种是绝对定位, 一种是使用布局管理器. Qt 中使用绝对定位的布局方式无法自适应窗口的变化, 因此 Qt 中提供了对界面组件进行布局管理的类, 用于对界面组件进行管理, 能够自动排列窗口中的界面组件, 窗口大小变化后自动更新界面组件的大小.
QLayout 是 Qt 中布局管理器的抽象基类, 通过对 QLayout 的继承, 实现了功能各异且互补的布局管理器. 布局管理器不是界面组件, 而是界面组件的定位策略; 任意容器类型的组件都可以指定布局管理器; 同一个布局管理器管理中的组件拥有相同的父组件, 在设置布局管理器的同时已经隐式指定了父子关系.
Qt 布局管理器的 addWidget 用于向布局管理器中插入控件, addLayout 用于向布局管理器插入子布局管理器.
二, 框布局
1,QHBoxLayout
QHBoxLayout 提供了水平方式对控件进行布局管理.
- import sys
- from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QPushButton, QSizePolicy
- class MainWindow(QWidget):
- def __init__(self, parent=None):
- super().__init__(parent)
- self.layout = QHBoxLayout()
- self.layout.setSpacing(20)
- button = QPushButton("Button1")
- button.setMinimumSize(60, 30)
- button.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
- self.layout.addWidget(button)
- button = QPushButton("Button2")
- button.setMinimumSize(60, 30)
- button.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
- self.layout.addWidget(button)
- self.setLayout(self.layout)
- if __name__ == "__main__":
- App = QApplication(sys.argv)
- Windows = MainWindow()
- Windows.resize(400, 200)
- Windows.show()
- sys.exit(App.exec_())
- 2,QVBoxLayout
QVBoxLayout 提供了垂直方式对控件进行布局管理.
- import sys
- from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QSizePolicy
- class MainWindow(QWidget):
- def __init__(self, parent=None):
- super().__init__(parent)
- self.layout = QVBoxLayout()
- self.layout.setSpacing(20)
- button = QPushButton("Button1")
- button.setMinimumSize(60, 30)
- button.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
- self.layout.addWidget(button)
- button = QPushButton("Button2")
- button.setMinimumSize(60, 30)
- button.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
- self.layout.addWidget(button)
- self.setLayout(self.layout)
- if __name__ == "__main__":
- App = QApplication(sys.argv)
- Windows = MainWindow()
- Windows.resize(400, 200)
- Windows.show()
- sys.exit(App.exec_())
3, 嵌套布局
布局管理器可以相互嵌套, 形成复杂的布局管理方式. QBoxLayout 布局管理器的嵌套使用实例如下:
- import sys
- from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QSizePolicy
- class MainWindow(QWidget):
- def __init__(self, parent=None):
- super().__init__(parent)
- self.layout = QVBoxLayout()
- self.layout.setSpacing(20)
- # 第一行按钮布局管理
- hLayout1 = QHBoxLayout()
- button = QPushButton("Button1")
- button.setMinimumSize(60, 30)
- button.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
- hLayout1.addWidget(button)
- button = QPushButton("Button2")
- button.setMinimumSize(60, 30)
- button.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
- hLayout1.addWidget(button)
- # 第二行按钮布局管理
- hLayout2 = QHBoxLayout()
- button = QPushButton("Button1")
- button.setMinimumSize(60, 30)
- button.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
- hLayout2.addWidget(button)
- button = QPushButton("Button2")
- button.setMinimumSize(60, 30)
- button.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
- hLayout2.addWidget(button)
- # 整体垂直布局管理
- self.layout.addLayout(hLayout1)
- self.layout.addLayout(hLayout2)
- self.setLayout(self.layout)
- if __name__ == "__main__":
- App = QApplication(sys.argv)
- Windows = MainWindow()
- Windows.resize(400, 200)
- Windows.show()
- sys.exit(App.exec_())
三, 网格布局
QGridLayout 布局管理器以网格的方式管理界面组件.
- import sys
- from PyQt5.QtWidgets import QApplication, QWidget, QGridLayout, QPushButton, QSizePolicy
- class MainWindow(QWidget):
- def __init__(self, parent=None):
- super().__init__(parent)
- self.layout = QGridLayout()
- self.layout.setSpacing(5)
- button = QPushButton("Button1")
- button.setMinimumSize(60, 30)
- button.setSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding)
- self.layout.addWidget(button, 0, 0, 1, 1)
- button = QPushButton("Button2")
- button.setMinimumSize(60, 30)
- button.setSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding)
- self.layout.addWidget(button, 0, 1, 1, 1)
- button = QPushButton("Button3")
- button.setMinimumSize(60, 30)
- button.setSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding)
- self.layout.addWidget(button, 1, 0, 1, 1)
- button = QPushButton("Button4")
- button.setMinimumSize(60, 30)
- button.setSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding)
- self.layout.addWidget(button, 1, 1, 1, 1)
- button = QPushButton("Button5")
- button.setMinimumSize(60, 30)
- button.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
- # 列扩展, 定位在第 2 行第 1 列位置, 占 1 行 2 列
- self.layout.addWidget(button, 2, 0, 1, 2)
- self.setLayout(self.layout)
- if __name__ == "__main__":
- App = QApplication(sys.argv)
- Windows = MainWindow()
- Windows.resize(400, 200)
- Windows.show()
- sys.exit(App.exec_())
四, 表单布局
QFormLayout 布局管理器使用表单的方式管理界面组件, 表单中的标签和组件是相互对应的关系, 支持嵌套使用.
- import sys
- from PyQt5.QtWidgets import QApplication, QWidget, QFormLayout, QVBoxLayout, QLineEdit
- from PyQt5.QtCore import Qt
- class MainWindow(QWidget):
- def __init__(self, parent=None):
- super().__init__(parent)
- self.layout = QFormLayout()
- self.layout.setSpacing(20)
- self.layout.setLabelAlignment(Qt.AlignLeft)
- self.layout.setFormAlignment(Qt.AlignRight)
- nameEdit = QLineEdit()
- mailEdit = QLineEdit()
- vLayout = QVBoxLayout()
- vLayout.setSpacing(6)
- addrEdit1 = QLineEdit()
- addrEdit2 = QLineEdit()
- vLayout.addWidget(addrEdit1)
- vLayout.addWidget(addrEdit2)
- self.layout.addRow("Name:", nameEdit)
- self.layout.addRow("Mail:", mailEdit)
- self.layout.addRow("Address:", vLayout)
- self.setLayout(self.layout)
- self.setWindowTitle("FTP")
- if __name__ == "__main__":
- App = QApplication(sys.argv)
- Windows = MainWindow()
- Windows.resize(400, 200)
- Windows.show()
- sys.exit(App.exec_())
五, 栈式布局
QStackedLayout 栈式布局管理器管理的所有组件在垂直于屏幕的方向上, 每次只有一个界面组件会显示在屏幕上, 只要最顶层的界面组件会被显示.
????QStackedLayout 栈式布局管理器的特点如下:
????A, 组件大小一致, 且充满父组件的显示区
????B, 不能直接嵌套其它布局管理器
????C, 能够自由切换需要显示的组件
????D, 每次仅能显示一个界面组件
- import sys
- from PyQt5.QtWidgets import QApplication, QWidget, QStackedLayout, QVBoxLayout, QPushButton
- class MainWindow(QWidget):
- def __init__(self, parent=None):
- super().__init__(parent)
- self.layout = QStackedLayout()
- self.layout.addWidget(QPushButton("Button1"))
- self.layout.addWidget(QPushButton("Button2"))
- self.layout.addWidget(QPushButton("Button3"))
- self.layout.addWidget(QPushButton("Button4"))
- self.setLayout(self.layout)
- self.setWindowTitle("Stack Layout")
- # 设置栈顶显示第 2 个组件
- self.layout.setCurrentIndex(2)
- if __name__ == "__main__":
- App = QApplication(sys.argv)
- Windows = MainWindow()
- Windows.resize(400, 200)
- Windows.show()
- sys.exit(App.exec_())
QStackedLayout 栈式布局管理器不能直接嵌套其它布局管理器, 但可以通过 QWidget 容器组件间接嵌套使用其它布局管理器.
- import sys
- from PyQt5.QtWidgets import QApplication, QWidget, QStackedLayout, QVBoxLayout, QPushButton
- class MainWindow(QWidget):
- def __init__(self, parent=None):
- super().__init__(parent)
- self.layout = QStackedLayout()
- self.layout.addWidget(QPushButton("Button1"))
- # 容器型组件
- widget = QWidget()
- vLayout = QVBoxLayout()
- vLayout.addWidget(QPushButton("Button2"))
- vLayout.addWidget(QPushButton("Button3"))
- widget.setLayout(vLayout)
- self.layout.addWidget(widget)
- self.layout.addWidget(QPushButton("Button4"))
- self.setLayout(self.layout)
- self.setWindowTitle("Stack Layout")
- # 设置栈顶显示第 1 个组件
- self.layout.setCurrentIndex(1)
- if __name__ == "__main__":
- App = QApplication(sys.argv)
- Windows = MainWindow()
- Windows.resize(400, 200)
- Windows.show()
- sys.exit(App.exec_())
六, 分割器
QSplitter 是一个带切分条 (splitter handle) 的布局管理器, 可以通过 setHandleWidth()函数来设置切分条的宽带. QSplitter 可以通过 setOrientation()函数来指定分割方向, 子组件按加载顺序进行指定方向排列.
- import sys
- from PyQt5.QtWidgets import QApplication, QWidget, QTextEdit, QVBoxLayout, QSplitter
- from PyQt5.QtCore import Qt
- class MainWindow(QWidget):
- def __init__(self, parent=None):
- super().__init__(parent)
- self.layout = QVBoxLayout()
- self.mainSplitter = QSplitter(self)
- self.layout.addWidget(self.mainSplitter)
- self.setLayout(self.layout)
- # 水平线分割
- self.mainSplitter.setOrientation(Qt.Horizontal)
- rightSplitter = QSplitter(self)
- # 垂直线分割
- rightSplitter.setOrientation(Qt.Vertical)
- textEdit = QTextEdit()
- textEdit.setText("Window2")
- rightSplitter.addWidget(textEdit)
- textEdit = QTextEdit()
- textEdit.setText("Window3")
- rightSplitter.addWidget(textEdit)
- textEdit = QTextEdit()
- textEdit.setText("Window1")
- self.mainSplitter.addWidget(textEdit)
- self.mainSplitter.addWidget(rightSplitter)
- # 分割比例
- self.mainSplitter.setStretchFactor(0, 1)
- self.mainSplitter.setStretchFactor(1, 2)
- self.mainSplitter.show()
- self.setWindowTitle("Splitter")
- if __name__ == "__main__":
- App = QApplication(sys.argv)
- Windows = MainWindow()
- Windows.resize(400, 200)
- Windows.show()
- sys.exit(App.exec_())
PyQt5 快速入门(五)PyQt5 布局管理
来源: http://www.bubuko.com/infodetail-3133682.html