Spec-Zone.ru › Qt 5.13

Тип QML StackView

Предоставляет модель навигации на основе стека. Подробнее...

Заявление об импорте: import QtQuick.Controls 1.4
С тех пор: Qt 5.1
Наследует:

FocusScope

  • Список всех членов, включая унаследованные

Свойства

  • busy : bool
  • currentItem : Item
  • delegate : StackViewDelegate
  • depth : int
  • initialItem : var

Методы

  • void clear()
  • void completeTransition()
  • Item find(function, bool onlySearchLoadedItems)
  • Item get(int index, bool dontLoad)
  • Item pop(Item item)
  • Item push(Item item)

Подробное описание

StackView реализует модель навигации на основе стека, которую можно использовать с набором взаимосвязанных страниц с информацией. Элементы добавляются в стек по мере продвижения пользователя по материалу, и удаляются, когда он хочет вернуться назад.

Пример галереи касаний показывает, как работает StackView. Следующий фрагмент из примера показывает, как его можно использовать:

StackView {
    id: stack
    initialItem: view

    Component {
        id: view

        MouseArea {
            Text {
                text: stack.depth
                anchors.centerIn: parent
            }
            onClicked: stack.push(view)
        }
    }
}

Использование StackView в приложении

Использование StackView в приложении обычно сводится к добавлению StackView как дочернего элемента окна. Стек обычно привязан к краям окна, за исключением верхней или нижней части, где он может быть привязан к строке состояния или какому-либо другому подобному UI-компоненту. Затем стек можно использовать, вызывая его методы навигации. Первый элемент, отображаемый в StackView, — это элемент, назначенный свойству initialItem.

Примечание: Элементы, добавленные в стек, имеют присоединенные свойства стека.

Базовая навигация

Существует три основных операции навигации в StackView: push(), pop() и замена (замена, указав аргумент replace в push()). Они соответствуют классическим операциям стека, где "push" добавляет элемент в верхнюю часть стека, "pop" удаляет верхний элемент из стека, а "replace" — это как pop, за которым следует push, так как он заменяет верхний элемент стека новым элементом (но применённый переход может быть другим). Верхний элемент стека соответствует элементу, который в настоящее время отображается на экране. Это означает, что "push" — это логический эквивалент перехода вперёд или глубже в приложение, "pop" — эквивалент возврата назад, а "replace" — эквивалент замены текущего элемента.

Иногда необходимо вернуться на несколько шагов назад в стеке, например, чтобы вернуться к главному элементу или какому-либо элементу раздела в приложении. В этом случае можно указать элемент в качестве параметра для pop(). Это называется операцией "разворачивания", так как стек разворачивается до указанного элемента. Если элемент не найден, стек разворачивается до тех пор, пока в нём не останется только один элемент, который затем становится текущим элементом. Для явного разворачивания до дна стека рекомендуется использовать pop(null), хотя технически подойдёт любой несуществующий элемент.

Учитывая стек [A, B, C]:

  • push(D) => [A, B, C, D] — анимация перехода "push" между C и D
  • pop() => [A, B] — анимация перехода "pop" между C и B
  • push(D, replace) => [A, B, D] — анимация перехода "replace" между C и D
  • pop(A) => [A] — анимация перехода "pop" между C и A

Примечание: Когда стек пуст, push() не выполняет анимацию перехода, поскольку нечего переходить (обычно во время запуска приложения). pop() в стеке с глубиной 1 или 0 — это пустая операция. Если необходимо удалить все элементы из стека, доступна отдельная функция clear().

Вызов push() возвращает элемент, который был добавлен в стек. Вызов pop() возвращает элемент, который был удалён из стека. При вызове pop() в операции разворачивания возвращается верхний элемент (первый элемент, который был удалён, а также элемент, который переходит наружу).

Глубокое связывание

Глубокое связывание означает запуск приложения в определённом состоянии. Например, приложение газеты можно запустить, показав определённую статью, минуя начальную страницу (и, возможно, раздел), через которые обычно нужно пройти, чтобы добраться до статьи. С точки зрения StackView глубокое связывание означает возможность изменить состояние стека, настолько, что можно добавить набор элементов в верхнюю часть стека или полностью сбросить стек до заданного состояния.

