在Eric4下用PyQt4编写Python的图形界面程序

 

  本文是PyQt4的入门教程。网上能搜到其它教程,但我以为讲得不是很清楚,但愿这篇文章对入门者更加有帮助。html

 

  先介绍一下PyQt4。Qt4图形库一经发布就好评不断,它在Python下的绑定PyQt4更是让我眼前一亮,不但漂亮,并且开发程序很是方便。app

 

在我看来,PyQt4最大的改进之一是它再也不拘泥与各类布局控件了,也就是说,如今写图形界面程序,和VB同样能够直接拖控件到窗口上并随便改变大小和位置了,再也不像之前那样要先放上布局控件,再在布局控件里放其它控件。编辑器

 

对PyQt4的介绍就限于此,我也不许备把它与其它Python图形库进行比较了,由于经验代表这些东西的比较,特别是Qt与Gtk的比较老是会引发没必要要的争吵。函数

 

IDE我使用Eric4。Eric4自己是用PyQt4写的,在使用Eric4时就能体会到用PyQt4能写出多棒的图形界面程序。Eric4的详细介绍与安装请见个人其它文章。布局

 

操做系统是Windows,在Linux下的操做彻底同样。ui

 

寒喧结束,进入正题。假设咱们要用Python写一个图形界面程序,一个对话框,里面两个button一个label。点击其中一个button能改变label的内容,点击另外一个button就退出。编码

 

1. 新建工程。spa

打开Eric4,选择菜单Project->New新建一个工程,名字咱们取为HelloPyQt,填好各项并选择工程所在文件夹以后点OK,一个新的不含任何文件的工程就建好了。操作系统

 

2. 新建对话框。设计

在左侧的ProjectViewer中切换到Forms选项卡(左数第二个),右键点空白位置,选New Form,在弹出的对话框中选择Form类型为Dialog,而后会问你保存到哪。我设定为保存为HelloDlg.ui文件。点OK以后就会新建这个文件并自动打开QtDesigner。

 

3. 设计界面。

先修改主对话框的属性。选中对话框,在右侧的属性编辑器中就能够查看/修改对话框的属性。将windowTitle改成"Hello, PyQt",将objectName改成"HelloDlg”,前者是对话框标题,后者在之后生成代码时有用,不建议使用默认值。

 

咱们拖动一个Label(在DisplayWidgets分类中)到对话框中,将属性text改成"Hello, PyQt",objectName改成helloLabel。

 

再拖动两个PushButton(在Buttons分类中)到对话框,分别将属性text改成"你好"和"退出"。将属性objectName分别改成helloButton和exitButton。

 

界面大概是这个样子:


4. 处理事件。

在PyQt4下,事件处理方面的术语为“信号”和“槽”,即signal和slot。事件对应信号signal,而事件的处理函数则为slot槽。

 

PyQt4有一些预约义的slot,咱们能够直接用,好比“退出”按钮的slot,其实就是关闭对话框,这个slot已经在PyQt4中有定义了。对于这样的slot,咱们不用单独写代码,在QtDesigner中就能够完成。而对于“你好”按钮,咱们须要本身写代码。对于这样的slot,咱们在QtDesigner中不作任何处理,甚至不作定义。

 

那么在这个例子中,在QtDesigner里咱们只处理退出按钮的单击事件。

单击“编辑信号/槽”按钮进入信号/槽编辑模式。点中退出按钮并拖动,会出现一个像是电路图中的接地图示同样的东西,以下:

 



松开鼠标,就会弹出“配置链接”对话框。勾上“显示从QWidget继承的信号和槽”,左侧选择clicked(),右侧选择close(),点肯定,就OK了。

 

若是要继续调整对话框外观,点击“编辑窗口部件”按钮回窗口编辑模式。

 

5. 生成界面代码

保存以后关闭QtDesigner,会发现Eric4的ProjectViewer的Forms选项卡中已经多出HelloDlg.ui了。右击它选择Compile Form,就能生成Ui_HelloDlg.py文件,并自动加入到工程中。在Sources选项卡中能够看到。

 

双击Ui_HelloDlg.py能够看它的内容,实际上是生成了一个Ui_HelloDlg类。Ui_HelloDlg.py是能够单独运行的,在Eric4中直接按F2能够运行,看看初步的效果。发现单击退出按钮果真能直接退出程序。

 

不建议手动修改Ui_HelloDlg.py,由于每次改动界面并生成代码后会将手动进行的修改给覆盖掉。

 

6. 添加额外的代码。

 

“你好”按钮的单击处理代码还须要手写。

 

在PyQt4中,界面代码与事件代码是分开的,这一点很赞,这样每次改界面就不会影响到事件处理的代码了。而wxPython这一点就作得很差。

 

事件处理要新建一个类并继承HelloDlg类,而后在这个新类里写事件处理函数。新建类的工做能够交给Eric4来完成。右键点HelloDlg.ui,选择Generate Dialog Code,在弹出的对话框中设定ClassName为HelloDlg,同时,在这个对话框中能够选择咱们感兴趣的事件,Eric4会一并生成事件处理函数的定义。以下图:

点肯定以后,HelloDlg.py就生成了。打开这个文件,“你好”按钮的事件被定义为:

   

    @pyqtSignature("")

    def on_helloButton_clicked(self):

        """

       Slot documentation goes here.

        """

        # TODO: not implemented yet

        raise NotImplementedError

 

注意这个@pyqtSignature("")自动处理了下面定义的槽slot(事件处理函数)与相对应的信号signal(事件)之间的关联,这里是指,单击helloButton按钮,就会自动执行这个函数。slot的命名规则就是“on_对象名_信号名”,若是想添加新的slot,按这个规则来添加函数就行,而且在函数定义语句以前加上@pyqtSignature(""),不用再从新生成一次HelloDlg.py文件。

 

其实另一种关联signal与slot之间的方法是在运行里绑定,好比按钮对象aboutButton的clicked信号的槽是about_clicked函数,那么在__init__函数中加入这样一句话:

 

        self.connect(self.btnAbout, PyQt4.QtCore.SIGNAL("clicked()"), self.about_clicked)

 

那么单击按钮aboutButton时就会执行about_clicked函数。

 

两种方法各有长处。第一种方法简单,第二种方法对于多个signal使用同一个slot时颇有效。

将on_helloButton_clicked函数改成:

    @pyqtSignature("")

    def on_helloButton_clicked(self):

        self.helloLabel.setText("你好,PyQt4")

 

在文件头部加上:

 

import PyQt4, PyQt4.QtGui, sys

 

再在代码最后加上(与Ui_HelloDlg.py末的几乎同样):

 

if __name__ == "__main__":

    app = PyQt4.QtGui.QApplication(sys.argv)

    dlg = HelloDlg()

    dlg.show()

    sys.exit(app.exec_())

 

这样就OK了。

 

 

7. 最后的收尾工做。

按F2运行脚本,发现点击“你好”按钮后helloLable label中的文字是乱码。

 

解决办法很简单,把代码中的("你好,PyQt4")改成(u"你好,PyQt4")就好了。PyQt4对中文的支持是很好的。代码统一使用utf8编码,能省去不少麻烦。