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.

Ausführen des Beispiels
Sie können das Beispiel wie folgt ausführen:
- Qt Creator
Öffnen Sie den Modus „ Welcome “ und wählen Sie das Beispiel unter „ Examples “ aus. Weitere Informationen finden Sie unter Qt Creator: Tutorial: Erstellen und Ausführen.
- Qt Extension for Visual Studio Code
Führen Sie den Befehl „ Qt: Open Qt examples “ über „ Command Palette “ aus und wählen Sie das Beispiel aus der Liste aus. Weitere Informationen finden Sie unter Qt Extension for Visual Studio Code: Tutorial: Erstellen und 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.

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:

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()));© 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.