Skip to content

graphicsview

Classes:

DragEventType

Bases: IntEnum

Attributes:

move class-attribute instance-attribute

move = auto()

repaint class-attribute instance-attribute

repaint = auto()

start class-attribute instance-attribute

start = auto()

stop class-attribute instance-attribute

stop = auto()

GraphicsImageItem

GraphicsImageItem(graphics_item: QGraphicsPixmapItem)

Methods:

Source code
37
38
39
def __init__(self, graphics_item: QGraphicsPixmapItem) -> None:
    self._graphics_item = graphics_item
    self._pixmap = self._graphics_item.pixmap()

contains

contains(point: QPointF) -> bool
Source code
41
42
def contains(self, point: QPointF) -> bool:
    return self._graphics_item.contains(point)

hide

hide() -> None
Source code
44
45
def hide(self) -> None:
    self._graphics_item.hide()

pixmap

pixmap() -> QPixmap
Source code
47
48
def pixmap(self) -> QPixmap:
    return self._graphics_item.pixmap()

setPixmap

setPixmap(
    new_pixmap: QPixmap | None,
    crop_values: CroppingInfo | None = None,
    ar_values: ArInfo | None = None,
) -> None
Source code
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
def setPixmap(
    self, new_pixmap: QPixmap | None,
    crop_values: CroppingInfo | None = None,
    ar_values: ArInfo | None = None
) -> None:

    sizes = (self._pixmap.width(), self._pixmap.height())

    if new_pixmap is None:
        new_pixmap = self._pixmap
    else:
        self._pixmap = new_pixmap

    if ar_values is not None and ar_values.active:
        new_pixmap = self._set_ar(new_pixmap, ar_values)

    if crop_values is not None and crop_values.active:
        new_pixmap = self._set_crop(new_pixmap, crop_values)

    self._graphics_item.setPixmap(new_pixmap)

    if sizes != (new_pixmap.width(), new_pixmap.height()):
        from ...core import main_window

        main_window().refresh_graphics_views()

show

show() -> None
Source code
76
77
def show(self) -> None:
    self._graphics_item.show()

GraphicsScene

GraphicsScene(view: GraphicsView)

Bases: QGraphicsScene

Methods:

Attributes:

Source code
127
128
129
130
131
132
133
def __init__(self, view: GraphicsView) -> None:
    self.view = view
    self.main = self.view.main

    self.graphics_items = list[GraphicsImageItem]()

    super().__init__(self.main)

current_scene property

current_scene: GraphicsImageItem

graphics_items instance-attribute

graphics_items = list[GraphicsImageItem]()

main instance-attribute

main = main

view instance-attribute

view = view

init_scenes

init_scenes() -> None
Source code
135
136
137
138
139
140
141
142
143
def init_scenes(self) -> None:
    self.clear()
    self.graphics_items.clear()

    for _ in range(len(self.main.outputs)):
        raw_frame_item = self.addPixmap(QPixmap())
        raw_frame_item.hide()

        self.graphics_items.append(GraphicsImageItem(raw_frame_item))

GraphicsView

GraphicsView(main: MainWindow, parent: QWidget | None = None)

Bases: QGraphicsView

Methods:

Attributes:

