-
Bug
-
Resolution: Unresolved
-
P2: Important
-
6.6.1
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?