PDA

View Full Version : I cannot translate a QPainter on the background of a scene



flixter
27th February 2019, 06:29
Hi all,

I have an SVG (a square with some contents) that I need to be fully visible on a QGraphicsView, and its origin I need it on the center of the SVG. What I am doing right now, (in PyQt5) in the __init__ method of the QGraphicsScene subclass, is:

# open the image
self.renderer = QtSvg.QSvgRenderer(target)

# the QGraphicsView widget has this size
self.imageRect = QtCore.QSize(550,550)

# instantiate a QPainter, with its image
self.image = QtGui.QImage(self.imageRect, QtGui.QImage.Format_ARGB32)
self.painter = QtGui.QPainter(self.image)

# render the SVG onto the image
self.renderer.render(self.painter)

# set the image as the background brush of the scene
self.setBackgroundBrush(QtGui.QBrush(self.image))

# translate the painter
self.painter.translate(-550/2, -550/2)

Wait I get is an image whose center is (0,0), but this (0,0) is still the top-left corner. If I set the sceneRect of the QGraphicsView to be

targetView.setSceneRect(-550/2, -550/2, 550, 550)

Then I get the bottom-right corner of the original image only, but this time properly centered in the QGraphicsView.

Any idea on how can I get this image centered in the view, with the origin on the center of it?

Thank you!

ChrisW67
2nd March 2019, 02:42
The default behaviour is to tile the background brush outward from the origin with the lower-left corner of the brush at the origin. However, a brush can carry a transform that is composed with the painter transform,and this can be used to offset the brush. The example below demonstrates the default behaviour and using the brush offset to alter it (see the comment).

If you want to suppress the tiling then I suspect you need to customise the drawBackground() method of the scene.
The background could also be installed on the view rather than the scene.



import sys
from PyQt5.QtGui import QImage, QPainter, QColor, QBrush, QLinearGradient, QTransform
from PyQt5.QtWidgets import QApplication, QGraphicsScene, QGraphicsView

if __name__ == '__main__':
app = QApplication(sys.argv)

# A background image
bgImage = QImage(250, 250, QImage.Format_ARGB32)
painter = QPainter(bgImage)
gradient = QLinearGradient(0, 0, 250, 0)
gradient.setColorAt(0, QColor( 0, 0, 255))
gradient.setColorAt(1, QColor(255, 255, 255))
painter.setBrush(gradient)
painter.setPen(QColor(255, 0, 0))
painter.drawRect(0, 0, 250, 250)

brush = QBrush(bgImage)
transform = QTransform()
transform.translate(-125, -125)
# Try it without, and then with, the following line
#brush.setTransform(transform)

s = QGraphicsScene()
s.setBackgroundBrush(brush)
# small reference circle around the origin
c = s.addEllipse(-20, -20, 40, 40)

w = QGraphicsView(s)
w.setSceneRect(-550, -550, 1100, 1100);
w.show()

sys.exit(app.exec_())

flixter
2nd March 2019, 08:14
Thank you very much!!! :-)