I am having a boost graph of a design. Traversing through boost graph, I am getting co-ordinates of rectangle and polylines. Through that co-ordinates I am drawing rectangle and polyline on QGraphicsView.
Now I want to select rectangle/polyline through scene with mouse click and should be able to print it's name and other property. It's name and other properties are in the boost graph node. But I dont want to interact boost graph again.
So when I was drawing rectangle/polyline through boost graph co-ordinates, I should be able to store some pointer of boost graph node on rectangle/polyline so when I will click on rectangle/polyline, then through that pointer I can access it's name and other properties.
Question is Is this possible ?
I tried but got run time errors.
one of the boost graph class.
class schVertexProps
{
public:
explicit schVertexProps(std::string moduleName = "",std::string name = "",
SCH_VERTEX_TYPE type = SCH_VERTEX_TYPE::SCH_INST_VERTEX,
long crossRefPtr = 0,int vertexLevel = -1,int xPos = 0.0,
int yPos = 0.0,schSymbol* symb = nullptr)
: _moduleName(moduleName),
_name(name),
_type(type),
_crossRefPtr(crossRefPtr),
_vertexLevel(vertexLevel),
_xPos(xPos),
_yPos(yPos),
_symb(symb){
};
Among all above parameters, I want to store only _crossRefPtr ( it is basically a pointer, but store as long
, while using it will be type cast )
rect = new guiSchematicRect();
while(true)
{
// traversing through boost graph
for(auto iter = verts.begin();iter != verts.end(); iter)
{
// getting co-ordinates of rectangle
QGraphicsRectItem* rectItem = rect->createRect(co-ordinates of rectangle);
rect->_boostRefPtr = iter->_crossRefPtr; // trying to store _crossRefPtr
}
// code somewhat similar for polyline
}
guiSchematicRect.h
class guiSchematicRect : public QGraphicsRectItem
{
........
QGraphicsRectItem* createRect(QRectF& rect);
long _boostRefPtr;
}
And when I will click on rectangle on scene through mouse I am doing like this:
if(_scene->selectedItems().count() != 0)
{
foreach(QGraphicsItem* currentItem, _scene->selectedItems())
{
QGraphicsRectItem* rItem = qgraphicsitem_cast<QGraphicsRectItem*>(currentItem);
if(rItem)
{
guiSchematicRect* r = reinterpret_cast<guiSchematicRect*>(rItem);
if(r)
{
// I am assuming _boostRefPtr has address of Instance (rectangle)
Instance* i = reinterpret_cast<Instance*>(r->_boostRefPtr);
qDebug()<< i->Name();
}
}
But aobve way is wrong. Getting run time errors ( Showing Verbose stack trace)
So the question is :
How to store pointer on QGraphicsItem so that, once they get selected, that pointer will be accessed ?
CodePudding user response:
Use Qt's dynamic properties, check QObject::setProperty
. It should do the trick.
But AFAIC, I would have used a double QMap
to associate directly <graph_node, QGraphicsItem>
AND <QGraphicsItem, graph_node>
- so you can search quickly for both associations, and both in O(log2(n)) complexity. You can store this either as a static part of your graph (better) or standalone (not the best idea). Obviously, if your graph is already in O(log2(n)), you don't need this map and you need only the <QGraphicsItem, graph_node>
one.