Evgenii Legotckoi
Evgenii Legotckoi13 жовтня 2015 р. 11:37

QML - Урок 003. Власне діалогове вікно в QML Android

Після того, як ми зробили кастомізовані кнопки в попередньому уроці , настав час зробити Custom Dialog , який буде виглядати більш нативно для Android пристрої, а може навіть скидатися по дизайну на IOS пристрій. У будь-якому випадку Ви зможете більш ґрунтовно підійди до реалізації гайдів цих пристроїв.

Для створення діалогу використовуватиметься об'єкт Dialog із бібліотеки QtQuick.Dialog . А нюанс при роботі з Custom Dialog під Android полягає в тому, що Стандартні Кнопки, які адекватно виглядають при розробці під Desktop, під Android виглядають вирвоочно, та й ще їх проблематично кастомізувати для розробника-початківця. Простіше реалізувати власні кнопки зі своєю стилізацією.

Розробка Custom Dialog

Розробку кастомізованого діалогу продовжимо з урахуванням проекту з попереднього уроку. Там у нас були створені дві Custom Button, які ми трохи підправимо по колірній гамі, щоб вони лаконічно виглядали по відношенню до Діалогу. А також, використовуючи прийом по їх стилізації, стилізуємо кнопки діалогового вікна, в якому будуть дві кнопки: "OK" і "Cancel". Ці кнопки будуть закривати діалог.

Кнопки діалогового вікна потрібно буде прибити до нижньої частини діалогу, а решту віддамо під повідомлення "Hello, World!!!", а також розділимо кнопки сірою лінією один з одним, і такою ж лінією відокремимо ці кнопки від повідомлення. Буде схоже трохи на IOS діалог. В якості лінії виступатиме прямокутник Rectangle, такий же прийом застосовується і при розробці під Android на Java , тільки замість QML використовується XML верстка.

Щоб зробити нормальний кастомізований вміст діалогового вікна, необхідно задати його параметру contentItem той об'єкт, який замінить вміст. Найбільш зручним об'єктом є Rectangle , а вже в ньому розміщуватимемо всі інші об'єкти. Природно, ніяких стандартних кнопок там вже і не буде, так що можете про них забути, але це не велика втрата насправді.


main.qml

Вся робота буде виконуватися лише у файлі main.qml, тому наводжу лише його. Решту інформації можете переглянути в попередній статті .

