PDA

View Full Version : How to communicate btw QGraphicsScene and QTreeWidget



Cal
20th November 2009, 02:56
Hey,

i wanna know whats the best way to communicate between a QGraphicScene and a QTreeWidget.

I have a QTreeWidget containing some QTreeWidgetItems and a QGraphicsView containing some QGraphicsItems, representing the positions of the items shown in the QTreeWidget.

What i want to do: if you select an item in the TreeView, the corresponding GraphicsItem in the GraphicsView should be selected. and the other way around: select an item in the graphics view and the corresponding QTreeWidgetItem should be highlighted.

I created a class which inherits both QGraphicItem and QTreeWidgetItem, but i couldnt figure out how to connect the view and the treewidget properly.

Maybe you have some ideas?

Greetings,
Lutz

yogeshgokul
20th November 2009, 06:04
Hey,

i wanna know whats the best way to communicate between a QGraphicScene and a QTreeWidget.

I have a QTreeWidget containing some QTreeWidgetItems and a QGraphicsView containing some QGraphicsItems, representing the positions of the items shown in the QTreeWidget.
What i want to do: if you select an item in the TreeView, the corresponding GraphicsItem in the GraphicsView should be selected. and the other way around: select an item in the graphics view and the corresponding QTreeWidgetItem should be highlighted.
I created a class which inherits both QGraphicItem and QTreeWidgetItem, but i couldnt figure out how to connect the view and the treewidget properly.
Maybe you have some ideas?

SIGNAL AND SLOT. :D
As Qt always says, signals and slots are used for interobject communication.
And here your graphics item and tree widgt are just 2 objects wanna talk to each other. :D

scascio
20th November 2009, 10:27
a QGraphicsItem is not a QObject. So no way to define and connect slots

You have to write your own item derived both from QObject and QGraphicsItem.
Note that QObject must be the first derived object, in order to let the macro Q_OBJECT work well.



class MyItem : public QObject, public QgraphicsItem {
Q_OBJECT
//then you can define slots ready to be connected
public slots:
void mySlot();
};

wysota
20th November 2009, 10:35
a QGraphicsItem is not a QObject. So no way to define and connect slots
But QGraphicsView and QGraphicsScene are objects and that's where one probably wants to place the connections anyway.

Cal
20th November 2009, 12:29
Yeah thats he point, instead of making thousands of connections btw the items and the views i wanted to handle the selection with connections between the QGraphicsView and QTreeWidget.

Selecting an Item in the GraphicsView is easy, just by calling QGraphicsItem::setSelected(true). I simply connect the signal QTreeWidget::currentItemChanged() with this slot function:
(nodes contains all the GraphicItems, table_root is the parent of the QTableWidgetItems)


void changeViewSelection(QTreeWidgetItem *current, QTreeWidgetItem *previous) {
view->scene()->clearSelection();
int c = table_root->indexOfChild(current);
int p = table_root->indexOfChild(previous);
if (c>-1&&c<nodes.size())
nodes[c]->QGraphicsItem::setSelected(true);
if (p>-1&&p<nodes.size())
nodes[p]->QGraphicsItem::setSelected(false);
}



The other way around is more difficult, because i cant figure out the Index of the QGraphicsItems, thats why i cannot call QTreeWidget::SetCurrentItem(). I can get the selected Items of a QGraphicsScene by calling

QList<QGraphicsItem *> list = view->scene()->selectedItems();
but i dont have any idea on which position in my nodes the items belong to. I could figure that out with a for loop testing for equality, but that doesnt seem nice and fast at all...

wysota
20th November 2009, 13:21
Either have a global hash (or event two) to map between objects or have pointers to appropriate graphicsitems in tree items and vice-versa.

scascio
20th November 2009, 14:06
But QGraphicsView and QGraphicsScene are objects and that's where one probably wants to place the connections anyway.

If the need is to manage selection, sure I agree with you. The way Item->View is obvious and for View->Item you need to manage a map of items.

So it depends on the kind of messages you need.
For my own case, I derived my items from QObject because I need to do complex computing when painting item images in an MVC design, that relies on GUI independant processes.

Cal
20th November 2009, 14:53
Either have a global hash (or event two) to map between objects or have pointers to appropriate graphicsitems in tree items and vice-versa.

ah yeah, youre right... a hash table should work.

But the other method (storing the pointers inside the items) sounds even better.
Lets say i derived a new Class "Node" from QGraphicsItem which stores a pointer to the corresponding QTreeWidgetItem. I find out my selected QGraphicsItem by calling view->scene()->selectedItems(), how can i get the stored pointer now? Because this function just returns me items of the base class QGraphicsItem.

What i could do, is to reimplement the setSelected function in my class "Node" and call the QTreeWidget::setCurrentItem() with the stored pointer from there. is that the way to go? cause it doesnt seem to work... isnt the QGraphicsView calling the setSelected() function on an Item, if you click on it in the view (its flag is set to QGraphicsItem::ItemIsSelectable)?

scascio
20th November 2009, 15:38
Since your have got 2 views that are reflecting the selection, is it not better to use a model, and manage some Ids for your items instead of pointers directly?

Then, each view cans have a map of [Id, item] to manage selection.