Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I’m developing a C++ plugin for Qgis and I want to filter/override the mouse-wheel event.

I created a “maptool” to select a polygon feature on a vector layer, the feature has two attributes : an id & an integer H.
I want to override the mouse wheel event so that once I select a polygon, the wheel will allow me to change (increment/decrement) the value of attribute H and not zoom/unzoom the mapcanvas!

I created and “eventFilter” on my plugin’s base class which I install on the mapcanvas (QgsMapCanvas::installEventFilter()) once my maptool is activated, works fine to filter a key press for example but when it comes to the mouse-wheel it seems that it bypasses the eventFilter and does the usual zoom/unzoom action !!

Any ideas on how to solve this problem?

Thank you !

share|improve this question
    
Hi Name, you will need to include more info on your plugin, like whether it generates a PyQt window, etc. (presumably where you want to capture the wheel event). Qt offers several different methods of overriding or filtering events. Knowing what you are trying to do with the event, and where, would help narrow it down. –  dakcarto May 2 '12 at 10:21
    
Hi dakcarto, I'm developing a C++ plugin. The thing is that I created a maptool to select a polygon feature on a vector layer, the feature has two attributes: an id & an integer H. I want to override the mouse wheel event so that once I select a polygon, the wheel will allow me to change (increment/decrement) the value of attribute H and not zoom/unzoom the mapcanvas! –  QgisTn May 2 '12 at 10:44
    
The event capturing stems from Qt, whether via C++, or via the PyQt binding. Still need more info on where you want to capture/ignore the event and what your plugin is trying to do. –  dakcarto May 2 '12 at 10:52
add comment

2 Answers

up vote 2 down vote accepted

This code should do what you need:

from PyQt4.QtCore import QEvent, QObject
from PyQt4.QtGui import QWheelEvent
from qgis.gui import QgsMapCanvas
from qgis.core import QgsMessageLog
import qgis

class EventHook(QObject):
  def eventFilter(self, object, event):
    if event.type() == QEvent.Wheel:
      QgsMessageLog.logMessage("Wheel event delta was %s" % event.delta(),"plugin")
      return True
    else:
      return False

hook = EventHook()
qgis.utils.iface.mapCanvas().viewport().installEventFilter(hook)

I would be careful how you use this as you are changing how QGIS behaves.

Like @dakcarto said, a better method is to popup a dialog, or widget, that grabs mouse wheel focus to adjust the required value.

Make sure you clean up using qgis.utils.iface.mapCanvas().viewport().removeEventFilter(hook)

share|improve this answer
    
I have the same logic (in c++) it works fine for the QEvent::keyPress but nothing happens for QEvent::wheel nor the QEvent::GraphicSceneWheel events ! I can't find anything about the "mapCanvas().viewport()" !! is it the same as "mapcanvas()->scene()" ? –  QgisTn May 3 '12 at 7:26
    
No QgsMapCanvas inherits QGraphicsView which inherits QAbstractScrollArea which has a viewport() method qt-project.org/doc/qt-4.8/qabstractscrollarea.html#viewport –  Nathan W May 3 '12 at 10:46
    
Can you post your C++ code –  Nathan W May 3 '12 at 10:46
    
.h : bool eventFilter(QObject *, QKeyEvent *) .cpp : 'bool myClass::eventFilter(QObject *obj, QEvent *ev) { if ( ev->type() == QEvent::Wheel ) { QMessageBox::information(this, "Wheel event", "Wheel event filtered!"); return true; } return false; }' and I install the eventfilter as : 'mapCanvas()->installEventFilter(this);' –  QgisTn May 3 '12 at 10:52
    
My code is different. mapCanvas().viewport().installEventFilter() NOT mapCanvas()->installEventFilter(this) –  Nathan W May 3 '12 at 10:56
show 4 more comments

@Name - It seems the event filter is the way to go. Be careful, though, they can slow down an app, as they filter many other events. Can't help you without any code to go on.

Alternatively, you could have your plugin pop up a 'zoom pad' to receive the wheeling focus. This small window, or dock widget, could be a down-and-dirty zoom-in on your selected object, or just a widget that accepts mouse wheeling, with feedback info on the wheeling (scaling). This could directly affect the selected object, instead of the map canvas, and offer other controls beyond mouse wheeling.

Creating another window also allows you to override the protected member functions (like the wheelEvent) of a widget (like QgsMapCanvas) to do what you want.

A new window/dock could also offer the user an interface from which to chose which attribute is being incremented by the mouse wheel.

share|improve this answer
    
popping-up a zoom pad is an option too but it would be nicer to do it without pop-ups ! –  QgisTn May 3 '12 at 7:24
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.