Important: Please read the Qt Code of Conduct -

QML Desktop Streaming

  • Hi, I have the following problem: I need to capture part of the desktop, specifically of the second monitor, given an x, an y, the width and the height. My question is: is it possible to stream a part of desktop and show it inside a box in a qml project.
    My first thought is to somehow find a c++ function that allows to do screenshot of my second monitor and after importing it inside qml I would call it like every 0.2 seconds with Timer to do screenshot and show it in a box in QML.

    Thank you.

  • Qt Champions 2018

    You can use QScreen::grabWindow for that.

    To use that in QML, you could feed this in a VideoOutput.

    To do that you would have to put your QObject derived class instance as the source of the VideoOutput :
    Your class needs to have a Q_PROPERTY(QAbstractVideoSurface* videoSurface READ videoSurface WRITE setVideoSurface NOTIFY videoSurfaceChange)

    In your setVideoSurface method, you need to call the start method of QAbstractVideoSurface with a correct format (your size and the pixelformat, pixelformat should be QVideoFrame::Format_ARGB32 for desktop I guess).

    And then when you want to update the VideoOutput (via a QTimer for example), you call the present method of QAbstractVideoSurface with a QVideoFrame you constructed from the QPixmap you got in QScreen::grabWindow.

  • Thank you for the instructions, I'm new to all of this so I hope to get to the bottom of this :D

  • Hi, I need some help. I really don't have idea how to do it. This is what I have done so far:

    #ifndef VIDEOSTREAM_H
    #define VIDEOSTREAM_H
    #include <QObject>
    #include <QAbstractVideoSurface>
    class videoStream: public QObject
        Q_PROPERTY(QAbstractVideoSurface* videoSurface READ videoSurface WRITE setVideoSurface NOTIFY videoSurfaceChange)
        explicit videoStream(QObject *parent = nullptr);
        QAbstractVideoSurface* videoSurface();
        void setVideoSurface(const QAbstractVideoSurface &videoSurface);
        void updateScreen();
        void videoSurfaceChange();
        QAbstractVideoSurface* m_videoSurface;
    #endif // VIDEOSTREAM_H


    #include "videostream.h"
    #include <QVideoSurfaceFormat>
    #include <QSize>
    #include <QGuiApplication>
    #include <QWidget>
    #include <QWindow>
    videoStream::videoStream(QObject *parent):
    QAbstractVideoSurface* videoStream::videoSurface()
        return m_videoSurface;
    void videoStream::setVideoSurface(const QAbstractVideoSurface &videoSurface)
        QVideoSurfaceFormat* qvideosurfaceformat;
        qvideosurfaceformat=new QVideoSurfaceFormat(QSize(800,600),QVideoFrame::Format_ARGB32);
    void videoStream::updateScreen(){
        QScreen *screen = QGuiApplication::primaryScreen();
        if (QWindow *window = QWidget::windowHandle())
            screen = window->QWindow::screen();
        if (!screen)


    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include "videostream.h"
    int main(int argc, char *argv[])
        QGuiApplication app(argc, argv);
        qmlRegisterType<BackEnd>("videostream", 1, 0, "VideoStream");
        QQmlApplicationEngine engine;
        if (engine.rootObjects().isEmpty())
            return -1;
        return app.exec();


    import QtQuick 2.9
    import QtQuick.Window 2.2
    import QtMultimedia 5.9
    import videostream 1.0
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
        Rectangle {
            width: 800
            height: 600
            VideoOutput {
                id: videoOutput
                source: video_stream.videoStream
                anchors.fill: parent
    Timer {
            interval: 500; running: true; repeat: true
            onTriggered: video_stream.updateScreen

    A part from errors with these lines

    if (QWindow *window = QWidget::windowHandle())

    I have no idea what should I do

  • Nevermind, thanks anyway. I simply solved it by using QScreen::grabWindow inside QQuickImageProvider and with a Timer inside QML I request and show the image every 33ms to have 30 frames per second of the screen.

Log in to reply