Добавление переходов для пользовательского элемента - PullRequest
0 голосов
/ 22 марта 2020

У меня есть простой код QML, подобный этому:

GridView {
    id: viewId

    anchors.fill: parent

    delegate: delegateId
    cellWidth: 100
    cellHeight: 100    
}

Component {
    id: delegateId

    Rectangle {
        id: rectId

        width:  100
        height: 100

        MyCystomItem {
            id: imageId
            anchors.centerIn: parent
            height: parent.height
            width:  parent.width

            myCustomProperty: myCustomRole                
        }
    }
}

В делегате я использую MyCustomItem, который определен на стороне c ++ моего проекта. Когда MyCustomItem::paint() вызывается впервые, я рисую некоторый индикатор ожидания, и, используя значение, переданное myCustomProperty, я начинаю некоторые вычисления в потоке. Когда вычисления завершены, я вызываю MyCustomItem::update() и рисую результат вычислений.

Я хотел бы поэкспериментировать с переходами QtQuick, чтобы сделать сетку более живой, поэтому я собираюсь добавить некоторый переход между состояния ожидания и окончательного результата. Неважно, какой именно, проблема в том, что я не знаю, как правильно это сделать. Я хотел бы избежать любых попыток на основе таймера в моем коде c ++. Я хотел бы поместить переходы непосредственно в файл qml, чтобы можно было легко поэкспериментировать с различными эффектами.

Следующим шагом будет добавление переходов к элементу, когда активно состояние ожидания. Каков был бы наиболее qml-подобный подход для этого?

1 Ответ

1 голос
/ 23 марта 2020

Не совсем понятно, что именно вы хотите оживить. Но я попытаюсь дать некоторую идею

Вариант 1

Вы можете предоставить внутреннее состояние пользовательского элемента со свойствами, такими как waiting (или лучше working) и done. В QML вы можете связать эти свойства в State объектах и Transition объектах :

MyCystomItem {
    id: imageId
    anchors.centerIn: parent
    height: parent.height
    width:  parent.width

    myCustomProperty: myCustomRole

    states: [
        State {
            name: "working"
            when: imageId.working && !imageId.done
            //you could set properties
        },
        State {
            name: "done"
            when: !imageId.working && imageId.done
            //you could set properties
        }
    ],
    transitions: [
        Transition {
            from: "*"
            to: "working" //here goes the name from the state
            NumberAnimation {
                properties: "x,y";
                easing.type: Easing.InOutQuad;
                duration: 200;
            }                
        }
    ]      
}

Опция 2

В зависимости от Что касается расчетов, вы можете добавить одно или несколько свойств, которые представляют результаты и использовать Behavior объектов. Так как вы идентифицировали пользовательский элемент imageId, я не думаю, что вы действительно заинтересованы в этом параметре, но просто поместите его здесь для полноты.

Обратите также внимание, что этот параметр предоставляет немного проблема со смешанными обязанностями ( см. википедию ); Расчеты выполняются в том же классе, что и представление. Поэтому в приведенном ниже коде я предполагаю, что MyCustomItem выполняет только вычисления (как только он будет создан)

Rectangle {
    id: tempView
    anchors.centerIn: parent
    height: parent.height
    width:  parent.width

    color: imageId.working ? "transparent" 
                           : imageId.temperature < 20 ? "blue" : "red"
    Behavior on color { ColorAnimation { duration: 500 } }

    MyCystomItem {
        id: imageId
    }
}

Вариант 3

Наконец, вы можете сделать сетку немного более живы с ProgressBar с. Для этого нужно иметь представление о том, как далеко находится расчет, и, конечно, выставить это значение

import QtQuick.Controls 2.3

MyCystomItem {
    id: imageId
    anchors.centerIn: parent
    height: parent.height
    width:  parent.width


    ProgressBar {
       anchors.left: parent.left
       anchors.right: parent.right
       anchors.bottom: parent.bottom
       value: imageId.progress
       visible: imageId.progress < 100
    }
}

Заключение

Я думаю, что наиболее ценная часть в этом ответе это разоблачить ваше внутреннее состояние вычислений на стороне QML с Q_PROPERTY. Так как вы можете контролировать только то, что видно.

...