Evgenii Legotckoi
Evgenii Legotckoi24 декабря 2015 г. 10:27

QML - Урок 021. Переключение между окнами в QML

В одной из статей довелось ответить на вопрос читателя, как реализовать переключение между окнами в Qt , так, чтобы при переключении неактивное окно скрывалось. По нажатию специальной кнопки открываем второе окно, а первое закрываем. И переключаемся обратно аналогичным образом.

А теперь задали тот же вопрос, но уже применительно для QML. Итак, посмотрим, как это реализовать на QML.

Структура проекта

  • question4.pro - профайл проекта, создаётся по умолчанию и не изменяется;
  • main.cpp - основной файл исходных кодов, создаётся по умолчанию и не изменяется;
  • main.qml - основной файл qml с главным окном приложения;
  • AnotherWindow.qml - тип второстепенных окон проекта.

AnotherWindow.qml

Пояснение кода начну с второстепенного окна приложения, поскольку передача информации о нажатии кнопки для открытия основного окна приложения реализуется с помощью сигнала. И удобнее будет описать этот момент в начале, прежде чем приступить к основному коду приложения.


Синтаксис сигнала выглядит следующим образом:

signal closeThisWindow

То есть объявляется сам signal и далее идёт его название. Обработчик же этого сигнала будет определяться в коде следующим образом:

onCloseThisWindow: {
    // Какой-то код
}

А вызывается сигнал как функция, что и показано в ниже следующем программном коде второстепенного окна приложения.

import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Window 2.2

Window {
    id: anotherWindow
    signal signalExit   // Задаём сигнал
    width:480
    height:320

    // Кнопка для открытия главного окна приложения
    Button {
        text: qsTr("Главное окно")
        width: 180
        height: 50
        anchors.centerIn: parent
        onClicked: {
            anotherWindow.signalExit() // Вызываем сигнал
        }
    }
}

main.qml

А в данном файле реализована вся остальная логика приложения. В главном окне присутствуют две кнопки. В обработчике каждой кнопки открывается соответствующее второстепенное окно и скрывается основное окно. Тогда как в обработчике нажатия кнопки каждого второстепенного окна происходит закрытие данного окно и открытие основного окна приложения.

import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1

ApplicationWindow {
    id: mainWindow
    visible: true
    width: 640
    height: 480
    title: qsTr("Переключение между окнами в QML")

    Rectangle {
        anchors.fill: parent
        color: "white"

        GridLayout {
            id: grid
            anchors.fill: parent

            rows: 2
            columns: 1

            Rectangle {
                Layout.fillHeight: true
                Layout.fillWidth: true
                Layout.column: 1
                Layout.row: 1

                // Кнопка для открытия первого второстепенного окна приложения
                Button {
                    text: qsTr("Первое окно")
                    anchors.centerIn: parent
                    width: 300
                    height: 50

                    onClicked: {
                        firstWindow.show()  // Открываем первое окно
                        mainWindow.hide()   // Скрываем основное окно
                    }
                }
            }

            Rectangle {
                Layout.fillHeight: true
                Layout.fillWidth: true
                Layout.column: 1
                Layout.row: 2

                // Кнопка для открытия второго второстепенного окна приложения
                Button {
                    text: qsTr("Второе окно")
                    anchors.centerIn: parent
                    width: 300
                    height: 50

                    onClicked: {
                        secondWindow.show() // Открываем второе окно
                        mainWindow.hide()   // Скрываем основное окно
                    }
                }
            }
        }
    }

    AnotherWindow {
        id: firstWindow
        title: qsTr("Первое окно")

        // Обработчик сигнала на открытие основного окна
        onSignalExit: {
            firstWindow.close()     // Закрываем первое окно
            mainWindow.show()       // Показываем основное окно
        }
    }

    AnotherWindow {
        id: secondWindow
        title: qsTr("Второе окно")

        // Обработчик сигнала на открытие основного окна
        onSignalExit: {
            secondWindow.close()    // Закрываем второе окно
            mainWindow.show()       // Показываем основное окно
        }
    }
}

Итог

В результате будет реализовано переключение между окнами приложения уже на QML, и при этом у Вас будет открыто всегда только одно окно приложения. Демонстрацию работы приложения Вы можете увидеть в видеоуроке.

Видеоурок

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

Вам это нравится? Поделитесь в социальных сетях!

Alex
  • 23 ноября 2017 г. 15:17

Спасибо за урок. Очень понравился. Подскажите если знаете сейчас везде системы управления автомобилей (выбор песни, навигатор, климат контроль (BMW, MERCEDES, etc))  делают с помощью Qt + Qml, там так же примерно сделан переход между окнами ?

Evgenii Legotckoi
  • 24 ноября 2017 г. 4:13

