Qt QtGraphicsView Example
In this article we cover QtGraphicsView overriding the main class.
The Qt Framework is a powerful developmental platform and somewhat tricky to learn.
- We will look at overriding the QGraphicsView example in this tutorial.
- This is the example overload that initializes itself:
class Mfft_draw(QtWidgets.QGraphicsView):
def __init__(self, parent):
super(Mfft_draw, self).__init__(parent)
Next we overload the draw function:
def draw(self, indata=None):
self.image = QImage(self.width, self.height, QImage.Format_RGB32)
self.image.fill(QColor(220,220,220))
qpainter = QPainter(self.image)
qpainter.setBrush(QColor(255,255,255))
qpainter.setPen(QColor(20,20,20))
qpainter.drawRect(x1, y1, box_size, box_size)
qpainter.end()
self.pixmap = QPixmap.fromImage(self.image)
self.pixmapItem = QGraphicsPixmapItem(self.pixmap)
scene = QGraphicsScene()
scene.clear()
scene.addItem(self.pixmapItem)
self.setScene(scene)
A lot of moving parts but lets go over it:
1. self.image is created matching QImage (the parent) and dimensions match
2. qpainter is created
3. qpainter.setBrush / setPen is created.
4. qpainter draws various rectangles / ellipses etc.
5. pixmap is created from self.image
6. pixmapItem is created from self.pixmap
7. scene is created from QGraphicsScene()
8. scene adds item (self.pixmapItem)
9. Finally self.setScene(scene)
Also it needs understanding that self.draw() is not automatically called!
Thus we can attach a call for it to the self.
QGraphicsView getting scene delta:
def wheelEvent(self, event):
# Override the wheel event to zoom in and out
zoom_factor = 1.05
if event.angleDelta().y() > 0:
self.scale(zoom_factor, zoom_factor)
else:
self.scale(1 / zoom_factor, 1 / zoom_factor)
- Scenes are like a sub-card inside the QImage / QGraphicsView Frame.
- Relative scene coordinates can be referenced against the main QGraphicsView.
scene_pos = self.mapToScene(event.pos())
print(f"Mouse position in scene coordinates: {scene_pos.x()}, {scene_pos.y()}")
- To set mouse tracking:
self.tab.setMouseTracking(True)
A full translation example:
- Mouse will be able to pan / zoom the current scene with these sub-functions!
def resizeEvent(self, event):
self.width = event.size().width()
self.height = event.size().height()
self.draw()
def wheelEvent(self, event):
#region Reference Scene Scaling Example
zoom_factor = 1.15
if event.angleDelta().y() > 0:
self.scale(zoom_factor, zoom_factor)
else:
self.scale(1 / zoom_factor, 1 / zoom_factor)
#endregion
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.startPos = event.pos()
print(f"Setting self.startPos: {self.startPos}")
self.click_mode = 'MOVE'
else:
self.startPos = None
# Override the mouse press event for custom behavior
epos = event.pos()
scene_pos = self.mapToScene(event.pos())
print(f"Mouse position in scene coordinates: {scene_pos.x()}, {scene_pos.y()}")
super().mousePressEvent(event)
def mouseMoveEvent(self, event):
if self.startPos is not None:
# compute the difference between the current cursor position and the
# previous saved origin point
delta = self.startPos - event.pos()
# get the current transformation (which is a matrix that includes the
# scaling ratios
transform = self.transform()
# m11 refers to the horizontal scale, m22 to the vertical scale;
# divide the delta by their corresponding ratio
deltaX = delta.x() / transform.m11()
deltaY = delta.y() / transform.m22()
# translate the current sceneRect by the delta
self.setSceneRect(self.sceneRect().translated(deltaX, deltaY))
# update the new origin point to the current position
self.startPos = event.pos()
def mouseReleaseEvent(self, event):
self.startPos = None