Storing and accessing a pointer stored in QTreeWidgetItem data
-
I'm thinking about using QTreeWidgetItem data to store and access a pointer. Is this a good idea? Are there any other good out of the box ways to link a Custom QGraphicsItem to it's representation in the form of a QTreeWidgetItem?
When I generate a custom QGraphicsItem, I'm then creating a QTreeWidgetItem to represent that graphics item. I want be able to click on the Tree widget item and then by accessing the pointer change the color of the graphics item to make it stand out from the others.
-
Storing a pointer as a QVariant data is not the nicest thing because you either need to type-erase it to void* or register the type with meta-object system (which admittedly might be already done for QGraphicsItem).
One other way would be to subclass the QTreeWidgetItem and have a typed pointer there.
It sounds that what you have might be a two-directional connection of the QTreeWidgetItem and QGraphicsItem. When you click the graphic item you might also want to select the item in the tree. Having that - an external mapping of the two might be a better idea than storing direct pointers inside. It would also nicely decouple them in sort of a "controller" pattern.
-
Chris,
Thank you for your response. I'm interested in your idea in an external mapping....how would you do that?I did some playing around with storing a QGraphicsItem in a QVariant. QGraphicsItems is not a type with the meta-object system and must be declared. The following seems to function good.
@
//register the QGraphicsItem type
Q_DECLARE_METATYPE(QGraphicsLineItem*)//stuff a QGraphicsItem into a QTreeWidgetItem data
QGraphicsLineItem *lineItem = new QGraphicsLineItem;myTreeWidgetItem->setData(0, Qt::UserRole, QVariant::fromValue<QGraphicsLineItem*>(lineItem));
//Accessing the pointer from QTreeWidgetItem Data
myTreeWidgetItem->data(0, Qt:UserRole).value<QGraphicsLineItem*>()->setLine(100,100,200,200);@
-
Great. If it works for you than it's ok.
I meant a separate object that would hold a "bimap":http://www.boost.org/doc/libs/1_55_0/libs/bimap/doc/html/index.html (or just two maps) of graphics item and tree item. You could subclass QTreeWidget and QGraphicsView to emit a signal with the clicked item and the connected "controller" would update the other side. It may or may not be worth the trouble, depending of how many items you have and how often you use them. One of the benefits is that clearing (or deleting) just one object severs the connection without traversing all the items and clearing data one by one.
-
I think Chris in principle has the right idea. Instead of storing direct pointers back and forth between items in your tree and items in your graphics view, think of both the graphics view and the tree as different views on the same underlying data model. You're displaying a different representation of the same thing. So, instead of the direct pointers, I'd consider making some kind of data store on top of which you build a QGraphicsScene on the one hand, and a QAbstractItemModel on the other, representing the same data. The scene you can display on a QGraphicsView, the model in your QTreeView.