Работа со страницами

Подробнее рассмотрим функции в ApplicationWindow и возможности Page

PageStack

Для добавления и извлечения страниц ApplicationWindow имеет объект pageStack. pageStack предоставляет ряд функций:

# параметр page принимает url || object



push(page, properties) # заносит страницу в стек, если это первая страница, то становиться initialPage

pop(page) # извлекает последнюю / текущую страницу

replace(page) # заменяет текущую страницу на page

get(idx) # возвращает объект страницы по индексу

flickBack() # извлекает все страницы кроме первой и встает на нее

goTo(page) # принимает объект страницы, если страница есть в стеке, то переходит к ней, если нет то "пушит" ее

ApplicationWindow

Для удобства в ApplicationWindow были добавлены аналогичные функции:

property alias pageStack # объект со стеком страниц, закрывает логику для splitForm

property alias initialPage # стартовая страница приложения, нужно устанавливать всегда

property alias currentPage # текущая страница на стеке страниц (последняя добавленная)

property alias pagePool # хранилище загруженных страниц, если необходимо держать страницу в памяти

property Drawer globalDrawer # глобальный Drawer, по умолчанию отсутствует

property bool wideScreen # если ширина экрана больше высоты

property bool landscapeMode # если устройство в горизонтальном режиме, используется для логики на страницах

readonly property bool tabletScreen # определяет экран планшета/десктоп

property bool tabletFormSupported: false # говорит о том, что дизайн приложения учитывает splitForm. выставить в true если хотите использовать splitForm

property bool splitForm: tabletScreen && tabletFormSupported # сообщает, что форма перешла в режим для планшета

property bool interactive: false # поддержка жеста swipe
pushPage(page, properties)

switchToPage(page, depth) # depth - до какой страницы нужно извлечь

popPage() # извлекает текущую страницу (кроме первой)

flickBackPage() # извлекает все страницы до первой

getPage(url, properties) # загружает объект страницы по url,

если дать тот же url, то отдаст уже загруженный page (используется PagePool)


goToPage(page) # принимает объект страницы или URL, если страница есть в стеке, то переходит к ней, если нет то "пушит" ее

PagePool

Он предоставляет возможность загружать и хранить объекты QML. Это используется в функциях getPage() и goToPage().

свойства:

lastLoadedPage

lastLoadedUrl



функции:

loadPage(url, properties) # загружает страницу, если загружена, вернет ее

contains(page) # page - string || object

getPage(url) # если объект не загружен, то вернет null

deletePage(page)

clear()

Примеры

Загрузка стартовой страницы

import QtQuick 2.15

import QtQuick.Controls 2.15



import RosaTheme 1.0 as Rosa

import RosaControls 1.0



ApplicationWindow {

width: Rosa.Theme.scale(360)

height: Rosa.Theme.scale(640)

initialPage: "qrc:/qml/InitPage.qml"

}

InitPage.qml — пушим следующие страницы

import QtQuick.Controls 2.15

import QtQuick.Layouts 1.15



import RosaTheme 1.0 as Rosa

import RosaControls 1.0



Page {

id: root

title: "Init Page"



header: PageHeader {

title: root.title



Action {

text: "Go to Simple Page"

onTriggered: {

applicationWindow().pushPage("qrc:/qml/SimplePage.qml", {title: "First Simple Page"})

}

}

}

}

Применение goToPage

Здесь применяется навигация с тремя страницами. Все страницы загружаются через poolPage — это функция getPage(). Также данная функция используется внутри goToPage(). goToPage() ищет страницу в pageStack и, если находит, выполняет pop(page), а если нет — push(page). Таким образом осуществляется навигация по страницам.

Есть возможность отключить анимацию переходов: pageStack.animationOff: true.

import QtQuick 2.15

import QtQuick.Controls 2.15

import QtQuick.Layouts 1.15



import RosaTheme 1.0 as Rosa

import RosaControls 1.0



ApplicationWindow {

width: Rosa.Theme.scale(360)

height: Rosa.Theme.scale(640)

color: Rosa.Theme.lightShadesBlueGrayColor

pageStack.animationOff: true



// init start page

initialPage: getPage("qrc:/qml/InitPage.qml", {title: "Media"}) // важно применить getPage(), это используется для goToPage()



footer: TabBar { // является общим для всех страниц, видимость можно контролировать с Page.showTabBar

visible: currentPage.showTabBar



Action {

text: i18n("Main")

icon.source: Rosa.Theme.icon("24/wallpapers" + (checked ? "-filled" : "-dark"))

checkable: true

checked: true

onTriggered: goToPage(initialPage)

}



Action {

text: "Secondary"

icon.source: Rosa.Theme.icon("24/albums" + (checked ? "-filled" : "-dark"))

checkable: true

onTriggered: goToPage("qrc:/qml/SecondaryPage.qml")

}



Action {

text: "Third"

icon.source: Rosa.Theme.icon("24/heart" + (checked ? "-filled" : "-dark"))

checkable: true

onTriggered: goToPage("qrc:/qml/ThirdPage.qml")

}

}

}

TabBar

Панель навигации имеет встроенные кнопки IconLabelButton. Также она поддерживает landscapeMode.

bool landscapeMode: applicationWindow().landscapeMode # поддержка горизонтального режима

color color: "transparent" # цвет фона

bool showBorder: true # отображать ли линию сверху

bool borderBottom: false # отображает линию внизу

alias delegate: __repeater.delegate # позволяет задать свой делегат для отображения

spacing: Rosa.Theme.scale(4) # расстояние между кнопками



signal buttonClicked(var button) # сигнал нажатия на кнопку

Пример

TabBar {

width: parent.width

landscapeMode: applicationWindow().landscapeMode


Action {

text: i18n("Tab 1")

icon.source: Rosa.Theme.icon('24/week' + (checked ? '' : '-dark'))

checkable: true

onTriggered: {

//Do something

}

}



Action {

text: i18n("Tab 2")

icon.source: Rosa.Theme.icon('24/week' + (checked ? '' : '-dark'))

checkable: true

onTriggered: {

//Do something

}

}



Action {

text: i18n("Tab 3")

icon.source: Rosa.Theme.icon('24/week' + (checked ? '' : '-dark'))

checkable: true

onTriggered: {

//Do something

}

}

}
TabBar Light
TabBar Dark

Пример с собственным delegate

TabBar {

width: parent.width

landscapeMode: applicationWindow().landscapeMode


delegate: Button {

Layout.fillWidth: true # делегаты TabBar располагаются в Layout

Layout.alignment: Qt.AlignCenter

action: modelData # передает из внутренней модели ваш Action

# если необходима поддержка landscapeMode в вашем компоненте, нужно добавлять ее самостоятельно

}



Action {

text: i18n("Tab 1")

icon.source: Rosa.Theme.icon('24/week')

onTriggered: {

//Do something

}

}



Action {

text: i18n("Tab 2")

icon.source: Rosa.Theme.icon('24/week')

onTriggered: {

//Do something

}

}



Action {

text: i18n("Tab 3")

icon.source: Rosa.Theme.icon('24/week')

onTriggered: {

//Do something

}

}

}
TabBar Light
TabBar Dark

Page

Основным компонентом для построения приложения является страница, состоящая из заголовка (title), верхней панели (header), нижней панели (footer) и контента в центре.

PageHeader

Заголовок страницы имеет ряд свойств, позволяющих кастомизировать его.

bool showBackButton: false # отображает кнопку "назад"

bool dark # делает панель как в темной теме

string title # текст заголовка

actions # список установленных Action

color foregroundColor # цвет текста

color backgroundColor # цвет фона

centerItemDelegate # компонент текста заголовка (title - располагается в центре панели)

overlayItemDelegate # собственный компонент, накладывается на всю панель, перекрывая все компоненты

contextMenu # позволяет добавить ContextMenu, выпадающий список, кнопка в правой части панели

bool landscapeMode: applicationWindow().landscapeMode # горизонтальный режим

bool showCancelButton: false # отображает кнопку "Отменить" в левой части заголовка

bool executePop: true # если TRUE, то при нажатии кнопки "назад" страница будет извлечена из стека

bool interactive: true # если FALSE, то компонент не будет реагировать на клики



signal backPressed() # вызывает при нажатии кнопки "назад" (стрелка влево)

signal cancelPressed() # вызывается при нажатии на "Отменить"

В ContextMenu можно добавлять как Action, так и ContextMenuItem. ContextMenuItem можно скрыть, установив свойство visible.

import QtQuick 2.15

import QtQuick.Controls 2.15



import RosaTheme 1.0 as Rosa

import RosaControls 1.0



Page {

id: root

title: "Init Page"



header: PageHeader {

title: root.title



Action {

text: "Go to Simple Page"

onTriggered: {

applicationWindow().pushPage("qrc:/qml/SimplePage.qml", {title: "First Simple Page"})

}

}



Action {

icon.source: Rosa.Theme.icon(_header.dark ? '24/trash' : '24/trash-color')

text: i18n('Удалить')

dangerous: true



onTriggered: {}

}



contextMenu: ContextMenu {



Action {

text: "Copy"

onTriggered: {

//Do something

}

}



ContextMenuItem {

text: "Edit"

onTriggered: {

//Do something

}

}



ContextMenuItem {

text: "Delete"

icon.source: Rosa.Theme.icon('24/trash-color')

dangerous: true

onTriggered: {

//Do something

}

}

}

}

}

PageFooter

Нижняя панель страницы обычно содержит кнопки навигации, но в неё можно добавить любой контент.

import QtQuick 2.15

import QtQuick.Controls 2.15



import RosaTheme 1.0 as Rosa

import RosaControls 1.0



Page {

id: root

title: "Init Page"



...



footer: PageFooter {



RowLayout {

anchors.fill: parent

spacing: Rosa.Theme.scale(4)



ToolButton {

Layout.fillHeight: true

Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter

icon.source: Rosa.Theme.icon('24/play-dark')

onClicked: {

//Do something

}

}



ToolButton {

Layout.fillHeight: true

Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter

icon.source: Rosa.Theme.icon('24/pause-dark')

onClicked: {

//Do something

}

}



ToolButton {

Layout.fillHeight: true

Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter

icon.source: Rosa.Theme.icon('24/stop-dark')

onClicked: {

//Do something

}

}

}

}

}