Source code
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
def __init__(self, main: MainWindow, parent: QWidget | None = None) -> None:
    from ...core import CheckBox, HBoxLayout
    from .combobox import ComboBox

    super().__init__(parent)

    self.main = main

    self.app = QApplication.instance()
    self.angleRemainder = 0
    self.zoomValue = 0.0
    self.currentZoom = 0.0
    self.setTransformationAnchor(QGraphicsView.ViewportAnchor.AnchorUnderMouse)
    self.drag_mode = self.dragMode()

    self.main.reload_stylesheet_signal.connect(
        lambda: self.setBackgroundBrush(self.main.palette().brush(QPalette.ColorRole.Window))
    )

    self.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
    self.setDragMode(QGraphicsView.DragMode.ScrollHandDrag)

    if self.main.settings.opengl_rendering_enabled:
        from PyQt6.QtOpenGLWidgets import QOpenGLWidget
        self.setViewport(QOpenGLWidget())

    self.wheelScrolled.connect(self.on_wheel_scrolled)
    self.main.reload_before_signal.connect(self.beforeReload)
    self.main.reload_after_signal.connect(self.afterReload)

    self.graphics_scene = GraphicsScene(self)
    self.setScene(self.graphics_scene)

    self.zoom_combobox = ComboBox[float](self, minimumContentsLength=4)

    self.auto_fit_button = CheckBox('Auto-fit', self, clicked=self.auto_fit_button_clicked)

    self.controls = QFrame()
    HBoxLayout(self.controls, [self.zoom_combobox, self.auto_fit_button])

    self.main.register_graphic_view(self)

    self.dragEvent.connect(self.propagate_move_event)

WHEEL_STEP class-attribute instance-attribute

WHEEL_STEP = 15 * 8

angleRemainder instance-attribute

angleRemainder = 0

app instance-attribute

app = instance()

auto_fit_button instance-attribute

auto_fit_button = CheckBox('Auto-fit', self, clicked=auto_fit_button_clicked)

autofit property writable

autofit: bool

content_height property

content_height: int

content_width property

content_width: int

controls instance-attribute

controls = QFrame()

currentZoom instance-attribute

currentZoom = 0.0

current_scene property

current_scene: GraphicsImageItem

dragEvent class-attribute instance-attribute

dragEvent = pyqtSignal(DragEventType)

drag_mode instance-attribute

drag_mode: DragMode = dragMode()

graphics_scene instance-attribute

graphics_scene = GraphicsScene(self)

last_positions class-attribute instance-attribute

last_positions = (0, 0)

main instance-attribute

main: MainWindow = main

mouseMoved class-attribute instance-attribute

mouseMoved = pyqtSignal(QMouseEvent)

mousePressed class-attribute instance-attribute

mousePressed = pyqtSignal(QMouseEvent)

mouseReleased class-attribute instance-attribute

mouseReleased = pyqtSignal(QMouseEvent)

underReload class-attribute instance-attribute

underReload = False

wheelScrolled class-attribute instance-attribute

wheelScrolled = pyqtSignal(int)

zoomValue instance-attribute

zoomValue = 0.0

zoom_combobox instance-attribute

zoom_combobox = ComboBox[float](self, minimumContentsLength=4)

afterReload

afterReload() -> None
Source code
371
372
373
374
375
def afterReload(self) -> None:
    self.underReload = False
    self.verticalScrollBar().setValue(self.last_positions[0])
    self.horizontalScrollBar().setValue(self.last_positions[1])
    self.setTransformationAnchor(QGraphicsView.ViewportAnchor.AnchorUnderMouse)

auto_fit_button_clicked

auto_fit_button_clicked(checked: bool) -> None
Source code
212
213
def auto_fit_button_clicked(self, checked: bool) -> None:
    self.autofit = checked

beforeReload

beforeReload() -> None
Source code
366
367
368
369
def beforeReload(self) -> None:
    self.underReload = True
    self.setTransformationAnchor(QGraphicsView.ViewportAnchor.AnchorViewCenter)
    self.last_positions = (self.verticalScrollBar().value(), self.horizontalScrollBar().value())

bind_to

bind_to(other_view: GraphicsView, *, mutual: bool = True) -> None
Source code
241
242
243
244
245
def bind_to(self, other_view: GraphicsView, *, mutual: bool = True) -> None:
    self.main.bound_graphics_views[other_view].add(self)

    if mutual:
        self.main.bound_graphics_views[self].add(other_view)

event

