Spec-Zone.ru › Qt 5.14

Тип QML StackView

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

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

FocusScope

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

Свойства

  • busy : bool
  • currentItem : Элемент
  • delegate : StackViewDelegate
  • depth : int
  • initialItem : var

Методы

  • void clear()
  • void completeTransition()
  • Элемент find(функция, bool onlySearchLoadedItems)
  • Элемент get(int индекс, bool неЗагружать)
  • Элемент pop(Элемент элемент)
  • Элемент push(Элемент элемент)

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

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

Пример галереи касаний qtquickcontrols1-touch-example — хорошая отправная точка для понимания работы StackView. Следующий фрагмент из примера показывает, как его можно использовать:

StackView {
    id: stack
    initialItem: view

    Component {
        id: view

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

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

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

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

Основная навигация

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

Иногда необходимо вернуться в стек более чем на один шаг, например, для возврата к «главному» элементу или какому-либо элементу раздела в приложении. Для этого случая можно указать элемент в качестве параметра для 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] - анимация перехода «замена» между 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] - анимация перехода «замена» между C и F
  • clear(); push([D, E, F]) => [D, E, F] - анимация перехода не выполняется (так как стек был пустым)

Помещение элементов

Элемент, помещаемый в StackView, может быть элементом, URL-адресом, строкой, содержащей URL-адрес, или компонентом. Чтобы поместить его, присвойте ему свойство «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 разворачивает стек до низа, если в качестве целевого элемента передается null, код работает правильно даже в случае, если соответствующего элемента не найдено.

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

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

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()

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

Item find(function, bool onlySearchLoadedItems = false)

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

Item get(int index, bool dontLoad = false)

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

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

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

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

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

Примеры:

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

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

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

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

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

Добавляет item в стек.

Функция также может принимать список свойств в качестве аргумента — 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}])

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

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

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

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

Spec-Zone.ru

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