API для глубокого связывания в StackView такой же, как и для базовой навигации. Добавление массива вместо одного элемента предполагает, что все элементы в этом массиве будут добавлены в стек. Однако анимация перехода будет выполняться так, как будто в стек был добавлен только последний элемент массива. Обычные семантики push() применяются для глубокого связывания, что означает, что push() добавляет то, что добавлено в стек. Обратите также внимание, что загружен только последний элемент массива. Остальные будут загружаться по мере необходимости при входе на экран при последующих вызовах pop (или при запросе элемента с помощью get).

Это даёт следующий результат, учитывая стек [A, B, C]:

  • push([D, E, F]) => [A, B, C, D, E, F] — анимация перехода "push" между C и F
  • push([D, E, F], replace) => [A, B, D, E, F] — анимация перехода "replace" между C и F
  • clear(); push([D, E, F]) => [D, E, F] — анимация перехода отсутствует (поскольку стек был пустым)

Добавление элементов

Элемент, добавленный в StackView, может быть элементом Item, URL, строкой, содержащей URL, или компонентом Component. Для его добавления назначьте его свойству "item" внутри списка свойств и передайте его как аргумент в push:

stackView.push({item: yourItem})

Список может содержать несколько свойств, которые управляют тем, как следует добавлять элемент:

  • item: это обязательное свойство, которое содержит добавляемый элемент.
  • properties: список свойств QML, которые должны быть назначены элементу при добавлении. Эти свойства будут скопированы в элемент при загрузке или когда элемент станет текущим (обычно при добавлении).
  • immediate: установите это свойство в true , чтобы пропустить эффекты перехода. При добавлении массива это свойство нужно установить только для первого элемента, чтобы сделать всю операцию мгновенной.
  • replace: установите это свойство для замены текущего элемента в стеке. При добавлении массива необходимо установить это свойство только для первого элемента, чтобы заменить столько элементов в стеке, сколько находится в массиве.
  • destroyOnPop: установите этот булево значение в true, если StackView должен уничтожить элемент, когда он будет удалён из стека. По умолчанию (если destroyOnPop не указано), StackView уничтожит элементы, добавленные в качестве компонентов или URL. Элементы, не уничтоженные, будут возвращены к исходным родительским элементам, которые они имели до добавления в стек, и скрыты. Если вам нужно установить это свойство, делайте это осторожно, чтобы элементы не протекали.

Если единственным необходимым аргументом является "item", можно использовать следующий сокращённый формат:

stackView.push(yourItem)

Можно добавить несколько элементов за один раз, используя массив списков свойств. Это более эффективно, чем добавлять элементы по одному, так как StackView может загрузить только последний элемент в списке. Остальные будут загружены, когда они собираются стать текущим элементом (что происходит при удалении из стека). Следующий пример показывает, как добавить массив элементов:

stackView.push([{item: yourItem1}, {item: yourItem2}])

Если элемент встраиваемого типа добавляется в стек, он временно переназначается родительскому элементу StackView. Когда элемент позже удаляется из стека, он снова переназначается своему первоначальному владельцу. Однако, если элемент добавляется как компонент или URL, фактический элемент будет создан как элемент из этого компонента. Это происходит автоматически, когда элемент должен стать текущим элементом в стеке. Владение элементом обычно переходит к StackView, который автоматически уничтожит элемент, когда он позже будет удалён. Компонент, который объявлял элемент, по контрасту, остаётся во владении приложения и не уничтожается стеком. Это можно переопределить, явно указав destroyOnPop в списке аргументов, переданных в push.

Если properties для добавления в стек определены, они будут скопированы в элемент во время загрузки (в случае компонента или URL) или когда элемент становится текущим элементом (в случае встраиваемого элемента). Следующий пример показывает, как это можно сделать:

stackView.push({item: someItem, properties: {fgcolor: "red", bgcolor: "blue"}})

Примечание: Если элемент объявлен внутри другого элемента, и этот родительский элемент уничтожается (даже если был использован компонент), этот дочерний элемент также будет уничтожен. Это следует нормальным правилам уничтожения родитель-потомок Qt, но иногда это вызывает удивление у разработчиков.

Жизненный цикл

Жизненный цикл элемента в StackView может иметь следующие переходы:

  1. создание
  2. неактивный
  3. активизация
  4. активный
  5. деактивация
  6. неактивный
  7. уничтожение

