Search code examples
pythongtk3

Getting mousewheel events in DrawArea with python GTK3


I'm trying to get a mousewheel event inside a Gtk.DrawArea. Does someone know howto achieve this? The method DrawTest.on_scroll() is never called currently:

#!/usr/bin/env python3                                                                                                                                                                   

import gi                                                                                                                                                                                
gi.require_version('Gtk', '3.0')                                                                                                                                                         
from gi.repository import Gtk                                                                                                                                                            

class DrawTest(Gtk.DrawingArea):                                                                                                                                                         
    def __init__(self):                                                                                                                                                                  
        super(DrawTest, self).__init__()                                                                                                                                                 
        self.connect("scroll-event", self.on_scroll)                                                                                                                                     

    def on_scroll(self, btn, event):                                                                                                                                                     
        print("Scroll event")                                                                                                                                                            
        return True                                                                                                                                                                      


class MainWindow(Gtk.Window):                                                                                                                                                            
    def __init__(self):                                                                                                                                                                  
        super(MainWindow, self).__init__()                                                                                                                                               
        self.connect("destroy", lambda x: Gtk.main_quit())                                                                                                                               

        evtest = DrawTest()                                                                                                                                                              

        self.add(evtest)                                                                                                                                                                 
        self.show_all()                                                                                                                                                                  

    def run(self):                                                                                                                                                                       
        Gtk.main()                                                                                                                                                                       

def main(args):                                                                                                                                                                          
    mainwdw = MainWindow()                                                                                                                                                               
    mainwdw.run()                                                                                                                                                                        
    return 0                                                                                                                                                                             

if __name__ == '__main__':                                                                                                                                                               
    import sys                                                                                                                                                                           
    sys.exit(main(sys.argv))

Solution

  • You need to set or add events that the Gtk.DrawingArea should handle.

    Just add this line of code to your DrawTest class in the init method:

    self.set_events (Gdk.EventMask.ALL_EVENTS_MASK)
    

    It should look like this:

    class DrawTest(Gtk.DrawingArea): 
        def __init__(self): 
            super(DrawTest, self).__init__()
            self.set_events (Gdk.EventMask.ALL_EVENTS_MASK)
            self.connect("scroll-event", self.on_scroll)
        ...
    

    The set_events method comes from Gtk.Widget class and it says:

    The event mask for a window determines which events will be reported for that window from all master input devices. For example, an event mask including Gdk.EventMask.BUTTON_PRESS_MASK means the window should report button press events. The event mask is the bitwise OR of values from the Gdk.EventMask enumeration.

    See the ‘input handling overview [event-masks]’ for details.

    For simplicity I've set the ALL_EVENTS_MASK, more on Gdk.EventMask.

    PS: Notice that Gdk.Window is not the same as Gtk.Window as you will see if you read more on the subject.