Spec-Zone.ru › Qt 5.12

Тип QML ViewTransition

Определяет элементы, находящиеся в процессе перехода в представлении. Подробнее...

Заявление импорта: import QtQuick 2.12
  • Список всех членов, включая унаследованные

Присоединенные свойства

  • destination : точка
  • index : int
  • item : элемент
  • targetIndexes : список
  • targetItems : список

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

С ListView и GridView можно указать переходы, которые должны применяться всякий раз, когда элементы в представлении изменяются в результате модификаций модели представления. У них оба есть следующие свойства, которые можно установить для соответствующих переходов, которые должны выполняться для различных операций:

  • populate - переход, применяемый к элементам, созданным изначально для представления или при изменении модели
  • add - переход, применяемый к элементам, которые добавляются в представление после его создания
  • remove - переход, применяемый к элементам, которые удаляются из представления
  • move - переход, применяемый к элементам, которые перемещаются в представлении (т.е. в результате операции перемещения в модели)
  • displaced - общий переход, применяемый к любым элементам, смещенным операцией добавления, перемещения или удаления
  • addDisplaced, removeDisplaced и moveDisplaced - переходы, которые применяются при смещении элементов операциями добавления, перемещения или удаления соответственно (эти переходы переопределяют общий переход при смещении, если он указан)

Для типов позиционеров Row, Column, Grid и Flow, которые работают со множествами дочерних элементов, а не с моделями данных, используются следующие свойства:

  • populate - переход, применяемый к элементам, которые были добавлены к позиционеру во время его создания
  • add - переход, применяемый к элементам, которые добавляются к позиционеру или перемещаются в него, или элементам, которые стали видимыми
  • move - переход, применяемый к элементам, которые были перемещены в позиционере, включая случаи, когда они были смещены из-за добавления или удаления других элементов, или когда элементы были иначе переупорядочены в позиционере, или когда элементы были перепозиционированы из-за изменения размера других элементов в позиционере

Переходы представления имеют доступ к присоединённому свойству ViewTransition, которое предоставляет подробности о элементах, находящихся в переходе, и о операции, которая вызвала переход. Поскольку переходы представления выполняются один раз на элемент, эти данные могут использоваться для настройки каждого перехода для каждого отдельного элемента.

Присоединенное свойство ViewTransition предоставляет следующие свойства, специфичные для элемента, к которому применяется переход:

  • ViewTransition.item - элемент, находящийся в переходе
  • ViewTransition.index - индекс этого элемента
  • ViewTransition.destination - (x, y)-координаты, к которым перемещается этот элемент для соответствующей операции представления

Кроме того, ViewTransition предоставляет свойства, специфичные для элементов, которые являются целевыми для операции, вызвавшей переход:

  • ViewTransition.targetIndexes - индексы целевых элементов
  • ViewTransition.targetItems - сами целевые элементы

(Обратите внимание, что для типов позиционеров Row, Column, Grid и Flow переход move предоставляет эти два дополнительных детали только тогда, когда переход вызывается добавлением элементов в позиционер.)

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

Ниже приведено введение в переходы представления и способы, которыми присоединенное свойство ViewTransition может быть использовано для расширения переходов представления.

Переходы представления: простой пример

Вот базовый пример использования переходов представления. Представление ниже указывает переходы для свойств add и displaced, которые будут выполняться при добавлении элементов в представление:

ListView {
    width: 240; height: 320
    model: ListModel {}

    delegate: Rectangle {
        width: 100; height: 30
        border.width: 1
        color: "lightsteelblue"
        Text {
            anchors.centerIn: parent
            text: name
        }
    }

    add: Transition {
        NumberAnimation { property: "opacity"; from: 0; to: 1.0; duration: 400 }
        NumberAnimation { property: "scale"; from: 0; to: 1.0; duration: 400 }
    }

    displaced: Transition {
        NumberAnimation { properties: "x,y"; duration: 400; easing.type: Easing.OutBounce }
    }

    focus: true
    Keys.onSpacePressed: model.insert(0, { "name": "Item " + model.count })
}

