一个widget在窗口中的位置可以通过指定以像素为单位的绝对坐标,该坐标是相对于使用setGeometry()方法定义的窗口的尺寸:
1
| QWidget.setGeometry(xpos, ypos, width, height)
|
这句代码设定了窗口位于显示器的坐标点,以及它的尺寸。
但是这种绝对坐标的方式有一些缺点:
- 当window尺寸改变的时候,该widget的位置却不变
- 在有不同分辨率的设备上可能显示不统一
- 当布局需要改变时,该更改会很费劲,因为需要重新设置位置
PyQt的API针对上述问题提供了一些更优雅的管理widget位置的方法:
- QBoxLayout类:垂直或水平地排列widgets。它的派生类是QVBoxLayout(垂直排列)和QHBoxLayout(水平排列)
- QGridLayout类:以网格单元的形式排列,包含addWidget()方法。任何Widget都可以通过指定单元的行数和列数来添加
- QFormLayout类:可以很方便地创建两列的表格,一列(通常是右列)是输入栏,一列(通常是左列)是相应的标签。
QHBoxLayout
添加进去的部件们在布局管理器中是水平排列的。这个时候这些部件是不能显示的,我们还要将他们与一个对象(QWidget对象、
QMainWindow对象或QDialog对象)进行“绑定”(原文里是install),然后调用该对象的show方法才能显示出来。
使用如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
import sys from PyQt4 import QtGui from PyQt4 import QtCore
def window(): app = QtGui.QApplication(sys.argv) w = QtGui.QWidget() w.setGeometry(100,100,400,300) w.setWindowTitle('test')
button1 = QtGui.QPushButton('1') button2 = QtGui.QPushButton('2') button3 = QtGui.QPushButton('3') button4 = QtGui.QPushButton('4') button5 = QtGui.QPushButton('5')
hbox = QtGui.QHBoxLayout() hbox.addStretch(10) hbox.addWidget(button1) hbox.addWidget(button2) hbox.addWidget(button3) hbox.addWidget(button4) hbox.addWidget(button5) hbox.addStretch(10) w.setLayout(hbox)
w.show() sys.exit(app.exec_())
if __name__ == '__main__': window()
|
QVBoxLayout
在这个布局里面我们创建了我们想要的widget(部件)。然后,我们创建了QVBoxLayout类的一个对象并且把我们刚才创建的widget(部件)加入到了这个对象里。 最后,我们调用了QWidget.setLayout()方法将QVBoxLayout对象“安装”到了widget里。在那一点上,布局里的各个widget(部件)让window(窗口)成为了他们的父部件。
使用如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
import sys from PyQt4 import QtGui from PyQt4 import QtCore
def window(): app = QtGui.QApplication(sys.argv) w = QtGui.QWidget() w.setGeometry(100,100,400,300) w.setWindowTitle('test')
button1 = QtGui.QPushButton('1') button2 = QtGui.QPushButton('2') button3 = QtGui.QPushButton('3') button4 = QtGui.QPushButton('4') button5 = QtGui.QPushButton('5')
vbox = QtGui.QVBoxLayout() vbox.addStretch(10) vbox.addWidget(button1) vbox.addWidget(button2) vbox.addWidget(button3) vbox.addWidget(button4) vbox.addWidget(button5) vbox.addStretch(10) w.setLayout(vbox)
w.show() sys.exit(app.exec_())
if __name__ == '__main__': window()
|
QGridLayout
网格布局(QGridLayout)。该布局方式将窗口空间划分为许多行和列。要创建该布局方式,我们需要使用QGridLayout类。
使用addWidget()方法,我们将部件加入到网格布局中。addWidget()方法的参数依次为要加入到局部的部件,行号和列号。
使用如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
|
import sys from PyQt4 import QtGui from PyQt4 import QtCore
def window(): app = QtGui.QApplication(sys.argv) w = QtGui.QWidget() w.setGeometry(100,100,400,300) w.setWindowTitle('test')
platform = QtGui.QLabel(u'登录平台') account = QtGui.QLabel(u'测试账号') password = QtGui.QLabel(u'账号密码')
platformEdit = QtGui.QLineEdit() accountEdit = QtGui.QLineEdit() passwordEdit = QtGui.QLineEdit()
save = QtGui.QPushButton() save.setText(u"保存") cancel = QtGui.QPushButton() cancel.setText(u"取消")
accountGrid = QtGui.QGridLayout() accountGrid.setSpacing(10)
accountGrid.addWidget(platform,1,0) accountGrid.addWidget(platformEdit,1,1)
accountGrid.addWidget(account,2,0) accountGrid.addWidget(accountEdit,2,1)
accountGrid.addWidget(password,3,0) accountGrid.addWidget(passwordEdit,3,1,5,1)
accountGrid.addWidget(save,8,0) accountGrid.addWidget(cancel,8,1)
w.setLayout(accountGrid) w.show() sys.exit(app.exec_())
if __name__ == '__main__': window()
|