© EVILEG 2015-2018
Рекомендует хостинг
TIMEWEB

Android. Java vs Qt QML - Урок 002. Обработка нажатий по кнопкам

Qt, Android, JAVA, button, 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

Файл вёрстки нашей главной activity. Для того, чтобы поместить обе кнопки в нижнюю часть экрана, понадобилось использовать 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.

Комментарии

Комментарии

Только авторизованные пользователи могут оставлять комментарии.
Пожалуйста, Авторизуйтесь или Зарегистрируйтесь
24 сентября 2018 г. 17:42
edorofeeva

C++ - Тест 001. Первая программа и типы данных

  • Результат 100баллов,
  • Очки рейтинга10
24 сентября 2018 г. 17:37
edorofeeva

C++ - Тест 001. Первая программа и типы данных

  • Результат 66баллов,
  • Очки рейтинга-1
23 сентября 2018 г. 14:38
No Names

C++ - Тест 001. Первая программа и типы данных

  • Результат 60баллов,
  • Очки рейтинга-1
Последние комментарии
24 сентября 2018 г. 15:09
Евгений Легоцкой

Qt Linux - Урок 001. Автозапуск Qt приложения под Linux

А вот здесь у меня есть пример использования supervisor. https://evileg.com/ru/post/3/ Вся статья вам там не интересна, интересен только шаг с настройкой supervisor. Он получается ...
24 сентября 2018 г. 15:00
avovana

Qt Linux - Урок 001. Автозапуск Qt приложения под Linux

Не могли бы дать ссылку на пример? Какое-то рабочее использование. Т.е. у меня есть Qt Gui App, которое я бы хотел запускать при старте системы и в случае, если оно грохнется. Если о чем Вы го...
24 сентября 2018 г. 14:55
Евгений Легоцкой

Qt Linux - Урок 001. Автозапуск Qt приложения под Linux

Если честно, то я не уверен, что это вообще можно реализовать через *.desktop файл. Я сделал предположение на основе того, что вы сказали про *.desktop и рестарт. Все варианты, котор...
24 сентября 2018 г. 14:47
avovana

Qt Linux - Урок 001. Автозапуск Qt приложения под Linux

Просто сейчас правлю сам файл example.desktop. Пытаюсь понять какую пару key=value мне нужно дописать.
24 сентября 2018 г. 14:42
Евгений Легоцкой

Qt Linux - Урок 001. Автозапуск Qt приложения под Linux

Ну я имел ввиду, что дописать в коде вот сюда то, о чём вы говорили про рестарт QString autorunContent("[Desktop Entry]\n" "Type=Application\n" ...
Сейчас обсуждают на форуме
24 сентября 2018 г. 16:47
Евгений_Канусовский@1981

Чтение файлов в python

Добрый вечер Евгений и форумчане! Столкнулся с проблемой чтения файлов в python: файлы с обычным текстом в формате las и txt читаются, например: ~Version information VERS.          ...
24 сентября 2018 г. 13:29
Евгений Легоцкой

Трансляция видео с помощью VLC по RTP

Добрый день! Я не сталкивался, но предположу, что нужно настроить Input Codec в VLC. В настройках есть секция Input Codec, возможно, что там установлено низкое разрешение. ...
21 сентября 2018 г. 8:25
Евгений Легоцкой

Прокси-модель, содержащая на 1 столбец больше, чем модель-источник.

Попробуйте ещё PySide 2 - это официально поддерживаемый пакет привязок Python к Qt, возможно, что там не будет таких проблем.
20 сентября 2018 г. 20:06
Евгений Легоцкой

Qt Installer Framework

Добрый день. Зачем собирать Qt Installer Framework-то из исходников? Я ещё понимаю Qt собирают из исходников статически (хотя тоже считаю по большей части бесполезной тратой времени),...
Присоединяйтесь к нам в социальных сетях