Нет. Там приложения работает в однооконном режиме, скорее всего в качестве базы используются объекты типа Rectangle, которые кастомизированы до состояния диалоговых окон. Также могут использоваться всякие StackView, SwipeView, Loader и т.д.


Хотя... Если там стоит полноценная Ubuntu с приложением в полноэкранном режиме, то вполне возможно наличие диалогов и окон, как в этой статье. Я могу только предполагать, как это работает, но у меня такие мысли на этот счёт.
a
  • 12 января 2018 г. 2:45

Добрый день! Подскажите пожалуйста. В учебных целях занимаюсь реализацией игры в шахматы, пока пишу игру для двух пользователей. Использую CPP + QML. Хочу сделать несколько окон. Главное окно с кнопками Игра и Просмотреть историю.

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    Logic logic;
    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("logic", &logic);
    engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));

    return app.exec();
}
В классе Logic у меня прописана логика фигур и обработка ходов. Отрисовка доски с фигурами реализована на QML. При нажатии кн. Игра хочу открывать окно с  QQmlApplicationEngine (так как реализовано у меня сейчас в однооконном режиме) и при закрытии окна с игрой возвращаться в главное окно. Вопрос в следующем: можно реализовать это с помощью QML или лучше создавать окна как описано https://evileg.com/post/112/ ?
Evgenii Legotckoi
  • 12 января 2018 г. 3:03

Добрый день!
Это всё можно реализовать средствами QML, однако я немного недопонимаю вашего вопроса в следующем отношении.
Вы хотите сделать это сохранив одноконный режим? (Что в рамках игры вполне логично, поскольку в большинстве случаев они делаются однооконными), или хотите повторить то, что сделано в этой статье?
В этой статье также используется только один QQmlApplicationEngine даже для двух окон, если ещё раз посмотрите статью, то можете обратить внимание на то, что там вызов окон осуществляется из файла main.qml.
Если хотите однооконный режим, то Вам может помочь Loader

Alex
  • 12 января 2018 г. 3:13
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    Logic logic;
    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("logic", &logic);
    engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));

    return app.exec();
}

Добрый день, этот код не ваш, я видел этот код так как тоже его делал. Это задание для прохождения на собеседование в одну из крупных украинских IT компаний. Для переключения между окнами используйте Loader QML Type . И на будущее если используете чужой код, изменяйте его, так как не честно использовать чужое, или хотя бы указывайте что код не мой. Будут вопросы пишите.
a
  • 12 января 2018 г. 4:13

Все верно, я и не говорил что этот кусок кода лично мое произведение. Это тоже верно:

Это задание для прохождения на собеседование в одну из крупных украинских IT компаний.
Логику написал и уперся в окна. Я же не прошу написать за меня, хочу разобраться сам, спашиваю совета. Если кого обидел - прошу прощения. Спасибо огромное за совет.
Alex
  • 12 января 2018 г. 4:16

Ничего сложного, делаете по тех заданию 3 файла qml, называете их как указанно в тех задании, потом из первого окна через Loader их переключаете, в окне 2 и 3 делаете сигналы которые при закрытии формы вызывают первое окно, подключаете потом к ним логику. Готово.

a
  • 16 января 2018 г. 7:40

Спасибо всем. Все получилось. Прикручиваю логику.

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
AD

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

  • Результат:50баллов,
  • Очки рейтинга-4
m
  • molni99
  • 26 октября 2024 г. 1:37

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

  • Результат:80баллов,
  • Очки рейтинга4
m
  • molni99
  • 26 октября 2024 г. 1:29

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

  • Результат:20баллов,
  • Очки рейтинга-10
Последние комментарии
ИМ
Игорь Максимов22 ноября 2024 г. 11:51
Django - Урок 017. Кастомизированная страница авторизации на Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
Evgenii Legotckoi
Evgenii Legotckoi31 октября 2024 г. 14:37
Django - Урок 064. Как написать расширение для Python Markdown Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
A
ALO1ZE19 октября 2024 г. 8:19
Читалка fb3-файлов на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Игорь Максимов5 октября 2024 г. 7:51
Django - Урок 064. Как написать расширение для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas55 июля 2024 г. 11:02
QML - Урок 016. База данных SQLite и работа с ней в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
Сейчас обсуждают на форуме
m
moogo22 ноября 2024 г. 7:17
Mosquito Spray System Effective Mosquito Systems for Backyard | Eco-Friendly Misting Control Device & Repellent Spray - Moogo ; Upgrade your backyard with our mosquito-repellent device! Our misters conce…
Evgenii Legotckoi
Evgenii Legotckoi24 июня 2024 г. 15:11
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
t
tonypeachey115 ноября 2024 г. 6:04
google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
NSProject
NSProject4 июня 2022 г. 3:49
Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…

Следите за нами в социальных сетях