Он может перемещаться любое количество раз между состояниями «неактивный» и «активный». Когда элемент активируется, он отображается на экране и считается текущим элементом. Элемент в StackView, который не виден, не активирован, даже если элемент в настоящее время является верхним элементом в стеке. Когда стек становится видимым, активируется верхний элемент. Аналогично, если стек затем скрывается, верхний элемент будет деактивирован. Удаление элемента из верхней части стека в этот момент не приведёт к дальнейшей деактивации, так как элемент не активен.

Существует присоединённое свойство Stack.status, которое отслеживает жизненный цикл. Это перечисление со следующими значениями: Stack.Inactive, Stack.Activating, Stack.Active и Stack.Deactivating. В сочетании с обычными сигналами Component.onComplete и Component.onDestruction, весь жизненный цикл выглядит следующим образом:

  • Создан: Component.onCompleted()
  • Активизация: Stack.onStatusChanged (Stack.status равен Stack.Activating)
  • Активирован: Stack.onStatusChanged (Stack.status равен Stack.Active)
  • Деактивация: Stack.onStatusChanged (Stack.status равен Stack.Deactivating)
  • Деактивирован: Stack.onStatusChanged (Stack.status равен Stack.Inactive)
  • Уничтожение: Component.onDestruction()

Поиск элементов

Иногда необходимо искать элемент, например, для возврата стека к элементу, на который у приложения нет ссылки. Это упрощается с помощью функции find() в StackView. Функция find() принимает в качестве единственного аргумента функцию обратного вызова. Обратный вызов вызывается для каждого элемента в стеке (начиная с верхнего). Если обратный вызов возвращает true, это означает, что совпадение найдено, и функция find() возвращает этот элемент. Если обратный вызов не возвращает true (совпадение не найдено), то find() возвращает null.

В приведённом ниже коде производится поиск элемента в стеке с именем «order_id», а затем происходит возврат к этому элементу. Обратите внимание, что поскольку find() возвращает null при отсутствии элемента, а pop возвращается в низ стека если target item равно null, код работает хорошо даже в случае отсутствия подходящего элемента.

stackView.pop(stackView.find(function(item) {
    return item.name == "order_id";
}));

Также можно получить доступ к элементу в стеке с помощью get(индекс). Вы должны использовать эту функцию, если ваш элемент зависит от другого элемента в стеке, так как функция гарантирует, что элемент с заданным индексом загрузится перед возвратом.

previousItem = stackView.get(myItem.Stack.index - 1));

Переходы

Переход выполняется всякий раз, когда элемент добавляется в стек или удаляется из него, и состоит из двух элементов: enterItem и exitItem. Сам StackView никогда не перемещает элементы, но вместо этого делегирует задачу внешнему набору анимаций, предоставляемому стилем или разработчиком приложения. Таким образом, то, как элементы должны визуально входить и выходить из стека (и геометрия, которой они должны обладать), полностью контролируется извне.

При запуске перехода StackView будет искать переход, соответствующий выполненной операции. На выбор есть три перехода: pushTransition, popTransition и replaceTransition. Каждый из них реализует, как enterItem должен анимироваться при входе, и exitItem при выходе. Переходы собираются внутри объекта StackViewDelegate, назначенного свойству delegate. По умолчанию, popTransition и replaceTransition будут такими же, как pushTransition, если вы не зададите им иное.

Простой переход с эффектом затемнения можно реализовать так:

StackView {
    delegate: StackViewDelegate {
        function transitionFinished(properties)
        {
            properties.exitItem.opacity = 1
        }

        pushTransition: StackViewTransition {
            PropertyAnimation {
                target: enterItem
                property: "opacity"
                from: 0
                to: 1
            }
            PropertyAnimation {
                target: exitItem
                property: "opacity"
                from: 1
                to: 0
            }
        }
    }
}

PushTransition должен наследовать от StackViewTransition, который является ParallelAnimation, содержащим свойства enterItem и exitItem. Эти элементы должны быть назначены свойству target анимаций внутри перехода. Поскольку один и тот же экземпляр элементов может быть добавлен в StackView несколько раз, вы всегда должны переопределять StackViewDelegate.transitionFinished(). Реализуйте эту функцию для сброса любых свойств, анимированных на exitItem, чтобы последующие переходы могли ожидать, что элементы будут в стандартном состоянии.

