3 Stimmen

Wie man Übergangsanimationen hat, wenn man QML ListView und C++ QList<QObject*> verwendet?

Ich verwende QtQuick 2.0 und QML ListView, das ich mit meinem Modell in C++ (eine QList von Objekten) verbunden habe. Die Verbindung wurde über QQmlContext::setContextProperty() hergestellt.

Jetzt hat mir die Dokumentation gesagt, dass es keinen direkten Weg für die Oberfläche gibt, über Änderungen informiert zu werden, also habe ich den Kontext nur aktualisiert, wann immer ich mein Modell geändert habe. Wenn ich dies jedoch tue, wird die Ansicht direkt aktualisiert, ohne ein Ereignis auszulösen (wie z.B. add oder remove Ereignisse), was mich ein wenig stört, da ich keine Kontrolle über die Übergänge habe.

Um es einfach auszudrücken, hier ist mein QML-Code:

ListView {
id : list
        boundsBehavior: Flickable.StopAtBounds

        anchors {
            top: titleBar.bottom
            topMargin: -1
            bottom: mainWindow.bottom
            bottomMargin: -1
        }
        width: mainWindow.width

        model: episodes
        delegate: Episode {
            id: myDelegate
            onShowClicked: episodes.append(episodes[index])
        }

        ScrollBar {
            flickable: list;
        }
    }

wo Episode mein benutzerdefinierter Delegat ist. Es enthält den folgenden Code:

ListView.onAdd: SequentialAnimation {
    PropertyAction { target: episodeDelegate; property: "height"; value: 0 }
    NumberAnimation { target: episodeDelegate; property: "height"; to: 80; duration: 250; easing.type: Easing.InOutQuad }
}

ListView.onRemove: SequentialAnimation {
    PropertyAction { target: episodeDelegate; property: "height"; value: true }
    NumberAnimation { target: episodeDelegate; property: "height"; to: 0; duration: 250; easing.type: Easing.InOutQuad }

    // Stellen Sie sicher, dass delayRemove wieder auf false gesetzt wird, damit das Element zerstört werden kann
    PropertyAction { target: episodeDelegate; property: "delayRemove"; value: false }
}

was eine direkte Kopie von Qt Beispielen ist.

Zusammenfassend ist das Modell korrekt verknüpft und synchronisiert, jedoch verhindert die Art und Weise, wie dies geschieht, dass ich die Art der Modelländerungen in meiner QML-Logik kenne.

Weiß jemand einen Trick?

2voto

Beni Murza Punkte 120

Wenn Sie die setContextProperty zurücksetzen, können Sie den Übergang populate verwenden. Dies wendet jedoch den Übergang gleichzeitig auf alle Elemente in der Liste an.

Wenn Sie möchten, dass jedes Mal, wenn Sie ein Element hinzufügen, eine Animation erfolgt, könnten Sie das mit Signalen tun. Zum Beispiel:

class SomeList : public QObject
{
    Q_OBJECT
public:
    explicit SomeList(QObject *parent = 0);

    void Add(QString color, QString value)
    {
        emit addNew(color,value);
    }

signals:
    void addNew(QString data1,QString data2);
};

und in main.cpp könnten Sie haben:

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    engine.rootContext()->setContextProperty("cppInstance",new SomeList);

    return app.exec();
}

und in QML:

ListModel{
    id:someListModel
}

Rectangle{
    width: 600
    height: 600
    ListView{
        model:someListModel
        delegate:Rectangle{
            width: parent.width
            height: parent.height/10
            color: model.color
            Text{
                text: value
            } 
        }
    }
    Connections{
        target: cppInstance
        onAddNew: { someListModel.insert(0,{"color":data1,"value":data2})}
    } 
}

In der Klasse SomeList könnten Sie auch eine QList als Member haben, die die Zeichenfolgen enthält, die Sie in QML einfügen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X