Qt QML GridView与更改模型的ListView

Qt QML GridView与更改模型的ListView,qt,listview,model,qml,Qt,Listview,Model,Qml,我花了几天时间解决这个问题。为了方便起见,我做了一个小样本 这是我的密码 main.cpp和model类 main.qml ListComponent.qml 如您所见,在ListComponent.qml中,我有一个与后端模型绑定的listview。 因此,我在main.qml和models中创建了ListComponent.qml的两个实例 我的要求是,如果我在cpp中有一个包含人名的MassDataList, 在ListView1中,我需要全部以字母A开头,在ListView2中,我需要全

我花了几天时间解决这个问题。为了方便起见,我做了一个小样本

这是我的密码

  • main.cpp和model类
  • main.qml
  • ListComponent.qml
  • 如您所见,在ListComponent.qml中,我有一个与后端模型绑定的listview。 因此,我在main.qml和models中创建了ListComponent.qml的两个实例

    我的要求是,如果我在cpp中有一个包含人名的MassDataList, 在ListView1中,我需要全部以字母A开头,在ListView2中,我需要全部以字母B开头

    代码示例如下所示:

    main.qml

    import QtQuick 2.6
    import QtQuick.Window 2.2
    import QtQuick.Controls 1.4
    
    Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    
    TextField {
    x: 0
    y: 0
    onTextChanged: Test.setModel(text)
    
    }
    
    ListComponent {
    id: component1
    x: 26
    y: 44
    width: 100
    height: 291
    }
    
    ListComponent {
    id: component2
    x: 163
    y: 44
    width: 100
    height: 291
    }
    }
    
    ListComponent.qml

    import QtQuick 2.0
    
    Item {
    Rectangle {
    id: rectangle
    color: "#ffffff"
    anchors.fill: parent
    
    ListView {
    id: listView
    width: 200; height: 300
    spacing: 5
    model: Test.model
    anchors.fill: parent
    delegate: Item {
    x: 5
    width: 80
    height: 40
    Row {
    id: row1
    spacing: 10
    Text {
    text: modelData
    font.bold: true
    anchors.verticalCenter: parent.verticalCenter
    }
    }
    }
    }
    }
    
    }
    
    C++端

    TestModel-Test.h

    #ifndef TEST_H
        #define TEST_H
        #include "QObject"
    
        class Test: public QObject {
            Q_OBJECT
               Q_PROPERTY(QStringList model MEMBER m_model NOTIFY modelChanged)
               QStringList m_model;
             public slots:
               void setModel(QString m) {
                   QStringList q;
                   for(int i=0;i<massList.length();i++)
                   {
                       if(massList.at(i).contains(m))
                           q.append(massList[i]);
                   }
                 //m_model = m.split(" ");
    
                   m_model = q;
                 modelChanged();
               }
             signals:
               void modelChanged();
        public:
               Test();
               QList<QString> massList;
           };
        #endif // TEST_H
    
    最后是main.cpp

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include "test.h"
    #include "QQmlContext"
    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);
        QQmlApplicationEngine engine;
    
        Test t;
        engine.rootContext()->setContextProperty("Test", &t);
    
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
        if (engine.rootObjects().isEmpty())
            return -1;
    
    
        return app.exec();
    }
    
    #包括
    #包括
    #包括“test.h”
    #包括“QQmlContext”
    int main(int argc,char*argv[])
    {
    QGUI应用程序应用程序(argc、argv);
    qqmlaplicationengine;
    试验t;
    engine.rootContext()->setContextProperty(“Test”和&t);
    engine.load(QUrl(QStringLiteral(“qrc:/main.qml”));
    if(engine.rootObjects().isEmpty())
    返回-1;
    返回app.exec();
    }
    
    请帮忙

    根据Eyllanesc的建议,我尝试了以下示例中的代表组。但问题是,对于每个过滤器,我需要创建不同的模型组。就我而言,这是不可能的

    我有一个GridView,其中ListView作为delegateItems,我希望不同的ListView有不同的模型

    这是我尝试过的delegateGroup示例

    /*
     * Copyright 2014 ImaginativeThinking
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *   http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    import QtQuick 2.2
    import QtQuick.Controls 1.1
    import QtQuick.Window 2.0
    import QtQml.Models 2.1
    import QtQml.Models 2.1
    
    ApplicationWindow {
        title: qsTr("DelegateModel Sample 2")
        width: 640
        height: 600
        visible: true
        menuBar: MenuBar {
            Menu {
                title: qsTr("File")
                MenuItem {
                    text: qsTr("Exit")
                    onTriggered: Qt.quit();
                }
            }
        }
    
        Item {
            id: root
            anchors.fill: parent
            readonly property int rowHeight: 25
    
            DelegateModel {
                id: detailsDelegateModel
                delegate: detailsDelegate
                model: MyModel // This is a root context set in the main.cpp file.
                groups: [
                    DelegateModelGroup {
                        includeByDefault: false
                        name: "detailsField"
                    }
                ]
                filterOnGroup: "detailsField"
                Component.onCompleted: {
                    var rowCount = MyModel.count;
                    items.remove(0,rowCount);
                    for( var i = 0;i < rowCount;i++ )
                    {
                        var entry = MyModel.get(i);
                        if(entry.role_details !== undefined) {
                            items.insert(entry, "detailsField");
                        }
                    }
                }
            }
            Component {
                id: detailsDelegate
    
                Rectangle {
                    anchors.left: parent.left
                    anchors.right: parent.right
                    height: root.rowHeight
                    color: "yellow"
                    border.color: "black"
    
                    Text {
                        text: role_details
                        anchors.centerIn: parent
                    }
                }
            }
            DelegateModel {
                id: displayDelegateModel
                delegate: displayDelegate
                model: MyModel
                groups: [
                    DelegateModelGroup {
                        includeByDefault: false
                        name: "displayField"
                    }
                ]
                filterOnGroup: "displayField"
                Component.onCompleted: {
                    var rowCount = MyModel.count;
                    items.remove(0,rowCount);
                    for(var i = 0;i < rowCount;i++)
                    {
                        var entry = MyModel.get(i);
                        if(entry.role_display !== undefined){
                            items.insert(entry, "displayField");
                        }
                    }
                }
            }
            Component{
                id: displayDelegate
    
                Rectangle {
                    anchors.left: parent.left
                    anchors.right: parent.right
                    height: root.rowHeight
                    color: "green"
                    border.color: "black"
    
                    Text {
                        text: role_display
                        anchors.centerIn: parent
                    }
                }
            }
            DelegateModel {
                id: evenValueDelegateModel
                delegate: valueDelegate
                model: MyModel
                groups: [
                    DelegateModelGroup {
                        includeByDefault: false
                        name: "evenNumbers"
                    }
                ]
                filterOnGroup: "evenNumbers"
                Component.onCompleted: {
                    var rowCount = MyModel.count;
                    items.remove(0,rowCount);
                    for( var i = 0;i < rowCount;i++ )
                    {
                        if ( MyModel.isEven(i) ) {
                            items.insert(MyModel.get(i), "evenNumbers");
                        }
                    }
                }
            }
            Component{
                id: valueDelegate
    
                Rectangle {
                    anchors.left: parent.left
                    anchors.right: parent.right
                    height: root.rowHeight
                    color: "lightblue"
                    border.color: "black"
    
                    Text {
                        text: role_value
                        anchors.centerIn: parent
                    }
                }
            }
            Column{
                id: theColumn
                anchors.left: parent.left
                anchors.right: parent.right
                anchors.top: parent.top
                anchors.margins: 10
                height: childrenRect.height
                spacing: 0
    
                Text {
                    anchors.horizontalCenter: parent.horizontalCenter
                    width: 600
                    wrapMode: Text.WordWrap
                    text: "In this example we have a single model with 12 entries and via a Delegate Model Group we are filtering that data so that we can display a sub-set of it in different ListViews"
                }
                Item { width: 20; height: 20; }
                Text {
                    text: "In this List View we are only showing the entries that have a details role."
                }
                ListView {
                    id: detailsListView
                    anchors.left: parent.left
                    anchors.right: parent.right
                    height: root.rowHeight * 5
                    model: detailsDelegateModel
                }
                Item { width: 20; height: 20; }
                Text {
                    text: "In this List View we are only showing the entries that have a display role."
                }
                ListView {
                    id: displayListView
                    anchors.left: parent.left
                    anchors.right: parent.right
                    height: root.rowHeight * 4
                    model: displayDelegateModel
                }
                Item { width: 20; height: 20; }
                Text {
                    text: "In this List View we are only showing the entries whose value are even."
                }
                ListView {
                    id: evenValueListView
                    anchors.left: parent.left
                    anchors.right: parent.right
                    height: root.rowHeight * 7
                    model: evenValueDelegateModel
                }
            }
        }
    }
    
    /*
    *版权所有2014想象思维
    *
    *根据Apache许可证2.0版(以下简称“许可证”)获得许可;
    *除非遵守许可证,否则不得使用此文件。
    *您可以通过以下方式获得许可证副本:
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    *除非适用法律要求或书面同意,软件
    *根据许可证进行的分发是按“原样”进行分发的,
    *无任何明示或暗示的保证或条件。
    *请参阅许可证以了解管理权限和权限的特定语言
    *许可证下的限制。
    */
    导入QtQuick 2.2
    导入QtQuick.Controls 1.1
    导入QtQuick.Window 2.0
    导入qtl.Models 2.1
    导入qtl.Models 2.1
    应用程序窗口{
    标题:qsTr(“委托模型样本2”)
    宽度:640
    身高:600
    可见:正确
    菜单栏:菜单栏{
    菜单{
    标题:qsTr(“文件”)
    梅努伊特姆{
    文本:qsTr(“退出”)
    onTriggered:Qt.quit();
    }
    }
    }
    项目{
    id:根
    锚定。填充:父级
    只读属性int行高:25
    委托模型{
    id:detailsDelegateModel
    代表:详情代表
    model:MyModel//这是main.cpp文件中的根上下文集。
    小组:[
    委派模型组{
    includeByDefault:false
    名称:“详细信息字段”
    }
    ]
    过滤器组:“详细信息字段”
    Component.onCompleted:{
    var rowCount=MyModel.count;
    删除(0,行计数);
    对于(变量i=0;i/*
     * Copyright 2014 ImaginativeThinking
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *   http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    import QtQuick 2.2
    import QtQuick.Controls 1.1
    import QtQuick.Window 2.0
    import QtQml.Models 2.1
    import QtQml.Models 2.1
    
    ApplicationWindow {
        title: qsTr("DelegateModel Sample 2")
        width: 640
        height: 600
        visible: true
        menuBar: MenuBar {
            Menu {
                title: qsTr("File")
                MenuItem {
                    text: qsTr("Exit")
                    onTriggered: Qt.quit();
                }
            }
        }
    
        Item {
            id: root
            anchors.fill: parent
            readonly property int rowHeight: 25
    
            DelegateModel {
                id: detailsDelegateModel
                delegate: detailsDelegate
                model: MyModel // This is a root context set in the main.cpp file.
                groups: [
                    DelegateModelGroup {
                        includeByDefault: false
                        name: "detailsField"
                    }
                ]
                filterOnGroup: "detailsField"
                Component.onCompleted: {
                    var rowCount = MyModel.count;
                    items.remove(0,rowCount);
                    for( var i = 0;i < rowCount;i++ )
                    {
                        var entry = MyModel.get(i);
                        if(entry.role_details !== undefined) {
                            items.insert(entry, "detailsField");
                        }
                    }
                }
            }
            Component {
                id: detailsDelegate
    
                Rectangle {
                    anchors.left: parent.left
                    anchors.right: parent.right
                    height: root.rowHeight
                    color: "yellow"
                    border.color: "black"
    
                    Text {
                        text: role_details
                        anchors.centerIn: parent
                    }
                }
            }
            DelegateModel {
                id: displayDelegateModel
                delegate: displayDelegate
                model: MyModel
                groups: [
                    DelegateModelGroup {
                        includeByDefault: false
                        name: "displayField"
                    }
                ]
                filterOnGroup: "displayField"
                Component.onCompleted: {
                    var rowCount = MyModel.count;
                    items.remove(0,rowCount);
                    for(var i = 0;i < rowCount;i++)
                    {
                        var entry = MyModel.get(i);
                        if(entry.role_display !== undefined){
                            items.insert(entry, "displayField");
                        }
                    }
                }
            }
            Component{
                id: displayDelegate
    
                Rectangle {
                    anchors.left: parent.left
                    anchors.right: parent.right
                    height: root.rowHeight
                    color: "green"
                    border.color: "black"
    
                    Text {
                        text: role_display
                        anchors.centerIn: parent
                    }
                }
            }
            DelegateModel {
                id: evenValueDelegateModel
                delegate: valueDelegate
                model: MyModel
                groups: [
                    DelegateModelGroup {
                        includeByDefault: false
                        name: "evenNumbers"
                    }
                ]
                filterOnGroup: "evenNumbers"
                Component.onCompleted: {
                    var rowCount = MyModel.count;
                    items.remove(0,rowCount);
                    for( var i = 0;i < rowCount;i++ )
                    {
                        if ( MyModel.isEven(i) ) {
                            items.insert(MyModel.get(i), "evenNumbers");
                        }
                    }
                }
            }
            Component{
                id: valueDelegate
    
                Rectangle {
                    anchors.left: parent.left
                    anchors.right: parent.right
                    height: root.rowHeight
                    color: "lightblue"
                    border.color: "black"
    
                    Text {
                        text: role_value
                        anchors.centerIn: parent
                    }
                }
            }
            Column{
                id: theColumn
                anchors.left: parent.left
                anchors.right: parent.right
                anchors.top: parent.top
                anchors.margins: 10
                height: childrenRect.height
                spacing: 0
    
                Text {
                    anchors.horizontalCenter: parent.horizontalCenter
                    width: 600
                    wrapMode: Text.WordWrap
                    text: "In this example we have a single model with 12 entries and via a Delegate Model Group we are filtering that data so that we can display a sub-set of it in different ListViews"
                }
                Item { width: 20; height: 20; }
                Text {
                    text: "In this List View we are only showing the entries that have a details role."
                }
                ListView {
                    id: detailsListView
                    anchors.left: parent.left
                    anchors.right: parent.right
                    height: root.rowHeight * 5
                    model: detailsDelegateModel
                }
                Item { width: 20; height: 20; }
                Text {
                    text: "In this List View we are only showing the entries that have a display role."
                }
                ListView {
                    id: displayListView
                    anchors.left: parent.left
                    anchors.right: parent.right
                    height: root.rowHeight * 4
                    model: displayDelegateModel
                }
                Item { width: 20; height: 20; }
                Text {
                    text: "In this List View we are only showing the entries whose value are even."
                }
                ListView {
                    id: evenValueListView
                    anchors.left: parent.left
                    anchors.right: parent.right
                    height: root.rowHeight * 7
                    model: evenValueDelegateModel
                }
            }
        }
    }
    
    /*
     * Copyright 2014 ImaginativeThinking
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *   http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    #ifndef MYVIEWMODEL_H
    #define MYVIEWMODEL_H
    
    #include <QStandardItemModel>
    #include <QObject>
    
    class MyViewModel : public QStandardItemModel
    {
        Q_OBJECT
        Q_PROPERTY( int count READ getRowCount() NOTIFY rowCountChanged() )
    
    public:
        /**
         * @brief Defines a list of application-specific roles particually related to this view model's data model.
         *
         * Each item in the view model has a set of data elements associated with it, each with its own role.
         * Roles are used by the view to indicate to the view model which type of data it needs.  The roles
         * defined in this enum are specific to this view models data model.
         * @see <a href="http://qt-project.org/doc/qt-5.0/qtcore/qt.html#ItemDataRole-enum" style="font-weight:bold;">Qt::ItemDataRole</a>
         */
        enum MyViewModel_Roles
        {
            MyViewModel_Roles_Display = Qt::UserRole + 1,   /**< This role holds the display string for an entry in the model. */
            MyViewModel_Roles_Details,                      /**< This role holds the details string for an entry in the model. **/
            MyViewModel_Roles_KeyId,                        /**< This role holds the key id for an entry in the model. **/
            MyViewModel_Roles_Value,                        /**< This role holds the value for an entry in the model. **/
        };
    
        /**
         * @brief MyViewModel is the Constructor that will create an instance of this class
         */
        MyViewModel();
    
        /**
         * @brief ~MyViewModel is the destructor that will clean up this object when its not needed anymore.
         */
        virtual ~MyViewModel();
    
        /**
         * @brief Initializes the ViewModel and populates it with data
         */
        void initialize();
    
        /**
         * @return A collection of the view models role names.
         * @see MenuRoles
         * @see <a href="http://qt-project.org/doc/qt-5.0/qtcore/qabstractitemmodel.html#roleNames" style="font-weight:bold;">QAbstractItemModel</a>
         */
        virtual QHash<int,QByteArray> roleNames() const;
    
        /**
         * @param rowNumber is the index within the model for the item we want to check.
         * @return Returns true if the entry's value role holds an even number.
         */
        Q_INVOKABLE bool isEven( int rowNumber );
    
        /**
         * @param rowNumber specifies which row within the model the item we want to check is located.
         * @return Returns a map that holds all the attributes about the item using the role names as the key.
         * @note The return value is a key/value pair where the keys are available in QML so we can
         * use the returned object to get any of the role information about the data (e.g. returnObject.role_display)
         */
        Q_INVOKABLE QVariantMap get( int rowNumber ) const;
    
    signals:
    
        /**
         * @brief rowCountChanged is emitted whenever the row count changes
         */
        void rowCountChanged();
    
    private slots:
        /**
         * @return Returns the number of rows in the model
         */
        int getRowCount();
    
    };
    
    #endif // MYVIEWMODEL_H
    
    #include "MyViewModel.h"
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    MyViewModel::MyViewModel()
    {
    }
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    MyViewModel::~MyViewModel()
    {
        this->clear();
    }
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    QHash<int,QByteArray> MyViewModel::roleNames() const
    {
        // Maps the role names used in the QML to the role name enum used in the code behind.
    
        QHash<int, QByteArray> roles;
        roles[MyViewModel_Roles_Display] = "role_display";
        roles[MyViewModel_Roles_Details] = "role_details";
        roles[MyViewModel_Roles_KeyId] = "role_keyid";
        roles[MyViewModel_Roles_Value] = "role_value";
    
        return roles;
    }
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    void MyViewModel::initialize()
    {
        auto root = this->invisibleRootItem();
    
        QStandardItem* entry = new QStandardItem();
        entry->setData("One", MyViewModel_Roles_Display );
        entry->setData(0, MyViewModel_Roles_Value );
        root->appendRow(entry);
    
        entry = new QStandardItem();
        entry->setData("One", MyViewModel_Roles_Display );
        entry->setData(2, MyViewModel_Roles_Value );
        root->appendRow(entry);
    
        entry = new QStandardItem();
        entry->setData("One", MyViewModel_Roles_Display );
        entry->setData(3, MyViewModel_Roles_Value );
        root->appendRow(entry);
    
        entry = new QStandardItem();
        entry->setData("One", MyViewModel_Roles_Display );
        entry->setData(4, MyViewModel_Roles_Value );
        root->appendRow(entry);
    
        entry = new QStandardItem();
        entry->setData("Two", MyViewModel_Roles_Details );
        entry->setData(5, MyViewModel_Roles_Value );
        root->appendRow(entry);
    
        entry = new QStandardItem();
        entry->setData("Three", MyViewModel_Roles_Details );
        entry->setData(6, MyViewModel_Roles_Value );
        root->appendRow(entry);
    
        entry = new QStandardItem();
        entry->setData("Four", MyViewModel_Roles_Details );
        entry->setData(7, MyViewModel_Roles_Value );
        root->appendRow(entry);
    
        entry = new QStandardItem();
        entry->setData("Five", MyViewModel_Roles_Details );
        entry->setData(8, MyViewModel_Roles_Value );
        root->appendRow(entry);
    
        entry = new QStandardItem();
        entry->setData("Six", MyViewModel_Roles_Details );
        entry->setData(9, MyViewModel_Roles_Value );
        root->appendRow(entry);
    
        entry = new QStandardItem();
        entry->setData("Seven", MyViewModel_Roles_KeyId );
        entry->setData(10, MyViewModel_Roles_Value );
        root->appendRow(entry);
    
        entry = new QStandardItem();
        entry->setData("Eight", MyViewModel_Roles_KeyId );
        entry->setData(11, MyViewModel_Roles_Value );
        root->appendRow(entry);
    
        entry = new QStandardItem();
        entry->setData("hello", MyViewModel_Roles_KeyId );
        entry->setData(12, MyViewModel_Roles_Value );
        root->appendRow(entry);
    
        emit rowCountChanged();
    }
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    int MyViewModel::getRowCount()
    {
        return this->rowCount();
    }
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    bool MyViewModel::isEven(int rowNumber)
    {
        bool ret( false );
        if ( this->invisibleRootItem() != nullptr )
        {
            if ( this->invisibleRootItem()->rowCount() > rowNumber )
            {
                auto entry = this->invisibleRootItem()->child( rowNumber );
                bool ok( false );
                auto value = entry->data( MyViewModel_Roles::MyViewModel_Roles_Value ).toInt( &ok );
                if ( ok )
                {
                    if ( ( value % 2) == 0 )
                    {
                        ret = true;
                    }
                }
            }
        }
        return ret;
    }
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    QVariantMap MyViewModel::get( int rowNumber ) const
    {
        // Create a map to hold all the role information about the data item in question
        // Use the role names as the keys for the map so that the same referances can be
        // used in the QML to get the data (i.e. role_display, role_value).
        QVariantMap map;
        QHash<int,QByteArray> roleName = roleNames();
        foreach (int i, roleName.keys())
        {
            map[roleName.value(i)] = data( index( rowNumber,0 ), i );
        }
        return map;
    }