import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.1

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World") // Ну как же без Приветствия Миру
    color: "white"

    MainForm {
        // Растягиваем объект главного окна по всему родительскому элементу
        anchors.fill: parent

        // Стилизуем первую кнопку
        button1.style: ButtonStyle {
            // Стилизуем внешний вид кнопки
            background: Rectangle {
                /* Если кнопка нажата, то она будет красного цвета
                 * с черным ободком со скруглёнными краями,
                 * в противном случае она будет черного цвета с красным ободком
                 */
                color: control.pressed ? "#d7d7d7" : "#f7f7f7"
                border.color: "#d7d7d7"
                border.width: 2
                radius: 5
            }

            // Стилизуем цвет текста кнопки
            label: Text {
                /* Если кнопка нажата, то цвет будет черным
                 * в противном случае красным
                 */
                text: qsTr("Press Me 1")
                color: "black"
            }
        }

        // Стилизуем вторую кнопку
        button2.style: ButtonStyle {
            // Стилизуем внешний вид кнопки
            background: Rectangle {
                /* аналогично, что и для первой кнопки,
                 * но в противоположном порядке
                 */
                color: control.pressed ? "#d7d7d7" : "#f7f7f7"
                border.color: "#d7d7d7"
                border.width: 2
                radius: 5
            }
            // Стилизуем цвет кнопки
            label: Text {
                /* аналогично, что и для первой кнопки,
                 * но в противоположном порядке
                 */
                text: qsTr("Press Me 2")
                color: "black"
            }
        }

        // Запускаем диалог по нажатию любой из кнопок в главном окне
        button1.onClicked: dialogAndroid.open();
        button2.onClicked: dialogAndroid.open();

        // Создаём объект диалогового окна
        Dialog {
            id: dialogAndroid
            /* Когда деплоите под Android-устройства,
             * обязательно закоментируйте эти две строки,
             * иначе словите глюки в работе устройства
             */
            width: 600  // Задаём ширину диалога, работает на десктопе, но на Android не сработает
            height: 500 // Задаём высоту диалога, работает на декстопе, но на Android не сработает

            // Создаём содержимое диалогового окна
            contentItem: Rectangle {
                width: 600          // Устанавливаем ширину, необходимо для Android-устройства
                height: 500         // Устанавливаем высоту, необходимо для Android-устройства
                color: "#f7f7f7"    // Задаём цвет

                // Область для сообщения диалогового окна
                Rectangle {
                    /* Прибиваем область к левой, правой и верхней частям диалога,
                     * а также снизу к разделителю, который отделяет область от кнопок
                     */
                    anchors.left: parent.left
                    anchors.right: parent.right
                    anchors.top: parent.top
                    anchors.bottom: dividerHorizontal.top
                    color: "#f7f7f7"  // Задаём цвет области

                    // Задаём сообщение диалогового окна
                    Label {
                        id: textLabel
                        text: qsTr("Hello, World!!!")
                        color: "#34aadc"
                        anchors.centerIn: parent // Помещаем сообщение в центре области для сообщения
                    }
                }

                // Создаём горизонтальный разделитель с помощью Rectangle
                Rectangle {
                    id: dividerHorizontal
                    color: "#d7d7d7"
                    height: 2 // Устанавливаем ширину в два пикселя
                    anchors.left: parent.left
                    anchors.right: parent.right
                    anchors.bottom: row.top
                }

                /* Создаём подложку для кнопок в виде объекта Строки
                 * В данном объекте для объектов детей не работают некоторые параметры
                 * anchors, кроме параметров anchors.top и anchors.bottom
                 */
                Row {
                    id: row
                    height: 100 // Задаём высоту
                    // А также прибиваем строку к низу диалогового окна
                    anchors.bottom: parent.bottom
                    anchors.left: parent.left
                    anchors.right: parent.right

                    Button {
                        id: dialogButtonCancel
                        // Растягиваем кнопку по высоте строки
                        anchors.top: parent.top
                        anchors.bottom: parent.bottom
                        // Задаём ширину кнопки на половину строки минус 1 пиксель
                        width: parent.width / 2 - 1

                        // Стилизуем кнопку
                        style: ButtonStyle {
                            background: Rectangle {
                                color: control.pressed ? "#d7d7d7" : "#f7f7f7"
                                border.width: 0
                            }

                            label: Text {
                                text: qsTr("Cancel")
                                color: "#34aadc"
                                // Устанавливаем текст в центр кнопки
                                verticalAlignment: Text.AlignVCenter
                                horizontalAlignment: Text.AlignHCenter
                            }
                        }
                        // По нажатию кнопки закрываем диалог
                        onClicked: dialogAndroid.close()
                    }

                    // Создаём разделитель между кнопками шириной в 2 пикселя
                    Rectangle {
                        id: dividerVertical
                        width: 2
                        // Растягиваем разделитель по высоте объекта строки
                        anchors.top: parent.top
                        anchors.bottom: parent.bottom
                        color: "#d7d7d7" // Задаём цвет разделителя
                    }

                    Button {
                        id: dialogButtonOk
                        // Растягиваем кнопку по высоте строки
                        anchors.top: parent.top
                        anchors.bottom: parent.bottom
                        // Задаём ширину кнопки на половину строки минус 1 пиксель
                        width: parent.width / 2 - 1

                        // Стилизуем кнопку
                        style: ButtonStyle {
                            background: Rectangle {
                                color: control.pressed ? "#d7d7d7" : "#f7f7f7"
                                border.width: 0
                            }

                            label: Text {
                                text: qsTr("Ok")
                                color: "#34aadc"
                                // Устанавливаем текст в центр кнопки
                                verticalAlignment: Text.AlignVCenter
                                horizontalAlignment: Text.AlignHCenter
                            }
                        }
                        // По нажатию кнопки закрываем диалог
                        onClicked: dialogAndroid.close()
                    }
                }
            }
        }
    }
}

