I'm building something that uses multiple scrollbars. This class is actually a wrapper for the tk.ScrollBar and it's used to create scrollable frames. What I want is to be able to set a "default" scroll-container.
Assume 90% of the time someone using the application would want to scroll some frame (Which we will call main_frame), and 10% of the time they would want to scroll a different frame. (normal_frame)
It would make sense to have the mousewheel scroll the normal_frame only when the user was hovering over it with the mouse, but to have the mousewheel scroll the main_frame in all instances except when hovering over normal_frame.
The problem is that whenever you call bind_all upon " <Enter>
"(ing) the normal_frame, when you " <Leave>
" it, the main_frame no longer scrolls. Any suggestions?
class ScrollThing(object):
def __init__(self, some_frame, default=False):
self.default = default
self.canvas = tkinter.Canvas(some_frame)
self.view_window = tkinter.Frame(self.canvas)
#things and stuff to setup scroll bar
def setup_view_window(self):
if self.default:
self.canvas.bind_all('<MouseWheel>', self.on_mousewheel)
else:
self.view_window.bind('<Enter>', self.focus_in)
self.view_window.bind('<Leave>', self.focus_out)
def focus_in(self, *args):
del args
# I'm a seperate ScrollThing from main_frame
# I don't have access to the other ScrollThing because
# we are both dynamically created.
# I want to save the current bound arguments somehow
# but .bindtags() returns only MY bindings
self.canvas.bind_all('<MouseWheel>', self.on_mousewheel)
def focus_out(self, *args):
self.canvas.unbind_all('<MouseWheel>', self.on_mousewheel
def on_mousewheel(self, event):
self.canvas.yview_scroll(int(-1*(event.delta//120)), 'units')
I just found a solution involving handing the function and the canvas back to the Master.
class Master(object)
def __init__(self, *args, **kwargs):
#Things and stuff
self.default_scroll = None
Then by setting default_scroll to hold the default parameters
def setup_view_window(self):
if self.default:
self.canvas.bind_all('<MouseWheel>', self.on_mousewheel)
# HERE
self.dynamic.stuff.MASTER.default_scroll = [self.canvas, self.on_mousewheel]
else:
self.view_window.bind('<Enter>', self.focus_in)
self.view_window.bind('<Leave>', self.focus_out)
You can then access it in the focus_out.
def focus_out(self, *args):
self.canvas.unbind_all('<MouseWheel>', self.on_mousewheel)
# HERE
if self.dynamic.stuff.MASTER.default_scroll is not None:
self.dynamic.stuff.MASTER.default_scroll[0].bind_all('<MouseWheel>', self.dynamic.stuff.MASTER.default_scroll[1])
Although, I would be interested to know if anyone knows of a way to access it in a more concise way, perhaps something in tkinter that lets you see all bound events in the entire application?
Arguably the simplest solution is to set a variable to be the widget you want to scroll, and then set a global binding to scroll that widget.
For example, your app would initialize the binding like this exactly once:
self.root.bind_all("<MouseWheel>", self.scroller)
Then, in scroller you scroll the default window:
def scroller(self, event):
self.default_window.yview(...)
You can also add the binding to the canvases themselves instead of calling bind_all
if you prefer. The basic concept still works without having to adjust the bindings on enter/leave events.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.