hi
ich hab ein kleines graph programm bei dem knoten als QGraphicsItem auf einer QGrahpicsView dargestellt sind. Zwischen den knoten soll man über rechts-klick drag&drop kanten einfügen können. d.h. konkret ich hab ein knoten objekt vom typ QGraphicsView, das einerseits dragable sein soll und andererseit drop events empfangen soll. meine funktion um kanten zu machen empfängt 2 pointer auf die beiden knoten (new Edge(node1, node2)). im drop event sollte das ganze jetzt etwa so aussehen:
new Edge(event->source(), this);
leider ist event->source() vom typ QWidget * und ich hab keinen weg gefunden das auf QGraphicsItem zu casten. Normale C++ static_cast und dynamic_cast funktionieren auch nicht. gibts hier ne möglichkeit den cast auszuführen?
ich hab dann versucht setFocusItem() dort zu setzen wo drag->start() gemacht wird und scene()->focusItem im drop event um die source zu kriegen. leider is im QGraphicsItem scene() nicht definiert. ich hab aber nen member auf die parent view (QGraphicsView *). diese sollte ja dann scene() haben. auf den aufruf graph->scene() krieg ich alle member von graph, die ich selbst implementiert habe, aber keine von QGraphicsView (ich mache public inheritance), also is auch scene() nicht da.
hat irgendjemand ne idee wie ich das machen kann? am liebsten natürlich über nen einfachen cast auf einen member von event, wie zuerst versucht, das wär code mässig einfach das sauberste.
danke!
drop event source in QGraphicsItem
sorry, is wohl etwas kryptisch beschrieben. also hier is mal die funktion um die es geht:
void DrawNode::dropEvent(QGraphicsSceneDragDropEvent *event)
{
QList<QGraphicsItem *> sel = scene()->selectedItems();
QGraphicsItem *item = sel.at(0);
//QGraphicsItem *item = scene()->focusItem();
DrawNode *otherNode = qgraphicsitem_cast<DrawNode *>(item);
if (otherNode != NULL && otherNode != this)
{
scene()->addItem(new Edge(otherNode, this));
}
update();
}
anstatt das ganze über selectedItems zu machen, würd ich eigentlich lieber den anderen knoten aus dem event pointer kriegen. der drag wird so gestartet:
void
DrawNode::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
update();
QGraphicsItem::mousePressEvent(event);
if (event->button() == Qt::RightButton)
{
QDrag *drag = new QDrag(event->widget());
QMimeData *mime = new QMimeData;
drag->setMimeData(mime);
this->setSelected(true);
//scene()->setFocusItem(this, Qt::MouseFocusReason);
drag->start();
}
}
beide funktionen werden in DrawNode definiert, welches vom Typ QGraphicsItem ist. das ganze macht also einen drag&drop von einem DrawNode zu einem anderen DrawNode (und erstellt dann ein Edge zwischen den beiden).
void DrawNode::dropEvent(QGraphicsSceneDragDropEvent *event)
{
QList<QGraphicsItem *> sel = scene()->selectedItems();
QGraphicsItem *item = sel.at(0);
//QGraphicsItem *item = scene()->focusItem();
DrawNode *otherNode = qgraphicsitem_cast<DrawNode *>(item);
if (otherNode != NULL && otherNode != this)
{
scene()->addItem(new Edge(otherNode, this));
}
update();
}
anstatt das ganze über selectedItems zu machen, würd ich eigentlich lieber den anderen knoten aus dem event pointer kriegen. der drag wird so gestartet:
void
DrawNode::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
update();
QGraphicsItem::mousePressEvent(event);
if (event->button() == Qt::RightButton)
{
QDrag *drag = new QDrag(event->widget());
QMimeData *mime = new QMimeData;
drag->setMimeData(mime);
this->setSelected(true);
//scene()->setFocusItem(this, Qt::MouseFocusReason);
drag->start();
}
}
beide funktionen werden in DrawNode definiert, welches vom Typ QGraphicsItem ist. das ganze macht also einen drag&drop von einem DrawNode zu einem anderen DrawNode (und erstellt dann ein Edge zwischen den beiden).
Es wird dir auch nichts bringen, das QWidget vom QDrag auszuwerten, da das QWidget immer auf die gesamte Scene bezogen ist und nicht auf ein einzelnes Item. Aber du könntest bei QMimeData als zusätzliche Daten eine ID (event. sogar einen Pointer) vom Quell-Item mitgeben und diese beim Drop dann auswerten?