关于PyQt示例程序

Jun*_*jie 9 python qt pyqt

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

我正在阅读有关PyQt的教程,并对以下示例程序感到困惑

#!/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()
Run Code Online (Sandbox Code Playgroud)

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

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

谢谢!

war*_*iuc 8

来自PyQt文档:

int QApplication.exec_ ()

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

必须调用此函数来启动事件处理.主事件循环从窗口系统接收事件并将这些事件分派给应用程序窗口小部件.

另一个来源:

sys.exit(app.exec_())

最后,我们进入应用程序的主循环.事件处理从这一点开始.mainloop从窗口系统接收事件并将它们分派给应用程序小部件.如果我们调用exit()方法或主窗口小部件被销毁,则mainloop结束.该sys.exit()方法确保干净的退出.将通知环境,应用程序如何结束.

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

关于绘画:

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()将paint事件放入事件队列,所以在当前方法退出并且控制返回到事件处理程序之前不会进行绘制.这是一件好事,因为其他事件可能正在等待处理,并且需要及时处理事件以使GUI顺利运行.

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

如果你在你的小部件上绘制一些东西paintEvent(),你仍然需要包含绘制相同内容所需的逻辑和命令paintEvent().否则,您下次更新窗口小部件时,您所做的绘画将会消失.