July 23, 2011

xcoder xcoder
Lab Rat
45 posts

[UNSOLVEABLE] Again problems with QWidget in QML this time HWND

 

Hi,

I’m trying to create custom QWidget to use in QML. Basically I want VLC to play in QML.
All I get is the sound from video, without picture.

And in QML designer it says that there is no property for anchors, width or height for my VLC extension.

I need to use QWidget because of the HWND property. Maybe QML has one of it’s own?

Here is my vlc_player.h

  1. #ifndef VLC_PLAYER_H
  2. #define VLC_PLAYER_H
  3.  
  4. #include <QtDeclarative/QDeclarativeExtensionPlugin>
  5. #include <QtDeclarative/qdeclarative.h>
  6. #include <QtGui/QGraphicsProxyWidget>
  7. #include <QtGui/QWidget>
  8. #include <QDebug>
  9. #include <vlc/vlc.h>
  10.  
  11.  
  12.  
  13. class vlc_player : public QGraphicsProxyWidget
  14. {
  15.     Q_OBJECT
  16.     Q_PROPERTY(QString texts WRITE play)
  17.  
  18. public:
  19.     vlc_player(QGraphicsItem* parent = 0);
  20.     libvlc_instance_t * inst;
  21.     libvlc_media_player_t * mp;
  22.     libvlc_media_t * m;
  23.  
  24.     void play(const QString &texts;);
  25.  
  26. private:
  27.     QWidget *vlcvideo;
  28. };
  29.  
  30.  
  31.  
  32. #endif // VLC_PLAYER_H

vlc_player.cpp

  1. #include "vlc_player.h"
  2.  #include <QtGui/QWidget>
  3.  #include <QDebug>
  4.  
  5. vlc_player::vlc_player(QGraphicsItem* parent)
  6.     : QGraphicsProxyWidget(parent)
  7. {
  8.     vlcvideo = new QWidget();
  9.     vlcvideo->setObjectName(QString::fromUtf8("vlcvideo"));
  10.     vlcvideo->setGeometry(QRect(10, 90, 431, 291));
  11.  
  12.     vlcvideo->setAttribute(Qt::WA_NoSystemBackground);
  13.     vlcvideo->setStyleSheet("background-color:black;");
  14.     vlcvideo->setMinimumSize(400,400);
  15.  
  16.     this->setWidget(vlcvideo);
  17.  
  18.     qDebug()<<vlcvideo->winId();
  19.  
  20.     /* Load the VLC engine */
  21.         inst = libvlc_new (0, NULL);
  22.  
  23.          setFlag(QGraphicsItem::ItemHasNoContents, false);
  24. }
  25.  
  26.  
  27.  
  28.      void vlc_player::play(const QString &texts;)
  29.      {
  30.  
  31.  
  32.             // if(isPlaying==true)   stop();
  33.  
  34.              /* Create a new item */
  35.              m = libvlc_media_new_path (inst, texts.toStdString().c_str());
  36.  
  37.              /* Create a media player playing environement */
  38.              mp = libvlc_media_player_new_from_media (m);
  39.  
  40.              /* No need to keep the media now */
  41.              libvlc_media_release (m);
  42.  
  43.              //Ievietojam vlc QWidget rāmi + ar pārbaudi kas tev par sistemu
  44.          #if defined(Q_WS_X11)
  45.              libvlc_media_player_set_xwindow(mp, vlcvideo->winId());
  46.          #elif defined(Q_WS_MAC)
  47.              libvlc_media_player_set_nsobject(mp, vlcvideo->winId());
  48.          #elif defined(Q_WS_WIN)
  49.              libvlc_media_player_set_hwnd(mp, vlcvideo->winId());
  50.          #else
  51.          #error "unsupported platform"
  52.          #endif
  53.  
  54.              /* play the media_player */
  55.              libvlc_media_player_play (mp);
  56.  
  57.      }
  58. --

and part of my qml

  1.     QWidget {
  2.         id: vlc1
  3.         texts: "nasa.wmv"
  4.         anchors.fill: parent
  5.         width:400
  6.         height:400
  7.  
  8.     }

Best regards
Raivis

 Signature 

