Работа со страницами
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
}
}
}
Пример с собственным 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
}
}
}
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
}
}
}
}
}