Seite 1 von 1
Mouse events weiterleiten?
Verfasst: 2. Mai 2010 19:18
von ttt
hi,
ich habe eine QGraphicsScene, die mousePressEvent(..), mouseReleaseEvent(..) und mouseMoveEvent(...) implementiert.
In der QGraphicsScene befinden sich andere QWidgets, bei denen die mouse events allerdings nicht mehr richtig ankommen(bei wildem klicken tut sich manchmal was)
wie kann ich die mouse events, nachdem ich sie in der graphics scene verarbeitet habe, an die widgets in der szene weiterleiten?
event->accept() und event->ignore() bewirken nichts.
vielen dank im vorraus
frank
Verfasst: 3. Mai 2010 11:01
von ttt
ich habe inzwischen auch versucht mit QCoreApplication::sendEvent(..) die events weiterzuleiten, hat aber nur unerwünschte effekte herbeigeführt.
hier mal zur verdeutlichung ein vereinfachtes beispiel.
problem: button läst sich nicht anklicken.
Code: Alles auswählen
#include <QApplication>
#include <QMainWindow>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QPushButton>
class GraphicsScene : public QGraphicsScene {
public:
void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) {}
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *mouseEvent) {}
void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) {}
void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) {}
};
class MainWindow : public QMainWindow {
public:
MainWindow() : QMainWindow() {
QGraphicsScene *scene = new GraphicsScene();
QGraphicsView *view = new QGraphicsView(scene);
setCentralWidget(view);
scene->addWidget(new QPushButton("hallo"));
}
};
int main(int argc, char **argv) {
QApplication app(argc, argv);
MainWindow *mw = new MainWindow();
mw->show();
return app.exec();
}
Verfasst: 3. Mai 2010 14:03
von franzf
Code: Alles auswählen
void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) {
QGraphicsScene::mouseMoveEvent(mouseEvent);
}
Und schon kannst du über den Button fahren und er ändert sich

selbes für mousePressEvent, mouseReleaseEvent usw. und der Button lässt sich normal bedienen.
Das Problem ist einfach dass du mit dem erhaltenen mouseEvent gar nichts machst, es also einfach "frisst". Die scene leitet nichts automatisch weiter, wenn du die Methoden implementierst aber nichts entsprechendes selber machst.
Mich hätte auch noch interessiert wie du das mit dem sendEvent() versucht hast

Verfasst: 3. Mai 2010 14:53
von ttt
cool danke, funktioniert.
mit sendEvent sahs etwa so aus:
Code: Alles auswählen
void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) {
// .... stuff
for all qwidgets in the scene {
QApplication::sendEvent(widget, &mouseEvent);
}
}
bei mir kann man die Widgets per drag&drop bewegen, und sendEvent hat dann dazu geführt dass die Widgest zwar am Zielort angekommen sind, aber unterwegs unkontrollierte Bewegungen gemacht haben. button klicken ging trotzdem nicht.
gruß
Frank
Verfasst: 3. Mai 2010 15:27
von franzf
Code: Alles auswählen
void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) {
// .... stuff
for all qwidgets in the scene {
QApplication::sendEvent(widget, &mouseEvent);
}
}

1) &mouseEvent ist hier vollkommen falsch! Du hast das direkt so aus der Doku übernommen, nehm ich an. mouseEVent ist schon ein pointer, sendEvent will nen pointer, und nicht die Adresse von dem

Dass das überhaupt kompiliert hat wundert mich, wenn es kompiliert hat ist das Verhalten undefiniert.
2) for all qwidgets in scene, naja... Du willst doch nicht allen Widgets das event senden, sondern nur dem welches gerade unter der Maus liegt.
Dazu nimmst du dir die pos() des events, suchst dir das entsprechende item in der scene mit QGraphicsScene::itemAt(), rechnest die Koordinaten von scenePos in itemPos um. Jetzt musst du natürlich noch in ein QEvent umbasteln, welches von einem QWidget verstanden wird. Ein QGraphicsSceneMouseEvent wird dein QWidget strikt ablehnen, es wird nichts ausführen!
Verfasst: 3. Mai 2010 20:09
von ttt
franzf hat geschrieben:Code: Alles auswählen
void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) {
// .... stuff
for all qwidgets in the scene {
QApplication::sendEvent(widget, &mouseEvent);
}
}

1) &mouseEvent ist hier vollkommen falsch! Du hast das direkt so aus der Doku übernommen, nehm ich an. mouseEVent ist schon ein pointer, sendEvent will nen pointer, und nicht die Adresse von dem

Dass das überhaupt kompiliert hat wundert mich, wenn es kompiliert hat ist das Verhalten undefiniert.
Ich habs jetzt ums hier zu posten nur zusammenkopiert, den alten Code hatte ich nichtmehr.
2) for all qwidgets in scene, naja... Du willst doch nicht allen Widgets das event senden, sondern nur dem welches gerade unter der Maus liegt.
Dazu nimmst du dir die pos() des events, suchst dir das entsprechende item in der scene mit QGraphicsScene::itemAt(), rechnest die Koordinaten von scenePos in itemPos um.
itemAt liefert mit aber ein QGraphicsItem, das müsste ich erst noch das dazugehörige QWidget bestimmen...
Hatte es auf die Schnelle so gemacht zum Testen, hast schon recht.
Jetzt musst du natürlich noch in ein QEvent umbasteln, welches von einem QWidget verstanden wird. Ein QGraphicsSceneMouseEvent wird dein QWidget strikt ablehnen, es wird nichts ausführen!
stimmt, dumm von mir;)
Verfasst: 3. Mai 2010 20:14
von franzf
ttt hat geschrieben:itemAt liefert mit aber ein QGraphicsItem, das müsste ich erst noch das dazugehörige QWidget bestimmen...
qgraphicsitem_cast nach QGraphicsProxyWidget, falls geklappt -> castedItem->widget().