Spec-Zone.ru › Qt 5.9

Тип 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 реализует модель навигации на основе стека, которую можно использовать с набором взаимосвязанных страниц с информацией. Элементы добавляются в стек по мере углубления пользователя в материал, и удаляются из стека, когда он выбирает вернуться назад.

Пример галереи касаний touch gallery — хороший отправной пункт для понимания того, как работает 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.

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

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

Существует три основных операции навигации в 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, может быть элементом Item, 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 может загрузить только последний элемент в списке. Остальные элементы будут загружены, когда они собираются стать текущими (что происходит при вызове pop). Следующий пример показывает, как добавить массив элементов:

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

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

Если 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

Элемент 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.9/qml-qtquick-controls-stackview.html

Spec-Zone.ru

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