Auf dieser Seite

QML-Video-Beispiel

Transformation von Video- und Kamerasucher-Inhalten.

QML-Video demonstriert die verschiedenen Transformationen (Verschieben, Größenänderung, Drehen, Seitenverhältnis ändern), die auf die QML-Typen „ VideoOutput “ und „ Camera “ angewendet werden können.

Außerdem wird gezeigt, wie nativer Code mit QML kombiniert werden kann, um erweiterte Funktionen zu implementieren – in diesem Fall wird C++-Code verwendet, um die QML-Bildrate zu berechnen. Dieser Wert wird in QML in einem halbtransparenten Element dargestellt, das über den Videoinhalt gelegt wird.

Das folgende Bild zeigt die Anwendung bei der Ausführung der Video-Overlay-Szene, die ein Dummy-Overlay-Element (einfach ein halbtransparentes ` Rectangle`) erzeugt, das sich über das ` VideoOutput `-Element bewegt.

Videoplayer mit halbtransparenter Überlagerung

Ausführen des Beispiels

Sie können das Beispiel wie folgt ausführen:

Anwendungsstruktur

Die Datei „ Main.qml “ erstellt eine Benutzeroberfläche, die folgende Elemente enthält:

  • Zwei „ Button “-Instanzen, von denen jede einen Dateinamen anzeigt und zum Starten eines „ FileDialog “ verwendet werden kann.
  • Ein „ Button “ zum Beenden.
  • Ein „ SceneSelectionPanel “, bei dem es sich um eine blätterbare Liste handelt, die die verfügbaren Szenen anzeigt.
  • Unten links ein Element, das die QML-Aktualisierungsrate anzeigt – die obere Zahl ist die momentane Bildrate und die untere Zahl der Durchschnitt der letzten Sekunde.

Auswahlfeld für Szenen mit einer Liste von Szenen für den Video- und Kameramodus

Jede Szene in der blätterbaren Liste ist in einer eigenen QML-Datei implementiert – beispielsweise ist die „video-basic“-Szene (die lediglich ein statisches „ VideoOutput “ in der Bildmitte anzeigt) in der Datei „ VideoBasic.qml “ implementiert. Wie aus dem Code ersichtlich ist, wird hier eine Art der Vererbung genutzt; ein „ VideoBasic “-Element …

SceneBasic {
    contentType: "video"
}

... ist vom Typ „ SceneBasic “ ...

import QtQuick
import QtQuick.Controls

Scene {
    id: root
    property string contentType
    ...
    Content {
        id: content
    ...
    }

    Label {
        anchors {
            horizontalCenter: parent.horizontalCenter
            bottom: parent.bottom
            margins: 20
        }
        text: content.started ? qsTr("Tap the screen to stop content")
                              : qsTr("Tap the screen to start content")
        z: 2.0
    }

    MouseArea {
        anchors.fill: parent
        onClicked: {
            if (content.started)
                content.stop()
            else
                content.start()
        }
    }

    Component.onCompleted: root.content = content
}

... das wiederum ein „ Scene “ ist:

import QtQuick
import QtQuick.Controls

Rectangle {
    id: root
    ...
    property QtObject content
    ...
    Button {
        id: closeButton
        anchors {
            top: parent.top
            right: parent.right
            margins: root.margins
        }
        z: 2.0
        text: qsTr("Back")
        onClicked: root.close()
    }
}

SceneBasic beschreibt die Struktur und das Verhalten der Szene, ist jedoch unabhängig von der Art des Inhalts, der angezeigt wird – dies wird durch „ Content “ abstrahiert.

Dieses Muster ermöglicht es uns, einen bestimmten Anwendungsfall zu definieren (in diesem Fall einfach die Anzeige eines statischen Inhalts) und diesen Anwendungsfall dann sowohl für Videoinhalte (VideoBasic) als auch für Kamera-Inhalte ( ({CameraBasic})) zu instanziieren. Dieser Ansatz wird zur Implementierung vieler anderer Szenen verwendet – beispielsweise wird „den Inhalt wiederholt von links nach rechts und wieder zurück schieben“ durch SceneMove implementiert, auf dem VideoMove und CameraMove basieren.

Abhängig vom Wert der Eigenschaft „contentType“ in der Instanz der obersten Ebene der Szene erstellt das eingebettete Element „ Content “ entweder ein Element „ MediaPlayer “ oder ein Element „ Camera “.

Berechnung und Anzeige der QML-Zeichenrate

Die QML-Zeichnungsrate wird von der Klasse „FrequencyMonitor“ berechnet, die einen Strom von Ereignissen (die über den Slot „notify()“ empfangen werden) in eine momentane und eine gemittelte Frequenz umwandelt:

class FrequencyMonitor : public QObject
{
    Q_OBJECT
    QML_ELEMENT
    Q_PROPERTY(qreal instantaneousFrequency READ instantaneousFrequency NOTIFY
                       instantaneousFrequencyChanged)
    Q_PROPERTY(qreal averageFrequency READ averageFrequency NOTIFY averageFrequencyChanged)
    ...
public slots:
    Q_INVOKABLE void notify();
};

Die Klasse „FrequencyMonitor“ wird für QML verfügbar gemacht, indem das Makro „ QML_ELEMENT “ wie oben gezeigt zur Klassendeklaration hinzugefügt wird. Ihre Daten werden durch die Definition eines QML-Elements namens „FrequencyItem“ wie folgt angezeigt:

import frequencymonitor

Rectangle {
    id: root
    ...
    function notify() {
        monitor.notify()
    }

    FrequencyMonitor {
        id: monitor
        onAverageFrequencyChanged: {
            averageFrequencyText.text = monitor.averageFrequency.toFixed(2)
        }
    }

    Text {
        id: labelText
        anchors {
            left: parent.left
            top: parent.top
            margins: 10
        }
        color: root.textColor
        font.pixelSize: 0.6 * root.textSize
        text: root.label
        width: root.width - 2*anchors.margins
        elide: Text.ElideRight
    }

    Text {
        id: averageFrequencyText
        anchors {
            right: parent.right
            bottom: parent.bottom
            margins: 10
        }
        color: root.textColor
        font.pixelSize: root.textSize
    }
}

Das Ergebnis sieht wie folgt aus:

62,5 Hz Momentanfrequenz und 53,15 Hz Durchschnittsfrequenz

Nun muss nur noch das Signal „afterRendering()“ des „ QQuickView “-Objekts mit einer JavaScript-Funktion verbunden werden, die schließlich „ frequencyItem.notify() “ aufruft:

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    ...
    QQuickView viewer;
    ...
    QQuickItem *rootObject = viewer.rootObject();
    ...
    QObject::connect(&viewer, SIGNAL(afterRendering()), rootObject, SLOT(qmlFramePainted()));

Beispielprojekt @ code.qt.io

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.