How to create a Tree of abstract object instances?



  • Hi,

    I have an abstract class, Foo, that has two properties; Name and Type. Name is populated in the constructor with a random hash (placeholder) and Type is hardcoded in any implementation of Foo.

    What I would like is to have a QTreeView that displays the Name and Type of each Foo instance.
    I would like the view to support internal drag and drop (to reorganise the tree), Copy/Paste and Undo/Redo.

    My efforts so far are the result of pulling apart the tree demo and tying together the display columns with the Foo object (Bar implements Foo):

    Model:
    @
    TreeNode *TreeModel::getNode(const QModelIndex &index) const
    {
    if(index.isValid()) {
    TreeNode item = static_cast<TreeNode>(index.internalPointer());
    if(item) {
    return item;
    }
    }
    return m_rootItem;
    }

    bool TreeModel::setFoo(Foo * foo, int row, const QModelIndex &parent)
    {
    bool result = false;
    QModelIndex i = index(row, 0, parent);
    TreeNode node = getNode(i);
    result = node->setFoo(QVariant::fromValue<Foo
    >(foo));
    return result;
    }

    QVariant TreeModel::data(const QModelIndex &index, int role) const
    {
    QVariant result = QVariant();
    if(index.isValid()) {
    if(role == Qt::DisplayRole || role == Qt::EditRole) {
    TreeNode *node = getNode(index);
    switch(column)
    {
    case TreeModel::NameColumn:
    result = node->getName();
    break;
    case TreeModel::TypeColumn:
    result = node->getType();
    break;
    }
    }
    }
    return result;
    }
    @

    TreeNode:
    @
    bool TreeNode::setFoo(const QVariant &value)
    {
    m_foo_instance = value.value<Foo *>();
    return true;
    }

    QVariant TreeNode::getName() const
    {
    Q_ASSERT(m_foo_instance);
    return QVariant(m_foo_instance->Name());
    }

    QVariant TreeNode::getType() const
    {
    Q_ASSERT(m_foo_instance);
    return QVariant(m_foo_instance->Type());
    }
    @

    Adding a node to the tree:
    @
    int row = model->rowCount(parent);
    model->insertRow(row, parent);
    model->setFoo(new Bar(), row, parent);
    @

    This all works but things got complicated with drag and drop when I needed to add mimeData. The only solution I could think of was to have a hash somewhere with all the Foo instances and create QMimeData from the key value. Just seems overkill when all I want to do is change the parent value of TreeNode.

    Alternatively I have exactly what I want when I use QTreeWidget (with drag/drop) but adding Undo/Redo and Copy/Paste is proving tricky.

    Am I going about this the right way?
    Is there a better way to 'have a tree of objects'?
    Would I be better of adding copy/paste/undo/redo to the QTreeWidget?

    Any help or advice would be greatly appreciated.

    Thanks



  • Abstract classes cannot be instantiated, so it is technically impossible to create a tree out of such.



  • Thanks for the reply.

    I understand what you are saying but I am dealing with instances that implement the abstract class. The code above works, so far as creating items in a QTreeItemView, I was just wondering if there is a better way that would allow easy addition of Copy/Paste and Undo/Redo.

    The class Bar in the above code implements Foo which you can see being instantiated in the last few lines.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.