Home > Back-end >  events on widgets that are drawn on a canvas?
events on widgets that are drawn on a canvas?

Time:12-16

I have placed some widgets on a canvas (ultimately to enable scrolling). Here is the simplified code:

import tkinter as tk
from tkinter import ttk

root = tk.Tk()
root.geometry('400x400')

canvas = tk.Canvas(root, background = 'white')
canvas.pack(expand = True, fill = 'both')
canvas.create_window((10,30), window = ttk.Label(root, text = 'A label'))
canvas.bind('<MouseWheel>', lambda event: print(event))

root.mainloop()

The mousewheel event does work on the canvas but does not work on the area where with the widget. Is there a way around it?

One solution I thought might work was to put the canvas in a container and run an event on that:

import tkinter as tk
from tkinter import ttk

class ScrollContainer(ttk.Frame):
    def __init__(self, parent):
        super().__init__(master = parent)
        canvas = tk.Canvas(self, background = 'white')
        canvas.pack(expand = True, fill = 'both', side = 'left')
        canvas.create_window((10,30), window = ttk.Label(root, text = 'A label'))

        self.bind('<MouseWheel>', lambda event: print(event))

        self.pack(expand = True, fill = 'both')


root = tk.Tk()
root.geometry('400x400')

ScrollContainer(root)

root.mainloop() 

But that one doesn't trigger an event at all. Can someone help with this problem? I just want to be able to trigger an event when the mouse is over the frame or canvas regardless of the children (or canvas windows). It does work to create an event on the root itself but I need this to be more focused.

CodePudding user response:

The second solution does not work because the canvas is above the Frame so that the event happens in the canvas and not the frame and there is no trigger defined for canvas event. The solution may be using bind_all to trigger events to all canvas items

canvas.bind_all('<MouseWheel>', lambda event: print(event))

Only be careful that the x and y coordinates captured from the event will be the item coordinates and not the canvas ones

  • Related