При нажатии клавиши пробела, добавляющей элемент в модель, новый элемент будет появляться с эффектом затухания и увеличения масштаба за 400 миллисекунд при добавлении в представление. Кроме того, любой элемент, смещенный добавлением нового элемента, будет анимирован до своего нового положения в представлении за 400 миллисекунд, как указано в переходе displaced.

Если пять элементов были вставлены последовательно с индексом 0, эффект будет таким:

Обратите внимание, что объекты NumberAnimation выше не должны указывать target для анимации соответствующего элемента. Кроме того, NumberAnimation в addTransition не нужно указывать значение to для перемещения элемента в его правильное положение в представлении. Это происходит потому, что представление неявно задаёт значения target и to с правильными значениями элемента и конечного положения элемента, если эти свойства не определены явно.

В самом простом случае переход представления может просто анимировать элемент до его нового положения после операции представления, как в переходе displaced выше, или анимировать некоторые свойства элемента, как в переходе add выше. Кроме того, переход представления может использовать присоединённое свойство ViewTransition для настройки поведения анимации для разных элементов. Ниже приведены некоторые примеры того, как это можно сделать.

Использование присоединенного свойства ViewTransition

Как уже отмечалось, различные свойства ViewTransition предоставляют подробности, специфичные для отдельного элемента, переходящего в состояние перехода, а также для операции, вызвавшей переход. В анимации выше пять элементов вставляются последовательно с индексом 0. Когда происходит пятая и последняя вставка, добавляя «Элемент 4» в представление, переход add выполняется один раз (для вставленного элемента), а переход displaced выполняется четыре раза (по одному разу для каждого из четырёх существующих элементов в представлении).

В этот момент, если мы изучим переход displaced, который выполнялся для смещенного нижнего элемента («Элемент 0»), значения свойств ViewTransition, предоставленные этому переходу, будут следующими:

Свойство Значение Описание
ViewTransition.item Экземпляр делегата «Элемент 0» Сам объект «Элемент 0» Rectangle
ViewTransition.index Значение 4 для int Индекс «Элемент 0» в модели после операции добавления
ViewTransition.destination Значение точки (0, 120) Позиция, в которую перемещается «Элемент 0»
ViewTransition.targetIndexes Массив, содержащий только целое число «0» (ноль) Индекс «Элемент 4», нового элемента, добавленного в представление
ViewTransition.targetItems Массив объектов, содержащий только экземпляр делегата «Элемент 4» Объект «Элемент 4» Rectangle — новый добавленный элемент представления

Списки ViewTransition.targetIndexes и ViewTransition.targetItems предоставляют элементы и индексы всех экземпляров делегатов, которые являются целевыми для соответствующей операции. Для операции добавления это все элементы, которые добавляются в представление; для удаления — все элементы, удаленные из представления, и так далее. (Обратите внимание, что эти списки будут содержать ссылки только на элементы, созданные внутри представления или в его кэшированных элементах; целевые элементы, которые не находятся в видимой области представления или в кэше элементов, не будут доступны.)

Таким образом, в то время как значения ViewTransition.item, ViewTransition.index и ViewTransition.destination варьируются для каждого отдельного перехода, который выполняется, значения ViewTransition.targetIndexes и ViewTransition.targetItems одинаковы для каждого перехода add и displaced , который вызывается конкретной операцией добавления.

Задержка анимации на основе индекса

Поскольку каждая перестройка представления выполняется один раз для каждого элемента, затронутого перестройкой, свойства ViewTransition могут использоваться в рамках перестройки для определения пользовательского поведения для перестройки каждого элемента. Например, ListView в предыдущем примере может использовать эту информацию для создания эффекта волн при перемещении перемещенных элементов.