Підсумок

В результаті у Вас вийде Custom Dialog , який вже буде виглядати на Вашому Android пристрої. Звичайно, під декстопом він виглядатиме жахливо, принаймні в цьому уроці, але це вже питання правильного масштабування та налаштувань розмірів елементів, які є питанням окремої статті.

А ось результат роботи діалогу на моєму смартфоні та десктопі Ви можете побачити на скріншотах та у відеоуроці.

QML Custom Dialog Desktop

QML Custom Dialog Android

QML Custom Dialog Android, натиснута кнопка OK

Відеоурок

Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Стабільний хостинг, на якому розміщується соціальна мережа EVILEG. Для проектів на Django радимо VDS хостинг.

Вам це подобається? Поділіться в соціальних мережах!

M
  • 04 жовтня 2017 р. 05:17

Немного не понял
Заполнение Row происходит слава направо?
Сначала устанавливаем ButtonCancel потом Вертикальный разделитель и следом ButtonOk

Evgenii Legotckoi
  • 04 жовтня 2017 р. 06:42

Ну да. Вас смущает последовательность? Можете и наоборот заполнить.
Это из разряда какой вариант юзабилити может быть удобнее. Начитался всяких гайдлайнов от Google да Apple, вот так и написал. А так дело вашего вкуса.

Коментарі

Only authorized users can post comments.
Please, Log in or Sign up
d
  • dsfs
  • 26 квітня 2024 р. 14:56

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:80бали,
  • Рейтинг балів4
d
  • dsfs
  • 26 квітня 2024 р. 14:45

C++ - Тест 002. Константы

  • Результат:50бали,
  • Рейтинг балів-4
d
  • dsfs
  • 26 квітня 2024 р. 14:35

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

  • Результат:73бали,
  • Рейтинг балів1
Останні коментарі
k
kmssr09 лютого 2024 р. 05:43
Qt Linux - Урок 001. Автозапуск програми Qt під Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
АК
Анатолий Кононенко05 лютого 2024 р. 12:50
Qt WinAPI - Урок 007. Робота з ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
EVA
EVA25 грудня 2023 р. 21:30
Boost - статичне зв&#39;язування в проекті CMake під Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
J
JonnyJo25 грудня 2023 р. 19:38
Boost - статичне зв&#39;язування в проекті CMake під Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
G
Gvozdik19 грудня 2023 р. 08:01
Qt/C++ - Урок 056. Підключення бібліотеки Boost в Qt для компіляторів MinGW і MSVC Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
Тепер обговоріть на форумі
Evgenii Legotckoi
Evgenii Legotckoi03 травня 2024 р. 00:07
Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Добрый день. По моему мнению - да, но то, что будет касаться вызовов к функционалу Андроида, может создать огромные трудности.
IscanderChe
IscanderChe30 квітня 2024 р. 14:22
Во Flask рендер шаблона не передаётся в браузер Доброе утро! Имеется вот такой шаблон: <!doctype html><html> <head> <title>{{ title }}</title> <link rel="stylesheet" href="{{ url_…
G
Gar22 квітня 2024 р. 15:46
Clipboard Как скопировать окно целиком в clipb?
Павел Дорофеев
Павел Дорофеев14 квітня 2024 р. 12:35
QTableWidget с 2 заголовками Вот тут есть кастомный QTableView с многорядностью проект поддерживается, обращайтесь
f
fastrex04 квітня 2024 р. 14:47
Вернуть старое поведение QComboBox, не менять индекс при resetModel Добрый день! У нас много проектов в которых используется QComboBox, в версии 5.5.1, когда модель испускает сигнал resetModel, currentIndex не менялся. В версии 5.15 при resetModel происходит try…

Слідкуйте за нами в соціальних мережах