Only a biker knows why a dog sticks his head out of a car window.

14 replies

July 23, 2011

Chuck Gao Chuck Gao
Lab Rat
342 posts

The QML property is define with Q_PROPERTY(..) statement, so if you want to use anchors, width or height, you need to declare them and write the “Read”, “Write” method at least. The common QML item is inherits from QDeclarativeItem, so they have those properties

And, QWidget is not a right name for custom QML element below:

  1.     id: vlc1
  2.     texts: "nasa.wmv"
  3.     anchors.fill: parent
  4.     width:400
  5.     height:400
  6.  
  7. }

 Signature 

Chuck

July 23, 2011

xcoder xcoder
Lab Rat
45 posts

Ok I changed the name, now QWidget is named VlcPlayer. Still No picture, just audio.

I’ll get back to QDeclarativeItem later, now my priority is video output

 Signature 

Only a biker knows why a dog sticks his head out of a car window.

July 23, 2011

Chuck Gao Chuck Gao
Lab Rat
342 posts

As you mentioned before, do you add width, height property for your widget? Is the code work well with just QWidget?

 Signature 

Chuck

July 23, 2011

xcoder xcoder
Lab Rat
45 posts

With just a QWidget my code works OK. Now I’ve made my extension with QDeclarativeItem, it seems that QDeclarativeItem doesn’t have setWidget command.

Basically the same effect, no video but I have a sound.

Here is my full code:

VlcPlayer.h

  1. #ifndef VLCPLAYER_H
  2. #define VLCPLAYER_H
  3.  
  4. #include <QtDeclarative/QDeclarativeExtensionPlugin>
  5. #include <QtDeclarative/qdeclarative.h>
  6. #include <QDeclarativeItem>
  7. #include <QtGui/QGraphicsProxyWidget>
  8. #include <QtGui/QWidget>
  9. #include <QDebug>
  10. #include <vlc/vlc.h>
  11.  
  12.  
  13.  
  14. class VlcPlayer : public QDeclarativeItem
  15. {
  16.     Q_OBJECT
  17.     Q_PROPERTY(QString media READ playing WRITE play)
  18.  
  19. public:
  20.     VlcPlayer(QDeclarativeItem* parent = 0);
  21.     libvlc_instance_t * inst;
  22.     libvlc_media_player_t * mp;
  23.     libvlc_media_t * m;
  24.  
  25.     void play(const QString &media;);
  26.     QString playing() const;
  27.  
  28. private:
  29.     QWidget *vlcvideo;
  30.     QString m_name;
  31.  
  32. };
  33.  
  34.  
  35.  
  36. #endif // VLCPLAYER_H

vlcplayer.cpp

  1. #include "vlcplayer.h"
  2.  #include <QtGui/QWidget>
  3.  #include <QDebug>
  4.  
  5. VlcPlayer::VlcPlayer(QDeclarativeItem* parent)
  6.     : QDeclarativeItem(parent)
  7. {
  8.     vlcvideo = new QWidget();
  9.     //setFlag(QDeclarativeItem::ItemHasNoContents, false);
  10.  
  11.     //setWidget(vlcvideo);
  12.  
  13.     /* Load the VLC engine */
  14.         inst = libvlc_new (0, NULL);
  15.  
  16.  
  17. }
  18.  
  19.  
  20. QString VlcPlayer::playing() const
  21. {
  22.     return m_name;
  23. }
  24.  
  25.  
  26.      void VlcPlayer::play(const QString &texts;)
  27.      {
  28.             m_name = texts;
  29.  
  30.             // if(isPlaying==true)   stop();
  31.  
  32.              /* Create a new item */
  33.              m = libvlc_media_new_path (inst, texts.toStdString().c_str());
  34.  
  35.              /* Create a media player playing environement */
  36.              mp = libvlc_media_player_new_from_media (m);
  37.  
  38.              /* No need to keep the media now */
  39.              libvlc_media_release (m);
  40.  
  41.              //Ievietojam vlc QWidget rāmi + ar pārbaudi kas tev par sistemu
  42.          #if defined(Q_WS_X11)
  43.              libvlc_media_player_set_xwindow(mp, vlcvideo->winId());
  44.          #elif defined(Q_WS_MAC)
  45.              libvlc_media_player_set_nsobject(mp, vlcvideo->winId());
  46.          #elif defined(Q_WS_WIN)
  47.              libvlc_media_player_set_hwnd(mp, vlcvideo->winId());
  48.          #else
  49.          #error "unsupported platform"
  50.          #endif
  51.  
  52.              /* play the media_player */
  53.              libvlc_media_player_play (mp);
  54.  
  55.      }