Этого можно достичь, изменив перестройку displaced, чтобы она откладывала анимацию каждого перемещенного элемента на основе разницы между его индексом (предоставленным ViewTransition.index) и индексом первого удаленного элемента (предоставленным ViewTransition.targetIndexes):

    displaced: Transition {
        id: dispTrans
        SequentialAnimation {
            PauseAnimation {
                duration: (dispTrans.ViewTransition.index -
                        dispTrans.ViewTransition.targetIndexes[0]) * 100
            }
            NumberAnimation { properties: "x,y"; duration: 400; easing.type: Easing.OutBounce }
        }
    }

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

Анимирование элементов до промежуточных позиций

Свойство ViewTransition.item предоставляет ссылку на элемент, к которому применяется перестройка. Это можно использовать для доступа к любым атрибутам элемента, пользовательским property значениям и так далее.

Ниже представлена модификация перестройки displaced из предыдущего примера. Она добавляет ParallelAnimation с вложенными объектами NumberAnimation, которые ссылаются на ViewTransition.item для доступа к значениям x и y каждого элемента в начале их перестроек. Это позволяет каждому элементу анимироваться до промежуточной позиции относительно его начальной точки для перестройки, прежде чем анимироваться до конечной позиции в представлении:

    displaced: Transition {
        id: dispTrans
        SequentialAnimation {
            PauseAnimation {
                duration: (dispTrans.ViewTransition.index -
                        dispTrans.ViewTransition.targetIndexes[0]) * 100
            }
            ParallelAnimation {
                NumberAnimation {
                    property: "x"; to: dispTrans.ViewTransition.item.x + 20
                    easing.type: Easing.OutQuad
                }
                NumberAnimation {
                    property: "y"; to: dispTrans.ViewTransition.item.y + 50
                    easing.type: Easing.OutQuad
                }
            }
            NumberAnimation { properties: "x,y"; duration: 500; easing.type: Easing.OutBounce }
        }
    }

Теперь перемещенный элемент сначала переместится в позицию (20, 50) относительно своей начальной позиции, а затем в свою конечную, правильную позицию в представлении:

Поскольку конечный NumberAnimation не задает значение to, представление неявно устанавливает это значение в конечную позицию элемента в представлении, и поэтому эта последняя анимация переместит элемент в правильное место. Если для перестройки требуется конечная позиция элемента для каких-либо вычислений, она доступна через ViewTransition.destination.

Вместо использования нескольких NumberAnimation, вы можете использовать PathAnimation для анимации элемента по кривой. Например, перестройка add в предыдущем примере может быть дополнена PathAnimation следующим образом: для анимации новых элементов вдоль пути:

    add: Transition {
        id: addTrans
        NumberAnimation { property: "opacity"; from: 0; to: 1.0; duration: 400 }
        NumberAnimation { property: "scale"; from: 0; to: 1.0; duration: 400 }

        PathAnimation {
            duration: 1000
            path: Path {
                startX: addTrans.ViewTransition.destination.x + 200
                startY: addTrans.ViewTransition.destination.y + 200
                PathCurve { relativeX: -100; relativeY: -50 }
                PathCurve { relativeX: 50; relativeY: -150 }
                PathCurve {
                    x: addTrans.ViewTransition.destination.x
                    y: addTrans.ViewTransition.destination.y
                }
            }
        }
    }

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

Обработка прерванных анимаций

Перестройка представления может быть прервана в любой момент, если необходимо применить другую перестройку представления, пока исходная перестройка находится в процессе. Например, предположим, что элемент A вставлен в индекс 0 и подвергается перестройке "добавления"; затем, элемент B вставляется в индекс 0 быстро, прежде чем перестройка элемента A завершится. Поскольку элемент B вставлен перед элементом A, он сместит элемент A, заставив представление прервать перестройку "добавления" элемента A на середине и начать перестройку "смещения" на элементе A вместо этого.

