PyQt5中文教程,翻译自 zetcode,项目地址:https://github.com/maicss/PyQt5-Chinese-tutoral
这个教程比较好的地方是,能讲解每一段代码的含义。
虽然PyQt的函数命名已经非常语义化了,但是对于新手来说,有这一步还是更好的。
所以我选择了翻译这篇教程,希望能给刚入门的你带来帮助。
翻译的水平有限(如有错误,请指出),而且有些地方是自己的理解,也加入了自己的提示在里面(并没有标注出来),所以并不完全等于原文。
我尽量让翻译不带英语腔,做到即使一个完全不懂编程的人来看,虽然不知道说的啥,但是最起码语句通顺,不会读着别扭。也算是对老师的一点敬意吧~~
翻译吐槽:
label这个词好难翻译,有时候就是个占位符的意思,说是文字说明吧,有专门的词caption,但是像checkbox的名称这种的,不是文字说明又是啥...,但是居然还用label说图标这种事情,也是醉了。
源文档更新了,但是没有更新日志,只能一段段的比对……长了记性,创建了一个源文档的文件,下次直接copy的时候用VCS对比就可以了。
更新了一些图片,主要是原来没有的。因为手头没有Windows,而且源文档的图片也是不是Windows10,都不是一个风格的,凑合着看吧……
更新:
2017-8
菜单和工具栏 【新增】 右键菜单 子菜单 勾选菜单
事件和信号 【新增】 事件对象
绘图 【新增】 贝塞尔曲线
PyQt5 简介
本教程的目的是带领你入门PyQt5。教程内所有代码都在Linux上测试通过。PyQt4 教程是PyQt4的教程,PyQt4是一个Python(同时支持2和3)版的Qt库。
关于 PyQt5
PyQt5 是Digia的一套Qt5应用框架与python的结合,同时支持2.x和3.x。本教程使用的是3.x。Qt库由Riverbank Computing开发,是最强大的GUI库之一 ,官方网站:www.riverbankcomputing.co.uk/news。
PyQt5是由一系列Python模块组成。超过620个类,6000函数和方法。能在诸如Unix、Windows和Mac OS等主流操作系统上运行。PyQt5有两种证书,GPL和商业证书。
PyQt5类分为很多模块,主要模块有:
QtCore 包含了核心的非GUI的功能。主要和时间、文件与文件夹、各种数据、流、URLs、mime类文件、进程与线程一起使用。
QtGui 包含了窗口系统、事件处理、2D图像、基本绘画、字体和文字类。
QtWidgets
QtMultimedia
QtBluetooth
QtNetwork
QtPositioning
Enginio
QtWebSockets
QtWebKit
QtWebKitWidgets
QtXml
QtSvg
QtSql
QtTest
QtWidgets类包含了一系列创建桌面应用的UI元素。 QtMultimedia包含了处理多媒体的内容和调用摄像头API的类。 QtBluetooth模块包含了查找和连接蓝牙的类。 QtNetwork包含了网络编程的类,这些工具能让TCP/IP和UDP开发变得更加方便和可靠。 QtPositioning包含了定位的类,可以使用卫星、WiFi甚至文本。 Engine包含了通过客户端进入和管理Qt Cloud的类。 QtWebSockets包含了WebSocket协议的类。 QtWebKit包含了一个基WebKit2的web浏览器。 QtWebKitWidgets包含了基于QtWidgets的WebKit1的类。 QtXml包含了处理xml的类,提供了SAX和DOM API的工具。 QtSvg提供了显示SVG内容的类,Scalable Vector Graphics (SVG)是一种是一种基于可扩展标记语言(XML),用于描述二维矢量图形的图形格式(这句话来自于维基百科)。 QtSql提供了处理数据库的工具。 QtTest提供了测试PyQt5应用的工具。
PyQt4和PyQt5的区别
PyQt5不兼容PyQt4。PyQt5有一些巨大的改进。但是,迁移并不是很难,两者的区别如下:
重新组合模块,一些模块已经被废弃(QtScript),有些被分为两个子模块(QtGui, QtWebKit)。
添加了新的模块,比如QtBluetooth, QtPositioning,和Enginio。
废弃了SINGAL()和SLOT()的调用方式,使用了新的信号和xx处理方式。
不再支持被标记为废弃的或不建议使用的API。
Python语言的介绍
这个部分建议看百科,这里写的很简略。如果你还不太熟悉Python,建议先去官网看看文档。
Python is a general-purpose, dynamic, object-oriented programming language. The design purpose of the Python language emphasizes programmer productivity and code readability. Python was initially developed by Guido van Rossum. It was first released in 1991. Python was inspired by ABC, Haskell, Java, Lisp, Icon, and Perl programming languages. Python is a high-level, general purpose, multiplatform, interpreted language. Python is a minimalistic language. One of its most visible features is that it does not use semicolons nor brackets. It uses indentation instead. There are two main branches of Python currently: Python 2.x and Python 3.x. Python 3.x breaks backward compatibility with previous releases of Python. It was created to correct some design flaws of the language and make the language more clean. The most recent version of Python 2.x is 2.7.9, and of Python 3.x is 3.4.2. Python is maintained by a large group of volunteers worldwide. Python is open source software. Python is an ideal start for those who want to learn programming.
Python programming language supports several programming styles. It does not force a programmer to a specific paradigm. Python supports object-oriented and procedural programming. There is also a limited support for functional programming.
Python语言的官方网站是python.org
Perl,Python,和Ruby都是使用最广泛的脚本语言,它们有很多共同的特点,也是相互的竞争对手。
Hello World
本章学习Qt的基本功能
例1,简单的窗口
这个简单的小例子展示的是一个小窗口。但是我们可以在这个小窗口上面做很多事情,改变大小,最大化,最小化等,这需要很多代码才能实现。这在很多应用中很常见,没必要每次都要重写这部分代码,Qt已经提供了这些功能。PyQt5是一个高级的工具集合,相比使用低级的工具,能省略上百行代码。
#!/usr/bin/python3# -*- coding: utf-8 -*-"""ZetCode PyQt5 tutorial In this example, we create a simplewindow in PyQt5.author: Jan Bodnarwebsite: zetcode.com Last edited: August 2017"""import sysfrom PyQt5.QtWidgets import QApplication, QWidgetif __name__ == '__main__': app = QApplication(sys.argv) w = QWidget() w.resize(250, 150) w.move(300, 300) w.setWindowTitle('Simple') w.show() sys.exit(app.exec_())运行上面的代码,能展示出一个小窗口。
import sysfrom PyQt5.QtWidgets import QApplication, QWidget这里引入了PyQt5.QtWidgets模块,这个模块包含了基本的组件。
app = QApplication(sys.argv)每个PyQt5应用都必须创建一个应用对象。sys.argv是一组命令行参数的列表。Python可以在shell里运行,这个参数提供对脚本控制的功能。
w = QWidget()QWidge控件是一个用户界面的基本控件,它提供了基本的应用构造器。默认情况下,构造器是没有父级的,没有父级的构造器被称为窗口(window)。
w.resize(250, 150)resize()方法能改变控件的大小,这里的意思是窗口宽250px,高150px。
w.move(300, 300)move()是修改控件位置的的方法。它把控件放置到屏幕坐标的(300, 300)的位置。注:屏幕坐标系的原点是屏幕的左上角。
w.setWindowTitle('Simple')我们给这个窗口添加了一个标题,标题在标题栏展示(虽然这看起来是一句废话,但是后面还有各种栏,还是要注意一下,多了就蒙了)。
w.show()show()能让控件在桌面上显示出来。控件在内存里创建,之后才能在显示器上显示出来。
sys.exit(app.exec_())最后,我们进入了应用的主循环中,事件处理器这个时候开始工作。主循环从窗口上接收事件,并把事件传入到派发到应用控件里。当调用exit()方法或直接销毁主控件时,主循环就会结束。sys.exit()方法能确保主循环安全退出。外部环境能通知主控件怎么结束。
exec_()之所以有个下划线,是因为exec是一个Python的关键字。
程序预览:
例2,带窗口图标
窗口图标通常是显示在窗口的左上角,标题栏的最左边。下面的例子就是怎么用PyQt5创建一个这样的窗口。
在某些环境下,图标显示不出来。如果你遇到了这个问题,看我在Stackoverfolw的回答
#!/usr/bin/python3# -*- coding: utf-8 -*-"""ZetCode PyQt5 tutorial This example shows an iconin the titlebar of the window.Author: Jan BodnarWebsite: zetcode.com Last edited: August 2017"""import sysfrom PyQt5.QtWidgets import QApplication, QWidgetfrom PyQt5.QtGui import QIconclass Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.setGeometry(300, 300, 300, 220) self.setWindowTitle('Icon') self.setWindowIcon(QIcon('web.png')) self.show()if __name__ == '__main__': app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_())前一个例子是使用的过程式编程。Python还支持面向对象的编程:
class Example(QWidget): def __init__(self): super().__init__() ...面向对象编程最重要的三个部分是类(class)、数据和方法。我们创建了一个类的调用,这个类继承自QWidget。这就意味着,我们调用了两个构造器,一个是这个类本身的,一个是这个类继承的。super()构造器方法返回父级的对象。__init__()方法是构造器的一个方法。
self.initUI()使用initUI()方法创建一个GUI。
# 自己准备一个web.pngself.setGeometry(300, 300, 300, 220)self.setWindowTitle('Icon')self.setWindowIcon(QIcon('web.png'))上面的三个方法都继承自QWidget类。setGeometry()有两个作用:把窗口放到屏幕上并且设置窗口大小。参数分别代表屏幕坐标的x、y和窗口大小的宽、高。也就是说这个方法是resize()和move()的合体。最后一个方法是添加了图标。先创建一个QIcon对象,然后接受一个路径作为参数显示图标。
if __name__ == '__main__': app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_())应用和示例的对象创立,主循环开始。
程序预览:
例3,提示框
#!/usr/bin/python3# -*- coding: utf-8 -*-"""ZetCode PyQt5 tutorial This example shows a tooltip on a window and a button.Author: Jan BodnarWebsite: zetcode.com Last edited: August 2017"""import sysfrom PyQt5.QtWidgets import (QWidget, QToolTip, QPushButton, QApplication)from PyQt5.QtGui import QFont class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): QToolTip.setFont(QFont('SansSerif', 10)) self.setToolTip('This is a QWidget widget') btn = QPushButton('Button', self) btn.setToolTip('This is a QPushButton widget') btn.resize(btn.sizeHint()) btn.move(50, 50) self.setGeometry(300, 300, 300, 200) self.setWindowTitle('Tooltips') self.show()if __name__ == '__main__': app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_())在这个例子中,我们为应用创建了一个提示框。
QToolTip.setFont(QFont('SansSerif', 10))这个静态方法设置了提示框的字体,我们使用了10px的SansSerif字体。
self.setToolTip('This is a QWidget widget')调用setTooltip()创建提示框可以使用富文本格式的内容。
btn = QPushButton('Button', self)btn.setToolTip('This is a QPushButton widget')创建一个按钮,并且为按钮添加了一个提示框。
btn.resize(btn.sizeHint())btn.move(50, 50)调整按钮大小,并让按钮在屏幕上显示出来,sizeHint()方法提供了一个默认的按钮大小。
程序预览:
例4,关闭窗口
关闭一个窗口最直观的方式就是点击标题栏的那个叉,这个例子里,我们展示的是如何用程序关闭一个窗口。这里我们将接触到一点single和slots的知识。
本例使用的是QPushButton组件类。
QPushButton(string text, QWidget parent = None)text参数是想要显示的按钮名称,parent参数是放在按钮上的组件,在我们的 例子里,这个参数是QWidget。应用中的组件都是一层一层(继承而来的?)的,在这个层里,大部分的组件都有自己的父级,没有父级的组件,是顶级的窗口。
#!/usr/bin/python3# -*- coding: utf-8 -*-"""ZetCode PyQt5 tutorial This program creates a quitbutton. When we press the button,the application terminates. Author: Jan BodnarWebsite: zetcode.com Last edited: August 2017"""import sysfrom PyQt5.QtWidgets import QWidget, QPushButton, QApplicationfrom PyQt5.QtCore import QCoreApplicationclass Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): qbtn = QPushButton('Quit', self) qbtn.clicked.connect(QCoreApplication.instance().quit) qbtn.resize(qbtn.sizeHint()) qbtn.move(50, 50) self.setGeometry(300, 300, 250, 150) self.setWindowTitle('Quit button') self.show()if __name__ == '__main__': app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_())这里创建了一个点击之后就退出窗口的按钮。
from PyQt5.QtCore import QCoreApplication程序需要QtCore对象。
qbtn = QPushButton('Quit', self)创建一个继承自QPushButton的按钮。第一个参数是按钮的文本,第二个参数是按钮的父级组件,这个例子中,父级组件就是我们创建的继承自Qwidget的Example类。
qbtn.clicked.connect(QCoreApplication.instance().quit)事件传递系统在PyQt5内建的single和slot机制里面。点击按钮之后,信号会被捕捉并给出既定的反应。QCoreApplication包含了事件的主循环,它能添加和删除所有的事件,instance()创建了一个它的实例。QCoreApplication是在QApplication里创建的。 点击事件和能终止进程并退出应用的quit函数绑定在了一起。在发送者和接受者之间建立了通讯,发送者就是按钮,接受者就是应用对象。
程序预览:
例5,消息盒子
默认情况下,我们点击标题栏的×按钮,QWidget就会关闭。但是有时候,我们修改默认行为。比如,如果我们打开的是一个文本编辑器,并且做了一些修改,我们就会想在关闭按钮的时候让用户进一步确认操作。
#!/usr/bin/python3# -*- coding: utf-8 -*-"""ZetCode PyQt5 tutorial This program shows a confirmation message box when we click on the closebutton of the application window. Author: Jan BodnarWebsite: zetcode.com Last edited: August 2017"""import sysfrom PyQt5.QtWidgets import QWidget, QMessageBox, QApplicationclass Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.setGeometry(300, 300, 250, 150) self.setWindowTitle('Message box') self.show() def closeEvent(self, event): reply = QMessageBox.question(self, 'Message', "Are you sure to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: event.accept() else: event.ignore() if __name__ == '__main__': app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_())如果关闭QWidget,就会产生一个QCloseEvent,并且把它传入到closeEvent函数的event参数中。改变控件的默认行为,就是替换掉默认的事件处理。
reply = QMessageBox.question(self, 'Message', "Are you sure to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No)我们创建了一个消息框,上面有俩按钮:Yes和No.第一个字符串显示在消息框的标题栏,第二个字符串显示在对话框,第三个参数是消息框的俩按钮,最后一个参数是默认按钮,这个按钮是默认选中的。返回值在变量reply里。
if reply == QMessageBox.Yes: event.accept()else: event.ignore()这里判断返回值,如果点击的是Yes按钮,我们就关闭组件和应用,否者就忽略关闭事件。
程序预览:
例6,窗口居中
#!/usr/bin/python3# -*- coding: utf-8 -*-"""ZetCode PyQt5 tutorial This program centers a window on the screen. Author: Jan BodnarWebsite: zetcode.com Last edited: August 2017"""import sysfrom PyQt5.QtWidgets import QWidget, QDesktopWidget, QApplicationclass Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.resize(250, 150) self.center() self.setWindowTitle('Center') self.show() def center(self): qr = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft())if __name__ == '__main__': app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_())QtGui.QDesktopWidget提供了用户的桌面信息,包括屏幕的大小。
self.center()这个方法是调用我们下面写的,实现对话框居中的方法。
qr = self.frameGeometry()获得主窗口所在的框架。
cp = QDesktopWidget().availableGeometry().center()获取显示器的分辨率,然后得到屏幕中间点的位置。
qr.moveCenter(cp)然后把主窗口框架的中心点放置到屏幕的中心位置。
self.move(qr.topLeft())然后通过move函数把主窗口的左上角移动到其框架的左上角,这样就把窗口居中了。
程序预览:
菜单和工具栏
这个章节,我们会创建状态栏、菜单和工具栏。菜单是一组位于菜单栏的命令。工具栏是应用的一些常用工具按钮。状态栏显示一些状态信息,通常在应用的底部。
主窗口
QMainWindow提供了主窗口的功能,使用它能创建一些简单的状态栏、工具栏和菜单栏。
主窗口是下面这些窗口的合称,所以教程在最下方。
状态栏
状态栏是用来显示应用的状态信息的组件。
#!/usr/bin/python3# -*- coding: utf-8 -*-"""ZetCode PyQt5 tutorial This program creates a statusbar.Author: Jan BodnarWebsite: zetcode.com Last edited: August 2017"""import sysfrom PyQt5.QtWidgets import QMainWindow, QApplicationclass Example(QMainWindow): def __init__(self): super().__init__() self.initUI() def initUI(self): self.statusBar().showMessage('Ready') self.setGeometry(300, 300, 250, 150) self.setWindowTitle('Statusbar') self.show()if __name__ == '__main__': app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_())状态栏是由QMainWindow创建的。
self.statusBar().showMessage('Ready')调用QtGui.QMainWindow类的statusBar()方法,创建状态栏。第一次调用创建一个状态栏,返回一个状态栏对象。showMessage()方法在状态栏上显示一条信息。
程序预览:
菜单栏
菜单栏是非常常用的。是一组命令的集合(Mac OS下状态栏的显示不一样,为了得到最相似的外观,我们增加了一句menubar.setNativeMenuBar(False))。
#!/usr/bin/python3# -*- coding: utf-8 -*-"""ZetCode PyQt5 tutorial This program creates a menubar. Themenubar has one menu with an exit action.Author: Jan BodnarWebsite: zetcode.com Last edited: January 2017"""import sysfrom PyQt5.QtWidgets import QMainWindow, QAction, qApp, QApplicationfrom PyQt5.QtGui import QIconclass Example(QMainWindow): def __init__(self): super().__init__() self.initUI() def initUI(self): exitAct = QAction(QIcon('exit.png'), '&Exit', self) exitAct.setShortcut('Ctrl+Q') exitAct.setStatusTip('Exit application') exitAct.triggered.connect(qApp.quit) self.statusBar() menubar = self.menuBar() fileMenu = menubar.addMenu('&File') fileMenu.addAction(exitAct) self.setGeometry(300, 300, 300, 200) self.setWindowTitle('Simple menu') self.show()if __name__ == '__main__': app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_())我们创建了只有一个命令的菜单栏,这个命令就是终止应用。同时也创建了一个状态栏。而且还能使用快捷键Ctrl+Q退出应用。
exitAct = QAction(QIcon('exit.png'), '&Exit', self) exitAct.setShortcut('Ctrl+Q')exitAct.setStatusTip('Exit application')QAction是菜单栏、工具栏或者快捷键的动作的组合。前面两行,我们创建了一个图标、一个exit的标签和一个快捷键组合,都执行了一个动作。第三行,创建了一个状态栏,当鼠标悬停在菜单栏的时候,能显示当前状态。
exitAct.triggered.connect(qApp.quit)当执行这个指定的动作时,就触发了一个事件。这个事件跟QApplication的quit()行为相关联,所以这个动作就能终止这个应用。
menubar = self.menuBar()fileMenu = menubar.addMenu('&File')fileMenu.addAction(exitAct)menuBar()创建菜单栏。这里创建了一个菜单栏,并在上面添加了一个file菜单,并关联了点击退出应用的事件。
程序预览:
子菜单
子菜单是嵌套在菜单里面的二级或者三级等的菜单。
#!/usr/bin/python3# -*- coding: utf-8 -*-"""ZetCode PyQt5 tutorial This program creates a submenu.Author: Jan BodnarWebsite: zetcode.com Last edited: August 2017"""import sysfrom PyQt5.QtWidgets import QMainWindow, QAction, QMenu, QApplicationclass Example(QMainWindow): def __init__(self): super().__init__() self.initUI() def initUI(self): menubar = self.menuBar() fileMenu = menubar.addMenu('File') impMenu = QMenu('Import', self) impAct = QAction('Import mail', self) impMenu.addAction(impAct) newAct = QAction('New', self) fileMenu.addAction(newAct) fileMenu.addMenu(impMenu) self.setGeometry(300, 300, 300, 200) self.setWindowTitle('Submenu') self.show()if __name__ == '__main__': app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_())这个例子里,有两个子菜单,一个在file菜单下面,一个在file的import下面。
impMenu = QMenu('Import', self)使用QMenu创建一个新菜单。
impAct = QAction('Import mail', self) impMenu.addAction(impAct)使用addAction添加一个动作。
程序预览:
勾选菜单
下面是一个能勾选菜单的例子
#!/usr/bin/python3# -*- coding: utf-8 -*-"""ZetCode PyQt5 tutorial This program creates a checkable menu.Author: Jan BodnarWebsite: zetcode.com Last edited: August 2017"""import sysfrom PyQt5.QtWidgets import QMainWindow, QAction, QApplicationclass Example(QMainWindow): def __init__(self): super().__init__() self.initUI() def initUI(self): self.statusbar = self.statusBar() self.statusbar.showMessage('Ready') menubar = self.menuBar() viewMenu = menubar.addMenu('View') viewStatAct = QAction('View statusbar', self, checkable=True) viewStatAct.setStatusTip('View statusbar') viewStatAct.setChecked(True) viewStatAct.triggered.connect(self.toggleMenu) viewMenu.addAction(viewStatAct) self.setGeometry(300, 300, 300, 200) self.setWindowTitle('Check menu') self.show() def toggleMenu(self, state): if state: self.statusbar.show() else: self.statusbar.hide()if __name__ == '__main__': app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_())本例创建了一个行为菜单。这个行为/动作能切换状态栏显示或者隐藏。
viewStatAct = QAction('