main.cpp

  1. #include <QtGui/QApplication>
  2. #include "qmlapplicationviewer.h"
  3. #include "vlcplayer.h"
  4. #include <qdeclarative.h>
  5. #include <QDeclarativeView>
  6.  
  7. int main(int argc, char *argv[])
  8. {
  9.    QApplication app(argc, argv);
  10.    qmlRegisterType<VlcPlayer>("Vlc", 1, 0, "VlcPlayer");
  11.  
  12.    QmlApplicationViewer viewer;
  13.    viewer.setMainQmlFile(QLatin1String("qml/widget/main.qml"));
  14.    viewer.showExpanded();
  15.  
  16.    return app.exec();
  17. }

main.qml

  1. import QtQuick 1.0
  2. import Vlc 1.0
  3.  
  4. Rectangle {
  5.    width: 360
  6.    height: 360
  7.  
  8.     VlcPlayer {
  9.         id: vlc1
  10.         clip: false
  11.         anchors.fill: parent
  12.         media: "nasa.wmv"      
  13.     }
  14. }

Now in Design mode I don’t have any errors. As I mentioned no video either, just the sound!

Here is a screen shot what I get when I run my app:
No video just audio

 Signature 

Only a biker knows why a dog sticks his head out of a car window.

July 24, 2011

xcoder xcoder
Lab Rat
45 posts

I solved my problem, the mistake was trying to use QWidget, somehow I can set the QWidget’s background through CSS and it will show up in QML, but vlc won’t draw anything on it.

The solution is to use QGraphicsScene instead. Well it worked for me.

 Signature 

Only a biker knows why a dog sticks his head out of a car window.

July 27, 2011

Freeuser Freeuser
Lab Rat
13 posts

Hi!
I have the same problem, but I use phonon module. Can you place code with integration QGraphicsScene to Qml here? Thank you in advance!

July 28, 2011

xcoder xcoder
Lab Rat
45 posts

Sorry when I made that conclusion, I thought I could implement QGraphicsSCene with valid winId, actually you can’t.

Only the main windows has valid WinId, so the VLC or maybe even phonon draws on top of the QML viewer.

I can give you code for how to implement Qgraphicscene without winid, you will be able to draw circles rectangles or anything you want. But you won’t get a valid winId.

And if you use phonon, maybe check out Qt Multimedia. I once came across, that QML or Qt Quick has built in video/audio player. If I remember correctly the library was called Qt Multimedia.

 Signature 

Only a biker knows why a dog sticks his head out of a car window.

July 28, 2011

Gerolf Gerolf
Area 51 Engineer
3210 posts

AFAIK, there is a possibility to fore a widget to be a real windows window. Then it will have a valid winId(). I think it was something like:

  1.     x->setAttribute(Qt::WA_NativeWindow, true);
  2.     x->setAttribute(Qt::WA_DontCreateNativeAncestors, true);

where x is the widget that should show the video.

as description, have a look at native vs. alient widgets [doc.qt.nokia.com]

 Signature 

Nokia Certified Qt Specialist.
Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

July 28, 2011

Freeuser Freeuser
Lab Rat
13 posts

Thanks…Unfortunately, player based on QtMobility, and Qml element “Video” are play stream video not correctly. That is why I use phonon modul. And recently I’ve learned that phonon player can output video to widget only…

July 28, 2011

xcoder xcoder
Lab Rat
45 posts

Still, even with set attribute in qt quick my VLC plugin doesn’t get a picture. If I understand correctly, when I embed QWidget in QML, it’s winId technically won’t exist anymore.

 Signature 

Only a biker knows why a dog sticks his head out of a car window.

February 23, 2012

