在一個GUI程序裏,佈局是一個很重要的方面。佈局就是如何管理應用中的元素和窗口。有兩種方式能夠搞定:絕對定位和PyQt5的layout類python
每一個程序都是以像素爲單位區分元素的位置,衡量元素的大小。因此咱們徹底可使用絕對定位搞定每一個元素和窗口的位置。可是這也有侷限性: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: August 2017 """ 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座標。x、y座標的原點是程序的左上角。函數
lbl1 = QLabel('Zetcode', self) lbl1.move(15, 10)
這個元素的左上角就在這個程序的左上角開始的(15, 10)的位置。佈局
程序展現:字體
使用盒佈局能讓程序具備更強的適應性。這個纔是佈局一個應用的更合適的方式。QHBoxLayout
和QVBoxLayout
是基本的佈局類,分別是水平佈局和垂直佈局。this
若是咱們須要把兩個按鈕放在程序的右下角,建立這樣的佈局,咱們只須要一個水平佈局加一個垂直佈局的盒子就能夠了。再用彈性佈局增長一點間隙。spa
#!/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: August 2017 """ 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")
這是建立了兩個按鈕。blog
hbox = QHBoxLayout() hbox.addStretch(1) hbox.addWidget(okButton) hbox.addWidget(cancelButton)
建立一個水平佈局,增長兩個按鈕和彈性空間。stretch函數在兩個按鈕前面增長了一些彈性空間。下一步咱們把這些元素放在應用的右下角。
vbox = QVBoxLayout() vbox.addStretch(1) vbox.addLayout(hbox)
爲了佈局須要,咱們把這個水平佈局放到了一個垂直佈局盒裏面。彈性元素會把全部的元素一塊兒都放置在應用的右下角。
self.setLayout(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 more complicated window layout using the QGridLayout manager. Author: Jan Bodnar Website: zetcode.com Last edited: August 2017 """ 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_())
咱們建立了一個有三個標籤的窗口。兩個行編輯和一個文版編輯,這是用QGridLayout
模塊搞定的。
grid = QGridLayout() grid.setSpacing(10)
建立標籤之間的空間。
grid.addWidget(reviewEdit, 3, 1, 5, 1)
咱們能夠指定組件的跨行和跨列的大小。這裏咱們指定這個元素跨5行顯示。
程序預覽: