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

Подробнее рассмотрим функции в 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
}

}

}

}

}