Qt Quick 안드로이드 스튜디오 프로젝트용
Qt Quick 용 안드로이드 API 예제는 안드로이드 스튜디오 프로젝트로 제공됩니다. 프로젝트 폴더는 Qt 설치 위치에서 찾을 수 있습니다.
예를 들어 기본 Windows 설치 경로 아래에는 여기에 있습니다:
C:\Qt\Examples\Qt-/1\platforms\android
개요
이 예제에는 안드로이드 스튜디오용 Qt 도구 플러그인을 사용하여 안드로이드 스튜디오로 임포트할 수 있는 QML 프로젝트와 QtQuickView API를 활용하여 QML 프로젝트를 뷰로 사용하는 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 구성 요소에 액세스하기 위해 보기 바인딩을 사용합니다:
m_binding = ActivityMainBinding.inflate(layoutInflater) val view = m_binding.root setContentView(view)
onCreate()
메서드 내에서 이전에 선언된 변수는 새로운 QtQuickView로 초기화됩니다. 이러한 새 QtQuickView 인스턴스는 Java/Kotlin 액티비티의 컨텍스트를 인수로 제공하여 생성됩니다.
QtQuickView m_firstQuickView = new QtQuickView(this); QtQuickView m_secondQuickView = new QtQuickView(this);
val firstQtQuickView = QtQuickView(this) val secondQtQuickView = QtQuickView(this)
적절한 레이아웃 매개 변수를 사용하여 QtQuickView를 Android 레이아웃에 추가합니다.
Kotlinfinal 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)
Main
및 Second
Java 클래스는 QtQuickViewContent
클래스를 상속합니다. 이러한 클래스는 임포트한 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()
Qt Quick 콘텐츠는 QtQuickView.loadContent()
메서드를 통해 로드되며, 이 메서드는 QtQuickViewContent
을 인수로 받습니다.
m_firstQuickView.loadContent(m_firstQmlContent); m_secondQuickView.loadContent(m_secondQmlContent);
firstQtQuickView.loadContent(m_firstQmlContent) secondQtQuickView.loadContent(m_secondQmlContent)
QML 구성 요소와 상호 작용하기
임베디드 QML 컴포넌트와 상호 작용하기 위해 QtQmlStatusChangeListener
인터페이스를 구현하고 onStatusChanged 메서드를 재정의하여 현재 QtQuickView에 로드 중인 QtQuickViewContent의 로드 상태를 가져옵니다.
public class MainActivity extends AppCompatActivity implements QtQmlStatusChangeListener { ... }
class MainActivity : AppCompatActivity(), QtQmlStatusChangeListener { ... }
onStatusChanged
구현:
@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() ) ) } } } }
MainActivity
은 m_mainQmlContent
및 m_secondQmlContent
의 statusChangeListener
으로 설정하고 QtQuickViewContent.setStatusChangeListener
메서드를 사용합니다.
m_firstQmlContent.setStatusChangeListener(this); m_secondQmlContent.setStatusChangeListener(this);
m_firstQmlContent.setStatusChangeListener(this) m_secondQmlContent.setStatusChangeListener(this)
재정의된 콜백 함수 onStatusChanged()
는 현재 QtQuickViewContent
로딩의 현재 상태(공용 Enum QtQmlStatus)가 포함된 StatusChanged()
신호를 QtQuickView로 수신합니다. 이 QtQmlStatus
이 QtQmlStatus.READY
으로 확인되면 QML 뷰와 상호작용을 시작할 수 있습니다.
QML 컴포넌트 속성 값 가져오기 및 설정하기
QML 컴포넌트 속성 값을 가져오고 설정하는 것은 Main.java
클래스에 설명된 메서드를 통해 이루어집니다. 이 경우 m_mainQmlContent.setColorStringProperty()
및 m_mainQmlContent.getColorStringProperty()
메서드를 사용합니다. 이러한 메서드는 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_mainQmlContent
의 colorStringFormat
속성 값을 Colors.java
(또는 Colors.kt
) 클래스에서 가져온 임의의 색상 값으로 설정합니다.
여기서 m_mainQmlContent.getColorStringProperty()
메서드는 m_mainQmlContent의 루트 객체의 현재 배경색을 가져온 다음 애플리케이션의 Java/Kotlin Android 쪽에서 사용자에게 표시하는 데 사용됩니다.
m_secondQmlContent
에는 생성된 m_secondQmlContent.setGridRotation()
메서드를 사용하여 Java 측에서 회전할 수 있는 Grid QML 컴포넌트가 있습니다.
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
클래스는 QML 컴포넌트 루트 객체에 선언된 신호 간에 신호 수신기를 연결하고 연결을 끊는 데 사용되는 connectSignalListener()
및 disconnectSignalListener()
메서드를 제공합니다. QtQuickViewContent.connectSignalListener()
메서드는 고유한 신호 수신기 ID를 반환하며, 나중에 수신기를 식별하고 연결을 끊을 때 저장하고 사용합니다.
여기서는 신호 리스너를 QML 컴포넌트의 onClicked()
신호에 연결합니다.
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() ) ) } }
QML 컴포넌트의 버튼을 클릭할 때마다 onClicked()
신호가 전송됩니다. 그러면 이 리스너가 이 신호를 수신하고 애플리케이션의 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.