将鼠标滚轮绑定到两个画布,但只有一个工作

时间:2018-05-25 11:21:37

标签: python python-3.x class tkinter widget

我尝试将鼠标滚轮绑定到两个框架中的滚动画布。但我无法做对!只有在一帧中鼠标滚轮才能正确绑定。

我在哪里弄错了?给每一个都不常见,让我调用CustomWidget并自己绑定到MouseWheel?

我是否必须以任何方式解除绑定?如果是,我怎样才能将其与我的" MyFirstGUI"上课?我有一些麻烦找到正确的"自我"。

一般来说,绑定适用于一个类。如果我在我的窗口中显示SystemsGUI的同时滚动鼠标滚轮,则MainGUI会滚动。

以下是我的代码摘录:

from tkinter import *
import tkinter.ttk as ttk

class MyFirstGUI(object):
    def __init__(self, master):
        self.master = master

        self.gui_control = ttk.Notebook(master)

        self.main_gui = ttk.Frame(self.gui_control, borderwidth=0) 
        self.systems_gui = ttk.Frame(self.gui_control, borderwidth=0)

        self.gui_control.add(self.main_gui, text='Main') 
        self.gui_control.add(self.systems_gui, text='Systems')

        self.gui_control.grid(column=1,row=1, columnspan=9, rowspan=50,sticky=N+E+S+W)  

        self.test_1 = Main.MainFrame(self.main_gui)
        self.test_1.grid(row=0, column=0, sticky="NESW") 

        self.test_2 = Systems.SystemFrame(self.systems_gui)
        self.test_2.grid(row=0, column=0, sticky="NESW") 

        #[...]

master.mainloop()

MainGUI:

class MainFrame(tk.Frame):    

    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)        

        self.main_canvas = tk.Canvas(self, borderwidth=0, highlightthickness=0)
        self.main_canvas.grid(row=0,column=0, sticky="NESW")  

        self.vsb = tk.Scrollbar(self, orient="vertical", command=self.main_canvas.yview)
        self.vsb.grid(row=0,column=1, sticky="NS") 

        self.main_canvas.bind_all("<MouseWheel>", self._on_mousewheel)

    def _on_mousewheel(self, event):
        self.main_canvas.yview_scroll(int(-1*(event.delta/120)), "units")

    #[...]

系统GUI(基本相同):

class SystemFrame(tk.Frame):    

    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)        

        self.system_canvas = tk.Canvas(self, borderwidth=0, highlightthickness=0)
        self.system_canvas.grid(row=0,column=0, sticky="NESW")  

        self.vsb = tk.Scrollbar(self, orient="vertical", command=self.system_canvas.yview)
        self.vsb.grid(row=0,column=1, sticky="NS") 

        self.system_canvas.bind_all("<MouseWheel>", self._on_mousewheel)

    def _on_mousewheel(self, event):
        self.system_canvas.yview_scroll(int(-1*(event.delta/120)), "units")

    #[...]

1 个答案:

答案 0 :(得分:2)

这是一个使用您的代码的完整示例:

import tkinter as tk
import tkinter.ttk as ttk

class MainFrame(tk.Frame):    

    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)        

        self.main_canvas = tk.Canvas(self, borderwidth=0, highlightthickness=0)
        self.main_canvas.grid(row=0,column=0, sticky="NESW")  

        self.vsb = tk.Scrollbar(self, orient="vertical", command=self.main_canvas.yview)
        self.vsb.grid(row=0,column=1, sticky="NS") 

        # must configure canvas to update scrollbar when scrolled
        self.main_canvas.configure(yscrollcommand=self.vsb.set)

        # add some content so can see scrolling
        self.main_canvas.create_line(0,0,200,500, fill='red')

        # tell canvas the scrollable region (used bbox(tk.ALL) to get everything)
        self.main_canvas.configure(scrollregion=self.main_canvas.bbox(tk.ALL))

        self.main_canvas.bind("<MouseWheel>", self._on_mousewheel)
        self.main_canvas.bind("<Button-4>", self._onmousewheel)
        self.main_canvas.bind("<Button-5>", self._onmousewheel)

    def _on_mousewheel(self, event):
        if event.num == 4 or event.delta == 120:
            self.main_canvas.yview_scroll(-1, "units")
        elif event.num == 5 or event.delta == -120:
            self.main_canvas.yview_scroll(1, "units")

class SystemFrame(tk.Frame):    

    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)        

        self.system_canvas = tk.Canvas(self, borderwidth=0, highlightthickness=0)
        self.system_canvas.grid(row=0,column=0, sticky="NESW")  

        self.vsb = tk.Scrollbar(self, orient="vertical", command=self.system_canvas.yview)
        self.vsb.grid(row=0,column=1, sticky="NS") 

        self.system_canvas.configure(yscrollcommand=self.vsb.set)

        self.system_canvas.create_line(0,0,200,500, fill='red')
        self.system_canvas.configure(scrollregion=self.system_canvas.bbox(tk.ALL))

        self.system_canvas.bind("<MouseWheel>", self._on_mousewheel)
        self.system_canvas.bind("<Button-4>", self._onmousewheel)
        self.system_canvas.bind("<Button-5>", self._onmousewheel)

    def _on_mousewheel(self, event):
        if event.num == 4 or event.delta == 120:
            self.system_canvas.yview_scroll(-1, "units")
        elif event.num == 5 or event.delta == -120:
            self.system_canvas.yview_scroll(1, "units")

class MyFirstGUI(object):
    def __init__(self, master):
        self.master = master

        self.gui_control = ttk.Notebook(master)

        self.main_gui = ttk.Frame(self.gui_control, borderwidth=0) 
        self.systems_gui = ttk.Frame(self.gui_control, borderwidth=0)

        self.gui_control.add(self.main_gui, text='Main') 
        self.gui_control.add(self.systems_gui, text='Systems')

        self.gui_control.grid(column=1,row=1, columnspan=9, rowspan=50,sticky=tk.N+tk.E+tk.S+tk.W)  

        self.test_1 = MainFrame(self.main_gui)
        self.test_1.grid(row=0, column=0, sticky="NESW") 

        self.test_2 = SystemFrame(self.systems_gui)
        self.test_2.grid(row=0, column=0, sticky="NESW") 

master = tk.Tk()
gui = MyFirstGUI(master)
master.mainloop()

请注意我添加了调用以告诉画布更新滚动条(您只告诉滚动条更新画布) 我还添加了一个调用告诉画布哪个区域是可滚动的,如果你进行任何更改/添加改变你想要看到的区域的小部件,你需要再次更新它(每次内部内容改变大小) 我还添加了一些内容,以便您可以看到滚动