Skip to content

Commit

Permalink
Modify duplicated implementations of qt previews, to use PySide6 rath…
Browse files Browse the repository at this point in the history
…er than PyQt5

Replace imports in new qt_pyside6.py file with new q_pyside6_picamera2.py and q_pyside6_gl_picamera2.py files

Alter imports and method/object references in new q_pyside6_picamera2.py and q_pyside6_gl_picamera2.py files to use that of PySide6 rather than PyQt5

Signed-off-by: Levi Dean <[email protected]>
  • Loading branch information
LODean committed Jan 24, 2025
1 parent 9b74e70 commit e2cff5e
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 23 deletions.
14 changes: 7 additions & 7 deletions picamera2/previews/q_pyside6_gl_picamera2.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
from OpenGL.GLES2.OES.EGL_image_external import *
from OpenGL.GLES2.VERSION.GLES2_2_0 import *
from OpenGL.GLES3.VERSION.GLES3_3_0 import *
from PyQt5.QtCore import QSocketNotifier, Qt, pyqtSignal, pyqtSlot
from PyQt5.QtWidgets import QWidget
from PySide6.QtCore import QSocketNotifier, Qt, Signal, Slot
from PySide6.QtWidgets import QWidget

from picamera2.previews.gl_helpers import *

Expand Down Expand Up @@ -72,15 +72,15 @@ def create_context(self):


class QGlPicamera2(QWidget):
done_signal = pyqtSignal(object)
done_signal = Signal(object)

def __init__(self, picam2, parent=None, width=640, height=480, bg_colour=(20, 20, 20),
keep_ar=True, transform=None, preview_window=None):
super().__init__(parent=parent)
self.resize(width, height)

self.setAttribute(Qt.WA_PaintOnScreen)
self.setAttribute(Qt.WA_NativeWindow)
self.setAttribute(Qt.WidgetAttribute.WA_PaintOnScreen)
self.setAttribute(Qt.WidgetAttribute.WA_NativeWindow)

self.bg_colour = [colour / 255.0 for colour in bg_colour] + [1.0]
self.keep_ar = keep_ar
Expand Down Expand Up @@ -108,7 +108,7 @@ def __init__(self, picam2, parent=None, width=640, height=480, bg_colour=(20, 20
self.preview_window = preview_window

self.camera_notifier = QSocketNotifier(self.picamera2.notifyme_r,
QSocketNotifier.Read, self)
QSocketNotifier.Type.Read, self)
self.camera_notifier.activated.connect(self.handle_requests)
# Must always run cleanup when this widget goes away.
self.destroyed.connect(lambda: self.cleanup())
Expand Down Expand Up @@ -396,7 +396,7 @@ def render_request(self, completed_request):
if self.own_current:
self.current_request.acquire()

@pyqtSlot()
@Slot()
def handle_requests(self):
if not self.running:
return
Expand Down
28 changes: 14 additions & 14 deletions picamera2/previews/q_pyside6_picamera2.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

import numpy as np
from libcamera import Transform
from PyQt5.QtCore import (QRect, QRectF, QSize, QSocketNotifier, Qt,
pyqtSignal, pyqtSlot)
from PyQt5.QtGui import QBrush, QColor, QImage, QPixmap, QTransform
from PyQt5.QtWidgets import QGraphicsScene, QGraphicsView
from PySide6.QtCore import (QRect, QRectF, QSize, QSocketNotifier, Qt,
Signal, Slot)
from PySide6.QtGui import QBrush, QColor, QImage, QPixmap, QTransform
from PySide6.QtWidgets import QGraphicsScene, QGraphicsView

try:
import cv2
Expand All @@ -15,8 +15,8 @@


class QPicamera2(QGraphicsView):
done_signal = pyqtSignal(object)
update_overlay_signal = pyqtSignal(object)
done_signal = Signal(object)
update_overlay_signal = Signal(object)

def __init__(self, picam2, parent=None, width=640, height=480, bg_colour=(20, 20, 20),
keep_ar=True, transform=None, preview_window=None):
Expand All @@ -36,14 +36,14 @@ def __init__(self, picam2, parent=None, width=640, height=480, bg_colour=(20, 20
self.setScene(self.scene)
self.setBackgroundBrush(QBrush(QColor(*bg_colour)))
self.resize(width, height)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
self.enabled = True
self.title_function = None

self.update_overlay_signal.connect(self.update_overlay)
self.camera_notifier = QSocketNotifier(self.picamera2.notifyme_r,
QSocketNotifier.Read, self)
QSocketNotifier.Type.Read, self)
self.camera_notifier.activated.connect(self.handle_requests)
# Must always run cleanup when this widget goes away.
self.destroyed.connect(lambda: self.cleanup())
Expand Down Expand Up @@ -94,12 +94,12 @@ def set_overlay(self, overlay):
if overlay is not None:
overlay = np.copy(overlay, order='C')
shape = overlay.shape
qim = QImage(overlay.data, shape[1], shape[0], QImage.Format_RGBA8888)
qim = QImage(overlay.data, shape[1], shape[0], QImage.Format.Format_RGBA8888)
new_pixmap = QPixmap(qim)
# No scaling here - we leave it to fitInView to set that up.
self.update_overlay_signal.emit(new_pixmap)

@pyqtSlot(object)
@Slot(object)
def update_overlay(self, pix):
if pix is None:
# Delete overlay if present
Expand All @@ -116,7 +116,7 @@ def update_overlay(self, pix):
self.overlay.setPixmap(pix)
self.fitInView()

@pyqtSlot(bool)
@Slot(bool)
def set_enabled(self, enabled):
self.enabled = enabled

Expand Down Expand Up @@ -188,7 +188,7 @@ def render_request(self, completed_request):
width = min(img.shape[1], stream_config["size"][0])
width -= width % 4
img = np.ascontiguousarray(img[:, :width, :3])
fmt = QImage.Format_BGR888 if stream_config['format'] in ('RGB888', 'XRGB8888') else QImage.Format_RGB888
fmt = QImage.Format.Format_BGR888 if stream_config['format'] in ('RGB888', 'XRGB8888') else QImage.Format.Format_RGB888
qim = QImage(img.data, width, img.shape[0], fmt)
pix = QPixmap(qim)
# Add the pixmap to the scene if there wasn't one, or replace it if the images have
Expand All @@ -203,7 +203,7 @@ def render_request(self, completed_request):
# Update pixmap
self.pixmap.setPixmap(pix)

@pyqtSlot()
@Slot()
def handle_requests(self):
if not self.running:
return
Expand Down
4 changes: 2 additions & 2 deletions picamera2/previews/qt_pyside6.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
# which is in any case what is required for remote preview windows.
from logging import getLogger

from .q_picamera2 import QPicamera2
from .q_pyside6_picamera2 import QPicamera2

_log = getLogger(__name__)

try:
from .q_gl_picamera2 import QGlPicamera2
from .q_pyside6_gl_picamera2 import QGlPicamera2
except Exception:
_log.warning("OpenGL will not be available")

0 comments on commit e2cff5e

Please sign in to comment.