Seite 1 von 1

Event "MouseButtonRelease" verschicken?

Verfasst: 3. August 2010 09:51
von Meiner0815
Morgen

ich hoffe ihr könnt mir helfen.
Folgende Situatuion:

Ich habe mir das Beispiel "DiagramScene" mal nächer angesehen und möchte
es etwas ändern.

Beschreibung: Auf einer "QGraphicsScene" werden verschiedene
"QGraphicsPolygonItem" erstellt, die man mit der Maus bewegen kann.

Änderung:
Ich möchte nun im "MouseMoveEvent" der "QGraphicsPolygonItem" prüfen ob
eine Kollision stattgefunden hat und darauf reagieren. Wenn die
Kollision da ist, möchte ich das das Objekt an der Maus, an eine Pos
setzen und es soll vom MouseCoursor verschwinden. Das Versetzen klapp,
aber ich bekomme das Objekt nicht von der Mouse, was kann ich tun???

Was ich mir vorgestellt hatte war das ich mal ebend ein
"MouseReleaseEvent" an die Scene verschicke und gut ist. ABER scheinbar
empfängt die Scene nicht mein Event und es wird nicht ausgeführt.

Code: Alles auswählen

void DiagramItem::mouseMoveEvent( QGraphicsSceneMouseEvent * event )
{
    // erst das Move ausführen
    QGraphicsPolygonItem::mouseMoveEvent( event);

    // und prüfen
    QList<QGraphicsItem *> list = collidingItems(); //
    if(list.count() > 0)
    {
     // Kollision ist da
     moveBy(10, 10);
     if (MyEvent != NULL)
     {
          delete MyEvent;
          MyEvent= NULL;
     }
     MyEvent= new QMouseEvent(QEvent::MouseButtonRelease, this->pos().toPoint(), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
     QApplication::sendEvent(this->scene(), MyEvent);
     }
}
PS: Wenn ich ein "GraphicsSceneMouseRelease" senden möchte, stürzt das
Programm ab!

Ich habe auch schon dies getestet:

Code: Alles auswählen

bool QGraphicsScene::sendEvent (QGraphicsItem *item, QEvent *event )
aber ohne Erfolg.

mfg
Stephan[/code]

Verfasst: 3. August 2010 10:35
von franzf
uiuiui ^^ im mouseMoveEvent() ein moveBy() (was ja wieder im mouseMoveEvent() endet!) kann zu einer gaaaanz bösen Rekursion werden ^^
Wenn du versuchst, an eine QGraphicsScene ein event zu schicken, das sie nicht bearbeitet, tut sich auch nix.
Wenn es crasht wäre deine Herangehensweise natürlich interessant -> Code.
Desweiteren wäre eine bessere Einrückung wünschenswert.
Und das hier:

Code: Alles auswählen

if(list.count() > 0)
    {
     // Kollision ist da
     moveBy(10, 10);
     if (MyEvent != NULL)
     {
          delete MyEvent;
          MyEvent= NULL;
     }
kann zusammen mit der Rekursion ein gaaaanz doofes Verhalten geben. Es zeugt auch noch von Unwissenheit und ist schlechter Stil :P
1) ein delete obj; wenn obj == NULL macht keine Probleme, delete prüft schon selber auf NULL.
2) Brauchst du hier gar kein auf dem Heap erzeugtes Objekt.

Code: Alles auswählen

QMouseEvent MyEvent(QEvent::MouseButtonRelease, this->pos().toPoint(), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
QApplication::sendEvent(this->scene(), &MyEvent);
Und das Event wird gesendet und danach AUTOMATISCH zerstört.

Am besten produzierst du ein kompilierbares minimales Beispiel (deine Scene, ein paar Items, eine view, eine main) und hängst es hier an.

Verfasst: 3. August 2010 11:04
von Meiner0815
Ok, kein Problem, ist ja ein Beispiel von QT!

anbei das Programm.
und das moveBy hab ich rausgenommen.

Als Reaktion auf moveBy wir eigendlich nur das Objekt bewegt aber nicht der MouseZeiger (MouseZeiger hat die selbe Position), wieso sollte dies in einen MouseMove enden???

freue mich schon auf ein paar Ideen von euch.

mfg
Stephan

Verfasst: 3. August 2010 12:42
von franzf
Meiner0815 hat geschrieben:Als Reaktion auf moveBy wir eigendlich nur das Objekt bewegt aber nicht der MouseZeiger (MouseZeiger hat die selbe Position), wieso sollte dies in einen MouseMove enden???
Stimmt, sry, war wohl ein Schnellschuss... Ich war da irgendwie beim moveEvent.
Der Segfault mit dem QEvent::GraphicsSceneMouseRelease kommt im button() - ist klar, du hast ja keinen gesetzt, überhaupt ist so kein ordentliches QGraphicsSceneMouseEvent-Objekt erstellt. Da du keine Möglichkeiten hast, so ein Event korrekt zu erstellen und dann zu versenden, musst du dir was anderes einfallen lassen. Spontan würde ich sagen, setze im mouseMoveEvent bei Collision einfach das Flag ItemIsMovable auf false. Im mouseReleaseEvent setzt du es wieder auf true.

Verfasst: 4. August 2010 10:46
von Meiner0815
Wen es interessiert :shock:

Code: Alles auswählen

void DiagramItem::mouseMoveEvent( QGraphicsSceneMouseEvent * event )
{
    QGraphicsPolygonItem::mouseMoveEvent( event);

    QList<QGraphicsItem *> list = collidingItems(); //
    if(list.count() > 0)
    {        
        QGraphicsSceneMouseEvent MyEvent(QEvent::GraphicsSceneMouseRelease);

        MyEvent.setButton(Qt::LeftButton);
        MyEvent.setButtons(Qt::NoButton);
        MyEvent.setScenePos(event->screenPos());
        MyEvent.setScenePos(event->scenePos());
        MyEvent.setModifiers(Qt::NoModifier);
        MyEvent.setButtonDownPos(Qt::LeftButton, event->pos());
        MyEvent.setButtonDownScenePos(Qt::LeftButton, event->scenePos());
        MyEvent.setButtonDownScreenPos(Qt::LeftButton, event->screenPos());

        QApplication::sendEvent(this->scene(), &MyEvent);
    }
}
so funktioniert es.... :lol:

mfg
Stephan

Verfasst: 4. August 2010 11:12
von franzf
Meiner0815 hat geschrieben:Wen es interessiert :shock:
[...]
so funktioniert es.... :lol:
Ist ja interessant... Ich hab mich auf die Doku verlassen, dass alle public Member dokumentiert sind, ist aber nicht so... Wer in den Header schaut, findet die ganze Schnittstelle. Die setter sind mit \internal markiert. K.A. ob die dann dauerhaft public bleiben.

Aber meinen Tipn mit dem ItemIsMovable-Flag hast du schon mitbekommen? Das wäre (von dem was ich über dein Vorhaben bisher mitbekommen hab) das Sauberste.