2005年07月03日

在前面的Blog中我写到我自已在Windows编译了 Qt 3.x和 PyQt 。不过Eric3运行不起来。由于开始学 PyQt 了,今天上到 Eric3 的主页发现一个链接 (http://pythonqt.vanrietpaap.nl/)。上到这个链接你会发现 PyQt 的windows下GPL版的安装包和 Eric3 的snapshot版的安装包。

这个安装包要求你的 Python 的版本是 2.4 的。不象我自已编译的是2.3的。安装它后,它会自动将所要用到的 qt 的动态库也自动安装。这样非常方便,不用再自已编译  Qt 了。

如果有想在 Windows 下学 PyQt 的,这是一个非常好的选择。不过 Eric3 我运行依然是报错。不过从 Eric3 的截屏可以看到它支持cvs, SubVersion, 调试,甚至还支持 Ruby 。功能的确强大。随着 for QT 4.0 的 PyQt 的出现,我想 PyQt 下的软件会越来越多。上到 PyQt 的 wiki 可以看到使用它的应用软件还不多,不过有一个 veusz 的plot生成软件感觉还不错,不过还没怎么样,还不知道对汉字的支持如何。

我还订阅了 PyKde 邮件列表,但从以前的邮件数量可以看出可能是由于版权的问题,邮件的确没有 wxPython 多。

教程在这里

这个教程以图解的形式一步步地演示了如何使用QtDesigner来开发 PyQt 的程序。的确,有了方便的设计工具可以加快在界面设计中所用的时间。不过,在某些时候使用代码来生成界面,速度和代码的清简洁上要好很多,但比较适合于老手。

于是我按照这个教程一步步地进行。可以看出它使用的 Designer 是3.0的。因为我3.0和4.0的都有。但当我做到在 Form1 中定义新的 slot 时,我在 3.0 中找不到哪里可以找到 form1.ui.h 这个指引。但在 object/member 属性框中可以找到新加入的 slot 函数 AddEntry() 。不过当我一点击告诉我没有安装可以编译C++的插件,因此无法编辑。当我改为 4.0 的 Designer 时,根本连在哪里增加自定义 slot 的地方都没有,差别真是很大。对 singal/slot 的绑定,3.0与4.0的界面都不一样了。从使用上感到 4.0 去掉了一些东西,但似乎要好于 3.0 。看来不手工生成代码是不行了。既然如此我就不再试验这个教程了。

4.0生成的ui文件,使用3.0的pyui处理有错。只要把ui文件开头的4.0版本号改为3.0即可。必竟只要使用基本的组件,应该不会有什么问题的。

不过上面的教程用来体会一下使用 Designer 和 PyQt 结合的处理过程也是有好处的。有兴趣可以看一看 PyQt 的wiki。我就是在上面发现的。

2005年07月01日

这个问题是在  PyQt 的教程上看到的。一个简单的完整程序如下:

import sys
from qt import *
class HelloButton(QPushButton):
    def __init__(self, *args):
        QPushButton.__init__(self, *args)
        self.setText("Hello World")
class HelloWindow(QMainWindow):
    def __init__(self, *args):
        QMainWindow.__init__(self, *args)
        self.button=HelloButton(self)
        self.setCentralWidget(self.button)
        self.connect(self.button, SIGNAL("clicked()"),
                     self, SLOT("close()"))
def main(args):
    app=QApplication(args)
    winlist=[]
    for i in range(10):
        win=HelloWindow()
        win.show()
        winlist.append(win)

    app.connect(app, SIGNAL("lastWindowClosed()"),
                app, SLOT("quit()"))
    app.exec_loop()
 
if __name__=="__main__":
    main(sys.argv)

上面的程序运行后会创建10个窗口。但一旦你把红色背景的代码注释掉会发现什么。结果是只剩下了一个。为什么呢?这就是因为如果注释掉那行代码,win是一个无人使用的对象,因此 Python 会尽可能地销毁它。结果就是你看到的结果。因此 winlist.append(win) 的作用就是将对象保存住。

记得以前在编 NewEdit 时出现过图像列表也是没有存住的问题,就是这个原因,后来把对象绑定到类实例上才正确了。对于想要保持的对象,如何使它有效有时需要注意,不然很可能出现一些错误。

在上面那个 Hello, world 例子学完之后,我已经知道了基本的程序结构,比如要创建 QApplication 对象,要设置主控件(窗体),然后显示它,再进入事件循环。看上去好象没什么,但下面这个例子就复杂多了,它要进行事件处理了。Qt 的事件处理采用了Signal和Slot的方式,以前看过,好象是说不象一般的事件回调的处理,是不是异步调用呢。而且说是比事件回调要灵活得多。在IBM的开发网站上有一篇关于 PyQt  的文章,看这里。这篇文章上有一些说明,并有一些对事件回调与 Qt 的信号/槽的比较,大家可以看一看。

这个例子的代码如下:

1       import sys
2       from qt import *
3      
4       class HelloButton(QPushButton):
5      
6           def __init__(self, *args):
7               QPushButton.__init__(self, *args)
8               self.setText("Hello World")
9      
10      class HelloWindow(QMainWindow):
11     
12          def __init__(self, *args):
13              QMainWindow.__init__(self, *args)
14              self.button=HelloButton(self)
15              self.setCentralWidget(self.button)
16     
17      def main(args):
18          app=QApplication(args)
19          win=HelloWindow()
20          win.show()
21          app.connect(app, SIGNAL("lastWindowClosed()"),
22                      app, SLOT("quit()"))
23          app.exec_loop()
24     
25      if __name__=="__main__":
26          main(sys.argv)

不过这个例子与教程的例子有区别。主要是在对基类的构造函数的调用上。原教程的调用是:

apply(QPushButton.__init__, (self,) + args)

它使用了apply方法,但这个方法已经不再建议了。于是我改成了上面的样子。

程序从整体上没什么好讲的。主要的改动就是:

  1. 创建了主窗体
  2. 使用了信号和槽

主要需要注意的就是:

    app.connect(app, SIGNAL("lastWindowClosed()"),
                app, SLOT("quit()"))

在Qt中connect其实是QObject的一个静态方法。connect()方法的原型为:

connect(sender, signal, receiver, member)

sender是发生器,signal是发出的信号,receiver是接收器,member是槽。在 Qt 所带的文档(你也可以去这里看到中文的译文,不过不是最新的)中有详细的关于信号和槽的说明。

今天开始学 PyQt ,不过因为工作忙,不知道可以坚持多久。

接下来的学习我主要是根据这本电子书《GUI Programming with Python: QT Edition》开始的。学习以试验源码为主,也许就是抄了,不过这样还是会的印象的。其实就我的学习经验来说,如何入门,如何写出一些简单的程序是非常重要的,感性认识是第一位。有了感性认识然后根据自已的需要再深入下去即可。必竟QT的东西非常多,在短时间内全部学会也是不可能的,就是长时间也未必。

至于 PyQt 的安装我就不说了。因为Linux下的可能会好一些。但在 Windows 下的,因为 for qt4 的包还没有出来,因此我现在学习还是使用 pyqt 3版本的。这个版本是我自已编译的。在以前的 Blog 中有说明,有兴趣可以查一查。的确有些麻烦。但先学一些基本的概念就行了,也许很快 PyQt 4.0 就出来了。

看下面的代码:

1       import sys
2       from qt import *
3       app=QApplication(sys.argv)
4       button=QPushButton("Hello World", None)
5       app.setMainWidget(button)
6       button.show()
7       app.exec_loop()

1-2 没什么可说的。
3 创建一个应用对象,这里可以把sys.argv(命令行参数)传给QApplication对象。我试了,如果不传就报错。
4 创建一个按钮,它的第一个参数是文本,第二个是父窗口。因为它将作为第一个窗口,因此父窗口那个参数为None。如果不传则报错。
5 设置主控件
6 显示出来
7 进入事件循环。在C++下是exec(),但在 Python 中因为exec是关键字,因此改为了exec_loop()。

好了运行一下。效果为:

然后我把按钮上的文字改为了中文,使用或不使用Unicode都可以正确显示。因为只是一个简单的测试还不能充分说明什么,不过挺方便的。

2005年06月30日

这次发布最令人兴奋的应该是终于昐来了Windows下的GPL版权的开源版,开发开源的QT程序没有问题了。希望PyQT早点出来。

此则消息最早是在 Python.cn 邮件列表中的alang yin发布出来的,于是我连夜下载。今天在 Windows XP 下装上了,并且看了它的演示程序。真是让我看得喜不自胜。看到这样好的一个软件,又可以方便地使用真是快哉!快哉!

而且我特别发现它的演示在sql中有一个qsqlite(在demonstration->SQL browser中)的驱动可以直接访问sqlite 3的数据库。我的项目数据库用它就可以访问。感觉非常好。还有它的图形示真好看。

有时间开始学QT了。

在QT的网站上面有他们的开发团队表演的一段视频,有舞蹈、有唱歌。动作很简单,但看到他们高兴的样子,不禁也被感染了。

这里在视频中他们摆成的图案。

BTW: QT在中国也有公司,网站在这里。但这里到目前为止还没有发布关于QT 4.0的任何消息,反应好慢呀。