Resurrection
Resurrection

Reputation: 4106

Storing two different types in QModelIndex

I have a graph represented by Nodes and Edges and I have written an adaptor so I can view the graph in a tabular form using Qt standard views like so:

Node1
   -Edge1
       -Node2
   -Edge2
       -Node3
   -Edge3
       -Node1
Node2
Node3
   -Edge4
       -Node1

I did it making use of the overloads for QAbstractItemModel::createIndex to store either an index position (quintptr overload) or pointer to correct item (void* overload). However that was foolish because it does not actually matter what overload one uses there is always just one value that is just converted for both QModelIndex::internalPointer() and QModelIndex::internalID(). Needless to say it creates conflicts that crashes the model under certain circumstances which is how I found out it was a bad idea.

Now I cannot figure out what to store as a third variable in the QModelIndex so that I could distinguish between:

1) Index points to an edge under some node

2) Index points to a node under some edge

The empty value is currently being "used" to identify top level nodes. What should I store in these two cases to reliably identify the parent? Is there even a way to store two different "things" (other than "nothing" and "one type of something") in the QModelIndex?

Upvotes: 0

Views: 340

Answers (2)

hmuelner
hmuelner

Reputation: 8221

Check out QVariant and (maybe) qRegisterMetaType.

Upvotes: 0

Tomas
Tomas

Reputation: 2210

Create your graph as a separated data structure. Your node and edge objects will have an unique ID. And than use this ID inside the QModelIndex.

Edit 1: How to distinguish node from edge.

class CGraphElement
{
public:
    enum Type
    {
        Node,
        Edge
    }

    CGraphElement(Type type) : m_type(type) {}

    bool isNode() const { return m_type == Node; }
    bool isEdge() const { return m_type == Edge; }

private:
    Type m_type;

};

// container mapping ID to graph Element (Node or Edge)
std::map<int, CGraphElement> mapId2Element;

void functionDealingWithModelIndex(const QModelIndex & index)
{
    int id = index.internalID();
    CGraphElement* element = mapId2Element[id];
    if (element->isEdge())
        qDebug() << "Edge";
    else if (element->isNode())
        qDebug() << "Node";
}

Upvotes: 1

Related Questions