QML 비디오 예제
비디오 및 카메라 뷰파인더 콘텐츠 변환하기.
QML 비디오는 QML VideoOutput 및 Camera 유형에 적용할 수 있는 다양한 변환(이동, 크기 조정, 회전, 화면 비율 변경)을 보여줍니다.
또한 네이티브 코드를 QML과 결합하여 고급 기능을 구현하는 방법(이 예에서는 C++ 코드를 사용하여 QML 프레임 속도를 계산하는 방법)도 보여줍니다. 이 값은 비디오 콘텐츠에 오버레이된 반투명 항목으로 QML에서 렌더링됩니다.
다음 이미지는 더미 오버레이 항목(반투명 Rectangle)을 생성하는 비디오 오버레이 장면을 실행하는 애플리케이션을 보여 주며, VideoOutput 항목을 가로질러 이동합니다.
예제 실행하기
에서 예제를 실행하려면 Qt Creator에서 Welcome 모드를 열고 Examples 에서 예제를 선택합니다. 자세한 내용은 예제 빌드 및 실행하기를 참조하세요.
애플리케이션 구조
Main.qml
파일은 다음 항목을 포함하는 UI를 만듭니다:
- 파일 이름을 표시하는 두 개의
Button
인스턴스, 각각을 사용하여FileDialog
을 시작하는 데 사용할 수 있습니다. - 출구
Button
. - 사용 가능한 장면을 표시하는 플릭 가능한 목록인
SceneSelectionPanel
. - 왼쪽 아래에는 QML 리페인팅 속도를 표시하는 항목이 있는데, 위쪽 숫자는 순간 프레임 속도이고 아래쪽 숫자는 지난 1초 동안의 평균입니다.
플릭 가능한 목록의 각 장면은 자체 QML 파일로 구현됩니다. 예를 들어 화면 중앙에 정적 VideoOutput 을 표시하는 비디오 기본 장면은 VideoBasic.qml
파일로 구현됩니다. 코드에서 볼 수 있듯이 이것은 일종의 상속을 사용합니다. VideoBasic
항목 ...
SceneBasic { contentType: "video" }
...는 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 }
... 그 자체는 Scene
:
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
는 장면의 구조와 동작을 설명하지만 표시될 콘텐츠 유형에 대해서는 무관하며, 이는 Content
에 의해 추상화됩니다.
이 패턴을 사용하면 특정 사용 사례(이 경우 단순히 정적 콘텐츠 표시)를 정의한 다음 비디오 콘텐츠(VideoBasic
)와 카메라 콘텐츠( ({CameraBasic})
) 모두에 대해 해당 사용 사례를 인스턴스화할 수 있습니다. 이 접근 방식은 다른 많은 장면을 구현하는 데 사용됩니다. 예를 들어 "콘텐츠를 왼쪽에서 오른쪽으로 반복적으로 밀었다가 다시 뒤로 밀기" 는 VideoMove
및 CameraMove
의 기반이 되는 SceneMove
에서 구현됩니다.
최상위 장면 인스턴스의 contentType 속성 값에 따라 임베드된 Content
항목은 MediaPlayer 또는 Camera 항목을 만듭니다.
QML 페인팅 비율 계산 및 표시
QML 페인팅 속도는 notify() 슬롯을 통해 수신된 이벤트 스트림을 순간 및 평균 주파수로 변환하는 FrequencyMonitor 클래스에 의해 계산됩니다:
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(); };
FrequencyMonitor 클래스는 다음과 같이 QML에 노출됩니다.
void FrequencyMonitor::qmlRegisterType() { ::qmlRegisterType<FrequencyMonitor>("FrequencyMonitor", 1, 0, "FrequencyMonitor"); }
다음과 같이 FrequencyItem이라는 QML 항목을 정의하여 데이터를 표시합니다:
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 } }
결과는 다음과 같습니다:
이제 남은 것은 QQuickView 객체의 afterRendering() 신호를 JavaScript 함수에 연결하여 frequencyItem.notify()
을 호출하는 것뿐입니다:
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.