Более сложный пример может выглядеть следующим образом. Здесь элементы лежат сбоку, прежде чем вращаться в вертикальное положение:

StackView {
    delegate: StackViewDelegate {
        function transitionFinished(properties)
        {
            properties.exitItem.x = 0
            properties.exitItem.rotation = 0
        }

        pushTransition: StackViewTransition {
            SequentialAnimation {
                ScriptAction {
                    script: enterItem.rotation = 90
                }
                PropertyAnimation {
                    target: enterItem
                    property: "x"
                    from: enterItem.width
                    to: 0
                }
                PropertyAnimation {
                    target: enterItem
                    property: "rotation"
                    from: 90
                    to: 0
                }
            }
            PropertyAnimation {
                target: exitItem
                property: "x"
                from: 0
                to: -exitItem.width
            }
        }
    }
}

Расширенное использование

Когда StackView нуждается в новом переходе, он сначала вызывает StackViewDelegate.getTransition(). Базовая реализация этой функции просто ищет свойство с именем properties.name внутри себя (корневой объект), что и позволяет найти property Component pushTransition в примерах выше.

function getTransition(properties)
{
    return root[properties.name]
}

Вы можете переопределить эту функцию для своего делегата, если вам нужна дополнительная логика для выбора перехода. Например, вы можете инспектировать элементы и возвращать различные анимации в зависимости от их внутреннего состояния. StackView ожидает, что вы вернёте компонент, содержащий StackViewTransition, или непосредственно StackViewTransition. Первый вариант проще, так как StackView затем создаст переход и позже уничтожит его, когда он завершит работу, избегая каких-либо побочных эффектов, связанных с тем, что переход живёт дольше, чем требуется. Возврат StackViewTransition непосредственно может быть полезен, если вам нужно реализовать кэширование переходов для повышения производительности. В качестве оптимизации вы также можете вернуть null для обозначения того, что вы хотите сразу отобразить/скрыть элементы без создания или запуска каких-либо переходов. Вы также можете переопределить эту функцию, если вам нужно изменить элементы каким-либо образом до начала перехода.

properties содержит свойства, которые будут назначены StackViewTransition перед его запуском. На самом деле, вы можете добавить больше свойств к этому объекту во время вызова, если вам нужно инициализировать дополнительные свойства вашего пользовательского StackViewTransition при создании возвращённого компонента.

Следующий пример показывает, как вы можете выбрать анимацию во время выполнения:

StackViewDelegate {
    function getTransition(properties)
    {
        return (properties.enterItem.Stack.index % 2) ? horizontalTransition : verticalTransition
    }

    function transitionFinished(properties)
    {
        properties.exitItem.x = 0
        properties.exitItem.y = 0
    }

    property Component horizontalTransition: StackViewTransition {
        PropertyAnimation {
            target: enterItem
            property: "x"
            from: target.width
            to: 0
            duration: 300
        }
        PropertyAnimation {
            target: exitItem
            property: "x"
            from: 0
            to: target.width
            duration: 300
        }
    }

    property Component verticalTransition: StackViewTransition {
        PropertyAnimation {
            target: enterItem
            property: "y"
            from: target.height
            to: 0
            duration: 300
        }
        PropertyAnimation {
            target: exitItem
            property: "y"
            from: 0
            to: target.height
            duration: 300
        }
    }
}

Поддерживаемые присоединённые свойства

Элементы в StackView поддерживают следующие присоединённые свойства:

  • Stack.index - Содержит индекс элемента внутри StackView
  • Stack.view - Содержит StackView, в котором находится элемент
  • Stack.status - Содержит статус элемента

Документация свойств

[только для чтения] busy : bool

busy равно true при выполнении перехода и false в противном случае.

[только для чтения] currentItem : Item

Текущий верхний элемент в стеке.

delegate : StackViewDelegate

Переходы, используемые при добавлении или удалении элементов. Для лучшего понимания применения пользовательских переходов, прочтите Переходы.

См. также Переходы.

[только для чтения] depth : int

Количество элементов, добавленных в стек.

initialItem : var

Первый элемент, который должен быть показан при создании StackView. initialItem может принимать такое же значение, как и первый аргумент для StackView.push(). Обратите внимание, что это просто удобный способ написания Component.onCompleted: stackView.push(myInitialItem)

