Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

What error causes the Treeview data model QAbstractItemModel replacement method to be unavailable?



  • bool TreeModel::replaceRows(int row, int count, QModelIndex parent)
    {
        if (parent.isValid())
        {
            QModelIndex idxRemove = parent.child(row, 0);
            TreeItem* fiModify    = static_cast<TreeItem*>(idxRemove.internalPointer());
            if (fiModify.child(0, 0).isValid())
            {
                beginRemoveRows(QModelIndex(),row,0);
                removeRows(0, 0, index(row, 0, QModelIndex()));
                endRemoveRows();
                QList<QVariant> TestItem;
                TestItem.append("TestItem");
                TreeItem* TestItem_Item = new TreeItem(TestItem);
                rootItem->replace(row,TestItem_Item);
                dataChanged(index(row,0),index(row,0),{NameEnum});
                return true;
            }
        }
        else
        {
            beginRemoveRows(QModelIndex(), row, 0);
            removeRows(row, 0, index(row, 0, QModelIndex()));
            endRemoveRows();
            QList<QVariant> TestItem;
            TestItem.append("TestItem");
            TreeItem* TestItem_Item = new TreeItem(TestItem);
            rootItem->replace(row,TestItem_Item);
            dataChanged(index(row,0),index(row,0),{NameEnum});
            return true;
        }
        return false;
    }
    


  • @mirro
    Your question reads

    What error causes the Treeview data model QAbstractItemModel replacement method to be unavailable?

    How does this relate to the code you show?



  • @JonB How are dataChanged signals used?Why can't the data be completely replaced.

    The data method is called once when I use the dataChanged signal.

    The data method is called three when I use the beginInsertRows(QModelIndex(), row, row) signal

    class ReaderModel :  public QAbstractListModel
    {
        Q_OBJECT
        Q_PROPERTY(Reader* me READ me WRITE setMe NOTIFY meChanged)
    public:
        enum ReaderRole {
            IdRole = Qt::DisplayRole, //0
            PasswordRole = Qt::UserRole,
            RecordRole
        };
        Q_ENUM(ReaderRole)
    
        ReaderModel(QObject *parent = nullptr){Q_UNUSED(parent);}
    
        int rowCount(const QModelIndex & = QModelIndex()) const;
        QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
        QHash<int, QByteArray> roleNames() const;
    
        Q_INVOKABLE void replace(int row, const QString &id,
                             const QString &password);
    private:
        QList<Reader*> m_readers;
    };
    
    
    QVariant ReaderModel::data(const QModelIndex &index, int role) const
    {
        if(index.row() < rowCount())
            switch(role){
            case IdRole: return m_readers.at(index.row())->id();
            case PasswordRole: return m_readers.at(index.row())->password();
            case RecordRole: return m_readers.at(index.row())->record();
            default: return QVariant();
            }
        return QVariant();
    }
    
    void ReaderModel::replace(int row, const QString &id, const QString &password)
    {
        if (row < 0 || row >= m_readers.count())
            return;
        Reader *r = new Reader(id, password == ""? m_readers[row]->password() : password);
        m_readers.replace(row, r);
        dataChanged(index(row, 0), index(row, 0), { IdRole,PasswordRole});
    }
    


  • @mirro
    Again, I'm sorry, but I just don't know what your question is, what behaviour you expect vs what happens, etc.? Perhaps someone else will understand better than I.

    Just one observation: you seem to be implementing a QAbstractListModel which is editable, so just as you have overridden the data() method I would expect to see you overriding the setData() method.



  • Why are you removing a row? You end up overwriting the next row down? Either remove and add a new row. Or overwrite the existing row. You cannot do both.



  • @JonB When I select a node, How do I traverse the children and sibling node in QML?
    Do I need to add methods to the QAbstractItemModel in C++ ?

    import QtQuick 2.2
    import QtQuick.Controls 1.4
    import QtQml.Models 2.2
    
    ApplicationWindow {
        visible: true
        width: 640
        height: 480
        title: qsTr("File System")
    
        ItemSelectionModel {
            id: sel
            model: fileSystemModel
            onSelectionChanged: {
                console.log("selected", selected)
                console.log("deselected", deselected)
            }
            onCurrentChanged: console.log("current", current)
        }
        TreeView {
            id: view
            anchors.fill: parent
            anchors.margins: 2 * 12
            model: fileSystemModel
            selection: sel
            onCurrentIndexChanged: console.log("current index", currentIndex)
    
            itemDelegate: Rectangle {
                color: ( styleData.row % 2 == 0 ) ? "white" : "lightblue"
                height: 40
                Text {
                    anchors.verticalCenter: parent.verticalCenter
                    anchors.left: parent.left
                    text: styleData.value 
                }
            }
            TableViewColumn {
                title: "Title"
                role: "name"
                resizable: true
            }
            TableViewColumn {
                title: "Summary"
                role: "summary"
                width: view.width/2
            }
            onClicked: console.log("clicked the index is ?", index)
            onDoubleClicked: isExpanded(index) ? collapse(index) : expand(index)
        }
    }
    


  • @fcarney

    HI~What method can I use to traverse the children under the selected node in QML?
    Do I need to add methods to the QAbstractItemModel in C++ ?

    MouseArea{
        OnPressed:{
                 //...
                 if(styleData.depth === 1)
                 {
                          var curIndex = treeView.indexAt(mouse.x,mouse.y)
                 }
        }
    }
    

Log in to reply