Spec-Zone.ru › Qt 5.11

Тип 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(function, bool onlySearchLoadedItems)
  • Элемент get(int index, bool dontLoad)
  • Элемент pop(Элемент item)
  • Элемент push(Элемент 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» удаляет верхний элемент из стека, а «замена» похожа на 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] - анимация перехода «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, может быть элементом, 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()

Немедленно завершить любой текущий переход. /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/archives/qt-5.11/qml-qtquick-controls-stackview.html

Spec-Zone.ru

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