Tk mouse wheel events?

Jeff Epler jepler at
Thu Aug 15 19:12:54 CEST 2002

On Thu, Aug 15, 2002 at 04:04:29PM +0000, Edward K. Ream wrote:
> I am trying to get a binding to fire when the mouse wheel moves.  Vertical
> scrolling is handled automatically by the Tk.Text widget, and I would like
> to scroll a canvas.  The canvas is in a toplevel that includes Text widgets.
> From a Google search it appears that Button-4 and Button-5 events might do
> the job. I don't see this documented on the Tk man pages though.
> The following doesn't seem ever to call the event handlers, no matter what
> kind of widget is used:
> widget.bind("<Button-4>",self.OnButton4)
> widget.bind("<Button-5>",self.OnButton5)
> Does anyone have any advice or example code?  Thanks!

I assume you're not talking about Windows, because things there should
Just Work, assuming you have the right mouse driver.  If not, do something
in the control panel.  (that's helpful advice, right?)

On Linux, you must configure your XFree86 to translate wheel events into
button 4/5 events.  You must also specify a mouse protocol that is
compatible with your mouse and includes information about the wheel.

My XF86Config-4 looks like this, for a Logitech scrolling mouse:
    Section "InputDevice"           
        Identifier  "Mouse0"
        Driver      "mouse"
        Option      "Device" "/dev/mouse"
        Option      "Protocol" "IMPS/2"
        Option      "Emulate3Buttons" "off"
        Option      "ZAxisMapping" "4 5" ######

You can use the "xev" program to see if the wheel actually sends any X

If you want to have these mouse events turned into actual wheel events,
so that the builtin widgets also respond "correctly" to them (as they
would under windows), and you can write a C extension, something like this
may "do the trick" for you.  Just arrange for 'register_mousewheel_proc'
to be called sometime after Tk is initialized. (this comes from another
project, wrapping it to a Python module is left as an exercise):

/* A function which translates button events to wheel events */
int mousewheel_proc(ClientData cd, XEvent *eventPtr) {
    if (eventPtr->type != ButtonPress && eventPtr->type != ButtonRelease)
	return 0;

    if (eventPtr->xbutton.button != 4 && eventPtr->xbutton.button != 5)
	return 0;

    if (eventPtr->type == ButtonRelease)
	return 1;

    eventPtr->type = MouseWheelEvent;
    if (eventPtr->xbutton.button == 4) {
	eventPtr->xkey.keycode = 120;
    } else {
	eventPtr->xkey.keycode = -120;

    return 0;

void register_mousewheel_proc(void) {
    Tk_CreateGenericHandler( mousewheel_proc, 0 );

More information about the Python-list mailing list