Seite 1 von 1

[gelöst]Nachschlag: Mouseevent auf QLabel begrenzen

Verfasst: 2. Januar 2009 20:59
von qtNiko
hallo,

der Tipp für mein bereits angesprochenes Problem war, ein eventFilter() zu verwenden. Aber der tut nicht ganz, wie ich es erwartet habe. Vielleicht habe ich auch etwas nicht richtig verstanden.

Situation: ich habe in meinem Hauptfenster ein QLabel, graphView_scene, für Bildausgaben. Außerdem habe ich mousePressEvent(..) für das Hauptfenster überschrieben mit eigenen Aktionen.

Meine Absicht: Mouseevents sollen so gefiltert werden, dass nur die Klicks im QLabel an mousePressEvent(..) weitergeleitet werden.

Realisierung:

Code: Alles auswählen

im Konstruktor meines Hauptfensters ipcSim:
...
graphView_scene->installEventFilter(this);
...

bool ipcSim::eventFilter(QObject *obj, QEvent *event)
 {
     if (obj == graphView_scene) {
         if (event->type() == QEvent::MouseButtonPress) {
        	 qDebug() << "Mousetaste ";
             return false;
         }
         else
             return true;
 
     } else {
         // pass the event on to the parent class
         return QMainWindow::eventFilter(obj, event);
     }
 }

vorläufige Version zur Visualisierung, was passiert:
void ipcSim::mousePressEvent(QMouseEvent* event) {
...
	if (event->button() == Qt::LeftButton) {
		qDebug() << "li(" << event->x() << ", " << event->y() << ")";
	else if (event->button() == Qt::RightButton) {
		qDebug() << "re(" << event->x() << ", " << event->y() << ")";
...
} 
prinzipieller Aufbau meines Hauptfensters:

linker Bereich: alles mit Bedienelementen voll
mittlerer Bereich: Bildausgabe auf QLabel
rechter Bereich: weitere Bedienelemente, Flächen des Hauptfensters zwischendrin sichtbar

was passiert:
Klicks im linken Bereich: nichts kommt zu mousePressEvent(..) durch --> ok
Klicks im mittleren Bereich: Klicks kommen in mousePressEvent(..) an, z.B. "Mousetaste li(.., ...)" --> ok
Klicks im rechten Bereich: Klicks auf einigen der Bedienelemente kommen nicht durch, auf anderen dagegen schon, und Klicks auf die sichtbaren Flächen des Hauptfensters kommen alle durch, wobei jeweils nur der Teil der Ausgaben aus mousePressEvent(..) ankommt, z.B. "li(.., ...)" --> ??

Weil ich dachte, der Grund dafür, dass im rechten Bereich Klick-Events durchkommen, liegt an der letzten Zeile von eventFilter(..), habe ich diese Zeile gelöscht. Am Verhalten hat sich jedoch überhaupt nichts geändert.

Warum kommen Klicks im rechten Bereich teilweise durch und im linken Bereich überhaupt nicht?

Verfasst: 2. Januar 2009 21:36
von RD1978
return true/false vielleicht vertauscht?

Verfasst: 2. Januar 2009 21:58
von upsala
Nein, das Prinzip vom eventFilter nicht verstanden, aber das Beispiel bei QObject::installEventFilter ist eigentlich aussagekräftig genug.

Verfasst: 2. Januar 2009 22:47
von RD1978
OK, ich hätte vielleicht noch dazu sagen sollen, daß Dein mousePressEvent( ... ) jetzt überflüssig ist.

Code: Alles auswählen

MainWindowImpl::MainWindowImpl( QWidget *parent, Qt::WFlags f ) : QMainWindow( parent, f )
{
	this->setupUi( this );
	m_pLabel->installEventFilter( this );
}

bool MainWindowImpl::eventFilter( QObject *object, QEvent *event )
{
	if( object == m_pLabel )
	{
		if( event->type() == QEvent::MouseButtonPress )
		{
			QMouseEvent *mouseEvent = static_cast<QMouseEvent*>( event );
			qDebug() << mouseEvent->pos();
			return true;
		}
		else
		{
			return false;
		}
	}
	else
	{
		return QMainWindow::eventFilter( object, event );
	}
}
Die Position wird bei Mouseklick jetzt nur innerhalb des Labels ausgegeben. Das wolltest Du doch erreichen oder was?

Verfasst: 2. Januar 2009 23:08
von qtNiko
Mir ist die Funktion des Eventfilters tatsächlich nicht recht klar. Aber das Beispiel zu installEventFilter() hilft mir auch nicht weiter. So, wie ich es verstanden habe, werden in dem Beispiel alle KeyPress-Events für pushButton und listView ausgefiltert, d.h. diese beiden Objekte bekommen KeyPress-Events nicht mit, egal woher sie kommen.

Mein Verständnisproblem geht weiter, nämlich in den ganzen Event-Verteilungs Prozess.

Zunächst, so nehme ich an, hat jedes Objekt eine Methode eventFilter(). Man kann aber mit installEventFilter() einer Methode ein anderes Filter übergeben, das dann das eigene ersetzt. Damit erspart man sich das Ableiten eines neuen Objekts und das Überschreiben des eventFilter() dieses neuen Objekts.

Mein Problem ist anders gelagert. Ich möchte die Klicks innerhalb meines QLabels in einer Methode des Hauptfensters bearbeiten, nämlich in mousePressEvent(). Und mousePressEvent() sollte nur dann aufgerufen werden, wenn ein Klick innerhalb QLabel stattfand. Jetzt verstehe ich nicht, wie ein eventFilter(), das ich dem QLabel übergebe, mir da weiterhelfen soll. Damit werden doch nur Events für das QLabel gefiltert, oder? Wenn ich innerhalb QLabel die Events weiterverarbeiten würde, dann denke ich, würde mir ein eventFilter() helfen. Dann müsste ich aber erst ein neues Objekt aus QLabel ableiten, um diese Bearbeitung durchzuführen, und dann könnte ich ja auch gleich das zu QLabel gehörende eventFilter() entsprechend modifizieren. Das alles wollte ich mir doch gerade ersparen.

Die einzige Möglichkeit sehe ich darin, innerhalb mousePressEvent() die Positionen selbst zu filtern, z.B. mit einem QRect->contains().

Verfasst: 2. Januar 2009 23:16
von qtNiko
hi,

die Antwort von RD1978 kam, während ich mit meiner Antwort beschäftigt war. Aber jetzt ist es klar, danke.

eventFilter() ersetzt mein mousePressEvent()!
Da hatte ich doch ein Brett vor dem Kopf. Ich suchte immer nach einem Weg, die Events, die zu mousePressEvent() kommen, entsprechend zu filtern.