'PySide2 QGraphicsView zoom widget in scene macOS
Apparently, a widget inside a QGraphicsView does not scale correctly on macOS. Does anyone have a workaround?
Problem:
I have a QGraphicsView where I am zooming by calling the scale method.
I also have some QWidgets in my QGraphicScene, but their UI graphics do not scale accordingly when I zoom.
I use a QGraphicsProxyWidget from within a QGraphicsItem to display the widgets, but the scale issue persists even by using the scene.addWidget.
I tested the code on macOS 10.15.7 and 10.14.6, both Intel CPUs.
Edit: As pointed out in the comments by musicamante, the QGraphicsItem.ItemIgnoresTransformations does the exact opposite, so I am taking the reference out of the question to avoid confusion since it was only a failed attempt.
Edit2: On Windows 10 seems to work fine.
import sys
from PySide2.QtCore import Qt
from PySide2.QtGui import QPainterPath, QColor, QBrush
from PySide2.QtWidgets import (
QGraphicsItem,
QPushButton,
QGraphicsScene,
QWidget,
QVBoxLayout,
QMainWindow,
QApplication,
QGraphicsView,
QGraphicsProxyWidget
)
class NodeGraphicsContent(QGraphicsProxyWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setWidget(QPushButton('QGraphicsItem Button'))
class GraphicsItem(QGraphicsItem):
def __init__(self):
super().__init__()
self.item_body = self.draw_item()
self.draw_content()
def draw_content(self):
NodeGraphicsContent(self)
def draw_item(self):
path = QPainterPath()
path.addRect(0, 0, 200, 200)
return path
def paint(self, painter, option, widget):
painter.setPen(Qt.NoPen)
painter.setBrush(QBrush(QColor("#FF313131")))
painter.drawPath(self.item_body)
def boundingRect(self):
return self.item_body.boundingRect()
class GraphicScene(QGraphicsScene):
def __init__(self, parent=None):
super().__init__(parent)
self.scene_width = 500
self.scene_height = 500
self._grid_pattern = QBrush(QColor("#282828"), Qt.Dense7Pattern)
self.setBackgroundBrush(QColor("#393939"))
self.setSceneRect(-self.scene_width // 2, -self.scene_height // 2,
self.scene_width, self.scene_height)
def drawBackground(self, painter, rect):
super().drawBackground(painter, rect)
painter.fillRect(rect, self._grid_pattern)
class GraphicsView(QGraphicsView):
def __init__(self, parent=None):
super().__init__(parent)
self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
def wheelEvent(self, event):
"""Zoom function."""
zoom_factor = 1.25
zoom_out = 1 / zoom_factor
zoom_factor = zoom_factor if event.delta() > 0 else zoom_out
self.scale(zoom_factor, zoom_factor)
class MainWidgets(QWidget):
def __init__(self):
super().__init__()
self.scene = GraphicScene()
self.view = GraphicsView(self.scene)
_layout = QVBoxLayout()
_layout.addWidget(self.view)
self.setLayout(_layout)
self.add_widgets()
def add_widgets(self):
"""Add first a normal widget, then a QGraphicsItem,
which both dont seem to scale correctly.
"""
button = self.scene.addWidget(QPushButton('Widget Button'))
button.setPos(-50, -100)
self.scene.addItem(GraphicsItem())
class MainWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.setCentralWidget(MainWidgets())
self.statusBar().showMessage('Zoom with mouse wheel')
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|


