原文:http://zetcode.com/gui/pyqt5/layout/python
佈局管理是GUI編程中的重要部分。佈局管理是如何將控件放置於窗體上的技術,它的實現有兩種基本方式:絕對佈局與layout類。程序員
##絕對佈局web
程序員要指定每一個控件的像素位置與大小。在使用絕對佈局時要知道它的侷限:編程
下面的示例中以絕對座標來放置控件。app
#!/usr/bin/python3 # -*- coding: utf-8 -*- """ ZetCode PyQt5 tutorial This example shows three labels on a window using absolute positioning. author: Jan Bodnar website: zetcode.com last edited: January 2015 """ import sys from PyQt5.QtWidgets import QWidget, QLabel, QApplication class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): lbl1 = QLabel('Zetcode', self) lbl1.move(15, 10) lbl2 = QLabel('tutorials', self) lbl2.move(35, 40) lbl3 = QLabel('for programmers', self) lbl3.move(55, 70) self.setGeometry(300, 300, 250, 150) self.setWindowTitle('Absolute') self.show() if __name__ == '__main__': app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_())
咱們使用move()
方法來放置控件。在例子中咱們經過設置x、y座標來放置label。座標系統的原點位於窗體左上角。x軸從左到右增加,y軸從上到下增加。佈局
lbl1 = QLabel('Zetcode', self) lbl1.move(15, 10)
label控件位於x=15,y=10的座標上。字體
佈局類提供的佈局管理具備更好的靈活性與實用性,它是在窗體上放置控件的首選方式。QHBoxLayout
與QVBoxLayout
是水平與垂直放置控件的兩個基本佈局類。ui
假如要在右下角放置兩個按鈕,咱們要藉助於HBoxLayout與VBoxLayout,並設置stretch factor(伸展係數)
來建立所需的空白空間。this
#!/usr/bin/python3 # -*- coding: utf-8 -*- """ ZetCode PyQt5 tutorial In this example, we position two push buttons in the bottom-right corner of the window. author: Jan Bodnar website: zetcode.com last edited: January 2015 """ import sys from PyQt5.QtWidgets import (QWidget, QPushButton, QHBoxLayout, QVBoxLayout, QApplication) class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): okButton = QPushButton("OK") cancelButton = QPushButton("Cancel") hbox = QHBoxLayout() hbox.addStretch(1) hbox.addWidget(okButton) hbox.addWidget(cancelButton) vbox = QVBoxLayout() vbox.addStretch(1) vbox.addLayout(hbox) self.setLayout(vbox) self.setGeometry(300, 300, 300, 150) self.setWindowTitle('Buttons') self.show() if __name__ == '__main__': app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_())
這個示例在窗體的右下角放置了兩個按鈕。當調整窗體尺寸時它們的位置不會改變。咱們同時用到了QHBoxLayout
與QVBoxLayout
。code
okButton = QPushButton("OK") cancelButton = QPushButton("Cancel")
這裏建立了兩個按鈕
hbox = QHBoxLayout() hbox.addStretch(1) hbox.addWidget(okButton) hbox.addWidget(cancelButton)
咱們建立了一個水平boxlayout並添加了一個伸展係數和兩個按鈕。stretch
方法會在兩按鈕前面添加一個伸展空間,從而將按鈕擠到窗體的右側。
vbox = QVBoxLayout() vbox.addStretch(1) vbox.addLayout(hbox)
經過將水平佈局置於垂直佈局內來獲得咱們須要的佈局。垂直佈局的伸展係數會將按鈕擠到窗體底部。
self.setLayout(vbox)
最後將vbox設爲窗體的主佈局。
網格佈局是最經常使用的佈局。它會按行列對空間進行切分。咱們使用類QGridLayout
建立網格佈局。
#!/usr/bin/python3 # -*- coding: utf-8 -*- """ ZetCode PyQt5 tutorial In this example, we create a skeleton of a calculator using a QGridLayout. author: Jan Bodnar website: zetcode.com last edited: January 2015 """ import sys from PyQt5.QtWidgets import (QWidget, QGridLayout, QPushButton, QApplication) class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): grid = QGridLayout() self.setLayout(grid) names = ['Cls', 'Bck', '', 'Close', '7', '8', '9', '/', '4', '5', '6', '*', '1', '2', '3', '-', '0', '.', '=', '+'] positions = [(i,j) for i in range(5) for j in range(4)] for position, name in zip(positions, names): if name == '': continue button = QPushButton(name) grid.addWidget(button, *position) self.move(300, 150) self.setWindowTitle('Calculator') self.show() if __name__ == '__main__': app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_())
在這個例子中咱們建立填滿整個網格的按鈕。
grid = QGridLayout() self.setLayout(grid)
這裏建立了一個QGridLayout
實例,並將它設爲窗體的佈局。
names = ['Cls', 'Bck', '', 'Close', '7', '8', '9', '/', '4', '5', '6', '*', '1', '2', '3', '-', '0', '.', '=', '+']
這些是按鈕的標籤。
positions = [(i,j) for i in range(5) for j in range(4)]
咱們在網格中建立了一系列位置座標。
for position, name in zip(positions, names): if name == '': continue button = QPushButton(name) grid.addWidget(button, *position)
經過addWidget()
方法將建立的按鈕添加到佈局中。
控件能夠在佈局中跨行或跨列。正以下面的例子所展現的。
#!/usr/bin/python3 # -*- coding: utf-8 -*- """ ZetCode PyQt5 tutorial In this example, we create a bit more complicated window layout using the QGridLayout manager. author: Jan Bodnar website: zetcode.com last edited: January 2015 """ import sys from PyQt5.QtWidgets import (QWidget, QLabel, QLineEdit, QTextEdit, QGridLayout, QApplication) class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): title = QLabel('Title') author = QLabel('Author') review = QLabel('Review') titleEdit = QLineEdit() authorEdit = QLineEdit() reviewEdit = QTextEdit() grid = QGridLayout() grid.setSpacing(10) grid.addWidget(title, 1, 0) grid.addWidget(titleEdit, 1, 1) grid.addWidget(author, 2, 0) grid.addWidget(authorEdit, 2, 1) grid.addWidget(review, 3, 0) grid.addWidget(reviewEdit, 3, 1, 5, 1) self.setLayout(grid) self.setGeometry(300, 300, 350, 300) self.setWindowTitle('Review') self.show() if __name__ == '__main__': app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_())
咱們建立了一個帶有三個Label、兩個LineEdit和一個TextEdit的窗體。採用了QGridLayout
佈局。
grid = QGridLayout() grid.setSpacing(10)
咱們建立了一個網格佈局併爲它設置了控件間距。
grid.addWidget(reviewEdit, 3, 1, 5, 1)
在添加控件的時候咱們能夠設置控件跨行或跨列。在例子中咱們將reviewEdit控件跨越5行。
這部分教程主要講解了佈局管理。