Для простых анимаций, которые просто анимируют перемещение элемента в его конечную позицию, эта прерывистость вряд ли потребует дополнительного рассмотрения. Однако, если перестройка изменяет другие свойства, это прерывание может привести к нежелательным побочным эффектам. Рассмотрим первый пример на этой странице, повторенный ниже для удобства:

ListView {
    width: 240; height: 320
    model: ListModel {}

    delegate: Rectangle {
        width: 100; height: 30
        border.width: 1
        color: "lightsteelblue"
        Text {
            anchors.centerIn: parent
            text: name
        }
    }

    add: Transition {
        NumberAnimation { property: "opacity"; from: 0; to: 1.0; duration: 400 }
        NumberAnimation { property: "scale"; from: 0; to: 1.0; duration: 400 }
    }

    displaced: Transition {
        NumberAnimation { properties: "x,y"; duration: 400; easing.type: Easing.OutBounce }
    }

    focus: true
    Keys.onSpacePressed: model.insert(0, { "name": "Item " + model.count })
}

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

Каждый вновь добавленный элемент проходит через перестройку add, но прежде чем перестройка может завершиться, добавляется другой элемент, смещающий ранее добавленный элемент. Из-за этого перестройка add на ранее добавленном элементе прерывается, и вместо этого запускается перестройка displaced на элементе. Из-за прерывания анимации opacity и scale не завершились, поэтому элементы имеют непрозрачность и масштаб ниже 1,0.

Для исправления этого перестройка displaced должна дополнительно гарантировать, что свойства элемента устанавливаются в конечные значения, указанные в перестройке add, эффективно сбрасывая эти значения при каждом смещении элемента. В данном случае это означает установку непрозрачности и масштаба элемента в 1,0:

    displaced: Transition {
        NumberAnimation { properties: "x,y"; duration: 400; easing.type: Easing.OutBounce }

        // ensure opacity and scale values return to 1.0
        NumberAnimation { property: "opacity"; to: 1.0 }
        NumberAnimation { property: "scale"; to: 1.0 }
    }

Теперь, когда перестройка add элемента прерывается, его непрозрачность и масштаб анимируются до 1,0 при смещении, предотвращая неверные визуальные эффекты, которые были ранее:

Тот же принцип применим к любой комбинации перестроек представления. Добавляемый элемент может быть перемещен, прежде чем завершится его перестройка добавления, или перемещаемый элемент может быть удален, прежде чем завершится его перестройка перемещения, и так далее; таким образом, общее правило состоит в том, что каждая перестройка должна обрабатывать тот же набор свойств.

Ограничения, связанные с ScriptAction

При инициализации перестройки представления любые привязки свойств, которые ссылаются на присоединенное свойство ViewTransition, оцениваются в подготовке к перестройке. Из-за характера внутренней конструкции перестройки представления атрибуты присоединенного свойства ViewTransition действительны только для соответствующего элемента при инициализации перестройки и могут быть недействительными при фактическом выполнении перестройки.

Поэтому ScriptAction в рамках перестройки представления не должен ссылаться на присоединенное свойство ViewTransition, поскольку он может не ссылаться на ожидаемые значения в момент фактического вызова ScriptAction.

Рассмотрим следующий пример:

ListView {
    width: 240; height: 320
    model: ListModel {
        Component.onCompleted: {
            for (var i=0; i<8; i++)
                append({"name": i})
        }
    }

    delegate: Rectangle {
        width: 100; height: 30
        border.width: 1
        color: "lightsteelblue"
        Text {
            anchors.centerIn: parent
            text: name
        }
        objectName: name
    }

    move: Transition {
        id: moveTrans
        SequentialAnimation {
            ColorAnimation { property: "color"; to: "yellow"; duration: 400 }
            NumberAnimation { properties: "x,y"; duration: 800; easing.type: Easing.OutBack }
            ScriptAction { script: moveTrans.ViewTransition.item.color = "lightsteelblue" }
        }
    }

    displaced: Transition {
        NumberAnimation { properties: "x,y"; duration: 400; easing.type: Easing.OutBounce }
    }

    focus: true
    Keys.onSpacePressed: model.move(5, 1, 3)
}

