首页 文章

如何在QML ListView和Grid之间共享模型的项目

提问于
浏览
-1

我想知道在QML中实现以下内容的最佳方法:

我有一个带有可放置元素的 ListView 和一个填充了 DropAreaGrid . ListView使用从 QAbstractItemModel 派生的模型 . 我想在网格上放一个元素并与之交互(例如重命名) . 目前,ListView中的任何修改都会更新模型,但网格中元素的修改如何更新模型?

可以在网格中删除与ListView模型的子集相对应的多个项目 . 我不知道如何实现这一目标 . 无法使用 Package ,因为Grid不是GridView,必须在特定位置移动/设置Items . 所以我试着:

  • 创建一个显示在已删除项目上的ListView,使用与用于拖动项目的源ListView相同的模型,

  • 设置相同的rootIndex,然后设置相同的索引

我接近解决方案,但我认为这不是最好的方法 .

任何线索?

谢谢

2 回答

  • 0

    我希望在ListView和Grid中的组件中具有相同模型项的不同视觉表示 . 因此,对ListView中项目的修改应更新网格中的项目,反之亦然 .

    如果模型的数据不是 NOTIFY 和属性派生的,则只能通过模型进行更改通知 .

    由于您不会将该模型用于网格,这意味着您的模型必须使用基础 QObject 实例 . A generic model object可能会派上用场 .

    如果有,只需要引用基础 QObject 模型项并使用绑定来设置列表视图委托 . 然后,当您拖放时,您只需要将对 QObject 的引用传递给您将在网格内创建的其他可视表示 .

    最后,当您从模型中删除项目时,请注意不要留下悬空引用,因为这很可能会使您的应用程序崩溃 . 当模型项目对象被销毁时,使用 onDestruction 附加信号清除网格中的元素 .

  • 0

    我终于通过创建一个继承自QObject的C类型找到了一个解决方案,它可以嵌入到QML对象中 . 此类型具有读/写属性,并使用与ListView相同的模型进行初始化 . 有趣的方法是:

    /* writing to a property **from QML** goes here */
    void ModelItem::setName(const QString& name)
    {
        setModelData(GroupMemberModel::Nom, name);
    }
    /* then here */
    bool ModelItem::setModelData(GroupMemberModel::Role role, const QVariant& value)
    {
        return m_model->setData(m_modelIndex, value, role);
    }
    
    /* any changes in the model fall here (signals/slots mecanism)*/
    void ModelItem::dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector<int>& roles)
    {
        if(m_modelIndex.row() < topLeft.row() || m_modelIndex.row() > bottomRight.row())
            return;
        if(m_modelIndex.column() < topLeft.column() || m_modelIndex.column() > bottomRight.column())
            return;
        //Index is modified, emit signal
        foreach(int role, roles) {
            emitDataChanged(role);
        }
    }
    /* **notify QML** by emit signal on property */
    void ModelItem::emitDataChanged(int role) const
    {
        if(role < (Qt::UserRole+1))
            role+=Qt::UserRole+1;
    
        switch(role)
        {
        case GroupMemberModel::Nom:
            emit nameChanged();
            break;
        default:
            qDebug() << "ModelItem::dataChanged, unknown role";
            break;
        }
    }
    

    这可以根据需要工作,比我想象的更简单 .

相关问题