Cast a QObject* to QMediaPlayer with qobject_cast
-
Goodmorning,
I'm trying to cast a QObject pointer taken from QML into a QMediaPlayer one. I always get null using the method qobject_cast.Here's the QML code, where volumeMeter has been made available to QML with context->setContextProperty("volumeMeter", &volume); from an object made in main.cpp
MediaPlayer { id: playMusic objectName: "playMusic" autoLoad: true autoPlay: true playlist: Playlist{id:playerList} Component.onCompleted: { volumeMeter.initVolume(playMusic)} }
and here the volumeLevel class:
#ifndef VOLUMELEVEL_H #define VOLUMELEVEL_H #include <QObject> #include <QAudioProbe> #include <QMediaPlayer> #include <QTimer> #include <vector> #include <memory> #include "playListModel_global.h" class PLAYLISTMODEL_EXPORT VolumeLevel : public QObject { Q_OBJECT public: explicit VolumeLevel(QObject *parent = nullptr); ~VolumeLevel(); // Must call Q_INVOKABLE so that this function can be used in QML Q_INVOKABLE void initVolume(QObject* obj); void initVolume(QString qmlObjectName); public slots: void processBuffer(QAudioBuffer buffer); void timerExpired(); private: QAudioProbe m_probe; QTimer m_timer; QMediaPlayer *m_player; };
#include "volumelevel.h" #include <QDebug> #include <QAudioProbe> VolumeLevel::VolumeLevel(QObject *parent) : QObject(parent) { qRegisterMetaType<QMediaPlayer*>("QMediaPlayer"); } void VolumeLevel::initVolume(QString qmlObjectName) { Q_UNUSED(qmlObjectName) } void VolumeLevel::initVolume(QObject* obj) { qDebug()<<obj; m_player = qobject_cast<QMediaPlayer*>(obj); if( m_player != nullptr ) { qDebug()<<m_player; if(m_probe.setSource(m_player)) { connect(&m_probe, &QAudioProbe::audioBufferProbed, this, &VolumeLevel::processBuffer); connect(&m_timer, &QTimer::timeout, this, &VolumeLevel::timerExpired); m_timer.start(2000); qDebug()<<"Connection done"; } else qDebug()<<"Connection not done"; } else qDebug()<<"cast wrong"; } void VolumeLevel::processBuffer(QAudioBuffer buffer) { // With a 16bit sample buffer: const quint16 *data = buffer.constData<quint16>(); qDebug()<<"Raw: "<<*data; } void VolumeLevel::timerExpired() { qDebug()<<"probe is active: "<<m_probe.isActive(); } VolumeLevel::~VolumeLevel() {}
The output from console is:
QDeclarativeAudio(0x142c458, name = "playMusic")
cast wrongSo the object is correctly identify but the cast fails..
Can you advice?Thanks.
Regards, Davide -
Foudn solution here:
https://doc.qt.io/qt-5/qml-qtmultimedia-mediaplayer.htmlQObject *qmlMediaPlayer; // The QML MediaPlayer object
QMediaPlayer *player = qvariant_cast<QMediaPlayer *>(qmlMediaPlayer->property("mediaObject"));Thank you
-
Hello @jsulm,
thank you for your answer.
As you can see in the code after the cast, m_probe.setSource() is called which requires QMediaObject* type as parameter.
QMediaPlayer subclasses QMediaObject, while QDeclarativeAudio doesn't.
Besides I'm not sure that I can use QDeclarativeAudio so unwary considering that in the class QDeclarativeAudio it's written://
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
// of other Qt classes. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//Does it means that I cannot create in QML a MediaPlayer and pass it to c++ as QMediaPlayer?
Do I have to create a QMediaPlayer in c++ and then register the class for its usage in QML? It would be crazy.. -
@davidino said in Cast a QObject* to QMediaPlayer with qobject_cast:
Do I have to create a QMediaPlayer in c++ and then register the class for its usage in QML? It would be crazy..
I'm not a QML expert but I think so, yes. I don't think MediaPlayer in QML is same as QMediaPlayer, but I may be wrong...
-
Foudn solution here:
https://doc.qt.io/qt-5/qml-qtmultimedia-mediaplayer.htmlQObject *qmlMediaPlayer; // The QML MediaPlayer object
QMediaPlayer *player = qvariant_cast<QMediaPlayer *>(qmlMediaPlayer->property("mediaObject"));Thank you