带网格的Tkinter滚动条:滚动到框架上方,滚动条为灰色

缺口

我正在尝试使用Tkinter在我的Python程序中实现滚动条。问题是滚动条可以在框架的顶部上方和底部下方滚动。此外,即使按钮和鼠标滚轮也可以工作,滚动条仍处于禁用状态。

大多数问题在使用.pack方法之前都会回答,而我不想/不想使用。而且,在大多数示例中,对象是在滚动条代码所在的范围内添加到框架的,但是我想通过loadColumnNames方法来实现。

    import tkinter as tk
from tkinter import ttk
from tkinter import filedialog


class MainWindow(tk.Frame):

    def build_widgets(self):

        # Create a notebook to later embed the tabs into it.
        self.nb = ttk.Notebook(self)
        self.nb.grid(row=1, column=0, columnspan=5, rowspan=5, sticky="NESW")

        tabStyle = ttk.Style()
        tabStyle.configure("new.TFrame", background="white")

        #---------------------------------------------------
        # Column renaming tab.
        #---------------------------------------------------

        tab2 = ttk.Frame(self.nb, style="New.TFrame")
        self.nb.add(tab2, text="Column Renaming")

        frame = tk.Frame(tab2)
        frame.grid(row=1, column=2, sticky="nesw")

        button = tk.Button(frame, text="Load Column Names", command=self.loadColumnNames)
        button.grid(row=1, column=0, sticky="nesw", padx=self.PadLeft)

        wrapperFrame = tk.LabelFrame(tab2)

        self.columnNamesCanvas = tk.Canvas(wrapperFrame)
        self.columnNamesCanvas.grid(row=0, column=0, sticky="nesw")

        yscrollbar = ttk.Scrollbar(wrapperFrame, orient="vertical", command=self.columnNamesCanvas.yview)
        yscrollbar.grid(row=0, column=4, sticky="ns")

        self.columnNamesCanvas.configure(yscrollcommand=yscrollbar.set)

        self.columnNamesFrame = tk.Frame(self.columnNamesCanvas)
        self.columnNamesCanvas.create_window((0,0), window=self.columnNamesFrame, anchor="nw")

        wrapperFrame.grid(row=1, column=1, sticky="nesw")

        self.columnNamesFrame.bind("<Enter>", self._bound_to_mousewheel)
        self.columnNamesFrame.bind("<Leave>", self._unbound_to_mousewheel)

        return

    def __init__(self, master=None):
        self.PadLeft = 10
        self.columNamesFrameVars = {}

        tk.Frame.__init__(self, master, bg=BG)
        self.pack()
        self.build_widgets()

        return

    def _bound_to_mousewheel(self, event):
        self.columnNamesCanvas.bind_all("<MouseWheel>", self._on_mousewheel)

    def _unbound_to_mousewheel(self, event):
        self.columnNamesCanvas.unbind_all("<MouseWheel>")

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

    def loadColumnNames(self):

        self.columNamesFrameVars = {}
        
        columns = ["a", "b", "c", "d", "e", "f", "h", "i", "j", "k", "l", "m", "n"]

        i = 0
        for column in columns:

            self.columNamesFrameVars[column] = []

            # New column name.
            newname = tk.Entry(self.columnNamesFrame)
            newname.grid(row=i, column=3, padx=self.PadLeft)
            newname.insert(0, str(column))
            self.columNamesFrameVars[column].append(newname)

            i += 1

        self.columnNamesCanvas.bind('<Configure>', lambda e: self.columnNamesCanvas.configure(scrollregion = self.columnNamesCanvas.bbox("all")))

        return


if __name__ == '__main__':
    BG = "white"

    root = tk.Tk()
    root.wm_title("")
    MainWindow(root)
    root.mainloop()

如何“激活”滚动条?如何限制滚动到帧中的第一个和最后一个元素?

小说

<Configure>事件应绑定到“框架”时,您已将事件绑定到“画布”。您还需要将其移至build_widgets方法。

为了清洁起见,我还建议您远离lambda并采用真实方法。因此,将其添加到build_widgets的末尾:

self.columnNamesFrame.bind('<Configure>', self._on_configure)
#     ^ note this is the Frame, not the Canvas

并添加此方法:

def _on_configure(self, event=None):
    self.columnNamesCanvas.configure(scrollregion = self.columnNamesCanvas.bbox("all"))

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章