summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Eftevaag <oliver.eftevaag@qt.io>2024-01-04 14:25:42 +0100
committerOliver Eftevaag <oliver.eftevaag@qt.io>2024-04-04 11:00:37 +0200
commit6e6fe9862aed124176a79027a92871fde49c0817 (patch)
tree5ca36b1bdf35167c9b16de14cb84b0eb22692a5f
parent2d7d8772764a0eaf0e2f300b4cb639ca0b3c1071 (diff)
Revamp qmlvideo example
In order to make the example adhere to our example guidelines, and to encourage the use of QML best practices. I've made numerous improvements in this patch. Which contains the following changes. - All root and context properties are replaced with a singleton. - User facing strings are wrapped with qsTr(). - QtQuick.Controls buttons are now used, instead of the homemade Button.qml. - We're now using colors from the palette, instead of hard coded color values. - QtQuick.Layouts are now used, where it makes sense. - Most qmllint warnings are now fixed, with a few being suppressed with qmllint enable/disable comments. Fixes: QTBUG-113689 Pick-to: 6.7 Change-Id: I685d68665657f631cba4d8f83519ca2ecc45e2d8 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
-rw-r--r--examples/multimedia/video/qmlvideo/CMakeLists.txt11
-rw-r--r--examples/multimedia/video/qmlvideo/main.cpp22
-rw-r--r--examples/multimedia/video/qmlvideo/performancemonitor/PerformanceItem.qml21
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo.pro27
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/Button.qml43
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/CMakeLists.txt9
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/CameraBasic.qml2
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/CameraDrag.qml2
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/CameraDummy.qml6
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/CameraFullScreen.qml2
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/CameraFullScreenInverted.qml2
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/CameraMove.qml2
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/CameraOverlay.qml2
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/CameraResize.qml2
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/CameraRotate.qml2
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/CameraSpin.qml2
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/Content.qml28
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/ErrorDialog.qml7
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/Main.qml172
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/Scene.qml11
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/SceneBasic.qml8
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/SceneFullScreen.qml12
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/SceneFullScreenInverted.qml10
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/SceneMove.qml2
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/SceneMulti.qml52
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/SceneOverlay.qml4
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/SceneRotate.qml15
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/SceneSelectionPanel.qml69
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/SeekControl.qml18
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/VideoBasic.qml2
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/VideoDrag.qml2
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/VideoDummy.qml6
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/VideoFillMode.qml15
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/VideoFullScreen.qml2
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/VideoFullScreenInverted.qml2
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/VideoMetadata.qml78
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/VideoMove.qml2
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/VideoOverlay.qml2
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/VideoPlaybackRate.qml23
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/VideoResize.qml2
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/VideoRotate.qml2
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/VideoSeek.qml8
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/VideoSpin.qml2
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/qmldir1
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/qmlvideo_global.h10
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/videosingleton.cpp54
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo/videosingleton.h48
47 files changed, 423 insertions, 403 deletions
diff --git a/examples/multimedia/video/qmlvideo/CMakeLists.txt b/examples/multimedia/video/qmlvideo/CMakeLists.txt
index fc7e2bd10..43975d584 100644
--- a/examples/multimedia/video/qmlvideo/CMakeLists.txt
+++ b/examples/multimedia/video/qmlvideo/CMakeLists.txt
@@ -36,18 +36,21 @@ target_compile_definitions(qmlvideoexample PUBLIC
PERFORMANCEMONITOR_SUPPORT
)
+add_subdirectory(qmlvideo)
+add_subdirectory(performancemonitor)
+add_subdirectory(frequencymonitor)
+
target_link_libraries(qmlvideoexample PRIVATE
Qt::Core
Qt::Gui
Qt::Multimedia
Qt::Qml
Qt::Quick
+ qmlvideo
+ performancemonitor
+ frequencymonitor
)
-add_subdirectory(qmlvideo)
-add_subdirectory(performancemonitor)
-add_subdirectory(frequencymonitor)
-
install(TARGETS qmlvideoexample
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
diff --git a/examples/multimedia/video/qmlvideo/main.cpp b/examples/multimedia/video/qmlvideo/main.cpp
index 15df44dd2..94c5bfea0 100644
--- a/examples/multimedia/video/qmlvideo/main.cpp
+++ b/examples/multimedia/video/qmlvideo/main.cpp
@@ -3,6 +3,7 @@
#include "performancemonitor.h"
#include "trace.h"
+#include "qmlvideo/videosingleton.h"
#ifdef PERFORMANCEMONITOR_SUPPORT
# include "performancemonitordeclarative.h"
#endif
@@ -78,16 +79,21 @@ int main(int argc, char *argv[])
url2 = QUrl::fromLocalFile(source2);
}
+ const QStringList moviesLocation = QStandardPaths::standardLocations(QStandardPaths::MoviesLocation);
+ const QUrl videoPath = QUrl::fromLocalFile(moviesLocation.isEmpty() ? app.applicationDirPath()
+ : moviesLocation.front());
+
QQuickView viewer;
+ VideoSingleton* singleton = viewer.engine()->singletonInstance<VideoSingleton*>("qmlvideo", "VideoSingleton");
+ singleton->setVideoPath(videoPath);
+ singleton->setSource1(source1);
+ singleton->setSource2(source2);
+ singleton->setVolume(volume);
viewer.loadFromModule("qmlvideo", "Main");
QObject::connect(viewer.engine(), &QQmlEngine::quit, &viewer, &QQuickView::close);
- QQuickItem *rootObject = viewer.rootObject();
- rootObject->setProperty("source1", url1);
- rootObject->setProperty("source2", url2);
- rootObject->setProperty("volume", volume);
-
#ifdef PERFORMANCEMONITOR_SUPPORT
+ QQuickItem *rootObject = viewer.rootObject();
if (performanceMonitorState.valid) {
rootObject->setProperty("perfMonitorsLogging", performanceMonitorState.logging);
rootObject->setProperty("perfMonitorsVisible", performanceMonitorState.visible);
@@ -95,12 +101,6 @@ int main(int argc, char *argv[])
QObject::connect(&viewer, SIGNAL(afterRendering()), rootObject, SLOT(qmlFramePainted()));
#endif
- const QStringList moviesLocation =
- QStandardPaths::standardLocations(QStandardPaths::MoviesLocation);
- const QUrl videoPath = QUrl::fromLocalFile(moviesLocation.isEmpty() ? app.applicationDirPath()
- : moviesLocation.front());
- viewer.rootContext()->setContextProperty("videoPath", videoPath);
-
QMetaObject::invokeMethod(rootObject, "init");
auto setupView = [&viewer]() {
diff --git a/examples/multimedia/video/qmlvideo/performancemonitor/PerformanceItem.qml b/examples/multimedia/video/qmlvideo/performancemonitor/PerformanceItem.qml
index 12253be62..5b501b104 100644
--- a/examples/multimedia/video/qmlvideo/performancemonitor/PerformanceItem.qml
+++ b/examples/multimedia/video/qmlvideo/performancemonitor/PerformanceItem.qml
@@ -41,8 +41,7 @@ Rectangle {
State {
name: "hidden"
PropertyChanges {
- target: root
- opacity: 0
+ root.opacity: 0
}
}
]
@@ -64,19 +63,19 @@ Rectangle {
function createQmlFrameRateItem() {
let component = Qt.createComponent("frequencymonitor", "FrequencyItem")
if (component.status === Component.Ready)
- d.qmlFrameRateItem = component.createObject(column, { label: "QML frame rate",
- displayed: root.displayed,
+ d.qmlFrameRateItem = component.createObject(column, { label: qsTr("QML frame rate"),
+ displayed: root.displayed,
logging: root.logging
- })
+ });
}
function createVideoFrameRateItem() {
let component = Qt.createComponent("frequencymonitor", "FrequencyItem")
if (component.status === Component.Ready)
- d.videoFrameRateItem = component.createObject(column, { label: "Video frame rate",
- displayed: root.displayed,
+ d.videoFrameRateItem = component.createObject(column, { label: qsTr("Video frame rate"),
+ displayed: root.displayed,
logging: root.logging
- })
+ });
videoFrameRateActiveConnections.target = d.videoFrameRateItem
}
@@ -87,13 +86,11 @@ Rectangle {
}
function videoFramePainted() {
- if (d.videoFrameRateItem)
- d.videoFrameRateItem.notify()
+ d.videoFrameRateItem?.notify()
}
function qmlFramePainted() {
- if (d.qmlFrameRateItem)
- d.qmlFrameRateItem.notify()
+ d.qmlFrameRateItem?.notify()
}
onVideoActiveChanged: {
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo.pro b/examples/multimedia/video/qmlvideo/qmlvideo.pro
index cabdddbe0..b61339264 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo.pro
+++ b/examples/multimedia/video/qmlvideo/qmlvideo.pro
@@ -12,27 +12,29 @@ DEFINES += \
PERFORMANCEMONITOR_SUPPORT
SOURCES += \
- main.cpp \
frequencymonitor.cpp \
frequencymonitordeclarative.cpp \
+ main.cpp \
performancemonitor.cpp \
- performancemonitordeclarative.cpp
+ performancemonitordeclarative.cpp \
+ qmlvideo/videosingleton.cpp
+
+INCLUDEPATH += qmlvideo
+
+DEFINES += QMLVIDEO_LIB
HEADERS += \
- trace.h \
frequencymonitor.h \
performancemonitor.h \
- performancemonitordeclarative.h
+ performancemonitordeclarative.h \
+ trace.h \
+ qmlvideo/videosingleton.h
resources.files = \
- qmlvideo/images/folder.png \
- qmlvideo/images/leaves.jpg \
- qmlvideo/images/up.png \
frequencymonitor/FrequencyItem.qml \
frequencymonitor/qmldir \
performancemonitor/PerformanceItem.qml \
performancemonitor/qmldir \
- qmlvideo/Button.qml \
qmlvideo/CameraBasic.qml \
qmlvideo/CameraDrag.qml \
qmlvideo/CameraDummy.qml \
@@ -46,6 +48,7 @@ resources.files = \
qmlvideo/CameraSpin.qml \
qmlvideo/Content.qml \
qmlvideo/ErrorDialog.qml \
+ qmlvideo/Main.qml \
qmlvideo/Scene.qml \
qmlvideo/SceneBasic.qml \
qmlvideo/SceneDrag.qml \
@@ -74,13 +77,19 @@ resources.files = \
qmlvideo/VideoRotate.qml \
qmlvideo/VideoSeek.qml \
qmlvideo/VideoSpin.qml \
- qmlvideo/Main.qml \
+ qmlvideo/images/folder.png \
+ qmlvideo/images/leaves.jpg \
+ qmlvideo/images/up.png \
qmlvideo/qmldir
resources.prefix = /qt/qml/
RESOURCES += resources
+CONFIG += qmltypes
+QML_IMPORT_NAME = qmlvideo
+QML_IMPORT_MAJOR_VERSION = 1
+
target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/video/qmlvideo
INSTALLS += target
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/Button.qml b/examples/multimedia/video/qmlvideo/qmlvideo/Button.qml
deleted file mode 100644
index 3e33d418a..000000000
--- a/examples/multimedia/video/qmlvideo/qmlvideo/Button.qml
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-import QtQuick
-
-Item {
- id: root
-
- property string text
- property color bgColor: "#757575"
- property color bgColorSelected: "#bdbdbd"
- property color textColor: "white"
- property color textColorSelected: "black"
- property alias enabled: mouseArea.enabled
- property alias radius: bgr.radius
-
- signal clicked
-
- Rectangle {
- id: bgr
- anchors.fill: parent
- color: mouseArea.pressed ? bgColorSelected : bgColor
- radius: height / 15
-
- Text {
- id: text
- anchors.centerIn: parent
- text: root.text
- font.pixelSize: 0.4 * parent.height
- color: mouseArea.pressed ? textColorSelected : textColor
- horizontalAlignment: Text.AlignHCenter
- verticalAlignment: Text.AlignVCenter
- }
-
- MouseArea {
- id: mouseArea
- anchors.fill: parent
- onClicked: {
- root.clicked()
- }
- }
- }
-}
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/CMakeLists.txt b/examples/multimedia/video/qmlvideo/qmlvideo/CMakeLists.txt
index f81a29386..84a65710e 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/CMakeLists.txt
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/CMakeLists.txt
@@ -9,8 +9,11 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/multimedia/video/qmlvideo/qmlvide
qt_add_qml_module(qmlvideo
URI qmlvideo
+ SOURCES
+ videosingleton.cpp
+ videosingleton.h
+ qmlvideo_global.h
QML_FILES
- "Button.qml"
"CameraBasic.qml"
"CameraDrag.qml"
"CameraDummy.qml"
@@ -24,6 +27,7 @@ qt_add_qml_module(qmlvideo
"CameraSpin.qml"
"Content.qml"
"ErrorDialog.qml"
+ "Main.qml"
"Scene.qml"
"SceneBasic.qml"
"SceneDrag.qml"
@@ -52,13 +56,14 @@ qt_add_qml_module(qmlvideo
"VideoRotate.qml"
"VideoSeek.qml"
"VideoSpin.qml"
- "Main.qml"
RESOURCES
"images/folder.png"
"images/leaves.jpg"
"images/up.png"
)
+target_compile_definitions(qmlvideo PRIVATE QMLVIDEO_LIB)
+
target_link_libraries(qmlvideo PRIVATE
Qt6::Core
Qt6::Gui
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/CameraBasic.qml b/examples/multimedia/video/qmlvideo/qmlvideo/CameraBasic.qml
index 4c85f358c..77072c6c9 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/CameraBasic.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/CameraBasic.qml
@@ -1,8 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-import QtQuick
-
SceneBasic {
contentType: "camera"
started: true
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/CameraDrag.qml b/examples/multimedia/video/qmlvideo/qmlvideo/CameraDrag.qml
index a733548dd..2ea3672c6 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/CameraDrag.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/CameraDrag.qml
@@ -1,8 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-import QtQuick
-
SceneDrag {
contentType: "camera"
}
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/CameraDummy.qml b/examples/multimedia/video/qmlvideo/qmlvideo/CameraDummy.qml
index cf59c04f1..c9d14e595 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/CameraDummy.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/CameraDummy.qml
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
+import QtQuick.Controls
// Item which is loaded by CameraItem if Qt Multimedia is not available
Rectangle {
@@ -13,12 +14,11 @@ Rectangle {
signal sizeChanged
signal framePainted
- Text {
+ Label {
anchors.fill: parent
anchors.margins: 10
- color: "white"
horizontalAlignment: Text.AlignHCenter
- text: "Failed to create Camera item\n\nCheck that Qt Multimedia is installed"
+ text: qsTr("Failed to create Camera item\n\nCheck that Qt Multimedia is installed")
verticalAlignment: Text.AlignVCenter
wrapMode: Text.Wrap
}
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/CameraFullScreen.qml b/examples/multimedia/video/qmlvideo/qmlvideo/CameraFullScreen.qml
index 03e3d2661..b204e74ab 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/CameraFullScreen.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/CameraFullScreen.qml
@@ -1,8 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-import QtQuick
-
SceneFullScreen {
contentType: "camera"
}
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/CameraFullScreenInverted.qml b/examples/multimedia/video/qmlvideo/qmlvideo/CameraFullScreenInverted.qml
index dd6874f16..ff7a40253 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/CameraFullScreenInverted.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/CameraFullScreenInverted.qml
@@ -1,8 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-import QtQuick
-
SceneFullScreenInverted {
contentType: "camera"
}
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/CameraMove.qml b/examples/multimedia/video/qmlvideo/qmlvideo/CameraMove.qml
index 1f7db298b..c4c5da914 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/CameraMove.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/CameraMove.qml
@@ -1,8 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-import QtQuick
-
SceneMove {
contentType: "camera"
}
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/CameraOverlay.qml b/examples/multimedia/video/qmlvideo/qmlvideo/CameraOverlay.qml
index 3b152ca5d..13136be00 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/CameraOverlay.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/CameraOverlay.qml
@@ -1,8 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-import QtQuick
-
SceneOverlay {
contentType: "camera"
}
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/CameraResize.qml b/examples/multimedia/video/qmlvideo/qmlvideo/CameraResize.qml
index 327541982..d89eef3ad 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/CameraResize.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/CameraResize.qml
@@ -1,8 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-import QtQuick
-
SceneResize {
contentType: "camera"
}
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/CameraRotate.qml b/examples/multimedia/video/qmlvideo/qmlvideo/CameraRotate.qml
index 86cac7a1b..8394fb6fd 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/CameraRotate.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/CameraRotate.qml
@@ -1,8 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-import QtQuick
-
SceneRotate {
contentType: "camera"
}
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/CameraSpin.qml b/examples/multimedia/video/qmlvideo/qmlvideo/CameraSpin.qml
index 55a51430d..642a0edfd 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/CameraSpin.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/CameraSpin.qml
@@ -1,8 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-import QtQuick
-
SceneSpin {
contentType: "camera"
}
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/Content.qml b/examples/multimedia/video/qmlvideo/qmlvideo/Content.qml
index b808002e1..b08d19325 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/Content.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/Content.qml
@@ -6,7 +6,7 @@ import frequencymonitor
Rectangle {
id: root
- border.color: "white"
+ border.color: palette.window
border.width: showBorder ? 1 : 0
color: "transparent"
property string contentType // "camera" or "video"
@@ -17,6 +17,7 @@ Rectangle {
property bool started: false
property bool showFrameRate: false
property bool showBorder: false
+ property alias contentItem: contentLoader.item
signal initialized
signal error
@@ -29,8 +30,7 @@ Rectangle {
Connections {
id: framePaintedConnection
function onFramePainted() {
- if (frameRateLoader.item)
- frameRateLoader.item.notify()
+ (frameRateLoader.item as FrequencyItem)?.notify()
root.videoFramePainted()
}
ignoreUnknownSignals: true
@@ -40,15 +40,20 @@ Rectangle {
id: errorConnection
function onFatalError() {
console.log("[qmlvideo] Content.onFatalError")
- stop()
+ root.stop()
root.error()
}
ignoreUnknownSignals: true
}
+ Component {
+ id: frequencyItem
+ FrequencyItem {}
+ }
+
Loader {
id: frameRateLoader
- sourceComponent: root.showFrameRate ? FrequencyItem : undefined
+ sourceComponent: root.showFrameRate ? frequencyItem : undefined
onLoaded: {
item.parent = root
item.anchors.top = root.top
@@ -58,13 +63,13 @@ Rectangle {
}
onWidthChanged: {
- if (contentItem())
- contentItem().width = width
+ if (root.contentItem)
+ root.contentItem.width = width
}
onHeightChanged: {
- if (contentItem())
- contentItem().height = height
+ if (root.contentItem)
+ root.contentItem.height = height
}
function initialize() {
@@ -105,6 +110,7 @@ Rectangle {
}
}
+ // qmllint disable
function stop() {
if (contentLoader.item) {
contentLoader.item.stop()
@@ -113,7 +119,7 @@ Rectangle {
root.started = false
}
}
+ // qmllint enable
- function contentItem() { return contentLoader.item }
- function updateRootSize() { root.height = contentItem().height }
+ function updateRootSize() { root.height = (root.contentItem as Item).height }
}
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/ErrorDialog.qml b/examples/multimedia/video/qmlvideo/qmlvideo/ErrorDialog.qml
index ce79b150f..f06079a35 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/ErrorDialog.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/ErrorDialog.qml
@@ -16,8 +16,7 @@ Rectangle {
State {
name: "on"
PropertyChanges {
- target: root
- opacity: 1.0
+ root.opacity: 1.0
}
}
]
@@ -42,8 +41,8 @@ Rectangle {
Rectangle {
anchors.centerIn: parent
- width: dialogWidth
- height: dialogHeight
+ width: root.dialogWidth
+ height: root.dialogHeight
radius: 5
color: "white"
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/Main.qml b/examples/multimedia/video/qmlvideo/qmlvideo/Main.qml
index aabafcb2c..49b94590c 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/Main.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/Main.qml
@@ -2,43 +2,39 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
import QtQuick.Dialogs
import performancemonitor
Rectangle {
id: root
anchors.fill: parent
- color: "black"
+ color: palette.window
- property string source1
- property string source2
- property color bgColor: "black"
- property real volume: 0.25
property bool perfMonitorsLogging: false
property bool perfMonitorsVisible: false
- QtObject {
- id: d
- property int itemHeight: root.height > root.width ? root.width / 10 : root.height / 10
- property int buttonHeight: 0.8 * itemHeight
- property int margins: 5
- }
-
Loader {
id: performanceLoader
Connections {
- target: inner
+ target: columnLayout
function onVisibleChanged() {
if (performanceLoader.item)
- performanceLoader.item.enabled = !inner.visible
+ performanceLoader.item.enabled = !columnLayout.visible
}
ignoreUnknownSignals: true
}
+ Component {
+ id: performanceItem
+ PerformanceItem {}
+ }
+
function init() {
var enabled = root.perfMonitorsLogging || root.perfMonitorsVisible
- sourceComponent = enabled ? PerformanceItem : undefined
+ sourceComponent = enabled ? performanceItem : undefined
}
onLoaded: {
@@ -51,106 +47,58 @@ Rectangle {
}
}
- Rectangle {
- id: inner
+ ColumnLayout {
+ id: columnLayout
anchors.fill: parent
- color: root.bgColor
+ spacing: 5
Button {
id: openFile1Button
- anchors {
- top: parent.top
- left: parent.left
- right: exitButton.left
- margins: d.margins
- }
- bgColor: "#212121"
- bgColorSelected: "#757575"
- textColorSelected: "white"
- height: d.buttonHeight
- text: (root.source1 == "") ? "Select file 1" : root.source1
+ text: (VideoSingleton.source1 == '') ? qsTr("Select file 1") : VideoSingleton.source1
+ Component.onCompleted: console.log("source1: " + VideoSingleton.source1)
onClicked: {
- fileBrowser.setFirstSource = true
- fileBrowser.open()
+ fileDialog.setFirstSource = true
+ fileDialog.open()
}
+
+ Layout.fillWidth: true
}
Button {
id: openFile2Button
- anchors {
- top: openFile1Button.bottom
- left: parent.left
- right: exitButton.left
- margins: d.margins
- }
- bgColor: "#212121"
- bgColorSelected: "#757575"
- textColorSelected: "white"
- height: d.buttonHeight
- text: (root.source2 == "") ? "Select file 2" : root.source2
+ text: (VideoSingleton.source2 == '') ? qsTr("Select file 2") : VideoSingleton.source2
+ Component.onCompleted: console.log("source2: " + VideoSingleton.source2)
onClicked: {
- fileBrowser.setFirstSource = false
- fileBrowser.open()
+ fileDialog.setFirstSource = false
+ fileDialog.open()
}
- }
- Button {
- id: exitButton
- anchors {
- top: parent.top
- right: parent.right
- margins: d.margins
- }
- bgColor: "#212121"
- bgColorSelected: "#757575"
- textColorSelected: "white"
- width: parent.width / 10
- height: d.buttonHeight
- text: "Exit"
- onClicked: Qt.quit()
+ Layout.fillWidth: true
}
- Row {
- id: modes
- anchors.top: openFile2Button.bottom
- anchors.margins: 0
- anchors.topMargin: 5
- Button {
- width: root.width / 2
- height: 0.8 * d.itemHeight
- bgColor: "#212121"
- radius: 0
- text: "Video Modes"
- enabled: false
- }
- Button {
- width: root.width / 2
- height: 0.8 * d.itemHeight
- bgColor: "#212121"
- radius: 0
- text: "Camera Modes"
- enabled: false
+ RowLayout {
+ Layout.fillWidth: true
+
+ Label {
+ text: qsTr("Video Modes")
+
+ horizontalAlignment: Qt.AlignHCenter
+ Layout.preferredWidth: 50
+ Layout.fillWidth: true
}
- }
+ Label {
+ text: qsTr("Camera Modes")
- Rectangle {
- id: divider
- height: 1
- width: parent.width
- color: "black"
- anchors.top: modes.bottom
+ horizontalAlignment: Qt.AlignHCenter
+ Layout.preferredWidth: 50
+ Layout.fillWidth: true
+ }
}
SceneSelectionPanel {
id: sceneSelectionPanel
- itemHeight: d.itemHeight
- color: "#212121"
- anchors {
- top: divider.bottom
- left: parent.left
- right: parent.right
- bottom: parent.bottom
- }
+ itemHeight: Math.min(width / 10, height / 10)
+ color: palette.dark
radius: 0
onSceneSourceChanged: {
sceneLoader.source = sceneSource
@@ -162,16 +110,15 @@ Rectangle {
} else {
scene = sceneLoader.item
if (scene) {
- if (scene.contentType === "video" && source1 === "") {
- errorDialog.show("You must first select a video file")
+ if (scene.contentType === "video" && VideoSingleton.source1 === "") {
+ errorDialog.show(qsTr("You must first select a video file"))
sceneSource = ""
} else {
scene.parent = root
- scene.color = root.bgColor
- scene.buttonHeight = d.buttonHeight
- scene.source1 = source1
- scene.source2 = source2
- scene.volume = volume
+ scene.color = root.palette.window
+ scene.source1 = VideoSingleton.source1
+ scene.source2 = VideoSingleton.source2
+ scene.volume = VideoSingleton.volume
scene.anchors.fill = root
scene.close.connect(closeScene)
scene.content.initialize()
@@ -180,8 +127,11 @@ Rectangle {
}
}
videoFramePaintedConnection.target = scene
- inner.visible = innerVisible
+ columnLayout.visible = innerVisible
}
+
+ Layout.fillWidth: true
+ Layout.fillHeight: true
}
}
@@ -191,42 +141,46 @@ Rectangle {
Connections {
id: videoFramePaintedConnection
+ // qmllint disable
function onVideoFramePainted() {
if (performanceLoader.item)
performanceLoader.item.videoFramePainted()
}
+ // qmllint enable
ignoreUnknownSignals: true
}
FileDialog {
- id: fileBrowser
+ id: fileDialog
property bool setFirstSource
- onAccepted: {
+ onAccepted: function() {
if (setFirstSource)
- root.source1 = currentFile
+ VideoSingleton.source1 = selectedFile
else
- root.source2 = currentFile
+ VideoSingleton.source2 = selectedFile
}
}
ErrorDialog {
id: errorDialog
anchors.fill: root
- dialogWidth: d.itemHeight * 5
- dialogHeight: d.itemHeight * 3
+ dialogWidth: Math.min(root.width, root.height) * 0.5
+ dialogHeight: Math.min(root.width, root.height) * 0.3
enabled: false
}
// Called from main() once root properties have been set
function init() {
performanceLoader.init()
- fileBrowser.currentFolder = videoPath
+ fileDialog.currentFolder = VideoSingleton.videoPath
}
+ // qmllint disable
function qmlFramePainted() {
if (performanceLoader.item)
performanceLoader.item.qmlFramePainted()
}
+ // qmllint enable
function closeScene() {
sceneSelectionPanel.sceneSource = ""
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/Scene.qml b/examples/multimedia/video/qmlvideo/qmlvideo/Scene.qml
index c2903f63d..e16478d41 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/Scene.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/Scene.qml
@@ -2,11 +2,11 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
+import QtQuick.Controls
Rectangle {
id: root
- color: "black"
- property alias buttonHeight: closeButton.height
+ color: palette.window
property string source1
property string source2
property int contentWidth: parent.width / 2
@@ -24,13 +24,8 @@ Rectangle {
right: parent.right
margins: root.margins
}
- width: Math.max(parent.width, parent.height) / 12
- height: Math.min(parent.width, parent.height) / 12
z: 2.0
- bgColor: "#212121"
- bgColorSelected: "#757575"
- textColorSelected: "white"
- text: "Back"
+ text: qsTr("Back")
onClicked: root.close()
}
}
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/SceneBasic.qml b/examples/multimedia/video/qmlvideo/qmlvideo/SceneBasic.qml
index 69b3a9ef4..8ad6c99b8 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/SceneBasic.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/SceneBasic.qml
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
+import QtQuick.Controls
Scene {
id: root
@@ -21,15 +22,14 @@ Scene {
onVideoFramePainted: root.videoFramePainted()
}
- Text {
+ Label {
anchors {
horizontalCenter: parent.horizontalCenter
bottom: parent.bottom
margins: 20
}
- text: content.started ? "Tap the screen to stop content"
- : "Tap the screen to start content"
- color: "#e0e0e0"
+ text: content.started ? qsTr("Tap the screen to stop content")
+ : qsTr("Tap the screen to start content")
z: 2.0
}
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/SceneFullScreen.qml b/examples/multimedia/video/qmlvideo/qmlvideo/SceneFullScreen.qml
index 3e9997f37..ec8564311 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/SceneFullScreen.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/SceneFullScreen.qml
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
+import QtQuick.Controls
Scene {
id: root
@@ -19,8 +20,10 @@ Scene {
states: [
State {
name: "fullScreen"
- PropertyChanges { target: content; width: content.parent.width }
- PropertyChanges { target: content; height: content.parent.height }
+ PropertyChanges {
+ content.width: content.parent.width
+ content.height: content.parent.height
+ }
}
]
@@ -49,14 +52,13 @@ Scene {
onVideoFramePainted: root.videoFramePainted()
}
- Text {
+ Label {
anchors {
horizontalCenter: parent.horizontalCenter
bottom: parent.bottom
margins: 20
}
- text: "Tap on the content to toggle full-screen mode"
- color: "#e0e0e0"
+ text: qsTr("Tap on the content to toggle full-screen mode")
z: 2.0
}
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/SceneFullScreenInverted.qml b/examples/multimedia/video/qmlvideo/qmlvideo/SceneFullScreenInverted.qml
index 837c440f9..cb96ac134 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/SceneFullScreenInverted.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/SceneFullScreenInverted.qml
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
+import QtQuick.Controls
Scene {
id: root
@@ -20,7 +21,7 @@ Scene {
states: [
State {
name: "nonFullScreen"
- PropertyChanges { target: content; width: content.parent.contentWidth }
+ PropertyChanges { content.width: root.contentWidth }
}
]
@@ -43,7 +44,7 @@ Scene {
MouseArea {
anchors.fill: parent
- onClicked: content.state = (content.state == "nonFullScreen") ? "baseState" : "nonFullScreen"
+ onClicked: content.state = (content.state === "nonFullScreen") ? "baseState" : "nonFullScreen"
}
onVideoFramePainted: root.videoFramePainted()
@@ -54,14 +55,13 @@ Scene {
}
}
- Text {
+ Label {
anchors {
horizontalCenter: parent.horizontalCenter
bottom: parent.bottom
margins: 20
}
- text: "Tap on the content to toggle full-screen mode"
- color: "#e0e0e0"
+ text: qsTr("Tap on the content to toggle full-screen mode")
z: 2.0
}
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/SceneMove.qml b/examples/multimedia/video/qmlvideo/qmlvideo/SceneMove.qml
index c8fe939d7..d1512831e 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/SceneMove.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/SceneMove.qml
@@ -19,7 +19,7 @@ Scene {
SequentialAnimation on x {
id: animation
loops: Animation.Infinite
- property int from: margin
+ property int from: root.margin
property int to: 100
property int duration: 1500
running: false
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/SceneMulti.qml b/examples/multimedia/video/qmlvideo/qmlvideo/SceneMulti.qml
index 54571b055..f93dabcdd 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/SceneMulti.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/SceneMulti.qml
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
+import QtQuick.Controls
Scene {
id: root
@@ -24,28 +25,30 @@ Scene {
id: root
color: "transparent"
- function content() {
- return root.parent
- }
+ signal start
+ signal stop
- Text {
+ Label {
anchors {
horizontalCenter: parent.horizontalCenter
bottom: parent.bottom
margins: 20
}
- text: content() ? content().started ? "Tap to stop" : "Tap to start" : ""
- color: "#e0e0e0"
+ // qmllint disable
+ text: root.started ? qsTr("Tap to stop") : qsTr("Tap to start")
+ // qmllint enable
}
MouseArea {
anchors.fill: parent
+ // qmllint disable
onClicked: {
- if (content().started)
- content().stop()
+ if (root.started)
+ root.stop()
else
- content().start()
+ root.start()
}
+ // qmllint enable
}
}
}
@@ -63,14 +66,19 @@ Scene {
showBorder: true
showFrameRate: started
source: parent.source1
- width: itemWidth
+ width: root.itemWidth
volume: parent.volume
Loader {
id: video1StartStopLoader
+
+ property bool started: parent.started
+
onLoaded: {
item.parent = video1
item.anchors.fill = video1
+ item.start.connect(video1.start)
+ item.stop.connect(video1.stop)
}
}
@@ -79,17 +87,19 @@ Scene {
Rectangle {
id: cameraHolder
+
+ property bool started: false
+
anchors {
horizontalCenter: parent.horizontalCenter
top: parent.top
topMargin: root.itemTopMargin
}
border.width: 1
- border.color: "white"
+ border.color: palette.base
color: "transparent"
- width: itemWidth
+ width: root.itemWidth
height: width
- property bool started: false
Loader {
id: cameraLoader
@@ -98,7 +108,7 @@ Scene {
item.anchors.centerIn = cameraHolder
item.contentType = "camera"
item.showFrameRate = true
- item.width = itemWidth
+ item.width = root.itemWidth
item.z = 1.0
cameraErrorConnection.target = item
item.initialize()
@@ -107,17 +117,22 @@ Scene {
Loader {
id: cameraStartStopLoader
+
+ property bool started: parent.started
+
sourceComponent: startStopComponent
onLoaded: {
item.parent = cameraHolder
item.anchors.fill = cameraHolder
item.z = 2.0
+ item.start.connect(cameraHolder.start)
+ item.stop.connect(cameraHolder.stop)
}
}
Connections {
id: cameraErrorConnection
- onError: {
+ function onError() {
console.log("[qmlvideo] SceneMulti.camera.onError")
cameraHolder.stop()
}
@@ -148,14 +163,19 @@ Scene {
showBorder: true
showFrameRate: started
source: parent.source2
- width: itemWidth
+ width: root.itemWidth
volume: parent.volume
Loader {
id: video2StartStopLoader
+
+ property bool started: parent.started
+
onLoaded: {
item.parent = video2
item.anchors.fill = video2
+ item.start.connect(video2.start)
+ item.stop.connect(video2.stop)
}
}
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/SceneOverlay.qml b/examples/multimedia/video/qmlvideo/qmlvideo/SceneOverlay.qml
index 96c7af802..5863d618c 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/SceneOverlay.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/SceneOverlay.qml
@@ -29,7 +29,7 @@ Scene {
SequentialAnimation on x {
id: xAnimation
loops: Animation.Infinite
- property int from: margin
+ property int from: root.margin
property int to: 100
property int duration: 1500
running: false
@@ -50,7 +50,7 @@ Scene {
SequentialAnimation on y {
id: yAnimation
loops: Animation.Infinite
- property int from: margin
+ property int from: root.margin
property int to: 180
property int duration: 1500
running: false
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/SceneRotate.qml b/examples/multimedia/video/qmlvideo/qmlvideo/SceneRotate.qml
index c38d4e1ce..1362522e6 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/SceneRotate.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/SceneRotate.qml
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
+import QtQuick.Controls
Scene {
id: root
@@ -26,10 +27,8 @@ Scene {
bottom: rotateNegativeButton.top
margins: parent.margins
}
- width: Math.max(parent.width, parent.height) / 10
- height: root.buttonHeight
- text: "Rotate +" + delta
- onClicked: content.rotation = content.rotation + delta
+ text: qsTr("Rotate +%1").arg(root.delta)
+ onClicked: content.rotation = content.rotation + root.delta
}
Button {
@@ -39,10 +38,8 @@ Scene {
verticalCenter: parent.verticalCenter
margins: parent.margins
}
- width: Math.max(parent.width, parent.height) / 10
- height: root.buttonHeight
- text: "Rotate -" + delta
- onClicked: content.rotation = content.rotation - delta
+ text: qsTr("Rotate -%1").arg(root.delta)
+ onClicked: content.rotation = content.rotation - root.delta
}
Button {
@@ -52,8 +49,6 @@ Scene {
verticalCenter: parent.verticalCenter
margins: parent.margins
}
- width: Math.max(parent.width, parent.height) / 25
- height: root.buttonHeight
enabled: false
text: content.rotation % 360
}
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/SceneSelectionPanel.qml b/examples/multimedia/video/qmlvideo/qmlvideo/SceneSelectionPanel.qml
index 0bced4372..0301f5452 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/SceneSelectionPanel.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/SceneSelectionPanel.qml
@@ -2,6 +2,9 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
+import QtQuick.Controls
+
+pragma ComponentBehavior: Bound
Rectangle {
id: root
@@ -10,48 +13,51 @@ Rectangle {
ListModel {
id: videolist
- ListElement { name: "Multi"; source: "SceneMulti.qml" }
- ListElement { name: "Video"; source: "VideoBasic.qml" }
- ListElement { name: "Drag"; source: "VideoDrag.qml" }
- ListElement { name: "Fillmode"; source: "VideoFillMode.qml" }
- ListElement { name: "Fullscreen"; source: "VideoFullScreen.qml" }
- ListElement { name: "Fullscreen-inverted"; source: "VideoFullScreenInverted.qml" }
- ListElement { name: "Metadata"; source: "VideoMetadata.qml" }
- ListElement { name: "Move"; source: "VideoMove.qml" }
- ListElement { name: "Overlay"; source: "VideoOverlay.qml" }
- ListElement { name: "Playback Rate"; source: "VideoPlaybackRate.qml" }
- ListElement { name: "Resize"; source: "VideoResize.qml" }
- ListElement { name: "Rotate"; source: "VideoRotate.qml" }
- ListElement { name: "Spin"; source: "VideoSpin.qml" }
- ListElement { name: "Seek"; source: "VideoSeek.qml" }
+ ListElement { name: qsTr("Multi"); source: "SceneMulti.qml" }
+ ListElement { name: qsTr("Video"); source: "VideoBasic.qml" }
+ ListElement { name: qsTr("Drag"); source: "VideoDrag.qml" }
+ ListElement { name: qsTr("Fillmode"); source: "VideoFillMode.qml" }
+ ListElement { name: qsTr("Fullscreen"); source: "VideoFullScreen.qml" }
+ ListElement { name: qsTr("Fullscreen-inverted"); source: "VideoFullScreenInverted.qml" }
+ ListElement { name: qsTr("Metadata"); source: "VideoMetadata.qml" }
+ ListElement { name: qsTr("Move"); source: "VideoMove.qml" }
+ ListElement { name: qsTr("Overlay"); source: "VideoOverlay.qml" }
+ ListElement { name: qsTr("Playback Rate"); source: "VideoPlaybackRate.qml" }
+ ListElement { name: qsTr("Resize"); source: "VideoResize.qml" }
+ ListElement { name: qsTr("Rotate"); source: "VideoRotate.qml" }
+ ListElement { name: qsTr("Spin"); source: "VideoSpin.qml" }
+ ListElement { name: qsTr("Seek"); source: "VideoSeek.qml" }
}
ListModel {
id: cameralist
- ListElement { name: "Camera"; source: "CameraBasic.qml" }
- ListElement { name: "Drag"; source: "CameraDrag.qml" }
- ListElement { name: "Fullscreen"; source: "CameraFullScreen.qml" }
- ListElement { name: "Fullscreen-inverted"; source: "CameraFullScreenInverted.qml" }
- ListElement { name: "Move"; source: "CameraMove.qml" }
- ListElement { name: "Overlay"; source: "CameraOverlay.qml" }
- ListElement { name: "Resize"; source: "CameraResize.qml" }
- ListElement { name: "Rotate"; source: "CameraRotate.qml" }
- ListElement { name: "Spin"; source: "CameraSpin.qml" }
+ ListElement { name: qsTr("Camera"); source: "CameraBasic.qml" }
+ ListElement { name: qsTr("Drag"); source: "CameraDrag.qml" }
+ ListElement { name: qsTr("Fullscreen"); source: "CameraFullScreen.qml" }
+ ListElement { name: qsTr("Fullscreen-inverted"); source: "CameraFullScreenInverted.qml" }
+ ListElement { name: qsTr("Move"); source: "CameraMove.qml" }
+ ListElement { name: qsTr("Overlay"); source: "CameraOverlay.qml" }
+ ListElement { name: qsTr("Resize"); source: "CameraResize.qml" }
+ ListElement { name: qsTr("Rotate"); source: "CameraRotate.qml" }
+ ListElement { name: qsTr("Spin"); source: "CameraSpin.qml" }
}
Component {
id: leftDelegate
Item {
width: root.width / 2
- height: 0.8 * itemHeight
+ height: 0.8 * root.itemHeight
+
+ required property string name
+ required property string source
Button {
anchors.fill: parent
anchors.margins: 5
anchors.rightMargin: 2.5
anchors.bottomMargin: 0
- text: name
- onClicked: root.sceneSource = source
+ text: parent.name
+ onClicked: root.sceneSource = parent.source
}
}
}
@@ -60,22 +66,25 @@ Rectangle {
id: rightDelegate
Item {
width: root.width / 2
- height: 0.8 * itemHeight
+ height: 0.8 * root.itemHeight
+
+ required property string name
+ required property string source
Button {
anchors.fill: parent
anchors.margins: 5
anchors.leftMargin: 2.5
anchors.bottomMargin: 0
- text: name
- onClicked: root.sceneSource = source
+ text: parent.name
+ onClicked: root.sceneSource = parent.source
}
}
}
Flickable {
anchors.fill: parent
- contentHeight: (itemHeight * videolist.count) + 10
+ contentHeight: (root.itemHeight * videolist.count) + 10
clip: true
Row {
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/SeekControl.qml b/examples/multimedia/video/qmlvideo/qmlvideo/SeekControl.qml
index 392f8afb2..646e5e8ef 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/SeekControl.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/SeekControl.qml
@@ -15,7 +15,7 @@ Item {
Rectangle {
id: background
anchors.fill: parent
- color: "white"
+ color: palette.base
opacity: 0.3
radius: parent.height / 15
}
@@ -24,7 +24,7 @@ Item {
id: progressBar
anchors { left: parent.left; top: parent.top; bottom: parent.bottom }
width: seekControl.duration == 0 ? 0 : background.width * seekControl.playPosition / seekControl.duration
- color: "black"
+ color: palette.highlight
opacity: 0.7
}
@@ -33,9 +33,9 @@ Item {
anchors { left: parent.left; top: parent.top; bottom: parent.bottom; leftMargin: 10 }
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
- color: "white"
+ color: palette.windowText
smooth: true
- text: formatTime(playPosition)
+ text: seekControl.formatTime(seekControl.playPosition)
}
Text {
@@ -43,16 +43,16 @@ Item {
anchors { right: parent.right; top: parent.top; bottom: parent.bottom; rightMargin: 10 }
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
- color: "white"
+ color: palette.windowText
smooth: true
- text: formatTime(duration)
+ text: seekControl.formatTime(seekControl.duration)
}
Rectangle {
id: progressHandle
height: parent.height
width: parent.height / 2
- color: "white"
+ color: palette.accent
opacity: 0.5
anchors.verticalCenter: progressBar.verticalCenter
x: seekControl.duration == 0 ? 0 : seekControl.playPosition / seekControl.duration * background.width
@@ -96,8 +96,8 @@ Item {
function formatTime(timeInMs) {
if (!timeInMs || timeInMs <= 0) return "0:00"
- var seconds = timeInMs / 1000;
- var minutes = Math.floor(seconds / 60)
+ let seconds = timeInMs / 1000;
+ let minutes = Math.floor(seconds / 60)
seconds = Math.floor(seconds % 60)
if (seconds < 10) seconds = "0" + seconds;
return minutes + ":" + seconds
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/VideoBasic.qml b/examples/multimedia/video/qmlvideo/qmlvideo/VideoBasic.qml
index 83ef7cb6b..15c25c978 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/VideoBasic.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/VideoBasic.qml
@@ -1,8 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-import QtQuick
-
SceneBasic {
contentType: "video"
}
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/VideoDrag.qml b/examples/multimedia/video/qmlvideo/qmlvideo/VideoDrag.qml
index ab0502e7c..4a5c5d49b 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/VideoDrag.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/VideoDrag.qml
@@ -1,8 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-import QtQuick
-
SceneDrag {
contentType: "video"
}
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/VideoDummy.qml b/examples/multimedia/video/qmlvideo/qmlvideo/VideoDummy.qml
index addc5bc3e..a30b9ebf6 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/VideoDummy.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/VideoDummy.qml
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
+import QtQuick.Controls
// Item which is loaded by VideoItem if Qt Multimedia is not available
Rectangle {
@@ -18,12 +19,11 @@ Rectangle {
signal sizeChanged
signal framePainted
- Text {
+ Label {
anchors.fill: parent
anchors.margins: 10
- color: "white"
horizontalAlignment: Text.AlignHCenter
- text: "Failed to create Video item\n\nCheck that Qt Multimedia is installed"
+ text: qsTr("Failed to create Video item\n\nCheck that Qt Multimedia is installed")
verticalAlignment: Text.AlignVCenter
wrapMode: Text.Wrap
}
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/VideoFillMode.qml b/examples/multimedia/video/qmlvideo/qmlvideo/VideoFillMode.qml
index 86216d17f..af950c735 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/VideoFillMode.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/VideoFillMode.qml
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
+import QtQuick.Controls
import QtMultimedia
Scene {
@@ -24,24 +25,24 @@ Scene {
verticalCenter: parent.verticalCenter
margins: parent.margins
}
- width: Math.max(parent.width, parent.height) / 5
- height: root.buttonHeight
- text: "PreserveAspectFit"
+ text: qsTr("PreserveAspectFit")
+ // qmllint disable
onClicked: {
if (!content.dummy) {
- var video = content.contentItem()
+ let video = content.contentItem
if (video.fillMode === VideoOutput.Stretch) {
video.fillMode = VideoOutput.PreserveAspectFit
- text = "PreserveAspectFit"
+ text = qsTr("PreserveAspectFit")
} else if (video.fillMode === VideoOutput.PreserveAspectFit) {
video.fillMode = VideoOutput.PreserveAspectCrop
- text = "PreserveAspectCrop"
+ text = qsTr("PreserveAspectCrop")
} else {
video.fillMode = VideoOutput.Stretch
- text = "Stretch"
+ text = qsTr("Stretch")
}
}
}
+ // qmllint enable
}
Component.onCompleted: root.content = content
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/VideoFullScreen.qml b/examples/multimedia/video/qmlvideo/qmlvideo/VideoFullScreen.qml
index 1fec029a9..e49faadb6 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/VideoFullScreen.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/VideoFullScreen.qml
@@ -1,8 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-import QtQuick
-
SceneFullScreen {
contentType: "video"
}
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/VideoFullScreenInverted.qml b/examples/multimedia/video/qmlvideo/qmlvideo/VideoFullScreenInverted.qml
index 0ff5037ec..0bf82941e 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/VideoFullScreenInverted.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/VideoFullScreenInverted.qml
@@ -1,8 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-import QtQuick
-
SceneFullScreenInverted {
contentType: "video"
}
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/VideoMetadata.qml b/examples/multimedia/video/qmlvideo/qmlvideo/VideoMetadata.qml
index d9b529607..f83cbffe9 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/VideoMetadata.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/VideoMetadata.qml
@@ -2,14 +2,17 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
+import QtQuick.Controls
import QtMultimedia
+pragma ComponentBehavior: Bound
+
Scene {
id: root
property string contentType: "video"
Content {
- id: content
+ id: videoContent
anchors.centerIn: parent
width: parent.contentWidth
contentType: "video"
@@ -26,61 +29,52 @@ Scene {
id: metadata
Column {
anchors.fill: parent
- property var videoMetaData: content.contentItem().metaData
- Text {
- color: "#e0e0e0"
- text: "Title:" + videoMetaData.value(MediaMetaData.Title)
+ // qmllint disable
+ property var videoMetaData: videoContent.contentItem?.metaData
+ // qmllint enable
+ Label {
+ text: qsTr("Title: %1").arg(parent.videoMetaData?.value(MediaMetaData.Title) ?? qsTr("Unknown"))
}
- Text {
- color: "#e0e0e0"
- text: "Resolution:" + videoMetaData.value(MediaMetaData.Resolution)
+ Label {
+ text: qsTr("Resolution: %1").arg(parent.videoMetaData?.value(MediaMetaData.Resolution) ?? qsTr("Unknown"))
}
- Text {
- color: "#e0e0e0"
- text: "Media type:" + videoMetaData.value(MediaMetaData.MediaType)
+ Label {
+ text: qsTr("Media type: %1").arg(parent.videoMetaData?.value(MediaMetaData.MediaType) ?? qsTr("Unknown"))
}
- Text {
- color: "#e0e0e0"
- text: "Video codec:" + videoMetaData.value(MediaMetaData.VideoCodec)
+ Label {
+ text: qsTr("Video codec: %1").arg(parent.videoMetaData?.value(MediaMetaData.VideoCodec) ?? qsTr("Unknown"))
}
- Text {
- color: "#e0e0e0"
- text: "Video bit rate:" + videoMetaData.value(MediaMetaData.VideoBitRate)
+ Label {
+ text: qsTr("Video bit rate: %1").arg(parent.videoMetaData?.value(MediaMetaData.VideoBitRate) ?? qsTr("Unknown"))
}
- Text {
- color: "#e0e0e0"
- text: "Video frame rate:" +videoMetaData.value(MediaMetaData.VideoFrameRate)
+ Label {
+ text: qsTr("Video frame rate: %1").arg(parent.videoMetaData?.value(MediaMetaData.VideoFrameRate) ?? qsTr("Unknown"))
}
- Text {
- color: "#e0e0e0"
- text: "Audio codec:" + videoMetaData.value(MediaMetaData.AudioCodec)
+ Label {
+ text: qsTr("Audio codec: %1").arg(parent.videoMetaData?.value(MediaMetaData.AudioCodec) ?? qsTr("Unknown"))
}
- Text {
- color: "#e0e0e0"
- text: "Audio bit rate:" + videoMetaData.value(MediaMetaData.AudioBitRate)
+ Label {
+ text: qsTr("Audio bit rate: %1").arg(parent.videoMetaData?.value(MediaMetaData.AudioBitRate) ?? qsTr("Unknown"))
}
- Text {
- color: "#e0e0e0"
- text: "Date:" + videoMetaData.value(MediaMetaData.Date)
+ Label {
+ text: qsTr("Date: %1").arg(parent.videoMetaData?.value(MediaMetaData.Date) ?? qsTr("Unknown"))
}
- Text {
- color: "#e0e0e0"
- text: "Description:" + videoMetaData.value(MediaMetaData.Description)
+ Label {
+ text: qsTr("Description: %1").arg(parent.videoMetaData?.value(MediaMetaData.Description) ?? qsTr("Unknown"))
}
- Text {
- color: "#e0e0e0"
- text: "Copyright:" + videoMetaData.value(MediaMetaData.Copyright)
+ Label {
+ text: qsTr("Copyright: %1").arg(parent.videoMetaData?.value(MediaMetaData.Copyright) ?? qsTr("Unknown"))
}
- Text {
- color: "#e0e0e0"
- text: "Seekable:" + content.contentItem().seekable
+ Label {
+ // qmllint disable
+ text: qsTr("Seekable: %1").arg(videoContent.contentItem?.seekable ?? qsTr("Unknown"))
+ // qmllint enable
}
- Text {
- color: "#e0e0e0"
- text: "Orientation:" + videoMetaData.value(MediaMetaData.Orientation)
+ Label {
+ text: qsTr("Orientation: %1").arg(parent.videoMetaData?.value(MediaMetaData.Orientation) ?? qsTr("Unknown"))
}
}
}
- Component.onCompleted: root.content = content
+ Component.onCompleted: root.content = videoContent
}
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/VideoMove.qml b/examples/multimedia/video/qmlvideo/qmlvideo/VideoMove.qml
index abfa32b25..2b9230f3c 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/VideoMove.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/VideoMove.qml
@@ -1,8 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-import QtQuick
-
SceneMove {
contentType: "video"
}
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/VideoOverlay.qml b/examples/multimedia/video/qmlvideo/qmlvideo/VideoOverlay.qml
index e664c36d6..576b33ff9 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/VideoOverlay.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/VideoOverlay.qml
@@ -1,8 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-import QtQuick
-
SceneOverlay {
contentType: "video"
}
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/VideoPlaybackRate.qml b/examples/multimedia/video/qmlvideo/qmlvideo/VideoPlaybackRate.qml
index 614dcd424..55e38ef19 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/VideoPlaybackRate.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/VideoPlaybackRate.qml
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
+import QtQuick.Controls
Scene {
id: root
@@ -26,12 +27,10 @@ Scene {
bottom: decreaseButton.top
margins: parent.margins
}
- width: Math.max(parent.width, parent.height) / 10
- height: root.buttonHeight
- text: "Increase"
+ text: qsTr("Increase")
onClicked: {
- var video = content.contentItem()
- video.playbackRate += delta
+ let video = (content.contentItem as VideoItem)
+ video.playbackRate += root.delta
}
}
@@ -42,12 +41,10 @@ Scene {
verticalCenter: parent.verticalCenter
margins: parent.margins
}
- width: Math.max(parent.width, parent.height) / 10
- height: root.buttonHeight
- text: "Decrease"
+ text: qsTr("Decrease")
onClicked: {
- var video = content.contentItem()
- video.playbackRate -= delta
+ let video = (content.contentItem as VideoItem)
+ video.playbackRate -= root.delta
}
}
@@ -58,10 +55,10 @@ Scene {
verticalCenter: parent.verticalCenter
margins: parent.margins
}
- width: Math.max(parent.width, parent.height) / 25
- height: root.buttonHeight
enabled: false
- text: Math.round(10 * content.contentItem().playbackRate) / 10
+ // qmllint disable
+ text: Math.round(10 * content.contentItem?.playbackRate ?? 1) / 10
+ // qmllint enable
}
Component.onCompleted: root.content = content
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/VideoResize.qml b/examples/multimedia/video/qmlvideo/qmlvideo/VideoResize.qml
index a530d96b7..88fe7a2d2 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/VideoResize.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/VideoResize.qml
@@ -1,8 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-import QtQuick
-
SceneResize {
contentType: "video"
}
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/VideoRotate.qml b/examples/multimedia/video/qmlvideo/qmlvideo/VideoRotate.qml
index ec74a55ea..d429ec413 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/VideoRotate.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/VideoRotate.qml
@@ -1,8 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-import QtQuick
-
SceneRotate {
contentType: "video"
}
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/VideoSeek.qml b/examples/multimedia/video/qmlvideo/qmlvideo/VideoSeek.qml
index 3c16ddd70..5e2584fb6 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/VideoSeek.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/VideoSeek.qml
@@ -25,9 +25,11 @@ Scene {
margins: 10
bottom: parent.bottom
}
- duration: content.contentItem() ? content.contentItem().duration : 0
- playPosition: content.contentItem() ? content.contentItem().position : 0
- onSeekPositionChanged: content.contentItem().seek(seekPosition);
+ // qmllint disable
+ duration: content.contentItem?.duration ?? 0
+ playPosition: content.contentItem?.position ?? 0
+ onSeekPositionChanged: content.contentItem?.seek(seekPosition);
+ // qmllint enable
}
Component.onCompleted: root.content = content
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/VideoSpin.qml b/examples/multimedia/video/qmlvideo/qmlvideo/VideoSpin.qml
index f6ba42d0e..7c365ddc7 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/VideoSpin.qml
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/VideoSpin.qml
@@ -1,8 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-import QtQuick
-
SceneSpin {
contentType: "video"
}
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/qmldir b/examples/multimedia/video/qmlvideo/qmlvideo/qmldir
index a43cb40ba..1cba13d95 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo/qmldir
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/qmldir
@@ -1,6 +1,5 @@
module qmlvideo
-Button 1.0 Button.qml
CameraBasic 1.0 CameraBasic.qml
CameraDrag 1.0 CameraDrag.qml
CameraDummy 1.0 CameraDummy.qml
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/qmlvideo_global.h b/examples/multimedia/video/qmlvideo/qmlvideo/qmlvideo_global.h
new file mode 100644
index 000000000..8df5b5b64
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/qmlvideo_global.h
@@ -0,0 +1,10 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QtCore/QtGlobal>
+
+#if defined(QMLVIDEO_LIB)
+#define QMLVIDEO_LIB_EXPORT Q_DECL_EXPORT
+#else
+#define QMLVIDEO_LIB_EXPORT Q_DECL_IMPORT
+#endif
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/videosingleton.cpp b/examples/multimedia/video/qmlvideo/qmlvideo/videosingleton.cpp
new file mode 100644
index 000000000..2b02fa505
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/videosingleton.cpp
@@ -0,0 +1,54 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "videosingleton.h"
+
+VideoSingleton::VideoSingleton(QObject * parent) : QObject(parent)
+{ }
+
+QUrl VideoSingleton::source1() const
+{
+ return m_source1;
+}
+void VideoSingleton::setSource1(const QUrl &source1)
+{
+ if (source1 == m_source1)
+ return;
+ m_source1 = source1;
+ emit source1Changed();
+}
+QUrl VideoSingleton::source2() const
+{
+ return m_source2;
+}
+void VideoSingleton::setSource2(const QUrl &source2)
+{
+ if (source2 == m_source2)
+ return;
+ m_source2 = source2;
+ emit source2Changed();
+}
+qreal VideoSingleton::volume() const
+{
+ return m_volume;
+}
+void VideoSingleton::setVolume(qreal volume)
+{
+ if (volume == m_volume)
+ return;
+ m_volume = volume;
+ emit volumeChanged();
+}
+QUrl VideoSingleton::videoPath() const
+{
+ return m_videoPath;
+}
+void VideoSingleton::setVideoPath(const QUrl &videoPath)
+{
+ if (m_videoPath == videoPath)
+ return;
+ m_videoPath = videoPath;
+ emit videoPathChanged();
+}
+
+#include "moc_videosingleton.cpp"
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/videosingleton.h b/examples/multimedia/video/qmlvideo/qmlvideo/videosingleton.h
new file mode 100644
index 000000000..3e0d56247
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qmlvideo/videosingleton.h
@@ -0,0 +1,48 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef QMLVIDEOSINGLETON_H
+#define QMLVIDEOSINGLETON_H
+
+#include "qmlvideo_global.h"
+
+#include <QtQml/qqml.h>
+
+class QMLVIDEO_LIB_EXPORT VideoSingleton : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QUrl source1 READ source1 WRITE setSource1 NOTIFY source1Changed FINAL)
+ Q_PROPERTY(QUrl source2 READ source2 WRITE setSource2 NOTIFY source2Changed FINAL)
+ Q_PROPERTY(QUrl videoPath READ videoPath WRITE setVideoPath NOTIFY videoPathChanged FINAL)
+ Q_PROPERTY(qreal volume READ volume WRITE setVolume NOTIFY volumeChanged FINAL)
+ QML_SINGLETON
+ QML_ELEMENT
+
+public:
+ explicit VideoSingleton(QObject *parent = nullptr);
+
+ QUrl source1() const;
+ void setSource1(const QUrl &source1);
+ QUrl source2() const;
+ void setSource2(const QUrl &source2);
+ QUrl videoPath() const;
+ void setVideoPath(const QUrl &videoPath);
+ qreal volume() const;
+ void setVolume(qreal volume);
+
+Q_SIGNALS:
+ void source1Changed();
+ void source2Changed();
+ void volumeChanged();
+ void videoPathChanged();
+
+private:
+ QUrl m_source1;
+ QUrl m_source2;
+ QUrl m_videoPath;
+ qreal m_volume = 0.5;
+};
+
+QML_DECLARE_TYPE(VideoSingleton);
+
+#endif // QMLVIDEOSINGLETON_H