Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. [PySide2 + QML] Error when registering a python class as QML type

[PySide2 + QML] Error when registering a python class as QML type

Scheduled Pinned Locked Moved Solved Qt for Python
7 Posts 2 Posters 1.6k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    NoodlesDev
    wrote on 27 Mar 2020, 00:53 last edited by
    #1

    Hi everyone,

    I'm trying to register my Python class as a QML type.
    This is the code I'm using:

    camera.py

    # This Python file uses the following encoding: utf-8
    from enum import Enum
    
    from PySide2.QtMultimedia import QCamera, QCameraImageCapture
    from PySide2.QtCore import QObject, QByteArray, Slot, Signal, Property
    
    
    class CameraMode(Enum):
        """Allowed camera modes.
    
        Modes represent a set of configurations used in particular scenarios.
        """
    
        PREVIEW = 0
        CAPTURE = 1
    
    
    class MyCamera(QObject):
        """Custom  camera controller class
    
        This class provides a wrapper around a QCamera instance that
        is used as the system camera."""
    
        cameraReady = Signal()
    
        def __init__(self):
            """Initialize the MyCamera instance."""
    
            QObject.__init__(self)
    
            camera_device = QByteArray(b"/dev/video2")
            self._camera = QCamera(camera_device)
            self._capture = QCameraImageCapture(self._camera)
    
            self._camera.statusChanged.connect(self._configure)
    
            self._camera.load()
    
        @Slot(QCamera.Status)
        def _configure(self, status):
    
            # Here we configure the camera
            if status == QCamera.LoadedStatus:
    
                encoding = self._capture.encodingSettings()
                encoding.setCodec("MJPEG")
                self.setMode(CameraMode.PREVIEW)
                self._camera.start()
    
            elif status == QCamera.ActiveStatus:
    
                self.cameraReady.emit()
    
            elif status == QCamera.Error:
    
                print("ERROR: {}".format(self._camera.errorString))
    
        def setMode(self, mode):
            """Switch the controlled camera to the desired resolution."""
    
            if not isinstance(mode, CameraMode):
    
                raise TypeError("mode should be of type CameraMode")
    
            if mode == CameraMode.PREVIEW:
    
                settings = self._camera.viewfinderSettings()
                settings.setResolution(1920, 1080)
    
            elif mode == CameraMode.CAPTURE:
    
                raise NotImplementedError
    
        def provideCamera(self, qml_camera):
            """Provide a new camera to a QDeclarativeCamera instance.
    
            This function is used to change the QCamera associated to a QML Camera
            in order to provide the configurations that are not allowed by the
            QML type.
            """
    
            qml_camera.setMediaObject(self._camera)
    
    

    man.py

    # This Python file uses the following encoding: utf-8
    
    # Stdlib imports
    import sys
    import os.path
    
    # Qt imports
    from PySide2.QtWidgets import QApplication
    from PySide2.QtQml import QQmlApplicationEngine, qmlRegisterType
    from PySide2.QtCore import QUrl
    
    # Our imports
    from camera import MyCamera
    
    
    if __name__ == "__main__":
        app = QApplication([])
        engine = QQmlApplicationEngine()
    
        # Expose MyCamera to QML
        qmlRegisterType(MyCamera, "Camera", 1, 0, "MyCamera")
    
        # Finally, we load the QML main file and launch the application
        engine.load(QUrl("qml/main.qml"))
    
        sys.exit(app.exec_())
    
    

    Howeven, when the code is run, i get the following error:

    QQmlApplicationEngine failed to load component
    ... main.qml:31 MyCamera is not a type
    

    I really don't see the problem, can anyone please help?

    Thanks in advance!

    1 Reply Last reply
    0
    • E Offline
      E Offline
      eyllanesc
      wrote on 27 Mar 2020, 02:15 last edited by eyllanesc
      #2

      share main.qml and try changing:

      class MyCamera(QObject):
          """Custom  camera controller class
      
          This class provides a wrapper around a QCamera instance that
          is used as the system camera."""
      
          cameraReady = Signal()
      
          def __init__(self, parent=None):
              """Initialize the MyCamera instance."""
      
              QObject.__init__(self, parent)
      

      If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

      1 Reply Last reply
      1
      • N Offline
        N Offline
        NoodlesDev
        wrote on 27 Mar 2020, 10:24 last edited by
        #3

        Hi eyllanesc,

        thanks for your reply. I've tried your suggestion but I'm still getting the same error.
        Here's my main.qml source code:

        import QtQuick 2.14
        import QtQuick.Controls 2.14
        
        ApplicationWindow {
        
            id: root
        
            title: "QCamera Test"
            visible: true
            visibility: "FullScreen"
        
            Item {
        
                id: quit_handler
        
                focus: true
                Keys.onPressed: {
        
                    // CTRL-Q quits the application
                    if (event.key === Qt.Key_Q) {
        
                        event.accepted = true
                        Qt.quit()
        
                    }
        
                }
        
            }
        
            MyCamera {
        
                onCameraReady: {
        
                    content_loader.source = "CameraScreen.qml";
                    provideCamera(content_loader.item.camera)
        
                }
        
            }
        
            // Used to dinamically change the application window content
            Loader {
        
                id: content_loader
        
                width: parent.width
                height: parent.height
        
                active: true
                visible: true
        
                source: "LoadingScreen.qml"
        
            }
        
        }
        
        1 Reply Last reply
        0
        • E Offline
          E Offline
          eyllanesc
          wrote on 27 Mar 2020, 16:28 last edited by
          #4

          @NoodlesDev You have registered the class "MyCamera" in the module "Camera 1.0" but you have not imported it in the .qml, the solution is:

          import QtQuick 2.14
          import QtQuick.Controls 2.14
          
          import Camera 1.0
          
          ApplicationWindow {
          
              // ...
          

          If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

          1 Reply Last reply
          3
          • N Offline
            N Offline
            NoodlesDev
            wrote on 27 Mar 2020, 17:19 last edited by
            #5

            Thank you again @eyllanesc ! It worked!

            I had already tried doing so, but QtCreator showed an error in the main.qml file saying

             "QML module not found (Camera)"
            

            soo I guessed the import was not necessary! My bad.

            The initial error now is gone, but I'm still not managing to make my custom QML type work as expected: when I try to call the provideCamera() method:

               MyCamera {
            
                    onCameraReady: {
            
                        content_loader.source = "CameraScreen.qml";
                        provideCamera(content_loader.item.camera)
            
                    }
            
                }
            

            I get

            ReferenceError: provideCamera is not defined
            

            If I change it to:

               MyCamera {
            
                    onCameraReady: {
            
                        content_loader.source = "CameraScreen.qml";
                        this.provideCamera(content_loader.item.camera)
            
                    }
            
                }
            

            I get:

            TypeError: Property 'provideCamera' of object MyCamera(0x556bfff82130) is not a function
            

            I'm quite confused...

            1 Reply Last reply
            0
            • E Offline
              E Offline
              eyllanesc
              wrote on 27 Mar 2020, 18:45 last edited by eyllanesc
              #6

              @NoodlesDev 1) Qt Creator has many disadvantages with PySide2 compatibility and among them they are not notified of registered types: Qt Quick Designer is not completely PySide2 compatible 2) Only qt-slots are visible from QML.

              @Slot(QObject) 
              def provideCamera(self, qml_camera):
                  # ...
              

              If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

              1 Reply Last reply
              1
              • N Offline
                N Offline
                NoodlesDev
                wrote on 27 Mar 2020, 21:15 last edited by
                #7

                @eyllanesc once again, thanks a lot, your suggestion solved the issue.
                I guess I trusted Qt Creator too much.

                1 Reply Last reply
                0

                2/7

                27 Mar 2020, 02:15

                topic:navigator.unread, 5
                • Login

                • Login or register to search.
                2 out of 7
                • First post
                  2/7
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved