1

Based on the QML example treeview given by Qt, how does one clear an entire tree model without destroying the model? Essentially, I want to wipe all of the items/elements from the tree, without destroying the tree itself. The specific code I am using was donated by eyllanesc.

I modified the original code to make *elementFromIndex(...) as Q_INVOKABLE

Within QML, I tried:

elementFromIndex(treemodel.index(0,0))->clear();
elementFromIndex(-1)->clear();

and then realized that QML doesn't understand pointers. So I'm sort of at a loss because of the logic of the tree. I know I essentially need to call something like: myRootItem.clear() but I don't know how to reference the identity of myRootItem. There is not a clear() function within the TreeModel itself, only the TreeElement object.

Complete code example here

TreeElement.h

class TreeElement : public QObject
{
    Q_OBJECT
public:
    Q_PROPERTY(QQmlListProperty<TreeElement> items READ items)
    Q_CLASSINFO("DefaultProperty", "items")
    TreeElement(QObject *parent = Q_NULLPTR);

    Q_INVOKABLE TreeElement *parentItem() const;
    bool insertItem(TreeElement *item, int pos = -1);
    QQmlListProperty<TreeElement> items();

    TreeElement *child(int index) const;
    void clear();

    Q_INVOKABLE int pos() const;
    Q_INVOKABLE int count() const;

private:
    static void appendElement(QQmlListProperty<TreeElement> *property, TreeElement *value);
    static int countElement(QQmlListProperty<TreeElement> *property);
    static void clearElement(QQmlListProperty<TreeElement> *property);
    static TreeElement *atElement(QQmlListProperty<TreeElement> *property, int index);

    QList<TreeElement *> m_childs;
    TreeElement *m_parent;
};

TreeModel.h

class TreeModel : public QAbstractItemModel
{
    Q_OBJECT
public:
    Q_PROPERTY(QQmlListProperty<TreeElement> items READ items)
    Q_PROPERTY(QVariantList roles READ roles WRITE setRoles NOTIFY rolesChanged)
    Q_CLASSINFO("DefaultProperty", "items")

    TreeModel(QObject *parent = Q_NULLPTR);
    ~TreeModel() override;

    QHash<int, QByteArray> roleNames() const Q_DECL_OVERRIDE;
    QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;
    Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE;
    QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
    QModelIndex parent(const QModelIndex &index) const Q_DECL_OVERRIDE;
    int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
    int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
    QQmlListProperty<TreeElement> items();

    QVariantList roles() const;
    void setRoles(const QVariantList &roles);

    Q_INVOKABLE QModelIndex indexFromElement(TreeElement *item);
    Q_INVOKABLE bool insertElement(TreeElement *item, const QModelIndex &parent = QModelIndex(), int pos = -1);

    TreeElement *elementFromIndex(const QModelIndex &index) const;

private:
    TreeElement *m_root;
    QHash<int, QByteArray> m_roles;

signals:
    void rolesChanged();
};
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Tyler M
  • 352
  • 4
  • 21
  • Do you have a cpp side helper class that helps you manage signals from QML? if not, create one and set it as context property, then you can have a placeholder for your model inside that class: `cpp_helper.setModel(&model_passed_to_qml);` and then create a `Q_INVOKABLE` that would do that for you and call it from QML: `cpp_helper_context_prop.clearModel()` and implement the clear in c++ – bardao May 31 '19 at 17:55

0 Answers0