两种方式:绝对定位或使用布局类
绝对定位:用像素指定每个控件的位置和尺寸。使用绝对定位的话,适合窗口大小和内容固定的情况,因为调整窗口的大小,组件的位置不会跟着改变,而且如果有修改字体可能会造成显示差异,修改布局几乎等于完全重做。
#!/usr/bin/python # -*- coding: utf-8 -*- import sys from PyQt4 import QtGui class Absolute(QtGui.QWidget): def __init__(self): super(Absolute, self).__init__() self.initUI() def initUI(self): label1 = QtGui.QLabel('Zetcode', self) label1.move(15, 10) label2 = QtGui.QLabel('tutorials for programmers', self) label2.move(35, 40) self.setWindowTitle('Absolute') self.resize(250, 150) app = QtGui.QApplication(sys.argv) a = Absolute() a.show() sys.exit(app.exec_())
布局类:基本的布局类是 QHBoxLayout 和 QVBoxLayout ,它们可以横向和纵向排列窗口组件。
框布局:假设想要摆放两个按钮到右下角,为了创建这样一个布局,需要一个水平框和一个垂直框。通过增加延展因素(addStretch)来创建必要的间隔。
#!/usr/bin/python # -*- coding: utf-8 -*- import sys from PyQt4 import QtGui class FrameLayout(QtGui.QWidget): def __init__(self): super(FrameLayout, 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.addStretch(5) hbox.addWidget(cancelButton) vbox = QtGui.QVBoxLayout() vbox.addStretch(1) vbox.addLayout(hbox) # 将水平框布局加入到垂直框布局中 vbox.addStretch(1) self.setLayout(vbox) # 使用设置好的布局 self.setWindowTitle('box layout') self.resize(300, 150) app = QtGui.QApplication(sys.argv) ex = FrameLayout() ex.show() sys.exit(app.exec_())
addStretch,表示剩下的空白处按比例填充,所以按钮处显示效果是1/6*总空白长+ok+5/6*总空白长+cancel:
最常用的布局类是网格布局,网格布局把空间划分成行和列,一般使用 QGridLayout 类来创建网格布局:
#!/usr/bin/python # -*- coding: utf-8 -*- import sys from PyQt4 import QtGui class GripLayout(QtGui.QWidget): def __init__(self): super(GripLayout, self).__init__() self.initUI() def initUI(self): self.setWindowTitle('grid layout') 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) # 添加Label组件 else: grid.addWidget(button, pos[j][0], pos[j][1]) # 添加按钮 j = j + 1 self.setLayout(grid) # 使用设置好的布局 app = QtGui.QApplication(sys.argv) ex = GripLayout() ex.show() sys.exit(app.exec_())
布局类型设置好以后使用addWidget() 方法来把窗口组件加到网格中,参数是部件( widget ),行( row )和列( column )数字。
表格布局:
#!/usr/bin/python # -*- coding: utf-8 -*- import sys from PyQt4 import QtGui class GripLayout2(QtGui.QWidget): def __init__(self): super(GripLayout2, 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) # 设置行跨度5,列跨度1,缺省可不设置 self.setLayout(grid) self.setWindowTitle('grid layout') self.resize(350, 300) app = QtGui.QApplication(sys.argv) ex = GripLayout2() ex.show() sys.exit(app.exec_())