- 1. Java
- 2. Qt QML
- 1. QMLButtons.pro
- 2. main.cpp
- 3. main.qml
Після того, як ми познайомилися з Hello World зі світу Java і Qt QML під Android, пропоную написати програму, яка матиме дві кнопки і натисканням на ці кнопки буде змінювати текст у невеликому текстовому полі. Програми мають виглядати однаково, але не на 100 відсотків ідентично. За бажання цього можна досягти, але в цьому прикладі не обов'язково.
В обох випадках використовуватиметься Material Design .
Перш ніж подивитися на програмний код, подивимося на зовнішній вигляд обох програм.
Додаток, написаний на Java
А тепер програма, яка написана на Qt QML
Ви можете бачити, що результат вийшов однаковим, і водночас ви можете бачити деякі візуальні відмінності. Якщо чесно, то варіант Material Design, який використовується в Qt QML, мені більше подобається, ніж той, що використовується в Java за замовчуванням.
А тепер перейдемо до вивчення програмного коду наших двох програм.
Java
Я відключив ToolBar, оскільки інформація щодо нього була дана ще в прикладі з Hello World, а в даному випадку для порівняння коду нам він уже не знадобиться.
activity_main.xml
Файл верстки нашої головної діяльності. Для того, щоб помістити обидві кнопки в нижню частину екрана, знадобилося використовувати Layout в горизонтальній орієнтації, що в QML вам це не знадобиться для подібного виду кнопки в цьому прикладі. Оскільки в QML використовуються якорі , які подібні за принципом з роботою властивостей layout_constraint , але на мій погляд дещо гнучкіші.
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.evileg.javabuttons.MainActivity"> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="32dp" android:text="Press Button" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:layout_marginEnd="8dp" android:layout_marginStart="8dp" android:orientation="horizontal" android:gravity="center_horizontal" android:weightSum="2" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent"> <Button android:id="@+id/OkButton" android:layout_width="0dp" android:layout_height="wrap_content" android:text="Ok" android:layout_weight="1"/> <Button android:id="@+id/Cancelbutton" android:layout_width="0dp" android:layout_height="wrap_content" android:text="Cancel" android:layout_weight="1"/> </LinearLayout> </android.support.constraint.ConstraintLayout>
MainActivity.java
А тепер перейдемо до написання коду обробки натискань кнопок Java. По суті, все зводиться до того, що нам необхідно знайти id кнопок і текстового поля, навішувати на них слухачі кліків по кнопках і додати функціонал установки тексту в дане текстове поле.
package com.evileg.javabuttons; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.Window; import android.widget.Button; import android.widget.TextView; public class MainActivity extends Activity { TextView textView1; Button okButton; Button cancelButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); // Найдём View элементы textView1 = findViewById(R.id.textView1); okButton = findViewById(R.id.OkButton); cancelButton = findViewById(R.id.Cancelbutton); // Создадим обработчик нажатия кнопок OK View.OnClickListener onClickListenerOkBtn = new View.OnClickListener() { @Override public void onClick(View v) { textView1.setText("OK Button is pressed"); } }; // Создадим обработчик нажатия кнопок Cancel View.OnClickListener onClickListenerCancelBtn = new View.OnClickListener() { @Override public void onClick(View v) { textView1.setText("Cancel Button is pressed"); } }; // Установим обработчики кликов на кнопки okButton.setOnClickListener(onClickListenerOkBtn); cancelButton.setOnClickListener(onClickListenerCancelBtn); } }
Qt QML
У проекті Qt QML я модифікую три файли... але не лякайтеся так, модифікації не будуть такими глобальними, як написання повноцінних класів і шаблону верстки, як це було в додатку на Java.
QMLButtons.pro
По-перше включимо підтримку модуля quickcontrols2 у проектному файлі, що дозволить включити стиль Material Design.
QT += quick quickcontrols2
main.cpp
По-друге включимо сам Material Design. Для цього потрібно додати всього два рядки до функції main.
Перша
#include <QQuickStyle>
Друга
QQuickStyle::setStyle("Material");
Вийде наступний код
#include <QGuiApplication> #include <QQmlApplicationEngine> #include <QQuickStyle> int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); QQuickStyle::setStyle("Material"); QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); if (engine.rootObjects().isEmpty()) return -1; return app.exec(); }
Обов'язково включайте підтримку Material Design до ініціалізації QQmlApplicationEngine, - це C++ і тут важлива послідовність виклику методів і функцій.
main.qml
А тепер подивимося на те, як отримати таку ж верстку програми, як і в Java і при цьому відразу ж зробити обробку натискань на кнопки, яке до речі написано в даному випадку в один рядок.
import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Controls 2.3 import QtQuick.Controls.Material 2.1 ApplicationWindow { visible: true width: 360 height: 520 title: qsTr("QML Buttons") Text { id: text_1 text: qsTr("Press Button") anchors { top: parent.top topMargin: 32 horizontalCenter: parent.horizontalCenter } } Button { anchors { left: parent.left bottom: parent.bottom right: parent.horizontalCenter margins: 8 } text: qsTr("Ok") // Обработка нажатия кнопки onClicked: text_1.text = qsTr("OK Button is Pressed") } Button { anchors { right: parent.right bottom: parent.bottom left: parent.horizontalCenter margins: 8 } text: qsTr("Cancel") // Обработка нажатия кнопки onClicked: text_1.text = qsTr("Cancel Button is Pressed") } }
Вже помітили, що код у цьому випадку чистіший? Та й його значно менше. Звичайно, ми дістанемося і до таких місць, де виграватиме Java, але саме в цьому прикладі поки що трохи простіше виглядає код на QML.
Здравствуйте Евгений!Просматривая уроки от разных авторов,заметил,что многие не используют QT дизайнер.Создают всё на Qml.Или мне показалось,что так лучше для разработки.Сам попробовал пользоваться дизайнером при разработке под Android-не всегда корректно отображается картинка на устройстве.
Добрый день, Слава!
На тот момент, когда лично я занялся QML, там всё было довольно криво реализовано в дизайнере, а многие вещи вовсе отсутствовали. Поэтому мне проще было сделать вёрстку вручную на QML. Тем более, что qml.ui файлы добавляют "дополнительный код", который скрывает некоторую функциональность и приходится дописывать alias и сигналы в самом ui файле, которые при дальнейшем открытии qml.ui в дизайнере могут быть удалены или переписаны. Это добавляет некоторое неудобство. Поэтому я предпочитаю писать код вручную, тем более, что он не добавляет так много вёрсточного кода обычно, как я если бы тоже самое реализовывалось на классических виджетах. С того времени, конечно, много воды утекло, и что-то возможно стало гораздо лучше, но времени разбираться в этом просто нет.
Спасибо Евгений! Я посмотрел ваши уроки по Java-Qml.Хотел найти ответ на вопрос-ориентация экрана телефона.В java если я не ошибаюсь это прописывается в манифесте
(import android.content.pm.ActivityInfo;
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);или portrait
А как и где это прописывается в Qml? Или у вас есть урок,тогда посмотрю?
Добрый день.
Также в манифест пишите. Вот статья про манифест для Android
На сайте часть статей по QML находятся в разделе QML, часть в разделе Android.
Я QMLем балуюсь по большей части, так что 50/50 смогу ответить на некоторые вопросы, но можете задавать вопросы на форуме . Кроме меня там уже много опытных программистов, которые могу подсобить, если обратят внимание на вопрос.
Спасибо большое!