QMLビデオの例
ビデオやカメラのビューファインダーのコンテンツを変換する。
QML Videoでは、QMLVideoOutput 、Camera タイプに適用できるさまざまな変換(移動、サイズ変更、回転、アスペクト比の変更)を紹介しています。
また、ネイティブコードとQMLを組み合わせることで、より高度な機能を実装できることも示しています。この例では、C++コードを使ってQMLのフレームレートを計算しています。QMLのフレームレートは、映像の上に半透明のアイテムとして表示されます。
次の画像は、アプリケーションがビデオオーバーレイシーンを実行しているところです。ダミーのオーバーレイアイテム(半透明のRectangle )が作成され、VideoOutput アイテムを横切って移動します。
例の実行
Qt Creator からサンプルを実行するには、Welcome モードを開き、Examples からサンプルを選択します。詳細については、Building and Running an Example を参照してください。
アプリケーションの構造
Main.qml
ファイルは、以下の項目を含む UI を作成します:
- 2 つの
Button
インスタンス。各インスタンスはファイル名を表示し、FileDialog
を起動するために使用できます。 - 終了
Button
。 - 利用可能なシーンを表示するフリック可能なリストである
SceneSelectionPanel
。 - 左下にはQMLの再描画レートを表示する項目があり、上の数字は瞬時のフレームレート、下の数字は過去1秒間の平均です。
例えば、video-basicシーン(画面中央に静的な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})
)の両方でインスタンス化することができます。このアプローチは、他の多くのシーンを実装するために使用される。例えば、「コンテンツを左から右へ繰り返しスライドさせる」は、SceneMove
によって実装され、VideoMove
とCameraMove
がベースになっている。
トップレベルのシーンインスタンスのcontentTypeプロパティの値によって、埋め込まれたContent
アイテムは、MediaPlayer またはCamera アイテムを作成します。
QMLペインティング率の計算と表示
FrequencyMonitorクラスは、(notify()スロットを介して受信した)イベントのストリームを、瞬間的な頻度と平均化された頻度に変換します:
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"); }
FrequencyMonitorクラスは次のようにQMLに公開され、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()));
©2024 The Qt Company Ltd. 本書に含まれるドキュメントの著作権は、それぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。