Reputation: 183
I am trying to write a basic game loop in PyQt5. I have a QWidget
and a QGraphicsView
inside it. I use QTimer
and update()
to trigger the paintEvent()
on QWidget
and QGraphicsView
. The QWidget
paintEvent()
gets updated but QGraphicsView
paintEvent()
does not.
Here is my code:
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_())
When I run the script I get the following output:
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 ...
Upvotes: 1
Views: 1106
Reputation: 183
The solution is to call the paintEvent()
of the base class (in this case 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_())
Upvotes: 1