第一个 PyQt4 的程序
本部分我们将学到一些基本的功能。
简单的例子
这里的代码非常简单。它仅仅显示一个小小的窗口。然后我们可以对这个窗口做很多事情。我们可以调正其大小,最大化,最小化。这个需要很多的代码。但某些人已经编写了这样的功能。因为在很多应用中重复出现了这样的代码,没有必要一再编写这样的代码。所以,对于程序员这样的代码就被隐藏了。PyQt4 是一个高层的工具。如果以更底层的开发,下面的例子可以要写上很多行。
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
ZetCode PyQt4 tutorial
In this example, we create a simple
window in PyQt4.
author: Jan Bodnar
website: zetcode.com
last edited: October 2011
"""
import sys
from PyQt4 import QtGui
def main():
app = QtGui.QApplication(sys.argv)
w = QtGui.QWidget()
w.resize(250, 150)
w.move(300, 300)
w.setWindowTitle('Simple')
w.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
上面的代码将会在屏幕上显示一个小窗口。
import sys
from PyQt4 import QtGui
这里我们提供一些必要的导入。最基本的 GUI widget 都在 QtGui 模块中。
app = QtGui.QApplication(sys.argv)
每个 PyQt4 应用必须创建一个 application 对象。此 application 对象处于 QtGui 模块中。参数 sys.argv 是从命令行获取的参数列表。Python 脚本可以从 shell 中运行。这是一种控制启动我们脚本的方式。
在 PyQt4 中, QtGui.QWidget 是所有用户接口对象的基类。我们提供了 QtGui.QWidget 的默认构造函数。默认的构造函数没有父类。一个没有父类的 widget 称为一个窗口。
resize() 方法调正了 widget 的大小。它宽 250px ,高 150px 。
move() 方法把 widget 移到屏幕坐标为 x = 300, y = 300 的地方。
w.setWindowTitle('Simple')
这里,我们设置了窗口的标题。标题在标题栏中显示。
show() 方法把这个 widget 显示到屏幕上。一个 widget 最先在内存中创建,然后显示于屏幕上。
最后,我们进入程序的主循环。事件的处理就从此时开始。主循环接受从窗口系统发送的事例,并把它们发给应用的 widget 。如果我们调用了 exit() 或者主窗口被销毁,主循环就终止了。 sys.exit() 方法确保完全退出。整个环境将被通知应用如何终止。
exec_() 方法有一个下划线。这是由于 exec 是 Python 中的关键字。因此使用了 exec_() 。
一个应用的图标
应用的图标就是一块小的图像,显示于标题栏的左上角。下面的例子讲说明在 PyQt4 中是怎么做的。我们也会接受一些新的方法。
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
ZetCode PyQt4 tutorial
This example shows an icon
in the titlebar of the window.
author: Jan Bodnar
website: zetcode.com
last edited: October 2011
"""
import sys
from PyQt4 import QtGui
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.setGeometry(300, 300, 250, 150)
self.setWindowTitle('Icon')
self.setWindowIcon(QtGui.QIcon('web.png'))
self.show()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
先前的例子是以过程式编写的。Python 支持过程式和面向对象式的编程。在 PyQt4 中编程就意味着以 OOP 编程。
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
在面向对象编程中三个最重要的东西是类,数据及方法。这里,我们创建了一个新的类称为 Example 。这个类从 QtGui.QWidget 派生。这就意味着我们必须调用两个构造器。第一个是 Example 这个类,第二个是被继承的类。 super() 方法就返回了 Example 的父对象,然后我们调用了其构造器。在 Python 中 __init__() 是构造器。
GUI 的创建就委托给了 initUI() 这个方法。
self.setGeometry(300, 300, 250, 150)
self.setWindowTitle('Icon')
self.setWindowIcon(QtGui.QIcon('web.png'))
这三个方法都是从类 QtGui.QWidget 中继承下来的。 setGeometry() 做了两件事情。首先是定位,然后是设置窗口大小。
前两个参数是窗口的 x 和 y 。第三个参数是宽度,第四个是高度。事实上,它结合了 resize() 和 move() 。最后一个方法设置了应用的图标。为此,我们创建了 QtGui.QIcon 对象。 QtGui.QIcon 接受要显示图标的路径。
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
启动代码放在了 main() 方法中。这是 Python 的惯用方式。
显示提示
我们可以给任何一个 widget 提供 balloon 式的提示。
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
ZetCode PyQt4 tutorial
This example shows a tooltip on
a window and a button
author: Jan Bodnar
website: zetcode.com
last edited: October 2011
"""
import sys
from PyQt4 import QtGui
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
QtGui.QToolTip.setFont(QtGui.QFont('SansSerif', 10))
self.setToolTip('This is a <b>QWidget</b> widget')
btn = QtGui.QPushButton('Button', self)
btn.setToolTip('This is a <b>QPushButton</b> widget')
btn.resize(btn.sizeHint())
btn.move(50, 50)
self.setGeometry(300, 300, 250, 150)
self.setWindowTitle('Tooltips')
self.show()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
在这个例子中,我们给 widget 都设置了 tooltip 。
QtGui.QToolTip.setFont(QtGui.QFont('SansSerif', 10))
这个静态方法设置了 tooltip 的字体。我们使用 10px 的 SansSerif 字体。
self.setToolTip('This is a <b>QWidget</b> widget')
为了创建 tooltip, 我们调用了 setTooltip() 方法。我们可以使用富文本格式(rich text formatting)。
btn = QtGui.QPushButton('Button', self)
btn.setToolTip('This is a <b>QPushButton</b> widget')
我们创建了一个按钮并为它设置了 tooltip 。
btn.resize(btn.sizeHint())
btn.move(50, 50)
这个按钮被重新设置大小并移到窗口相应的位置。 sizeHint() 方法给出一个推荐的大小。
关闭窗口
关闭窗口最直观的方式就是点击标题栏上的 x 。在后面的例子中,我们将会展示如何编程来关闭窗口。我们将会简单的接触信号(signal)和槽(slot)。
下面是 QtGui.QPushButton 的构造器,我们将在例子中用到。
QPushButton(string text, QWidget parent = None)
参数中的 text 是将在按钮中显示的文字。而 parent 则是将要放置我们按钮的 widget 。在我们这个情况下则是 QtGui.QWidget 。
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
ZetCode PyQt4 tutorial
This program creates a quit
button. When we press the button,
the application terminates.
author: Jan Bodnar
website: zetcode.com
last edited: October 2011
"""
import sys
from PyQt4 import QtGui, QtCore
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
qbtn = QtGui.QPushButton('Quit', self)
qbtn.clicked.connect(QtCore.QCoreApplication.instance().quit)
qbtn.resize(qbtn.sizeHint())
qbtn.move(50, 50)
self.setGeometry(300, 300, 250, 150)
self.setWindowTitle('Quit button')
self.show()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
在这个例子中,我们创建了一个退出按钮。按了这个后,应用就将结束。
from PyQt4 import QtGui, QtCore
在这个例子中,我们用到了 QtCore 模块中的一个对象。
qbtn = QtGui.QPushButton('Quit', self)
我们创建了一个按钮。这个按钮是 QtGui.QPushButton 的实例。第一个参数是按钮的标签。第二个是父 widget 。此处的父 widget 是 Example 这个 widget。
qbtn.clicked.connect(QtCore.QCoreApplication.instance().quit)
在 PyQt4 中,事件系统(event processing system)建立于信号和槽机制。如果我们点击了一个按钮,点击的信号就被发送了。槽可以是 Qt 的槽或者任何 Python 可调用的。 QtCore.QCoreApplication 包含了事件的主循环。它处理所有的事件。 instance() 方法给我们它当前的实例。注意, QtCore.QCoreApplication 是和 QtGui.QApplication 一起创建的。点击的信号则和终止应用的 quit() 方法连接了起来。通信是在两个对象间完成。一个是发送者,也就是按钮,另一个是接受者,就是应用对象。
消息框
默认情况下,如果我们点击了关闭按钮, QtGui.QWidget 就被关闭了。有些时候我们需要修改默认的行为。例如,如果在编辑器中我们对某文件进行了修改。那么我们退出时就要弹出消息框进行确认。
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
ZetCode PyQt4 tutorial
This program shows a confirmation
message box when we click on the close
button of the application window.
author: Jan Bodnar
website: zetcode.com
last edited: October 2011
"""
import sys
from PyQt4 import QtGui
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.setGeometry(300, 300, 250, 150)
self.setWindowTitle('Message box')
self.show()
def closeEvent(self, event):
reply = QtGui.QMessageBox.question(self, 'Message',
"Are you sure to quit?", QtGui.QMessageBox.Yes |
QtGui.QMessageBox.No, QtGui.QMessageBox.No)
if reply == QtGui.QMessageBox.Yes:
event.accept()
else:
event.ignore()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
如果我们关闭 QtGui.QWidget ,就会产生 QtGui.QCloseEvent 。为了修改 widget 的行为,我们需要重新实现 closeEvent() 。
reply = QtGui.QMessageBox.question(self, 'Message',
"Are you sure to quit?", QtGui.QMessageBox.Yes |
QtGui.QMessageBox.No, QtGui.QMessageBox.No)
我们的消息框中有两个按钮, Yes 和 No 。第一个字符串显示在标题栏上。第二个则是对话框中的消息。第三个参数指定了要显示的按钮。最后的则是默认的按钮。焦点是默认在这个按钮上。返回值存在 reply 变量中。
if reply == QtGui.QMessageBox.Yes:
event.accept()
else:
event.ignore()
这里,我们可以测试返回值。如果我们点击了 Yes 按钮,我们接受了关闭应用的事件。否则,忽略这个事件。
居中窗口
下面的脚本将会演示如何把窗口在屏幕中居中。
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
ZetCode PyQt4 tutorial
This program centers a window
on the screen.
author: Jan Bodnar
website: zetcode.com
last edited: October 2011
"""
import sys
from PyQt4 import QtGui
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.resize(250, 150)
self.center()
self.setWindowTitle('Center')
self.show()
def center(self):
qr = self.frameGeometry()
cp = QtGui.QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
将会把窗口居中。
把窗口居中的代码放在了自定制的 center() 方法中。
qr = self.frameGeometry()
我们得到一个指定主窗口几何的矩形。这个包含任何窗口框架。
cp = QtGui.QDesktopWidget().availableGeometry().center()
我们计算出显示器的分辨率,并且从分辨率中得到了中间点。
我们的矩形已经有其宽度和高度了。现在,我们把矩形的中心移到屏幕的中心。矩形的大小并未改变。
我们应用窗口的左上角移到 qr 的左上角,这样就完成了居中。
在本部分,我们涉及一些基本的知识。