Вызов функции update для обновления paintEvent

Есть какие-нибудь варианты выполнять функцию paintEvent раз 30 в секунду без зависания интерфейса?

from typing import Sized
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QRadialGradient, QPainter, QPainterPath, QPen, QBrush, QGradient, QColor
from PyQt5.QtCore import QPointF, Qt, QRect
import sys

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        
        self.centralwidget = QtWidgets.QWidget()
        self.setCentralWidget(self.centralwidget)
        self.resize(600, 400)
       
    def paintEvent(self, event):
        self.painter = QPainter(self)
        
        radialGrad = QRadialGradient(QPointF(300, 450), 200)
        
        radialGrad.setColorAt(0, QColor('#1B2735'))
        radialGrad.setColorAt(1, QColor('#090A0F'))

        self.painter.setBrush(radialGrad)
        self.painter.drawRect(0, 0, 600, 400) 

        self.painter.setBrush(QBrush(Qt.white))

        self.painter.drawRect(100, 390, 2, 2) 
        self.painter.drawRect(200, 390, 3, 3) 
        self.painter.drawRect(300, 390, 4, 4)
        self.update()

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

Ответы (1 шт):

Автор решения: S. Nick

Класс QTimer предоставляет повторяющиеся и однократные таймеры.
Больше https://doc.qt.io/qt-5/qtimer.html

import sys
from typing import Sized
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QRadialGradient, QPainter, QPainterPath, QPen, QBrush, QGradient, QColor
from PyQt5.QtCore import QPointF, Qt, QRect, QTimer


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.centralwidget = QtWidgets.QWidget()
        self.setCentralWidget(self.centralwidget)
        self.resize(600, 400)

# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv        
        self.h = 390
        
        #                           1000*30                # <---- раз 30 в секунду
        self.timer = QTimer(interval=1000, timeout=self.handle_timeout)
        self.timer.start()

    def handle_timeout(self):
        self.h -= 10
        print(self.h)
        if self.h < 10:
            self.h = 390
            
        self.update()                                                       # !!!       
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
       
    def paintEvent(self, event):
        painter = QPainter(self)
        
        radialGrad = QRadialGradient(QPointF(300, 450), 200)
        radialGrad.setColorAt(0, QColor('#1B2735'))
        radialGrad.setColorAt(1, QColor('#090A0F'))
        painter.setBrush(radialGrad)
        painter.drawRect(0, 0, 600, 400) 

        painter.setBrush(QBrush(Qt.white))
        painter.drawRect(100, self.h, 2, 2) 
        painter.drawRect(200, self.h, 3, 3) 
        painter.drawRect(300, self.h, 4, 4)
#        self.update()
        

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

введите сюда описание изображения

→ Ссылка