|
PyQt4的 layout 管理
在编程中一个重要的事情就是 layout 的管理。layout 管理就是在窗口中布置 widget。管理有两种方式。我们可以使用 绝对定位 或者 layout 类 。
绝对定位
程序员可以指定每个 widget 的位置和大小。当你使用绝对定位时,你需要理解一些事情。
- 如果你改变了窗口的大小,widget 的大小和位置是不会改变的。
- 在不同平台上应用可能看起来不太一样。
- 在你的应用中改变字体会毁掉你的 layout。
- 如果你决定改变你的 layout,那么你必须要重新设计你的 layout,这意味着麻烦及耗时。
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
ZetCode PyQt4 tutorial
This example shows three labels on a window
using absolute positioning.
author: Jan Bodnar
website: zetcode.com
last edited: October 2011
"""
import sys
from PyQt4 import QtGui
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
lbl1 = QtGui.QLabel('Zetcode', self)
lbl1.move(15, 10)
lbl2 = QtGui.QLabel('tutorials', self)
lbl2.move(35, 40)
lbl3 = QtGui.QLabel('for programmers', self)
lbl3.move(55, 70)
self.setGeometry(300, 300, 250, 150)
self.setWindowTitle('Absolute')
self.show()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
我们简单地调用 move() 方法来定位我们的 widget 。在我们这个情况下,这些 widget 是标签。我们通过给定 x 和 y 坐标进行定位。坐标系统是从左上角开始。x 的值从左到右增加。y 则是从上到下。
Box Layout
通过 layout 类管理会更加灵活和实用。这是优先考虑的方法。基本的 layout 类是 QtGui.QHBoxLayout 和 QtGui.QVBoxLayout 。它们分别以水平和垂直方式对 widget 进行布局。
假设我们想把两个按钮放置在右下角。为了创建这样的 layout,我们可以使用一个水平的和垂直的盒子。为了创建必要的空间,我们将会增加一个 缩放比例 。
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
ZetCode PyQt4 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: October 2011
"""
import sys
from PyQt4 import QtGui
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
okButton = QtGui.QPushButton("OK")
cancelButton = QtGui.QPushButton("Cancel")
hbox = QtGui.QHBoxLayout()
hbox.addStretch(1)
hbox.addWidget(okButton)
hbox.addWidget(cancelButton)
vbox = QtGui.QVBoxLayout()
vbox.addStretch(1)
vbox.addLayout(hbox)
self.setLayout(vbox)
self.setGeometry(300, 300, 300, 150)
self.setWindowTitle('Buttons')
self.show()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
这里在窗口的右下角放置了两个按钮。他们在窗口调整时,会保持处于那个位置。我们使用了 QtGui.HBoxLayout 和 QtGui.QVBoxLayout 。
okButton = QtGui.QPushButton("OK")
cancelButton = QtGui.QPushButton("Cancel")
此处,我们创建了两个按钮。
hbox = QtGui.QHBoxLayout()
hbox.addStretch(1)
hbox.addWidget(okButton)
hbox.addWidget(cancelButton)
我们创建了一个水平的 layout 。增加了缩放比例和按钮。这个缩放在两个按钮前增加了合适的缩放空白。这就使得按钮在窗口的右边。
vbox = QtGui.QVBoxLayout()
vbox.addStretch(1)
vbox.addLayout(hbox)
为了创建必要的 layout,我们把水平的 layout 放置到垂直的 layout 中。而垂直盒子中的缩放因子使得水平的盒子处于窗口的底部。
最后,我们设置了窗口的 layout 。
QtGui.QGridLayout
最通用的 layout 类是网格 layout 。这个 layout 把空间分为行和列。为了创建一个网格的 layout,我们可以使用 QtGui.QGridLayout 类。
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
ZetCode PyQt4 tutorial
In this example, we create a skeleton
of a calculator using a QtGui.QGridLayout.
author: Jan Bodnar
website: zetcode.com
last edited: October 2011
"""
import sys
from PyQt4 import QtGui
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
names = ['Cls', 'Bck', '', 'Close', '7', '8', '9', '/',
'4', '5', '6', '*', '1', '2', '3', '-',
'0', '.', '=', '+']
grid = QtGui.QGridLayout()
j = 0
pos = [(0, 0), (0, 1), (0, 2), (0, 3),
(1, 0), (1, 1), (1, 2), (1, 3),
(2, 0), (2, 1), (2, 2), (2, 3),
(3, 0), (3, 1), (3, 2), (3, 3 ),
(4, 0), (4, 1), (4, 2), (4, 3)]
for i in names:
button = QtGui.QPushButton(i)
if j == 2:
grid.addWidget(QtGui.QLabel(''), 0, 2)
else: grid.addWidget(button, pos[j][0], pos[j][1])
j = j + 1
self.setLayout(grid)
self.move(300, 150)
self.setWindowTitle('Calculator')
self.show()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
在我们的例子中,我们创建了一组按钮,并以网格放置。为了填补一个空格,我们增加了一个 QtGui.QLable 的 widget 。
grid = QtGui.QGridLayout()
这里,我们创建了一个网格 layout 。
if j == 2:
grid.addWidget(QtGui.QLable(''), 0, 2)
else: grid.addWidget(button, pos[j][0], pos[j][1])
为了把一个 widget 增加到网格中,我们调用了 addWidget() 方法。参数是 widget,行和列的数字。
再看例子
在网格中,widget 可以跨多行或多列。下面的例子我们就将介绍这个。
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
ZetCode PyQt4 tutorial
In this example, we create a bit
more complicated window layout using
the QtGui.QGridLayout manager.
author: Jan Bodnar
website: zetcode.com
last edited: October 2011
"""
import sys
from PyQt4 import QtGui
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
title = QtGui.QLabel('Title')
author = QtGui.QLabel('Author')
review = QtGui.QLabel('Review')
titleEdit = QtGui.QLineEdit()
authorEdit = QtGui.QLineEdit()
reviewEdit = QtGui.QTextEdit()
grid = QtGui.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()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
我们创建了一个窗口,其中有三个标签,两个行编辑区及一个文本编辑区。layout 由 QtGui.QGridLayout 创建。
grid = QtGui.QGridLayout()
grid.setSpacing(10)
我们创建了网格 layout,并设置了 widget 间的间隔。
grid.addWidget(reviewEdit, 3, 1, 5, 1)
如果我们增加一个 widget 到网格中,我们可以提供行和列的跨度。我们使得 reviewEdit 的跨度为 5 。
这个部分我们讲述了 layout 管理。
|