Mouse events weiterleiten?

Alles rund um die Programmierung mit Qt
Antworten
ttt
Beiträge: 8
Registriert: 14. März 2010 20:43

Mouse events weiterleiten?

Beitrag 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
ttt
Beiträge: 8
Registriert: 14. März 2010 20:43

Beitrag 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();		
}
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag 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 :)
ttt
Beiträge: 8
Registriert: 14. März 2010 20:43

Beitrag 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
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Code: Alles auswählen


void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) {
         // .... stuff

        for all qwidgets in the scene {
            QApplication::sendEvent(widget, &mouseEvent);
        }
}
:D
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!
ttt
Beiträge: 8
Registriert: 14. März 2010 20:43

Beitrag 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);
        }
}
:D
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;)
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag 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().
Antworten