HWND in QML



  • Hi there!

    I'm trying to capture'n'display a video from a cam on QML

    At the moment I'm having a QML extension plugin containing a QGraphicsProxyWidget proxying a QWidget wich acts as a container for the Cam-API to display the video.
    Sadly the API is quite high-level, so I don't have the possibility at the moment to directly convert it to a QIODevice or something, but uses Windows' WindowHandle (HWND) to directly draw into a Window.

    I'm not quite sure, if this HWND gets lost in a QDeclarativeView, as I assume, that this is Window on its own and doesn't manage childs as seperate windows.

    Is there a possibility to draw into a qml component with HWND or is there a workaround?

    Qt Mobility seems to be not a solution, as it wasn't possible to compile it for Windows Mobile 6.5...

    Thanks in advance!
    Ali



  • Noone?

    Well, to cut it down:
    Is the WindowHandle of a QWidget ( winId() )still valid, when loaded as a QML ExtensionPlugin through a QGraphicsProxyWidget?

    Would be great if someone could help me out here, as I don't know where I'm wrong and this is one of the critical points ;)

    Thanks
    Ali



  • Using PyQt on Windows XP, I was able to create a QWidget as a child widget under a QWidget bound to QDeclarativeView, and get a valid HWND. In my case, I bound VLC player's output to the child widget, as VLC python API only accepts HWND to bind a surface. Of course, you lose all fancy stuffs from QML for the child widget but it works.

    I'm afraid QGraphicsProxyWidget doesn't return a valid HWND.



  • I had the same problem a while ago.
    I've managed to solve it by creating a hidden (setWindowOpacity(0)) window (QWidget) and a custom QML control. QId of the hidden window will get Cam-API for drawing in it and also a custom QML control that captures this window on timer and draws it on paint event:

    @void paint(QPainter *painter,
    const QStyleOptionGraphicsItem *option,
    QWidget *widget)
    {
    Q_UNUSED(option);
    Q_UNUSED(widget);

    int w = width();
    int h = height();
    
    QPixmap scaledPixmap(QPixmap::grabWindow(hwnd_).scaled(QSize(w,h),
                         Qt::KeepAspectRatio,
                         Qt::SmoothTransformation));
    
    painter->drawPixmap(x(), y(), scaledPixmap.width(), scaledPixmap.height(), scaledPixmap);
    

    }@

    You'll get the best performance when the hidden window and your QDeclarativeItem have the same size...



  • 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:

    @ class QmlVideo : public QDeclarativeItem
    {
    Q_OBJECT
    public:
    explicit QmlVideo(QDeclarativeItem *parent = 0);
    public slots:
    void play();
    private:
    Phonon::VideoPlayer *m_pPhononPlayer;
    };
    QmlVideo::QmlVideo(QDeclarativeItem parent) :
    QDeclarativeItem(parent)
    {
    m_pPhononPlayer = new Phonon::VideoPlayer(Phonon::VideoCategory);
    QGraphicsProxyWidget
    proxy = new QGraphicsProxyWidget(this);
    proxy->setWidget(m_pPhononPlayer);
    }

    void QmlVideo::play()
    {
        m_pPhononPlayer->play(QUrl("C:\\test.avi"));
    }
    

    @

    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:

    @ class QmlVideo : public QDeclarativeItem
    {
    Q_OBJECT
    public:
    explicit QmlVideo(QDeclarativeItem *parent = 0);
    public slots:
    void play();
    private:
    QWidget *m_pWidget;
    IPlayerCore *m_pPlayerCore;
    };
    QmlVideo::QmlVideo(QDeclarativeItem *parent) :
    QDeclarativeItem(parent)
    {
    m_pWidget = new QWidget();
    m_pWidget->resize(300, 300);
    m_pWidget->show();

        QGraphicsProxyWidget* proxy = new QGraphicsProxyWidget(this);
        proxy->setWidget(m_pWidget);
    }
     
    void QmlVideo::play()
    {
     WId hwnd = m_pWidget->winId();
        if (CreatePlayerCore(hwnd, &m_pPlayerCore) != IPlayerCore::STATUS_OK || m_pPlayerCore == 0) {
            qDebug() << "Failed to create player core!\n";
        }
        if (m_pPlayerCore->Subscribe(new IPlayerCoreNotifyImpl(hwnd, m_pPlayerCore)) < 0) {
            qDebug() << "Failed to subscribe to core events!\n";
        }
        if (m_pPlayerCore->Load(false, L"C:\\test.avi") != IPlayerCore::STATUS_OK) {
            qDebug() << Q_FUNC_INFO << "error";
        }
    }
    

    @

    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?



  • @Roman90
    Have you solved the problem ? I'm using MPlayer + QML, but failed .


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.