1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#!/usr/bin/python3

'''
Программа для демонстрации анимации с помощью таймера.
Программа показывает шарик, движущийся по окружности.
'''

from PyQt4 import QtGui, QtCore
import sys
import math


class MyWidget(QtGui.QWidget):
    def __init__(self):
        super().__init__()
        self.t = 0.0  # время
        self.setFixedSize(200, 200)
        # Создаём таймер и записываем его в слойство для последующего доступа.
        self.timer = QtCore.QBasicTimer()
        # Период у таймера будет 30 миллисекунд, получателем событий таймера
        # будет объект наш виджет, то есть self. При наступлении события таймера
        # будет вызываться метод timerEvent.
        self.timer.start(30, self)

    def timerEvent(self, e):
        # Изменим параметры системы, которые заставляют её жить своей жизнью.
        # В данном случае это просто время, в более сложных случаях нужно
        # менять координаты одного или нескольких тел в системе.
        self.t += 0.1
        # Ставим в очередь событие на перерисовку виджета.
        self.update()

    def paintEvent(self, e):
        p = QtGui.QPainter()
        p.begin(self)
        # сдвигаем начало координат в центр виджета
        p.translate(self.width() / 2, self.height() / 2)
        # Красная ручка с шириной 3
        p.setPen(QtGui.QPen(QtGui.QColor(255, 0, 0), 3))
        # Синяя кисть
        p.setBrush(QtGui.QBrush(QtGui.QColor(0, 0, 255)))
        # шарик радиусом 10 будет двигаться по окружности радиусом 50
        x = 50 * math.cos(self.t)
        y = 50 * math.sin(self.t)
        r = 10  # радиус эллипса
        p.drawEllipse(x - r, y - r, 2 * r, 2 * r)
        p.end()

    def closeEvent(self, e):
        '''
        Метод closeEvent вызывается, когда мы хотим закрыть виджет.
        В отдельной программе мы бы обошлись без остановки таймера,
        так как он бы сам останавливался при завершении программы.
        Но так как при запуске через IDLE программа не завершается,
        а переходит в режим консоли, таймер работать не прекратит.
        Он будет ударно выдавать тонны отладочной печати из метода
        timerEvent, если она там есть, уже после закрытия окна.
        Поэтому остановим таймер вручную.
        '''
        self.timer.stop()

def main():
    app = QtGui.QApplication(sys.argv)
    w = MyWidget()
    w.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()