Qt Quick Android Studio プロジェクト用

Qt Quick for Android API のサンプルは、Android Studio プロジェクトとして提供されています。プロジェクトフォルダは Qt のインストール場所にあります。

例えば、デフォルトの Windows インストールパスでは、ここにあります:

C:\Qt\Examples\Qt-/1\platforms\android

概要

この例では、Qt Tools for Android Studioプラグインを使用してAndroid StudioにインポートできるQMLプロジェクトと、QtQuickViewAPIを使用してQMLプロジェクトをViewとして使用するJavaおよびKotlinプロジェクトが含まれています。

QMLの仕組みについては Qt Qml.このドキュメントでは、QMLコンポーネントをJavaやKotlinベースのAndroidアプリケーションに組み込む方法を中心に説明します。

まず、JavaとKotlinプロジェクトのMainActivity'のonCreate()メソッドを見てみましょう。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    m_qmlViewBackgroundText = findViewById(R.id.qmlViewBackgroundText);
    m_qmlStatus = findViewById(R.id.qmlStatusText);
    m_androidControlsLayout = findViewById(R.id.javaRelative);
    m_colorBox = findViewById(R.id.qmlColorBox);
    m_switch = findViewById(R.id.disconnectQmlListenerSwitch);
    m_switch.setOnClickListener(view -> switchListener());
    QtQuickView m_firstQuickView = new QtQuickView(this);
    QtQuickView m_secondQuickView = new QtQuickView(this);

    // Set status change listener for m_qmlView
    // listener implemented below in OnStatusChanged
    m_firstQmlContent.setStatusChangeListener(this);
    m_secondQmlContent.setStatusChangeListener(this);
    final ViewGroup.LayoutParams params = new FrameLayout.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
    FrameLayout m_firstQmlFrameLayout = findViewById(R.id.firstQmlFrame);
    m_firstQmlFrameLayout.addView(m_firstQuickView, params);
    FrameLayout m_secondQmlFrameLayout = findViewById(R.id.secondQmlFrame);
    m_secondQmlFrameLayout.addView(m_secondQuickView, params);
    m_firstQuickView.loadContent(m_firstQmlContent);
    m_secondQuickView.loadContent(m_secondQmlContent);

    Button m_changeColorButton = findViewById(R.id.changeQmlColorButton);
    m_changeColorButton.setOnClickListener(view -> onClickListener());
    Button m_rotateQmlGridButton = findViewById(R.id.rotateQmlGridButton);
    m_rotateQmlGridButton.setOnClickListener(view -> rotateQmlGrid());
}
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    m_binding = ActivityMainBinding.inflate(layoutInflater)
    val view = m_binding.root
    setContentView(view)

    m_binding.disconnectQmlListenerSwitch.setOnCheckedChangeListener { button, checked ->
        switchListener(
            button,
            checked
        )
    }

    val firstQtQuickView = QtQuickView(this)
    val secondQtQuickView = QtQuickView(this)

    // Set status change listener for m_qmlView
    // listener implemented below in OnStatusChanged
    m_firstQmlContent.setStatusChangeListener(this)
    m_secondQmlContent.setStatusChangeListener(this)

    val params: ViewGroup.LayoutParams = FrameLayout.LayoutParams(
        ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT
    )
    m_binding.firstQmlFrame.addView(firstQtQuickView, params)
    m_binding.secondQmlFrame.addView(secondQtQuickView, params)
    firstQtQuickView.loadContent(m_firstQmlContent)
    secondQtQuickView.loadContent(m_secondQmlContent)

    m_binding.changeQmlColorButton.setOnClickListener { onClickListener() }
    m_binding.rotateQmlGridButton.setOnClickListener { rotateQmlGrid() }
}

注: Kotlinプロジェクトでは、アプリケーションのUIコンポーネントにアクセスするためにViewバインディングを使用しています:

m_binding = ActivityMainBinding.inflate(layoutInflater)
val view = m_binding.root
setContentView(view)

onCreate() メソッド内で、以前に宣言された変数は新しいQtQuickViewsで初期化されます。これらのQtQuickViewの新しいインスタンスは、Java/KotlinアクティビティのContextを引数として与えることで作成されます。

QtQuickViewは、Java/アクティビティで使用されます。
QtQuickView m_firstQuickView = new QtQuickView(this);
QtQuickView m_secondQuickView = new QtQuickView(this);
val firstQtQuickView = QtQuickView(this)
val secondQtQuickView = QtQuickView(this)

QtQuickViewは、適切なレイアウトパラメータでAndroidレイアウトに追加されます。