Roman90 Roman90
Lab Rat
10 posts

Hello

We built QML plugin that used Phonon as video play engine and it works correct in our QML project. Here are worked QML Phonon component sources:

  1.     class QmlVideo : public QDeclarativeItem
  2.     {
  3.         Q_OBJECT
  4.     public:
  5.         explicit QmlVideo(QDeclarativeItem *parent = 0);
  6.     public slots:
  7.         void play();
  8.     private:
  9.         Phonon::VideoPlayer *m_pPhononPlayer;
  10.     };
  11.     QmlVideo::QmlVideo(QDeclarativeItem *parent) :
  12.         QDeclarativeItem(parent)
  13.     {
  14.         m_pPhononPlayer = new Phonon::VideoPlayer(Phonon::VideoCategory);
  15.         QGraphicsProxyWidget* proxy = new QGraphicsProxyWidget(this);
  16.         proxy->setWidget(m_pPhononPlayer);
  17.     }
  18.      
  19.     void QmlVideo::play()
  20.     {
  21.         m_pPhononPlayer->play(QUrl("C:\\test.avi"));
  22.     }

Now we decided to replace Phonon on another video play engine. This another video play engine draws video in external lib and requires only HWND window where to paint. So we replaced Phonon widget to usual QWidget in our QML video component and passed QWidget winId() to video lib but it doesn’t work. We can hear sound but video is not visible (WM_PAINT doesn’t come to this widget). Below are NOT worked QML component with using external video lib:

  1.     class QmlVideo : public QDeclarativeItem
  2.     {
  3.         Q_OBJECT
  4.     public:
  5.         explicit QmlVideo(QDeclarativeItem *parent = 0);
  6.     public slots:
  7.         void play();
  8.     private:
  9.      QWidget *m_pWidget;
  10.         IPlayerCore *m_pPlayerCore;
  11.     };
  12.     QmlVideo::QmlVideo(QDeclarativeItem *parent) :
  13.         QDeclarativeItem(parent)
  14.     {
  15.      m_pWidget = new QWidget();
  16.      m_pWidget->resize(300, 300);
  17.      m_pWidget->show();
  18.      
  19.         QGraphicsProxyWidget* proxy = new QGraphicsProxyWidget(this);
  20.         proxy->setWidget(m_pWidget);
  21.     }
  22.      
  23.     void QmlVideo::play()
  24.     {
  25.      WId hwnd = m_pWidget->winId();
  26.         if (CreatePlayerCore(hwnd, &m_pPlayerCore) != IPlayerCore::STATUS_OK || m_pPlayerCore == 0) {
  27.             qDebug() << "Failed to create player core!\n";
  28.         }
  29.         if (m_pPlayerCore->Subscribe(new IPlayerCoreNotifyImpl(hwnd, m_pPlayerCore)) < 0) {
  30.             qDebug() << "Failed to subscribe to core events!\n";
  31.         }
  32.         if (m_pPlayerCore->Load(false, L"C:\\test.avi") != IPlayerCore::STATUS_OK) {
  33.             qDebug() << Q_FUNC_INFO << "error";
  34.         }
  35.     }

In the same time we can see video in this m_pWidget if comment line
//proxy->setWidget(m_pWidget);
but then window is not part of QML scene.

So how is to get video painted from external video lib on QWidget that will be a part of scene as QML component?

February 23, 2012

xcoder xcoder
Lab Rat
45 posts

Well, I had this problem last summer, I ‘ve to look for my old code. I think I solved it, but I couldn’t found my source code at this moment. I think it’s on my other computer.

 Signature 

Only a biker knows why a dog sticks his head out of a car window.

February 27, 2012

Roman90 Roman90
Lab Rat
10 posts

Could you inform me about your search results please?
It’s urgent, for a long time already can’t find the solution.

March 4, 2012

pythoneer pythoneer
Lab Rat
7 posts

@xcoder:
would be nice to see a working example, still facing the same problems as you and Roman90. couldn’t this be considered as a bug from qt side?

regards ..

 
  ‹‹ Global js to use in more QML files (SOLVED)      Calling a .QML file using XML ››

You must log in to post a reply. Not a member yet? Register here!