Лекция 13, шаблонные методы, пример рисования и анимации вращения

Пример работы с шаблонными методами:

'''
Программа для демонстрации перехвата событий мыши и клавиатуры
виджетом.
'''
import sys
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtGui import QPainter, QPen
from PyQt5.QtCore import Qt

class MyWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.points = []

    def mousePressEvent(self, e):
        print("Mouse pressed at", e.x(), e.y())
        self.points.append([e.x(), e.y()])
        self.update() # вся перерисовка только через update,
                      # который сам вызовет paintEvent.

    def mouseReleaseEvent(self, e):
        print("Mouse released at", e.x(), e.y())

    def mouseMoveEvent(self, e):
        print("Mouse moved to", e.x(), e.y())

    def keyPressEvent(self, e):
        if e.key() == Qt.Key_Left:
            print('Left')
        elif e.key() == Qt.Key_Right:
            print('Right')
        elif e.key() == Qt.Key_Up:
            print('Up')
        elif e.key() == Qt.Key_Down:
            print('Down')
        print("Key pressed, text is", repr(e.text()))

    def keyReleaseEvent(self, e):
        print("Key released, text is", repr(e.text()))

    def paintEvent(self, e):
        p = QPainter()
        p.begin(self)
        pen = QPen(Qt.red, 10)
        p.setPen(pen)

        for x, y in self.points:
            p.drawPoint(x, y)

        p.end()

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

if __name__ == "__main__":
    main()

Пример рисования квадрата в полярной системе координат:

'''
Программа для демонстрации перехвата событий мыши и клавиатуры
виджетом.
'''
import sys
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtGui import QPainter, QPen
from PyQt5.QtCore import Qt
from math import sin, cos, pi

class MyWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.resize(500, 500)

    def paintEvent(self, event):
        p = QPainter()
        p.begin(self)
        pen = QPen(Qt.red, 10)
        p.setPen(pen)

        for i in range(4):
            p.drawPoint(
                250 + 200 * cos(pi / 4 + pi / 2 * i),
                250 + 200 * sin(pi / 4 + pi / 2 * i)
            )
        p.end()

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

if __name__ == "__main__":
    main()


Пример рисования квадрата в полярной системе координат с анимацией вращения:

'''
Программа для демонстрации перехвата событий мыши и клавиатуры
виджетом.
'''
import sys
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtGui import QPainter, QPen
from PyQt5.QtCore import Qt, QTimer
from math import sin, cos, pi

class MyWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.timer = QTimer()
        self.timer.timeout.connect(self.process_timeout)
        self.timer.start(50)  # 50 -- период в милисекундах
        self.phi = 0  # Угол в радианах.
        self.resize(500, 500)

    def process_timeout(self):
        self.phi += 0.01
        self.update()

    def paintEvent(self, e):
        p = QPainter()
        p.begin(self)
        pen = QPen(Qt.red, 10)
        p.setPen(pen)

        for i in range(4):
            angle = (self.phi + pi / 4 + pi / 2 * i)
            p.drawPoint(
                250 + 200 * cos(angle),
                250 + 200 * sin(angle)
            )

        p.end()

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

if __name__ == "__main__":
    main()


Программа, позволяющая регулировать скорость вращения n-угольников и количество их углов:

'''
Программа, позволяющая регулировать скорость вращения n-угольников
и количество их углов
'''
import sys
from PyQt5.QtWidgets import QWidget, QApplication, QSlider, QSpinBox
from PyQt5.QtGui import QPainter, QPen
from PyQt5.QtCore import Qt, QTimer
from math import sin, cos, pi


class MyWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.timer = QTimer()
        self.timer.timeout.connect(self.process_timeout)
        self.timer.start(16)  # 16 -- период в милисекундах
        self.phi = 0  # Угол в радианах.
        self.speed = 0.01  # На сколько изменяется self.phi за
                           # один отсчёт таймера.
        self.resize(600, 500)
        self.slider = QSlider(Qt.Horizontal, self)
        self.slider.move(500, 50)
        self.slider.setValue(0.01)
        self.slider.valueChanged.connect(self.change_rotation_speed)
        self.spinbox = QSpinBox(self)
        self.spinbox.move(500, 100)
        self.n = 4
        self.spinbox.setValue(self.n)
        self.spinbox.valueChanged.connect(self.change_number_of_angles)

    def process_timeout(self):
        self.phi += self.speed
        self.update()

    def change_number_of_angles(self, new_n):
        self.n = new_n

    def change_rotation_speed(self, new_speed):
        print(new_speed)
        self.speed = 0.1 * new_speed / 100

    def paintEvent(self, e):
        p = QPainter()
        p.begin(self)
        pen = QPen(Qt.red, 10)
        p.setPen(pen)

        centerx, centery = 250, 250
        n = self.n
        for i in range(n):
            angle = self.phi + pi / n + ((2 * pi) / n) * i
            p.drawPoint(centerx + 200 * cos(angle),
                        centery + 200 * sin(angle))

        p.end()


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

if __name__ == "__main__":
    main()