Spec-Zone.ru › Qt 5.11

Тип QML ViewTransition

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

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

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

  • 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. При выполнении пятой и последней вставки, добавляя "Item 4" в представление, переход add выполняется один раз (для вставленного элемента), а переход displaced выполняется четыре раза (по одному разу для каждого из четырех существующих элементов в представлении).

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

Свойство Значение Описание
ViewTransition.item "Item 0" экземпляр делегата Сам объект Rectangle "Item 0"
ViewTransition.index значение 4 для int Индекс "Item 0" в модели после операции добавления
ViewTransition.destination значение точки point (0, 120) Положение, в которое перемещается "Item 0"
ViewTransition.targetIndexes массив int, содержащий только целое число "0" (ноль) Индекс "Item 4", нового элемента, добавленного в представление
ViewTransition.targetItems массив объектов, содержащий только экземпляр делегата "Item 4" Объект "Item 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.

Вместо использования нескольких NumberAnimations вы можете использовать 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/archives/qt-5.11/qml-qtquick-viewtransition.html

Spec-Zone.ru

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