Details
-
Bug
-
Resolution: Unresolved
-
P2: Important
-
6.6.1
Description
I want to add a new property to the QtMultimedia VideoOutput QML object. It appears I should use QML_EXTENDED to do that.
https://doc.qt.io/qt-6/qtqml-cppintegration-definetypes.html#registering-extension-objects
It's not clear from the documentation how to do this. I see two approaches, include the private header so I can use QQuickVideoOutput - the undocumented private implementation of the VideoOutput QML object:
#include <QtMultimediaQuick/private/qquickvideooutput_p.h> struct VideoOutputForeign { Q_GADGET QML_FOREIGN(QQuickVideoOutput) QML_NAMED_ELEMENT(VideoOutput) QML_EXTENDED(VideoOutputExtension) };
Or add my property to the public base class of QQuickVideoOutput - QQuickItem:
#include <QQuickItem> struct VideoOutputForeign { Q_GADGET QML_FOREIGN(QQuickItem) QML_NAMED_ELEMENT(Item) QML_EXTENDED(VideoOutputExtension) };
and then deal with users attempting to use my property on classes I don't support (i.e. anything other than VideoOutput)
I implemented both approaches in the attached project and both seem to work.
cmake -DPRIVATE=1 to use the QQuickVideoOutput approach, and don't define PRIVATE to use the QQuickItem approach.
One oddity is I log the object I'm extending in my extension constructor:
VideoOutputExtension::VideoOutputExtension(QObject *object) : QObject(object) , m_videoOutput(object) { QVideoSink* videoSink = nullptr; auto* mo = m_videoOutput->metaObject(); mo->invokeMethod(m_videoOutput, "videoSink", Q_RETURN_ARG(QVideoSink*, videoSink)); qDebug() << m_videoOutput << "class" << mo->className() << "videoSink" << videoSink; }
In both cases it logs itself as VideoOutputExtension instead of QQuickItem or QQuickVideoOutput - but when it is attached to a VideoOutput, it has a videoSink property so it must be the correct object.
QQuickItem implementation logs:
QMetaObject::invokeMethod: No such method VideoOutputExtension::videoSink() VideoOutputExtension(0x600001a4c0e0) class VideoOutputExtension videoSink QObject(0x0) setFoobar 42 VideoOutputExtension(0x154a18a80) class VideoOutputExtension videoSink QVideoSink(0x600002305540) setFoobar 23 qml: loaded video-item.qml
QQuickVideoOutput implementation logs:
VideoOutputExtension(0x142106ad0) class VideoOutputExtension videoSink QVideoSink(0x600000948a00) setFoobar 23 qml: loaded video.qml
Could the QML_EXTENDED documentation be enhanced to recommend the preferred way to extend QML objects that have private Qt implementations?