Вопрос по pyqt, qt, python – О программе примера PyQt

9

Мне сейчас нужна библиотека 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()

Здесь в функции main создается объект Example, таким образом__init__() функция,initUI() называется. Мой вопрос гдеpaintEvent() функция называется ?? так как если мы запустим программу,self.text(some Russian letters) точно появится на виджете.

Другими словами, что делаетsys.exit(app.exec_()) на самом деле делать? почему это будет звонитьpaintEvent() функционировать?

Спасибо!

Ваш Ответ

3   ответа
7

ОтPyQt документы:

int QApplication.exec_ ()

Enters the main event loop and waits until exit() is called, then returns the value that was set to exit() (which is 0 if exit() is called via quit()).

It is necessary to call this function to start event handling. The main event loop receives events from the window system and dispatches these to the application widgets.

Отдругой источник:

sys.exit(app.exec_())

Finally, we enter the mainloop of the application. The event handling starts from this point. The mainloop receives events from the window system and dispatches them to the application widgets. The mainloop ends, if we call the exit() method or the main widget is destroyed. The sys.exit() method ensures a clean exit. The environment will be informed, how the application ended.

The exec_() method has an underscore. It is because the exec is a Python keyword. And thus, exec_() was used instead.

Околокартина:

4.2.1. When Painting Occurs

The paintEvent() method is called automatically when

  • Your widget is shown for the first time.

  • After a window has been moved to reveal some part (or all) of the widget.

  • The window in which the widget lies is restored after being minimized.

  • The window in which the widget lies is resized.

  • The user switches from another desktop to the desktop on which the widget's window lies.

You can generate paint events manually by calling QWidget::update(). QWidget::update() erases the widget before generating the paint event. You can pass arguments to update(), which can restrict painting only to areas (rectangles, in particular) that need it. The two equivalent forms of the method are QWidget::update (int x, int y, int width, int height) and QWidget::update (QRect rectangle), where x and y give the upper-left corner of the rectangle, and width and height are obvious. Because update() places a paint event into the event queue, no painting occurs until the current method exits and control returns to the event handler. This is a good thing because other events may be waiting there to be processed, and events need to be processed in a timely manner for the GUI to operate smoothly.

You can also invoke painting of the widget by calling QWidget::repaint (int x, int y, int width, int height, bool erase) (or one of several convenience-method forms), where all the arguments mean the same as in the case of the update() method, and erase tells repaint whether to erase the rectangle before painting it. repaint() calls paintEvent() directly. It does not place a paint event into the event queue, so use this method with care. If you try to call repaint() repeatedly from a simple loop to create an animation, for example, the animation will be drawn, but the rest of your user interface will be unresponsive because the events corresponding to mouse button clicks, keyboard presses, and so on will be waiting in the queue. Even if you are not performing a task as potentially time-consuming as animation, it is generally better to use update() to help keep your GUI alive.

If you paint something on your widget outside the paintEvent(), you still need to include the logic and commands necessary to paint that same thing in paintEvent(). Otherwise, the painting you did would disappear the next time the widget is updated.

Спасибо за ваше такое подробное объяснение. Junjie
1

app.exec_() запускает основной цикл qt, который заканчивается, когда уничтожается каждый созданный виджет (например, при закрытии его окна).paintEvent Функция - это метод, который вы можете перегрузить изQWidget подкласс как данныйExample класс, который вызывается, когда QT отображает, обновляет или перерисовывает виджет.

Вы можете посмотреть эти вещи вДокументация Qt илиPyQt Документация (который в основном является просто копией документации QT в другом формате, но иногда содержит некоторую ценную информацию, касающуюся специфических для PyQt вещей).

1

Это становится более ясным, когда у вас есть некоторый опыт программирования низкого уровня, например, в Winapi или инструментарий X на языке C. PyQt - это (очень) высокоуровневый инструментарий. Он поставляется с огромной встроенной функциональностью. Подобный пример потребует сотен или даже тысяч строк кода на Си. Как следствие, много происходит за кулисами. Кто-то уже создал код, который занимается рисованием на базовом уровне. Программирование GUI очень сложно, и с современными инструментами GUI программист приложения защищен от этой сложности. Программисты в замешательстве неизбежны, если не знают всех технических деталей.

В PyQt мы по существу имеем дело с событиями двумя способами. Мы подключаем сигналы к слотам или переопределяем обработчики событий (обработчик событий является синонимом слота). Приведенный пример унаследован отQtGui.QWidget в котором уже есть некоторый код рисования. Для того, чтобы сделать нашу собственную картину, мы должны переопределить существующиеpaintEvent() событие обработчик. В зависимости от ситуации мы можем или не можем позвонить родителямpaintEvent() метод.

sys.exit(app.exec_()) не вызываетpaintEvent() метод.exec_() Метод запускает цикл обработки событий. Цикл событий перехватывает и отправляет события. События рисования запускаются пользователями или операционной системой. Например, когда мы запускаем пример, Событие рисования запускается дважды. (Положитьprint "Event occurred" строка в обработчике событий, чтобы увидеть, сколько раз вызывается этот метод.) Изменение размера окон, потеря или усиление фокуса, сворачивание или сворачивание окон - все это вызывает запуск событий рисования.

Похожие вопросы