event(event: QEvent) -> bool
Source code
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
def event(self, event: QEvent) -> bool:
    if self.underReload:
        event.ignore()
        return False

    if isinstance(event, QNativeGestureEvent):
        typ = event.gestureType()
        if typ == Qt.NativeGestureType.BeginNativeGesture:
            self.zoomValue = 0.0
        elif typ == Qt.NativeGestureType.ZoomNativeGesture:
            self.zoomValue += event.value()
        if typ == Qt.NativeGestureType.EndNativeGesture:
            self.wheelScrolled.emit(-1 if self.zoomValue < 0 else 1)

    return super().event(event)

mouseMoveEvent

mouseMoveEvent(event: QMouseEvent) -> None
Source code
330
331
332
333
334
335
336
337
338
339
def mouseMoveEvent(self, event: QMouseEvent) -> None:
    if self.underReload or self.autofit:
        return event.ignore()

    super().mouseMoveEvent(event)

    if self.hasMouseTracking():
        self.mouseMoved.emit(event)

    self.dragEvent.emit(DragEventType.move)

mousePressEvent

mousePressEvent(event: QMouseEvent) -> None
Source code
341
342
343
344
345
346
347
348
349
350
351
352
def mousePressEvent(self, event: QMouseEvent) -> None:
    if self.underReload or self.autofit:
        return event.ignore()

    if event.button() == Qt.MouseButton.LeftButton:
        self.drag_mode = self.dragMode()
        self.setDragMode(QGraphicsView.DragMode.ScrollHandDrag)

    super().mousePressEvent(event)

    self.mousePressed.emit(event)
    self.dragEvent.emit(DragEventType.start)

mouseReleaseEvent

mouseReleaseEvent(event: QMouseEvent) -> None
Source code
354
355
356
357
358
359
360
361
362
363
364
def mouseReleaseEvent(self, event: QMouseEvent) -> None:
    if self.underReload or self.autofit:
        return event.ignore()

    super().mouseReleaseEvent(event)

    if event.button() == Qt.MouseButton.LeftButton:
        self.setDragMode(self.drag_mode)

    self.mouseReleased.emit(event)
    self.dragEvent.emit(DragEventType.stop)

on_wheel_scrolled

on_wheel_scrolled(steps: int) -> None
Source code
247
248
249
250
251
252
253
254
255
def on_wheel_scrolled(self, steps: int) -> None:
    new_index = self.zoom_combobox.currentIndex() + steps

    if new_index < 0:
        new_index = 0
    elif new_index >= len(self.main.settings.zoom_levels):
        new_index = len(self.main.settings.zoom_levels) - 1

    self.zoom_combobox.setCurrentIndex(new_index)

propagate_move_event

propagate_move_event(_: Any = None) -> None
Source code
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
def propagate_move_event(self, _: Any = None) -> None:
    scrollbarW, scrollbarH = self.horizontalScrollBar(), self.verticalScrollBar()

    if not any({scrollbarW.isVisible(), scrollbarH.isVisible()}):
        return

    widthMax, heightMax = scrollbarW.maximum(), scrollbarH.maximum()

    for view in self.main.bound_graphics_views[self] - {self}:
        if view.isVisible():
            wBar, hBar = view.horizontalScrollBar(), view.verticalScrollBar()

            if widthMax:
                wBar.setValue(int(scrollbarW.value() * wBar.maximum() / widthMax))

            if heightMax:
                hBar.setValue(int(scrollbarH.value() * hBar.maximum() / heightMax))

resizeEvent

resizeEvent(event: QResizeEvent) -> None
Source code
377
378
379
def resizeEvent(self, event: QResizeEvent) -> None:
    super().resizeEvent(event)
    self.setZoom(None)

setZoom

setZoom(value: float | None) -> None
Source code
257
258
259
def setZoom(self, value: float | None) -> None:
    for view in self.main.bound_graphics_views[self]:
        view._setZoom(value)

setup_view

setup_view() -> None
Source code
234
235
236
237
238
239
def setup_view(self) -> None:
    for item in self.graphics_scene.graphics_items:
        item.hide()

    self.current_scene.show()
    self.graphics_scene.setSceneRect(QRectF(self.current_scene.pixmap().rect()))

wheelEvent

