【问题标题】:How to have transition animations when using QML ListView and C++ QList<QObject*>?使用 QML ListView 和 C++ QList<QObject*> 时如何有过渡动画?
【发布时间】:2014-02-26 08:51:32
【问题描述】:

我正在使用 QtQuick 2.0 和 QML ListView,我用 C++ 连接到我的模型(对象的 QList)。连接是通过 QQmlContext::setContextProperty() 建立的。

现在文档告诉我,界面无法直接了解更改,因此我只在更改模型时才实现上下文。但是,当我这样做时,视图会直接实现而不触发任何事件(例如添加或删除事件),这让我有点恼火,因为我无法控制转换。

简单来说就是我的qml代码:

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;
        }
    }

Episode 是我的自定义委托。它包含以下代码:

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: "ListView.delayRemove"; value: true }
    NumberAnimation { target: episodeDelegate; property: "height"; to: 0; duration: 250; easing.type: Easing.InOutQuad }

    // Make sure delayRemove is set back to false so that the item can be destroyed
    PropertyAction { target: episodeDelegate; property: "ListView.delayRemove"; value: false }
}

这是 Qt 示例的直接副本。

总而言之,模型已正确链接和同步,但这样做的方式使我无法了解 QML 逻辑中模型更改的性质。

有人知道什么技巧吗?

【问题讨论】:

    标签: c++ qt listview qml


    【解决方案1】:

    当您重置setContextProperty 时,您可以使用populate 转换。但是,这会将转换同时应用于列表中的所有元素。

    如果您希望每次添加项目时都有动画,您可以使用信号来实现。例如:

    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);
    };
    

    在 main.cpp 中你可以:

    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();
    }
    

    在 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})}
        } 
    }
    

    SomeList 类中,您还可以将QList 作为成员,其中包含您在QML 中插入的字符串。

    【讨论】:

    • 我现在真的脱离了主题,但我相信你的解决方案确实回答了我当时的问题。我尽我所能只为显示而坚持使用 QML,这就是为什么我在 C++ 中没有列表项,而只有 QML 中的视图。感谢您抽出宝贵时间。
    • 这是一个不错的解决方案。
    • 直到现在才看到您提出问题的日期...我偶然发现了您的问题,因为一周前我遇到了同样的问题。希望这个答案能帮助和我一样处境的人。
    猜你喜欢
    • 2014-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多