关于PyQt示例程序

时间:2012-08-03 06:35:39

标签: python qt pyqt

我目前需要一个项目的GUI库。我熟悉python,发现PyQt可能是个不错的选择。

我正在阅读a tutorial about PyQt,并对以下example program

感到困惑
#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
ZetCode PyQt4 tutorial 

In this example, we draw text in Russian azbuka.

author: Jan Bodnar
website: zetcode.com 
last edited: September 2011
"""

import sys
from PyQt4 import QtGui, QtCore

class Example(QtGui.QWidget):

    def __init__(self):
        super(Example, self).__init__()

        self.initUI()

    def initUI(self):      

        self.text = u'\u041b\u0435\u0432 \u041d\u0438\u043a\u043e\u043b\u0430\
\u0435\u0432\u0438\u0447 \u0422\u043e\u043b\u0441\u0442\u043e\u0439: \n\
\u0410\u043d\u043d\u0430 \u041a\u0430\u0440\u0435\u043d\u0438\u043d\u0430'

        self.setGeometry(300, 300, 280, 170)
        self.setWindowTitle('Draw text')
        self.show()

    def paintEvent(self, event):

        qp = QtGui.QPainter()
        qp.begin(self)
        self.drawText(event, qp)
        qp.end()

    def drawText(self, event, qp):

        qp.setPen(QtGui.QColor(168, 34, 3))
        qp.setFont(QtGui.QFont('Decorative', 10))
        qp.drawText(event.rect(), QtCore.Qt.AlignCenter, self.text)        


def main():

    app = QtGui.QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

这里,在main函数中,创建了一个Example对象,因此调用了__init__()函数initUI()。 我的问题是paintEvent()函数在哪里被调用?因为如果我们运行程序,self.text(some Russian letters)将完全出现在小部件上。

换句话说,sys.exit(app.exec_())实际上做了什么?为什么它会调用paintEvent()函数?

谢谢!

3 个答案:

答案 0 :(得分:8)

来自PyQt docs

  

int QApplication.exec_ ()

     

进入主事件循环并等待exit()被调用,然后   返回设置为exit()的值(如果exit()为0则为0   通过quit())调用。

     

必须调用此函数才能启动事件处理。该   主事件循环从窗口系统接收事件并发送   这些应用程序小部件。

来自another source

  

sys.exit(app.exec_())

     

最后,我们进入了主循环   应用。事件处理从这一点开始。主循环   从窗口系统接收事件并将它们发送到   应用程序小部件。如果我们调用exit()方法,则主循环结束   或主要小部件被销毁。 sys.exit()方法可确保清洁   出口。将通知环境,应用程序如何结束。

     

exec_()方法有下划线。这是因为exec是一个   Python关键字。因此,改为使用exec_()

关于painting

  

<强> 4.2.1。当绘画发生时

     

时会自动调用paintEvent()方法      
      
  • 您的小部件首次显示。

  •   
  • 移动窗口后显示部分(或全部)   窗口小部件。

  •   
  • 小部件所在的窗口在最小化后恢复。

  •   
  • 调整小部件所在的窗口的大小。

  •   
  • 用户从另一个桌面切换到桌面上   小部件的窗口在于。

  •   
     

您可以通过调用QWidget::update()手动生成绘画事件。   QWidget::update()在生成绘制事件之前擦除小部件。   您可以将参数传递给update(),这可以仅限制绘画   到需要它的区域(特别是矩形)。两个相当   该方法的形式为QWidget::update (int x, int y, int width, int height)QWidget::update (QRect rectangle),其中xy给出了   矩形的左上角,宽度和高度都很明显。   因为update()将一个绘制事件放入事件队列中,所以没有   绘制发生,直到当前方法退出并且控制返回   事件处理程序。这是一件好事,因为其他事件可能是   等待处理,需要处理事件   及时使GUI顺利运行。

     

您还可以通过调用QWidget::repaint (int x, int y, int width, int height, bool erase)(或其中一个)来调用窗口小部件的绘制   方便方法形式),其中所有参数与in中的相同   update()方法的情况,擦除告诉重绘是否   在绘制之前擦除矩形。 repaint()来电paintEvent()   直。它不会将paint事件放入事件队列中,因此请使用   这种方法要小心。如果您尝试反复拨打repaint()   用于创建动画的简单循环,例如,动画将是   已绘制,但您的用户界面的其余部分将无法响应   因为鼠标按键对应的事件,键盘   按,等等将在队列中等待。即使你不是   执行任务可能像动画一样耗费时间   通常最好使用update()来帮助保持GUI的活跃。

     

如果您在paintEvent()之外的小部件上绘制某些内容,则表示您   仍然需要包含绘制它所需的逻辑和命令   paintEvent()中同样的事情。否则,你做的画会   下次更新小部件时消失。

答案 1 :(得分:1)

app.exec_()启动qt主循环,该循环在每个创建的小部件被销毁时结束(例如,通过关闭其窗口)。 paintEvent函数是一个方法,您可以从QWidget子类重载,如给定的Example类,当QT显示,更新或重新绘制Widget时,它会被调用。

您可以在Qt documentationPyQt Documentation中查找这些内容(这些内容大多只是QT文档的副本,格式不同,但有时会包含一些有关PyQt特定内容的重要信息)。

答案 2 :(得分:1)

当一个人有一些低级编程经验时,会变得更加清晰 例如在Winapi或C语言的X工具包中。 PyQt是一个(非常)高级工具包。 它具有巨大的内置功能。类似的例子需要数百甚至数千行C代码。因此,有很多事情要发生 在幕后。有人已经创建了在基本级别处理绘画的代码。 GUI编程非常复杂,使用现代GUI工具包,应用程序员可以避免这种复杂性。如果程序员不了解所有技术细节,那就不可避免地会感到困惑。

在PyQt中,我们基本上以两种方式处理事件。我们将信号连接到插槽或重新实现事件处理程序(事件处理程序是插槽的同义词)。提供的示例继承自QtGui.QWidget,其中已有一些绘制代码可用。 为了进行自定义绘画,我们必须重新实现现有的paintEvent()事件 处理程序。根据具体情况,我们可能会或可能不会调用父母的paintEvent()方法。

sys.exit(app.exec_())未调用paintEvent()方法。 exec_()方法启动事件循环。事件循环捕获和分派事件。绘制事件由用户或操作系统触发。例如,当我们启动示例时, paint事件被触发两次。 (在事件处理程序中放置一个print "Event occurred"行,以查看调用此方法的次数。)调整窗口大小,放松或获得焦点,最小化或最大化窗口,所有这些都会导致绘制事件被触发。