本文是对TutorialsPoint上的教程的翻译。
概述
PyQt是一个GUI控件工具箱,是Qt的Python接口。
PyQt有两个主要版本:PyQt 4.x和PyQt 5.x,两者不兼容,且前者基于Python 2和Python 3,后者仅基于Python 3。
Linux下载安装:1
2
3sudo apt-get install python-qt4
or
sudo apt-get install pyqt5-dev-tools
PyQt4由以下Modules组成:QtCore、QtGui、QtNetwork、QtXml、QtSvg、QtOpenGL、QtSql。
- QtCore包含非GUI的核心功能,用来处理时间、文件和目录、数据类型、流、URL、MIME类型、线程和进程。
- QtGui包含图形组件及相关类,比如按钮、窗口、状态栏、工具栏、滑块、位图、颜色、字体等。
- QtNetwork包含网络编程的相关类,比如用于TCP/IP和UDP服务端和客户端的编程。
- QtXml包含处理XML文件的类,提供了用于SAX和DOM这些API的实现。
- QtSvg提供了显示SVG文件内容的类。
- QtOpenGL使用OpenGL库来处理2D和3D的图像,将Qt GUI库和OpenGL库无缝链接起来。
- QtSql包含处理数据库的类。
Hello World
使用PyQt创建”Hello World”的步骤如下:
- 导入QtGui模块
- 创建一个应用对象app
- 创建一个QWidget对象w来创建最顶层的窗口,在上面添加一个QLabel对象b
- 设置label的标题为“Hello World”
- 通过setGeometry()方法定义窗口的尺寸和位置
- 通过app.exec()方法来进入应用对象的主体
源码为:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#! /usr/bin/python
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtGui
def window():
app = QtGui.QApplication(sys.argv)
w = QtGui.QWidget()
b = QtGui.QLabel(w)
b.setText("Hello World!")
w.setGeometry(100,100,200,50)
b.move(50,20)
w.setWindowTitle("PyQt")
w.show()
sys.exit(app.exec_())
if __name__ == '__main__':
window()
信号和槽
与一般按顺序执行的控制台模式的应用程序不同,基于GUI的程序是由事件驱动的。事件events是响应用户动作的函数或方法,比如点击按钮、选择项目、鼠标点击等。用来构建GUI界面的挂件Widgets是这些事件的来源。每个PyQt Widget,都派生自QObject类,用来发射“信号”signals来响应一个或多个事件。信号本身不执行动作,它们连接到“槽”slot上。“槽”是可调用的Python函数。
在PyQt中,信号和槽的连接有多种方式。
最常用的方式是:1
QtCore.QObject.connect(widget, QtCore.SIGNAL(‘signalname’), slot_function)
更方便的方式是当widget发射signal时,调用slot函数:1
widget.signal.connect(slot_function)
以下是两种方式的举例: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#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
def window():
app = QApplication(sys.argv)
win = QDialog()
b1 = QPushButton(win)
b1.setText("Button1")
b1.move(50,20)
b1.clicked.connect(b1_clicked)
b2 = QPushButton(win)
b2.setText("Button2")
b2.move(50,50)
QObject.connect(b2,SIGNAL("clicked()"),b2_clicked)
win.setGeometry(100,100,200,100)
win.setWindowTitle("PyQt")
win.show()
sys.exit(app.exec_())
def b1_clicked():
print "Button 1 clicked"
def b2_clicked():
print "Button 2 clicked"
if __name__ == '__main__':
window()
布局管理
一个widget在窗口中的位置可以通过指定以像素为单位的绝对坐标,该坐标是相对于使用setGeometry()方法定义的窗口的尺寸:1
QWidget.setGeometry(xpos, ypos, width, height)
上面这句代码设定了窗口位于显示器的坐标点,以及它的尺寸。
具体的某个widget的位置代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#!/usr/bin/python
# -*- coding: utf-8 -*-
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()
但是这种绝对坐标的方式有一些缺点:
- 当window尺寸改变的时候,该widget的位置却不变
- 在有不同分辨率的设备上可能显示不统一
- 当布局需要改变时,该更改会很费劲,因为需要重新设置位置
PyQt的API针对上述问题提供了一些更优雅的管理widget位置的方法:
- QBoxLayout类:垂直或水平地排列widgets。它的派生类是QVBoxLayout(垂直排列)和QHBoxLayout(水平排列)
- QGridLayout类:以网格单元的形式排列,包含addWidget()方法。任何Widget都可以通过指定单元的行数和列数来添加
- QFormLayout类:可以很方便地创建两列的表格,一列(通常是右列)是输入栏,一列(通常是左列)是相应的标签。