要在Linux下开发具有图形界面的桌面应用程序,我们有许多选择。当然,除了语言方面的考虑外,我们更多的是考虑窗口部件工具箱(以前称为控件库或组件库)的选择,这将在很大程度上影响我们的开发效率。
如果考虑到跨平台应用,选择Java的Swing可能非常合适。但是目前的swing尽管很强大也很灵活,我们始终还是会觉得有些不顺手:例如默认的界面不好看也不像本地程序,第三方皮肤又不好找;开发周期相对较长;执行速度相对慢些等等。
除了java之外,在Windows下,我们一般可以在MFC(VC)和VCL(Delphi)中作选择(当然还有别的);在Linux下,我们可以选择QT或GTK。
QT具有相当不错的架构以及先进的事件处理机制,文档也很齐全,当然还少不了一个功能不错的可视化窗体设计器QtDesigner。著名的桌面环境KDE就是使用qt库进行开发的。
GTK的架构也不错,不过界面相对而言没有qt的那么炫目。gtk当然也有自己的可视化窗体设计器glade。另一个著名的桌面环境gnome就是使用gtk库进行开发的。另外,gtk也获得了广泛的商业支持。
就我个人而言,我更喜欢qt,桌面环境也更喜欢kde,因为界面确实很漂亮,看着养眼;执行效率也很不错。更重要的是,使用qt进行rad快速开发似乎更为方便。
可惜在linux下使用c++开发程序并非易事,至少你得先熟悉gnu版本的c/c++库才行。我虽然很希望能使用qt做出漂亮的gui桌面应用,但是面对c++本身的复杂以及完全陌生的函数库,我望而却步。
这时,我发现了python。这是一种很简单的脚本语言,其语言特性本身就十分简单易用。更惊人的是,这种语言还可以绑定到多种部件工具箱,包括GTK、QT、MFC、Swing等!而Pyqt就是python和qt部件库的结合。简单易用的python配合强大方便的qtdesigner,我找到了当年在windows下使用vb编程的感觉。
为了使用pyqt进行编程,首先是安装和配置系统环境。我的环境如下:Kubuntu Linux breezy(5.10);python 2.4;qt 3.3;pyqt 3.14;KDE 3.5。
当然,这样还不够。我们当然可以使用记事本kate来编写代码,但是一款好用的IDE将能够使我们的开发工作事半功倍。我们可以选择KDevelop或者Eric。
KDevelop是KDE下老牌的IDE了,支持N多种语言的开发,其中也包括python,还自带了pyqt的示例程序。
不过,我还是选择了Eric。Eric是KDE下的python集成开发环境,本身就是用pyqt开发的(由此可以看出pyqt的强大……)。eric同样集成了版本管理系统、项目管理、重构等功能。和kdevelop相比,eric中的源代码分类功能更方便,py脚本、qt窗体、语言包等文件是分类管理的。除了任务窗格外,eric还集成了一个python的shell控制台窗格,显得更加适合开发pyqt程序。
一个简单的示例
下面实验一下,使用Eric 3.7来开发一个简单的Helloworld程序。
我们将要使用qtdesigner设计一个窗体,上面放置一个按钮和一个label,点击按钮时显示Hello World,再次点击时则隐藏。
首先我们需要建立一个新工程。
打开Eric后,选择Project->New,然后是填写工程信息。在Project Name栏中填写工程名称,Prog. Language选择Python,UI Type选择QT,Project Directory中选择工程的目录,其他的几项可填可不填,点击<确定>即可。
接下来Eric会询问新工程要使用什么版本控制系统,这里我们还没用到版本控制,就选<无>吧。
现在要新建一个窗体。在左边的工程浏览器切换到窗体标签页,在右键菜单中选择<New Form>。
Eric会询问新窗体的类型,简单起见,我们选择<Dialog>,点击<确定>后输入新窗体的文件名HelloDialog并点击<保存>。
这时Eric会启动窗体设计器QTDesigner(我系统上用KDevDesigner代替了)并打开新窗体。
QtDesigner的使用相当简单,相信用过delphi或者vb的朋友都不会陌生。这里就不详述其用法了。
在窗体上加入一个PushButton和一个TextLabel,各部件属性设置如下:
部件 |
属性 |
值
|
Form
|
name
|
helloForm
|
|
caption
|
Pyqt示例
|
TextLabel
|
name
|
helloText
|
|
text
|
Hello, world!
|
PushButton
|
name
|
showHelloButton
|
|
text
|
打个招呼(&H)
|
调整部件的位置和大小,如图所示。
QT库中的事件处理使用的是信号/插槽(Signal/Slot)机制,现在我们需要准备自定义的事件处理插槽。
在主菜单选择Edit->Slots,点击<New Function>来新建一个插槽函数toggleHelloTextVisibility()。
接着就要将按钮的点击信号连接到这个插槽上。在主菜单选择Edit->Connections,新建一个连接。
Sender选择showHelloButton,Signal选择clicked,Receiver选择helloForms,Slot就选择刚刚新建的插槽函数toggleHelloTextVisibility,点击<确定>即可。
好了,窗体制作完成啦,现在按Ctrl+S保存吧。
现在回到Eric中,我们会看到新建的窗体HelloDialog.ui已经出现在窗体标签页中了。
要把窗体文件编译为一个python单元,我们需要使用pyuic命令。而当未来窗体文件发生改变时,eric可以自动运行pyuic命令来更新相应的python单元。因此,我们不能直接修改生成的python单元,而需要继承它。
在Eric中,这一切都很简单。首先选中这个窗体,在快捷菜单中选择Compile Form,Eric会自动编译窗体,并将生成的窗体单元加入到工程中。然后我们要继承它,在快捷菜单中选择Generate Subclass,输入子类名并确定。
在新的子类单元中,找到插槽函数toggleHelloTextVisibility,修改如下:
def toggleHelloTextVisibility(self):
if(self.helloText.isVisible()):
self.helloText.hide()
else:
self.helloText.show()
然后按Ctrl+S将子类保存到工程目录下,命名为HelloForm_Impl.py。
在工程浏览器中选择源代码(Sources)标签页,可以看到窗体单元HelloDialog.py已经在工程中了,但新的子类单元还不在其中,我们需要将其手动加入。
在工程浏览器的快捷菜单中选择<Add source file>,并选择刚才建立的子类单元HelloForm_Impl.py,确定即可。
下面我们还需要一个启动单元作为工程的主单元。当然,直接把这些代码放在HelloForm_Impl.py中也是可以的,不过为了清晰起见,我们最好还是另外建立一个启动单元。
按Ctrl+N来建立一个新文件,在其中输入以下代码:
#!/usr/bin/env python
import sys
from qt import *
from HelloForm_Impl import HelloForm_Impl
def main(args):
app=QApplication(args)
window=HelloForm_Impl()
window.show()
app.connect(app,SIGNAL("lastWindowClosed()"),app,SLOT("quit()"))
app.exec_loop()
if __name__=="__main__":
main(sys.argv)
以上代码创建了一个QApplication对象,并将我们的HelloForm_Impl类作为其主窗体显示,当主窗体关闭时退出程序。
按Ctrl+S将新文件保存为SayHello.py,然后把它加入到工程中。
从主菜单中选择 Project->Properties 打开工程属性对话框,将其中的主单元(Main Script)一项改为SayHello.py。
现在,按下Shift+F2来运行一下看看最终效果吧!点击按钮即可切换Label的显示状态。
小结
呵呵,怎么样,是不是很有VB的感觉呢?从这个简单的例子就可以看出,Pyqt用于RAD开发GUI桌面应用是相当不错的,至少比Java、C++都要简单得多。除了能够使用python本身的系统函数之外,我们还可以直接调用qt的各种类,也能借助qt的信号/插槽机制轻松实现事件处理。
另外,我们还可以借由pyqt开发原型程序,在正式版开发时可以很轻松的将其转换为C/C++程序。
不过,由于绑定了qt库,pyqt在跨平台运行时,就要求目标平台必须安装有qt运行库。这也就是和java相比的一个不足之处了。
参考资料
中国Python社区GTK可视化窗体设计器Glade官方网站QT官方网站Eric Python集成开发环境官方网站《Dive Into Python》简体中文版《GUI Programming with Python: QT Edition》:Pyqt编程指南