QGraphicsView - Smooth Rescaling quality (PyQt5)
-
I am trying to create a "clone" of Gwenview with some extra (very) specific features. One of the key features is the ability to display multiple media (images, gifs, videos and audio) in a grid.
I had a first implementation using QLabel to display Pixmap and it was working perfectly. I decided to try QGraphicsView for the ability to display videos as well but the quality of the images is often atrocious:
I can try to provide the relevant part of the code (I am, however, using PyQt5 bindings and no C++) because the full code is quite a mess at the moment:
Left - QGraphicsView Implementation:
class clsMediaView(QtWidgets.QGraphicsView): # ---------------------------------------------------------------------------- def __init__(self, filePath): self.scene = QtWidgets.QGraphicsScene() super().__init__(self.scene) self.filePath = filePath self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.setSizePolicy(QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Ignored) self.setAlignment(QtCore.Qt.AlignCenter) self.setRenderHints(QtGui.QPainter.Antialiasing | QtGui.QPainter.SmoothPixmapTransform) self.media = QtGui.QPixmap(self.filePath) self.item = QtWidgets.QGraphicsPixmapItem(self.media) self.scene.addItem(self.item) self.fitInView(self.item, QtCore.Qt.KeepAspectRatio) # ---------------------------------------------------------------------------- def resizeEvent(self, a0: QtGui.QResizeEvent) -> None: super().resizeEvent(a0) self.fitInView(self.item, QtCore.Qt.KeepAspectRatio | QtCore.Qt.SmoothTransformation)
Right - QLabel Implementation:
class clsMediaView(QtWidgets.QLabel): # ---------------------------------------------------------------------------- def __init__(self, filePath): super().__init__() self.filePath = filePath self.setSizePolicy(QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Ignored) self.setAlignment(QtCore.Qt.AlignCenter) self.media = QtGui.QPixmap(self.filePath) self.setPixmap(self.media) # ---------------------------------------------------------------------------- def resizeEvent(self, a0: QtGui.QResizeEvent) -> None: super().resizeEvent(a0) self.setPixmap(self.media.scaled(self.size(), QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation))
Am I doing something obviously wrong? Thanks in advance?
-
Hi and welcome to devnet,
Looks like you are missing a call to QGraphicsPixmapItem::setTransformationMode.
-
Hi and welcome to devnet,
Looks like you are missing a call to QGraphicsPixmapItem::setTransformationMode.
-
Actually, let me reiterate - it does NOT solve the problem, though it does look better.
Antialiasing is still missing.And apparently, after some googling, the setRenderHints are ignored by the painter device for some reason. Several people suggest another workaround:
# ---------------------------------------------------------------- def resizeEvent(self, a0: QtGui.QResizeEvent) -> None: super().resizeEvent(a0) self.item.setPixmap(self.media.scaled(self.size(), QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation))
In this case, fitInView/setRenderHints/setTransformationMode and so on are not even needed. This solution, however, completely ruins the alignment. Resizing the window causes the item to lose the center-alignment.
I'm sorry, but isn't this a bug?
-
Do you have the links to these renderHints comment ?
Which resizeEvent is that ?
-
@SGaist said in QGraphicsView - Smooth Rescaling quality (PyQt5):
Do you have the links to these renderHints comment ?
See the comment of user136036, for instance:
https://stackoverflow.com/questions/17734290/antialiasing-not-working-in-qgraphicsviewWhich resizeEvent is that ?
This is the resizeEvent of clsMediaView (extending QGraphicsView).
-
Is it me or did you drop the fitInView from your code ?
-
You don't need "fitInView" if you're resizing the Pixmap yourself, and you need to resize the Pixmap yourself because QGraphicsView is unable to support antialiasing. I would argue that that should be the default behaviour, but I have given up the whole QGraphicsView thing altogether.