bugfix> python > 投稿

マウスホイールを2つのフレームでスクロールキャンバスにバインドしようとしています。しかし、私はそれを正しく得ることができません! 1つのフレームでのみ、マウスホイールが正しくバインドされます。

どこで間違いを犯しましたか?すべてを提供することは一般的ではありませんが、CustomWidgetとMouseWheelへの独自のバインディングを呼び出してみましょうか?

バインドを解除する必要がありますか? 「はい」の場合、「MyFirstGUI」クラスからどのようにバインドを解除できますか?正しい「自己」を見つけるのに苦労しています。

一般に、バインディングは1つのクラスで機能します。 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 件
  • コードを使用した本格的な例を次に示します。

    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()
    
    

    キャンバスにスクロールバーを更新するように指示する呼び出しを追加したことに注意してください(キャンバスを更新するようにスクロールバーに指示しただけです) また、キャンバスにどの領域がスクロール可能であるかを伝える呼び出しを追加しました。表示したい領域を変更するウィジェットを追加/変更する場合は、これを再度更新する必要があります(内部コンテンツのサイズが変更されるたびに) スクロールが見えるようにコンテンツも追加しました

あなたの答え