QtQuickView は適切なレイアウトパラメータに追加されます。
final ViewGroup.LayoutParams params = new FrameLayout.LayoutParams(
        ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
FrameLayout m_firstQmlFrameLayout = findViewById(R.id.firstQmlFrame);
m_firstQmlFrameLayout.addView(m_firstQuickView, params);
FrameLayout m_secondQmlFrameLayout = findViewById(R.id.secondQmlFrame);
m_secondQmlFrameLayout.addView(m_secondQuickView, params);
val params: ViewGroup.LayoutParams = FrameLayout.LayoutParams(
    ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT
)
m_binding.firstQmlFrame.addView(firstQtQuickView, params)
m_binding.secondQmlFrame.addView(secondQtQuickView, params)

MainSecond Java クラスはQtQuickViewContent クラスを継承しています。これらのクラスは、インポートしたQMLプロジェクトから生成されます。

tコンテンツは、QMLプロジェクトを通じて読み込まれます。
private final Main m_firstQmlContent = new Main();
private final Second m_secondQmlContent = new Second();
private val m_firstQmlContent: Main = Main()
private val m_secondQmlContent: Second = Second()

QtQuickViewContent を引数にとるQtQuickView.loadContent() メソッドによって、Qt Quick コンテンツがロードされる。

QMLコンポーネントとのインタラクション。
m_firstQuickView.loadContent(m_firstQmlContent);
m_secondQuickView.loadContent(m_secondQmlContent);
firstQtQuickView.loadContent(m_firstQmlContent)
secondQtQuickView.loadContent(m_secondQmlContent)

QMLコンポーネントとの対話

埋め込まれた QML コンポーネントと対話するために、QtQmlStatusChangeListener インターフェースを実装し、onStatusChanged メソッドをオーバーライドして、QtQuickViews に現在ロードされている QtQuickViewContent のロードステータスを取得します。

tの実装です。
public class MainActivity extends AppCompatActivity implements
QtQmlStatusChangeListener {
    ...
}
class MainActivity : AppCompatActivity(), QtQmlStatusChangeListener {
    ...
}

onStatusChanged の実装:

tに設定されている。
@Override
public void onStatusChanged(QtQmlStatus qtQmlStatus, QtQuickViewContent content) {
    Log.i(TAG, "Status of QtQuickView: " + qtQmlStatus);

    // Show current QML View status in a textview
    m_qmlStatus.setText(getString(R.string.qml_view_status, m_statusNames.get(qtQmlStatus)));
    updateColorDisplay();

    if (content == m_firstQmlContent) {
        // Connect signal listener to "onClicked" signal from main.qml
        // addSignalListener returns int which can be used later to identify the listener
        if (qtQmlStatus == QtQmlStatus.READY && m_switch.isChecked()) {
            m_qmlButtonSignalListenerId = m_firstQmlContent.connectOnClickedListener(
                    (String name, Void v) -> {
                        Log.i(TAG, "QML button clicked");
                        m_androidControlsLayout.setBackgroundColor(Color.parseColor(
                                m_colors.getColor()
                        ));
                    });
        }
    }
}
override fun onStatusChanged(status: QtQmlStatus?, content: QtQuickViewContent?) {
    Log.v(TAG, "Status of QtQuickView: $status")

    // Show current QML View status in a textview
    m_binding.qmlStatusText.text = getString(R.string.qml_view_status, m_statusNames[status])

    updateColorDisplay()

    if (content == m_firstQmlContent) {
        // Connect signal listener to "onClicked" signal from main.qml
        // addSignalListener returns int which can be used later to identify the listener
        if (status == QtQmlStatus.READY && m_binding.disconnectQmlListenerSwitch.isChecked) {
            m_qmlButtonSignalListenerId =
                m_firstQmlContent.connectOnClickedListener { _: String, _: Void? ->
                    Log.i(TAG, "QML button clicked")
                    m_binding.kotlinRelative.setBackgroundColor(
                        Color.parseColor(
                            m_colors.getColor()
                        )
                    )
                }
        }
    }
}

MainActivitym_mainQmlContentm_secondQmlContentstatusChangeListener としてQtQuickViewContent.setStatusChangeListener メソッドで設定される。

オーバーライドされたコールバック関数。
m_firstQmlContent.setStatusChangeListener(this);
m_secondQmlContent.setStatusChangeListener(this);
m_firstQmlContent.setStatusChangeListener(this)
m_secondQmlContent.setStatusChangeListener(this)

オーバーライドされたコールバック関数onStatusChanged() は、現在のQtQuickViewContentQtQuickView へのロードのステータス(public Enum QtQmlStatus)を含むStatusChanged() シグナルを受け取ります。このQtQmlStatusQtQmlStatus.READY であることが確認されれば、QML ビューとのインタラクションを開始することができます。

QMLコンポーネントのプロパティ値の取得と設定

QMLコンポーネントのプロパティ値の取得と設定は、Main.java クラスに記述されているメソッドを通して行います。ここでは、m_mainQmlContent.setColorStringProperty()m_mainQmlContent.getColorStringProperty() のメソッドを使用します。これらのメソッドは、QMLコンポーネントがどのようなプロパティを含むかに応じて生成されます。

t、QMLコンポーネントのプロパティを設定します。
public void onClickListener() {
    // Set the QML view root object property "colorStringFormat" value to
    // color from Colors.getColor()
    m_firstQmlContent.setColorStringFormat(m_colors.getColor());
    updateColorDisplay();
}
private void updateColorDisplay() {
    String qmlBackgroundColor = m_firstQmlContent.getColorStringFormat();
    // Display the QML View background color code
    m_qmlViewBackgroundText.setText(qmlBackgroundColor);

    // Display the QML View background color in a view
    // if qmlBackGroundColor is not null
    if (qmlBackgroundColor != null) {
        m_colorBox.setBackgroundColor(Color.parseColor(qmlBackgroundColor));
    }
}
private fun onClickListener() {
    // Set the QML view root object property "colorStringFormat" value to
    // color from Colors.getColor()
    m_firstQmlContent.colorStringFormat = m_colors.getColor()
    updateColorDisplay()
}

private fun updateColorDisplay() {
    val qmlBackgroundColor = m_firstQmlContent.colorStringFormat
    // Display the QML View background color code
    m_binding.qmlViewBackgroundText.text = qmlBackgroundColor
    // Display the QML View background color in a view
    // if qmlBackgroundColor is not null
    if (qmlBackgroundColor != null) {
        m_binding.qmlColorBox.setBackgroundColor(Color.parseColor(qmlBackgroundColor))
    }
}

m_mainQmlContent.setColorStringProperty() メソッドでは、m_mainQmlContentcolorStringFormat プロパティ値に、Colors.java (またはColors.kt )クラスから取得したランダムな色の値を設定します。

m_mainQmlContent.getColorStringProperty() メソッドは、m_mainQmlContent のルート・オブジェクトの現在の背景色を取得し、Java/Kotlin Android アプリケーション側でユーザーに表示するために使用します。

m_secondQmlContent Grid QMLコンポーネントがあり、生成された メソッドを使ってJava側から回転させることができます。m_secondQmlContent.setGridRotation()

private void rotateQmlGrid() {
    Integer previousGridRotation = m_secondQmlContent.getGridRotation();
    if (previousGridRotation != null) {
        m_secondQmlContent.setGridRotation(previousGridRotation + 45);
    }
}
private fun rotateQmlGrid() {
    val previousGridRotation = m_secondQmlContent.gridRotation
    if (previousGridRotation != null) {
        m_secondQmlContent.gridRotation = previousGridRotation + 45
    }
}

シグナルリスナー

QtQuickViewContent クラスはconnectSignalListener()disconnectSignalListener() メソッドを提供し、QML コンポーネントのルート オブジェクトで宣言されたシグナル間のシグナルリスナーの接続と切断を行います。QtQuickViewContent.connectSignalListener() は一意なシグナルリスナーIDを返し、これを保存しておき、後でリスナーの識別や切断に使用します。

ここでは、シグナルリスナーをQMLコンポーネントのonClicked() シグナルに接続しています。

合 #tab-kotlin:checked ~ .tab-kotlin{display: block;} シグナルは、QMLコンポーネントの シグナルに毎回発信されます。
if (qtQmlStatus == QtQmlStatus.READY && m_switch.isChecked()) {
    m_qmlButtonSignalListenerId = m_firstQmlContent.connectOnClickedListener(
            (String name, Void v) -> {
                Log.i(TAG, "QML button clicked");
                m_androidControlsLayout.setBackgroundColor(Color.parseColor(
                        m_colors.getColor()
                ));
            });
}
if (status == QtQmlStatus.READY && m_binding.disconnectQmlListenerSwitch.isChecked) {
    m_qmlButtonSignalListenerId =
        m_firstQmlContent.connectOnClickedListener { _: String, _: Void? ->
            Log.i(TAG, "QML button clicked")
            m_binding.kotlinRelative.setBackgroundColor(
                Color.parseColor(
                    m_colors.getColor()
                )
            )
        }
}

onClicked() シグナルは、QML コンポーネントのボタンがクリックされるたびに発せられます。このシグナルをリスナーが受信すると、Android側のレイアウトの背景色がColors.java クラスから取得したランダムな色に設定されます。

次に、QtQuickViewContent.disconnectSignalListener() メソッドを使用して、シグナル・リスナーに固有のシグナル・リスナーIDを与えて、シグナル・リスナーを切断します。

m_firstQmlContent.disconnectSignalListener(m_qmlButtonSignalListenerId);
m_firstQmlContent.disconnectSignalListener(m_qmlButtonSignalListenerId)

© 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.