При нажатии клавиши пробела три элемента перемещаются из индекса 5 в индекс 1. Для каждого перемещенного элемента последовательность moveTransition предположительно анимирует цвет элемента в «желтый», затем анимирует его в конечную позицию, а затем изменяет цвет элемента обратно в «lightsteelblue» с помощью ScriptAction. Однако при выполнении перестройка не дает ожидаемого результата:

Только последний перемещенный элемент возвращается к цвету «lightsteelblue»; остальные остаются желтыми. Это происходит потому, что ScriptAction не выполняется до тех пор, пока перестройка не будет инициализирована, к этому моменту значение ViewTransition.item изменяется на ссылку на другой элемент; элемент, который скрипт намеревался указать, не является тем, который удерживает ViewTransition.item в момент фактического вызова ScriptAction.

В этом случае, чтобы избежать этой проблемы, представление может установить свойство с помощью PropertyAction вместо этого:

    move: Transition {
        id: moveTrans
        SequentialAnimation {
            ColorAnimation { property: "color"; to: "yellow"; duration: 400 }
            NumberAnimation { properties: "x,y"; duration: 800; easing.type: Easing.OutBack }
            //ScriptAction { script: moveTrans.ViewTransition.item.color = "lightsteelblue" } BAD!

            PropertyAction { property: "color"; value: "lightsteelblue" }
        }
    }

При инициализации перестройки PropertyAction target будет установлен для соответствующего ViewTransition.item для перестройки и будет позже выполнен с правильным целевым элементом, как ожидалось.

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

ViewTransition.destination : point

Это присоединённое свойство содержит конечную позицию перемещаемого элемента в представлении.

Это значение свойства — point со свойствами x и y.

ViewTransition.index : int

Это присоединённое свойство содержит индекс элемента, который перестраивается.

Обратите внимание, что если элемент перемещается, это свойство содержит индекс, в который переходит элемент, а не откуда.

ViewTransition.item : item

Это присоединенное свойство содержит элемент, который перестраивается.

Предупреждение: Этот элемент не следует хранить и ссылаться на него за пределами перестройки, так как он может стать недействительным при изменении представления.

ViewTransition.targetIndexes : list

Это присоединенное свойство содержит список индексов элементов в представлении, являющихся целью соответствующей операции.

Цели — это элементы, являющиеся предметом операции. При операции добавления это добавляемые элементы; при удалении — это удаляемые элементы; при перемещении — это перемещаемые элементы.

Например, если перестройка была вызвана операцией вставки, которая добавила два элемента в индекс 1 и 2, этот список targetIndexes будет иметь значение [1,2].

END_OF_DOCUMENT_MARKER

Примечание: Список targetIndexes содержит только индексы элементов, которые фактически находятся в представлении или будут находиться в представлении после завершения соответствующей операции.

См. также QtQuick::ViewTransition::targetItems.

ViewTransition.targetItems : list

Это присоединённое свойство содержит список элементов в представлении, которые являются целевыми для соответствующей операции.

Цели — это элементы, являющиеся объектом операции. Для операции добавления это добавляемые элементы; для удаления — удаляемые элементы; для перемещения — перемещаемые элементы.

Например, если переход был вызван операцией вставки, которая добавила два элемента с индексами 1 и 2, этот список targetItems будет содержать эти два элемента.

Примечание: Список targetItems содержит только элементы, которые фактически находятся в представлении или будут находиться в представлении после завершения соответствующей операции.

Предупреждение: Объекты в этом списке не должны сохраняться и использоваться за пределами перехода, так как элементы могут стать недействительными. targetItems являются действительными только при первоначальном создании перехода; это также означает, что они не должны использоваться объектами ScriptAction в переходе, которые не вычисляются до запуска перехода.

См. также QtQuick::ViewTransition::targetIndexes.

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

Spec-Zone.ru

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