带网格的 Tkinter 滚动条:滚动过框架和滚动条灰色
Tkinter Scrollbar with Grid: Scrolls past frame and scrollbar gray
我正在尝试使用 Tkinter 在我的 Python 程序中实现滚动条。问题是滚动条可以滚动到框架顶部上方和底部下方。此外,滚动条看起来已停用,即使按钮和鼠标滚轮有效。
大多数问题都是在使用 .pack 方法之前回答的,我t/don不想使用它。此外,在大多数示例中,对象被添加到与滚动条代码相同范围内的框架,但我想通过 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>
事件绑定到 Canvas,而它应该绑定到框架。您还需要将其移动到 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"))
我正在尝试使用 Tkinter 在我的 Python 程序中实现滚动条。问题是滚动条可以滚动到框架顶部上方和底部下方。此外,滚动条看起来已停用,即使按钮和鼠标滚轮有效。
大多数问题都是在使用 .pack 方法之前回答的,我t/don不想使用它。此外,在大多数示例中,对象被添加到与滚动条代码相同范围内的框架,但我想通过 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>
事件绑定到 Canvas,而它应该绑定到框架。您还需要将其移动到 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"))