Python 3.x Qt5将事件传播到子窗口小部件

Python 3.x Qt5将事件传播到子窗口小部件,python-3.x,events,qt5,pyqt5,Python 3.x,Events,Qt5,Pyqt5,我正在尝试用PyQt5编写一个基本的游戏循环。我有一个QWidget和一个QGraphicsView。我使用QTimer和update()在QWidget和QGraphicsView上触发paintEvent()。QWidgetpaintEvent()会更新,但QGraphicsViewpaintEvent()不会更新 这是我的密码: import sys, random from PyQt5.QtWidgets import QWidget, QGridLayout, QApplicatio

我正在尝试用PyQt5编写一个基本的游戏循环。我有一个
QWidget
和一个
QGraphicsView
。我使用
QTimer
update()
QWidget
QGraphicsView
上触发
paintEvent()
QWidget
paintEvent()
会更新,但
QGraphicsView
paintEvent()
不会更新

这是我的密码:

import sys, random

from PyQt5.QtWidgets import QWidget, QGridLayout, QApplication, QGraphicsView, QGraphicsScene
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtGui import QPainter, QColor, QPen, QBrush, QColor



class Window(QWidget):

    WIDTH = 800
    HEIGHT = 480
    SPEED = 500

    def __init__(self):

        super().__init__()
        self.initUi()
        self.initDisplay()
        self.show()

    def initUi(self):

        layout = QGridLayout()

        scene = GraphicsScene()        
        self.view = GraphicsView()
        self.view.setScene(scene)

        layout.addWidget(self.view)
        self.setLayout(layout)


    def initDisplay(self):     

        self.resize(Window.WIDTH, Window.HEIGHT)

        self.timer = QTimer()
        self.timer.setInterval(Window.SPEED)
        self.timer.timeout.connect(self.timerEvent)
        self.isStarted = False
        self.isPaused = False

        self.timer.start()


    def start(self):

        if self.isPaused:
            return

        self.isStarted = True
        self.timer.start(Display.SPEED)


    def pause(self):

        if not self.isStarted:
            return

        self.isPaused = not self.isPaused

        if self.isPaused:
            self.timer.stop()            
        else:
            self.timer.start(Display.SPEED)

        self.update()


    def paintEvent(self, event):
        print('paint event ...')


    def timerEvent(self):
        self.update()
        self.view.update()
        print('timer event ...')



class GraphicsView(QGraphicsView):


    def __init__(self):
        super(GraphicsView, self).__init__()


    def paintEvent(self, event):
        self.scene().add_shapes()
        print('view paint event')



class GraphicsScene(QGraphicsScene):

    def __init__(self):
        super(GraphicsScene, self).__init__()


    def add_shapes(self):

        self.setSceneRect(0.0, 0.0, 800.0, 640.0)

        self.addRect(100, 100, 150, 150)

        pen = QPen(Qt.SolidLine)
        pen.setColor(Qt.red)
        brush = QBrush(Qt.Dense3Pattern)
        brush.setColor(Qt.darkGreen)
        self.addEllipse(300, 300, 100, 100, pen, brush)
        print('add shapes')        



if __name__ == '__main__':

    app = QApplication([])
    window = Window()    
    sys.exit(app.exec_())
运行脚本时,我得到以下输出:

paint event ...
add shapes
view paint event
paint event ...
add shapes
view paint event
timer event ...
paint event ...
paint event ...
timer event ...
paint event ...
paint event ...
timer event ...
paint event ...
paint event ...
timer event ...
paint event ...
paint event ...
timer event ...
paint event ...
paint event ...

解决方案是调用基类的
paintEvent()
(在本例中为
QGraphicsView

import sys, random

from PyQt5.QtWidgets import QWidget, QGridLayout, QApplication, QGraphicsView, QGraphicsScene
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtGui import QPainter, QColor, QPen, QBrush, QColor



class Window(QWidget):

    WIDTH = 800
    HEIGHT = 480
    SPEED = 500

    def __init__(self):

        super().__init__()
        self.initUi()
        self.initDisplay()
        self.show()

    def initUi(self):

        layout = QGridLayout()

        self.scene = GraphicsScene()
        self.view = GraphicsView(self, self.scene)

        layout.addWidget(self.view)
        self.setLayout(layout)


    def initDisplay(self):     

        self.resize(Window.WIDTH, Window.HEIGHT)

        self.timer = QTimer()
        self.timer.setInterval(Window.SPEED)
        self.timer.timeout.connect(self.timerEvent)
        self.isStarted = False
        self.isPaused = False

        self.timer.start()


    def start(self):

        if self.isPaused:
            return

        self.isStarted = True
        self.timer.start(Display.SPEED)


    def pause(self):

        if not self.isStarted:
            return

        self.isPaused = not self.isPaused

        if self.isPaused:
            self.timer.stop()            
        else:
            self.timer.start(Display.SPEED)

        self.update()


    def paintEvent(self, event):
        print('paint event ...')


    def timerEvent(self):
        self.update()
        self.view.update()
        self.scene.update()
        print('timer event ...')



class GraphicsView(QGraphicsView):


    def __init__(self, parent, scene):

        super(GraphicsView, self).__init__()
        self.scene = scene   
        self.parent = parent
        self.setScene(self.scene)


    def paintEvent(self, event):
        QGraphicsView.paintEvent(self, event)#########
        self.setScene(self.scene)
        self.scene.add_shapes()
        print('view paint event')



class GraphicsScene(QGraphicsScene):

    def __init__(self):
        super(GraphicsScene, self).__init__()


    def add_shapes(self):

        self.setSceneRect(0.0, 0.0, 700.0, 450.0)

        self.addRect(100, 100, 150, 150)

        pen = QPen(Qt.SolidLine)
        pen.setColor(Qt.red)
        brush = QBrush(Qt.Dense3Pattern)
        brush.setColor(Qt.darkGreen)
        self.addEllipse(300, 300, 100, 100, pen, brush)
        print('add shapes')        



if __name__ == '__main__':

    app = QApplication([])
    window = Window()    
    sys.exit(app.exec_())