参考:
1、https://maicss.gitbooks.io/pyqt5/content/
2、https://github.com/maicss/PyQt5-Chinese-tutoral
3、https://doc.qt.io/qt-5/classes.html API
在一个GUI程序里,布局是一个很重要的方面。布局就是如何管理应用中的元素和窗口。有两种方式可以搞定:绝对定位和PyQt5的layout类
每个程序都是以像素为单位区分元素的位置,衡量元素的大小。所以我们完全可以使用绝对定位搞定每个元素和窗口的位置。但是这也有局限性:
#!/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): # 使用move()方法定位了每一个元素,使用x、y坐标。x、y坐标的原点是程序的左上角 lbl1 = QLabel('Zetcode', self) lbl1.move(15, 10) # 这个元素的左上角就在这个程序的左上角开始的(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_())
使用盒布局能让程序具有更强的适应性。这个才是布局一个应用的更合适的方式。QHBoxLayout
和QVBoxLayout
是基本的布局类,分别是水平布局和垂直布局。
#!/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) # stretch函数在两个按钮前面增加了一些弹性空间 # 把这些元素放在应用的右下角 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_())
最常用的还是栅格布局了。这种布局是把窗口分为行和列。创建和使用栅格布局,需要使用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): # 创建一个QGridLayout实例,并把它放到程序窗口里 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) # 创建按钮,并使用addWidget()方法把按钮放到布局里面 self.move(300, 150) self.setWindowTitle('Calculator') self.show() if __name__ == '__main__': app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_())
组件能跨列和跨行展示,这个例子里,我们就试试这个功能。
#!/usr/bin/python3 # -*- coding: utf-8 -*- """ ZetCode PyQt5 tutorial In this example, we create a more complicated window layout using the QGridLayout manager. 创建了一个有三个标签的窗口。两个行编辑和一个文版编辑, 这是用QGridLayout模块搞定的 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) # (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) # 指定组件的跨行和跨列的大小,指定这个元素跨5行显示 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_())