接下来这个专题介绍PyQt的一些内容 教程翻译自: [https://www.tutorialspoint.com/pyqt/pyqt_introduction.htm](https://www.tutorialspoint.com/pyqt/pyqt_introduction.htm) 由于本人也是学习状态,翻译可能不准确,请及时指出,我会很快修正 一些关键字会直接使用英文 目前该专题为纯理论,实际操作在完成后有演示 PyQt版本: PyQt4 [TOC] ##1. 绝对位置 我们可以使用setGeometry() 方法设置widget在窗体上的位置和大小 ``` import sys from PyQt4 import QtGui def window(): app = QtGui.QApplication(sys.argv) w = QtGui.QWidget() b = QtGui.QPushButton(w) b.setText("Hello World!") b.move(50,20) w.setGeometry(10,10,300,200) w.setWindowTitle(“PyQt”) w.show() sys.exit(app.exec_()) if __name__ == '__main__': window() ``` 上面例子中 最外层Widget 300*200 像素大小 在显示器中位置为(10,10) QPushButton 放在靠窗体右边50像素,窗体下面20像素的位置 **绝对位置的劣处** 1. 当窗体改变大小时不会自动变化 2. 不同设备不同分辨率上显示不一致 3. 更改布局可能需要重新设计代码 [image:140 size:orig] ## 2. 自动布局 PyQt 提供一种方便的自动的布局方式,他可以 1. 窗体上的widget会随着窗体的大小改变而自动改变 2. 确保不同设备不同分辨率有同意的显示 3. 更改某个widget不用重新设计代码 如下为一些常用的布局方式 ###2.1 QBoxLayout 将widget 垂直或水平排列在一起 该布局通过如下2个类创建 - QVBoxLayout 垂直排列 - QHBoxLayout 水平排列 他们有如下方法: **addWidget()** 增加一个widget到BoxLayout **addStretch()** 增加一个空的空间到BoxLayout **addLayout()** 增加另一个嵌套的BoxLayout **应用举例** ``` import sys from PyQt4.QtCore import * from PyQt4.QtGui import * def window(): app = QApplication(sys.argv) win = QWidget() b1 = QPushButton("Button1") b2 = QPushButton("Button2") vbox = QVBoxLayout() vbox.addWidget(b1) vbox.addStretch() vbox.addWidget(b2) hbox = QHBoxLayout() b3 = QPushButton("Button3") b4 = QPushButton("Button4") hbox.addWidget(b3) hbox.addStretch() hbox.addWidget(b4) vbox.addStretch() vbox.addLayout(hbox) win.setLayout(vbox) win.setWindowTitle("PyQt") win.show() sys.exit(app.exec_()) if __name__ == '__main__': window() ``` 下面的例子创建一个QVBoxLayout 和一个QHBoxLayout 各放置2个button 之后将hbox嵌套至vbox [image:141 size:orig] 更多例子请参考 [https://www.tutorialspoint.com/pyqt/pyqt_qboxlayout_class.htm](https://www.tutorialspoint.com/pyqt/pyqt_qboxlayout_class.htm) ###2.2 QGridLayout 网格布局方式将widget按照表格(行列)的方式排列起来 我们可以将widget 放在制定的行和列中 可选的 我们还可以扩展行和列的大小,这样可使其相对于其他的widget更高和宽 它有如下方法 **addWidget(QWidget, int r, int c)** 在指定的行列增加widget **addWidget(QWidget, int r, int c, int rowspan, int columnspan)** 在指定的行列增加widget并设定大小 **addLayout(QLayout, int r, int c)** 使用addLayout可以将其他layout插入到指定行列 **应用举例** ``` import sys from PyQt4.QtCore import * from PyQt4.QtGui import * def window(): app = QApplication(sys.argv) win = QWidget() grid = QGridLayout() for i in range(1,5): for j in range(1,5): grid.addWidget(QPushButton("B"+str(i)+str(j)),i,j) win.setLayout(grid) win.setGeometry(100,100,200,100) win.setWindowTitle("PyQt") win.show() sys.exit(app.exec_()) if __name__ == '__main__': window() ``` 上面的程序首先新建一个QGridLayout 之后使用循环的形式增加QPushButton [image:142 size:orig] ###2.3 QFormLayout 该布局可以让我们很方便的创建一个表单布局 即只有两列的网格布局 第一列为label 第二列为输入框 它有如下3个方法 **addRow(QLabel, QWidget)** 增加包含label和input的一行 **addRow(QLabel, QLayout)** 在第二列增加一个Layout **addRow(QWidget)** 增加一个widget,该widget扩展在两列 **应用举例** 代码很简单,看下就行 ``` import sys from PyQt4.QtCore import * from PyQt4.QtGui import * def window(): app = QApplication(sys.argv) win = QWidget() l1 = QLabel("Name") nm = QLineEdit() l2 = QLabel("Address") add1 = QLineEdit() add2 = QLineEdit() fbox = QFormLayout() fbox.addRow(l1,nm) vbox = QVBoxLayout() vbox.addWidget(add1) vbox.addWidget(add2) fbox.addRow(l2,vbox) hbox = QHBoxLayout() r1 = QRadioButton("Male") r2 = QRadioButton("Female") hbox.addWidget(r1) hbox.addWidget(r2) hbox.addStretch() fbox.addRow(QLabel("sex"),hbox) fbox.addRow(QPushButton("Submit"),QPushButton("Cancel")) win.setLayout(fbox) win.setWindowTitle("PyQt") win.show() sys.exit(app.exec_()) if __name__ == '__main__': window() ``` [image:143 size:orig]