Question

I'm using QTreeView to show some data to the user. What I want is to attach an actual object to each node represented using QStandardItem.

To save the object reference into QStandardItem:

QStandardItem *child = new QStandardItem(s);
child->setFlags(child->flags() & ~Qt::ItemIsEditable);
child->setData(QVariant(QVariant::UserType, i), Qt::UserRole + 10);

To access the actual object when it is clicked in the UI:

void MyOtherClass::handleTreeViewSelectionChanged(const QModelIndex &i)
{
     MyClass* o = i.data(Qt::UserRole + 10).value<MyClass*>();
     // do other stuff with o
}

The above call just returns NULL. Anybody knows how to deal with such a requirement?

I found absolutely nothing useful on the web.

Any help would be highly appreciated.

Was it helpful?

Solution

To store your item in the QStandardItem you need to make sure that you've registered your type with QMetaType. For example, you might have this definition:

class MyType
{
public:
    MyType() : m_data(0) {}
    int someMethod() const { return m_data; }

private:
    int m_data;
};

Q_DECLARE_METATYPE(MyType*);  // notice that I've declared this for a POINTER to your type

Then you would store it into a QVariant like so:

MyType *object = new MyType;
QVariant variant;
variant.setValue(object);

Given a properly registered metatype for your type, you can now do something like this with your QStandardItems:

MyType *object = new MyType;
QStandardItemModel model;
QStandardItem *parentItem = model.invisibleRootItem();
QStandardItem *item = new QStandardItem;
item->setData(QVariant::fromValue(myType));  // this defaults to Qt::UserRole + 1
parentItem->appendRow(item);

And then later extract it:

void MyOtherClass::handleTreeViewSelectionChanged(const QModelIndex &i)
{
     MyType* o = i.data(Qt::UserRole + 1).value<MyType*>();
     // do other stuff with o
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top