Примеры:

  • initialItem: Qt.resolvedUrl("MyItem.qml")
  • initialItem: myItem
  • initialItem: {"item" : Qt.resolvedUrl("MyRectangle.qml"), "properties" : {"color" : "red"}}

См. также push.

Документация методов

void clear()

Удалить все элементы из стека. Анимации не будут применены.

void completeTransition()

Немедленно завершить любой текущий переход. /sa Animation.complete

Элемент find(функция, bool толькоИскатьЗагруженныеЭлементы = false)

Поиск определенного элемента внутри стека. функция будет вызываться для каждого элемента в стеке (с элементом в качестве аргумента), пока функция не вернёт значение true. Возвращаемое значение — найденный элемент. Например: find(function(item, index) { return item.isTheOne }) Установите толькоИскатьЗагруженныеЭлементы в true для того, чтобы не загружать элементы, которые не загружены в память.

Элемент get(int индекс, bool неЗагружать = false)

Возвращает элемент в позиции индекс в стеке. Если неЗагружать равно true, элемент не будет вынужден загружаться (и null будет возвращено, если он ещё не загружен).

Элемент pop(Элемент элемент = undefined)

Извлекает один или несколько элементов из стека.

Функция также может принимать список свойств в качестве аргумента — Item StackView::pop(jsobject dict), который может содержать одно или несколько из следующих свойств:

  • item: если указано, все элементы до (но не включая) элемент будут извлечены. Если элемент равен null, все элементы до (но не включая) первого элемента будут извлечены. Если не указано, будет извлечён только текущий элемент.
  • immediate: установите это свойство в true для пропуска эффектов перехода.

Примеры:

  • stackView.pop()
  • stackView.pop({item:someItem, immediate: true})
  • stackView.pop({immediate: true})
  • stackView.pop(null)

Примечание: Если единственным необходимым аргументом является «элемент», вы можете применить следующее сокращение: stackView.pop(anItem).

Возвращает элемент, который был извлечён.

См. также clear().

Элемент push(Элемент элемент)

Добавляет элемент в стек.

Функция также может принимать список свойств в качестве аргумента — Item StackView::push(jsobject dict), который должен содержать одно или несколько из следующих свойств:

  • item: это свойство является обязательным и содержит элемент, который нужно добавить.
  • properties: список свойств QML, которые должны быть назначены элементу при добавлении. Эти свойства будут скопированы в элемент при его загрузке (в случае компонента или URL), или когда он впервые становится текущим элементом (обычно при добавлении).
  • immediate: установите это свойство в true для пропуска эффектов перехода. При добавлении массива, необходимо установить это свойство только для первого элемента, чтобы сделать всю операцию немедленной.
  • replace: установите это свойство для замены текущего элемента в стеке. При добавлении массива, необходимо установить это свойство только для первого элемента, чтобы заменить столько элементов в стеке, сколько их в массиве.
  • destroyOnPop: установите это свойство, чтобы указать, нужно ли уничтожить элемент при его извлечении из стека. По умолчанию (если destroyOnPop не указано), StackView уничтожит элементы, добавленные как компоненты или URL. Элементы, не уничтоженные, будут переродителями к исходным родителям, которые у них были до добавления в стек, и скрыты. Если вам нужно установить это свойство, делайте это осторожно, чтобы не допустить утечки памяти.

Также можно добавить массив элементов (списков свойств), если нужно добавить несколько элементов за один раз. Переход затем будет происходить только между текущим элементом и последним элементом в списке. Загрузка других элементов будет отложена до необходимости.

Примеры:

  • stackView.push({item:anItem})
  • stackView.push({item:aURL, immediate: true, replace: true})
  • stackView.push({item:aRectangle, properties:{color:"red"}})
  • stackView.push({item:aComponent, properties:{color:"red"}})
  • stackView.push({item:aComponent.createObject(), destroyOnPop:true})
  • stackView.push([{item:anitem, immediate:true}, {item:aURL}])

Примечание: Если единственным необходимым аргументом является «элемент», вы можете применить следующее сокращение: stackView.push(anItem).

Возвращает элемент, который стал текущим.

См. также initialItem и Добавление элементов.

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.13/qml-qtquick-controls-stackview.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API