QML-Video-Beispiel
Transformieren von Video- und Kamerasucherinhalten.
QML Video demonstriert die verschiedenen Transformationen (Verschieben; Größenänderung; Drehen; Änderung des Seitenverhältnisses), die auf die QML-Typen VideoOutput und Camera angewendet werden können.
Es zeigt auch, 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 gerendert, das den Videoinhalt überlagert.
Das folgende Bild zeigt die Anwendung, die die Video-Overlay-Szene ausführt, die ein Dummy-Overlay-Element erstellt (nur ein halbtransparentes Rectangle), das sich über das Element VideoOutput bewegt.
Ausführen des Beispiels
Zum Ausführen des Beispiels von Qt Creatorzu starten, öffnen Sie den Modus Welcome und wählen Sie das Beispiel unter Examples aus. Weitere Informationen finden Sie unter Erstellen und Ausführen eines Beispiels.
Struktur der Anwendung
Die Datei Main.qml
erstellt eine Benutzeroberfläche, die die folgenden Elemente enthält:
- Zwei
Button
Instanzen, von denen jede einen Dateinamen anzeigt und zum Starten einerFileDialog
verwendet werden kann. - Eine Beendigung
Button
. - Eine
SceneSelectionPanel
, die eine blätterbare Liste mit den verfügbaren Szenen darstellt. - Unten links befindet sich ein Element, das die QML-Wiederholungsrate anzeigt - die obere Zahl ist die momentane Bildrate und die untere Zahl ist der Durchschnitt der letzten Sekunde.
Jede Szene in der Flickable-Liste ist in einer eigenen QML-Datei implementiert - zum Beispiel ist die Video-Basisszene (die nur ein statisches VideoOutput in der Mitte des Bildschirms anzeigt) in der Datei VideoBasic.qml
implementiert. Wie Sie aus dem Code ersehen können, macht dies von einer Art Vererbung Gebrauch; ein Element VideoBasic
...
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 }
... der selbst 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 aber unabhängig von der Art des Inhalts, der angezeigt werden soll - dieser wird durch Content
abstrahiert.
Dieses Muster ermöglicht es uns, einen bestimmten Anwendungsfall zu definieren (in diesem Fall die einfache Anzeige eines statischen Inhalts) und diesen Anwendungsfall dann sowohl für Videoinhalte (VideoBasic
) als auch für Kamerainhalte ({CameraBasic})
zu instanziieren. Dieser Ansatz wird zur Implementierung vieler anderer Szenen verwendet - zum Beispiel 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 obersten Szeneninstanz erzeugt das eingebettete Element Content
entweder ein Element MediaPlayer oder ein Element Camera.
Berechnen und Anzeigen der QML-Malrate
Die QML-Malrate wird von der Klasse FrequencyMonitor berechnet, die einen Strom von Ereignissen (die über den notify()-Slot empfangen werden) in eine momentane und eine gemittelte Frequenz umwandelt:
class FrequencyMonitor : public QObject { Q_OBJECT Q_PROPERTY(qreal instantaneousFrequency READ instantaneousFrequency NOTIFY instantaneousFrequencyChanged) Q_PROPERTY(qreal averageFrequency READ averageFrequency NOTIFY averageFrequencyChanged) public: ... static void qmlRegisterType(); public slots: Q_INVOKABLE void notify(); };
Die FrequencyMonitor-Klasse wird in QML wie folgt dargestellt
void FrequencyMonitor::qmlRegisterType() { ::qmlRegisterType<FrequencyMonitor>("FrequencyMonitor", 1, 0, "FrequencyMonitor"); }
und ihre Daten werden angezeigt, indem ein QML-Element namens FrequencyItem wie folgt definiert wird:
import FrequencyMonitor 1.0 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:
Es bleibt nur noch, das Signal afterRendering() des QQuickView -Objekts mit einer JavaScript-Funktion zu verbinden, 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()));
© 2025 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.