wheelEvent(event: QWheelEvent) -> None
Source code
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
def wheelEvent(self, event: QWheelEvent) -> None:
    if self.underReload or self.autofit:
        return event.ignore()

    assert self.app

    modifier = event.modifiers()
    mouse = event.buttons()

    self.propagate_move_event()

    if modifier == Qt.KeyboardModifier.ControlModifier or mouse in {
        Qt.MouseButton.RightButton, Qt.MouseButton.MiddleButton
    }:
        angleDelta = event.angleDelta().y()

        # check if wheel wasn't rotated the other way since last rotation
        if self.angleRemainder * angleDelta < 0:
            self.angleRemainder = 0

        self.angleRemainder += angleDelta

        if abs(self.angleRemainder) >= self.WHEEL_STEP:
            self.wheelScrolled.emit(self.angleRemainder // self.WHEEL_STEP)
            self.angleRemainder %= self.WHEEL_STEP
        return
    elif modifier == Qt.KeyboardModifier.NoModifier:
        self.verticalScrollBar().setValue(self.verticalScrollBar().value() - event.angleDelta().y())
        self.horizontalScrollBar().setValue(self.horizontalScrollBar().value() - event.angleDelta().x())
        return
    elif modifier == Qt.KeyboardModifier.ShiftModifier:
        self.verticalScrollBar().setValue(self.verticalScrollBar().value() - event.angleDelta().x())
        self.horizontalScrollBar().setValue(self.horizontalScrollBar().value() - event.angleDelta().y())
        return

    event.ignore()

MainVideoOutputGraphicsView

MainVideoOutputGraphicsView(main: MainWindow, parent: QWidget | None = None)

Bases: GraphicsView

Methods:

Attributes:

Source code
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
def __init__(self, main: MainWindow, parent: QWidget | None = None) -> None:
    from ...core import CheckBox, HBoxLayout
    from .combobox import ComboBox

    super().__init__(parent)

    self.main = main

    self.app = QApplication.instance()
    self.angleRemainder = 0
    self.zoomValue = 0.0
    self.currentZoom = 0.0
    self.setTransformationAnchor(QGraphicsView.ViewportAnchor.AnchorUnderMouse)
    self.drag_mode = self.dragMode()

    self.main.reload_stylesheet_signal.connect(
        lambda: self.setBackgroundBrush(self.main.palette().brush(QPalette.ColorRole.Window))
    )

    self.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
    self.setDragMode(QGraphicsView.DragMode.ScrollHandDrag)

    if self.main.settings.opengl_rendering_enabled:
        from PyQt6.QtOpenGLWidgets import QOpenGLWidget
        self.setViewport(QOpenGLWidget())

    self.wheelScrolled.connect(self.on_wheel_scrolled)
    self.main.reload_before_signal.connect(self.beforeReload)
    self.main.reload_after_signal.connect(self.afterReload)

    self.graphics_scene = GraphicsScene(self)
    self.setScene(self.graphics_scene)

    self.zoom_combobox = ComboBox[float](self, minimumContentsLength=4)

    self.auto_fit_button = CheckBox('Auto-fit', self, clicked=self.auto_fit_button_clicked)

    self.controls = QFrame()
    HBoxLayout(self.controls, [self.zoom_combobox, self.auto_fit_button])

    self.main.register_graphic_view(self)

    self.dragEvent.connect(self.propagate_move_event)

WHEEL_STEP class-attribute instance-attribute

WHEEL_STEP = 15 * 8

angleRemainder instance-attribute

angleRemainder = 0

app instance-attribute

app = instance()

auto_fit_button instance-attribute

auto_fit_button = CheckBox('Auto-fit', self, clicked=auto_fit_button_clicked)

autofit property writable

autofit: bool

content_height property

content_height: int

content_width property

content_width: int

controls instance-attribute

controls = QFrame()

currentZoom instance-attribute

currentZoom = 0.0

current_scene property

current_scene: GraphicsImageItem

dragEvent class-attribute instance-attribute

dragEvent = pyqtSignal(DragEventType)

drag_mode instance-attribute

drag_mode: DragMode = dragMode()

graphics_scene instance-attribute

graphics_scene = GraphicsScene(self)

last_positions class-attribute instance-attribute

last_positions = (0, 0)

main instance-attribute

main: MainWindow = main

mouseMoved class-attribute instance-attribute

mouseMoved = pyqtSignal(QMouseEvent)

mousePressed class-attribute instance-attribute

mousePressed = pyqtSignal(QMouseEvent)

mouseReleased class-attribute instance-attribute

mouseReleased = pyqtSignal(QMouseEvent)

underReload class-attribute instance-attribute

underReload = False

wheelScrolled class-attribute instance-attribute

wheelScrolled = pyqtSignal(int)

zoomValue instance-attribute

zoomValue = 0.0

zoom_combobox instance-attribute

zoom_combobox = ComboBox[float](self, minimumContentsLength=4)

afterReload

afterReload() -> None
Source code
371
372
373
374
375
def afterReload(self) -> None:
    self.underReload = False
    self.verticalScrollBar().setValue(self.last_positions[0])
    self.horizontalScrollBar().setValue(self.last_positions[1])
    self.setTransformationAnchor(QGraphicsView.ViewportAnchor.AnchorUnderMouse)

auto_fit_button_clicked

auto_fit_button_clicked(checked: bool) -> None
Source code
212
213
def auto_fit_button_clicked(self, checked: bool) -> None:
    self.autofit = checked

beforeReload

beforeReload() -> None
Source code
366
367
368
369
def beforeReload(self) -> None:
    self.underReload = True
    self.setTransformationAnchor(QGraphicsView.ViewportAnchor.AnchorViewCenter)
    self.last_positions = (self.verticalScrollBar().value(), self.horizontalScrollBar().value())

bind_to

bind_to(other_view: GraphicsView, *, mutual: bool = True) -> None
Source code
241
242
243
244
245
def bind_to(self, other_view: GraphicsView, *, mutual: bool = True) -> None:
    self.main.bound_graphics_views[other_view].add(self)

    if mutual:
        self.main.bound_graphics_views[self].add(other_view)

event

event(event: QEvent) -> bool
Source code
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
def event(self, event: QEvent) -> bool:
    if self.underReload:
        event.ignore()
        return False

    if isinstance(event, QNativeGestureEvent):
        typ = event.gestureType()
        if typ == Qt.NativeGestureType.BeginNativeGesture:
            self.zoomValue = 0.0
        elif typ == Qt.NativeGestureType.ZoomNativeGesture:
            self.zoomValue += event.value()
        if typ == Qt.NativeGestureType.EndNativeGesture:
            self.wheelScrolled.emit(-1 if self.zoomValue < 0 else 1)

    return super().event(event)

mouseMoveEvent

mouseMoveEvent(event: QMouseEvent) -> None
Source code
330
331
332
333
334
335
336
337
338
339
def mouseMoveEvent(self, event: QMouseEvent) -> None:
    if self.underReload or self.autofit:
        return event.ignore()

    super().mouseMoveEvent(event)

    if self.hasMouseTracking():
        self.mouseMoved.emit(event)

    self.dragEvent.emit(DragEventType.move)

mousePressEvent

mousePressEvent(event: QMouseEvent) -> None
Source code
341
342
343
344
345
346
347
348
349
350
351
352
def mousePressEvent(self, event: QMouseEvent) -> None:
    if self.underReload or self.autofit:
        return event.ignore()

    if event.button() == Qt.MouseButton.LeftButton:
        self.drag_mode = self.dragMode()
        self.setDragMode(QGraphicsView.DragMode.ScrollHandDrag)

    super().mousePressEvent(event)

    self.mousePressed.emit(event)
    self.dragEvent.emit(DragEventType.start)

mouseReleaseEvent

mouseReleaseEvent(event: QMouseEvent) -> None
Source code
354
355
356
357
358
359
360
361
362
363
364
def mouseReleaseEvent(self, event: QMouseEvent) -> None:
    if self.underReload or self.autofit:
        return event.ignore()

    super().mouseReleaseEvent(event)

    if event.button() == Qt.MouseButton.LeftButton:
        self.setDragMode(self.drag_mode)

    self.mouseReleased.emit(event)
    self.dragEvent.emit(DragEventType.stop)

on_wheel_scrolled

on_wheel_scrolled(steps: int) -> None
Source code
247
248
249
250
251
252
253
254
255
def on_wheel_scrolled(self, steps: int) -> None:
    new_index = self.zoom_combobox.currentIndex() + steps

    if new_index < 0:
        new_index = 0
    elif new_index >= len(self.main.settings.zoom_levels):
        new_index = len(self.main.settings.zoom_levels) - 1

    self.zoom_combobox.setCurrentIndex(new_index)

propagate_move_event

propagate_move_event(_: Any = None) -> None
Source code
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
def propagate_move_event(self, _: Any = None) -> None:
    scrollbarW, scrollbarH = self.horizontalScrollBar(), self.verticalScrollBar()

    if not any({scrollbarW.isVisible(), scrollbarH.isVisible()}):
        return

    widthMax, heightMax = scrollbarW.maximum(), scrollbarH.maximum()

    for view in self.main.bound_graphics_views[self] - {self}:
        if view.isVisible():
            wBar, hBar = view.horizontalScrollBar(), view.verticalScrollBar()

            if widthMax:
                wBar.setValue(int(scrollbarW.value() * wBar.maximum() / widthMax))

            if heightMax:
                hBar.setValue(int(scrollbarH.value() * hBar.maximum() / heightMax))

resizeEvent

resizeEvent(event: QResizeEvent) -> None
Source code
377
378
379
def resizeEvent(self, event: QResizeEvent) -> None:
    super().resizeEvent(event)
    self.setZoom(None)

setZoom

setZoom(value: float | None) -> None
Source code
257
258
259
def setZoom(self, value: float | None) -> None:
    for view in self.main.bound_graphics_views[self]:
        view._setZoom(value)

setup_view

setup_view() -> None
Source code
234
235
236
237
238
239
def setup_view(self) -> None:
    for item in self.graphics_scene.graphics_items:
        item.hide()

    self.current_scene.show()
    self.graphics_scene.setSceneRect(QRectF(self.current_scene.pixmap().rect()))

wheelEvent

wheelEvent(event: QWheelEvent) -> None
Source code
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
def wheelEvent(self, event: QWheelEvent) -> None:
    if self.underReload or self.autofit:
        return event.ignore()

    assert self.app

    modifier = event.modifiers()
    mouse = event.buttons()

    self.propagate_move_event()

    if modifier == Qt.KeyboardModifier.ControlModifier or mouse in {
        Qt.MouseButton.RightButton, Qt.MouseButton.MiddleButton
    }:
        angleDelta = event.angleDelta().y()

        # check if wheel wasn't rotated the other way since last rotation
        if self.angleRemainder * angleDelta < 0:
            self.angleRemainder = 0

        self.angleRemainder += angleDelta

        if abs(self.angleRemainder) >= self.WHEEL_STEP:
            self.wheelScrolled.emit(self.angleRemainder // self.WHEEL_STEP)
            self.angleRemainder %= self.WHEEL_STEP
        return
    elif modifier == Qt.KeyboardModifier.NoModifier:
        self.verticalScrollBar().setValue(self.verticalScrollBar().value() - event.angleDelta().y())
        self.horizontalScrollBar().setValue(self.horizontalScrollBar().value() - event.angleDelta().x())
        return
    elif modifier == Qt.KeyboardModifier.ShiftModifier:
        self.verticalScrollBar().setValue(self.verticalScrollBar().value() - event.angleDelta().x())
        self.horizontalScrollBar().setValue(self.horizontalScrollBar().value() - event.angleDelta().y())
        return

    event.ignore()