我对python3上的 Tkinter 非常陌生,并尝试在画布上创建一个可滚动框架。 我可以创建默认窗口大小,没有问题。但是当 windows最大化时,画布会突然在顶部添加额外的可滚动区域,我一直在寻找删除它的方法/保持我的可滚动框架在顶部。
import tkinter as tk
class MainWindow(tk.Tk):
def __init__(self, *args, **kwargs):
super().__init__()
self.geometry("1500x800")
self.configure(background="#303030")
class Table(tk.Frame):
def __init__(self, master, rows=2, columns=2):
tk.Frame.__init__(self, master, background="#36363d")
# Set table as list of rows
self.table = []
for row in range(rows):
# Create list to store cell info in a rows
current_row = []
for column in range(columns):
label = tk.Label(self, text="", borderwidth=0, width=columns, bg="#474756", )
label.grid(row=row, column=column, sticky="nsew", padx=1, pady=1, )
# Append cell (column) into rows
current_row.append(label)
# Append rows into whole table
self.table.append(current_row)
for column in range(columns):
self.grid_columnconfigure(column, weight=1)
class ScrollablePage(tk.Frame):
def __init__(self, master, *args, **kw):
super().__init__(master)
self.canvas = tk.Canvas(self, borderwidth=0, highlightthickness=0, bg="red") # THIS TO EMPHASIZE THE CANVAS,
self.frame = tk.Frame(self.canvas, *args, **kw)
self.vsb = tk.Scrollbar(self, orient="vertical", command=self.canvas.yview)
self.canvas.configure(yscrollcommand=self.vsb.set)
self.vsb.pack(side="right", fill="y")
self.canvas.pack(side="left", fill="both", expand=True)
self.canvas_frame = self.canvas.create_window((0, 0), window=self.frame, anchor="nw", tags="self.frame")
# Dynamic frame setup
self.frame.bind("<Configure>", self.frame_conf)
self.canvas.bind("<Configure>", self.frame_width)
# Bind canvas to mousewheel
self.canvas.bind("<Enter>", self.bound_to_mousewheel)
self.canvas.bind("<Leave>", self.unbound_to_mousewheel)
def frame_conf(self, event):
"""
Reset the scroll region to encompass the inner frame
"""
self.canvas.configure(scrollregion=self.canvas.bbox("all"))
def frame_width(self, event):
"""
Function to adjust canvas's frame upon expand (can't use pack)
"""
self.canvas.itemconfig(self.canvas_frame, width=event.width)
def mouse_wheel(self, event):
"""
Capture mouse wheel changes to scroll page
"""
self.canvas.yview_scroll(-1 * int(event.delta / 60), "units")
def bound_to_mousewheel(self, event):
self.canvas.bind_all("<MouseWheel>", self.mouse_wheel)
def unbound_to_mousewheel(self, event):
self.canvas.unbind_all("<MouseWheel>")
class PageTwo(ScrollablePage):
def __init__(self, master):
# Create page
super().__init__(master, bg="#36363d")
# EXAMPLE CONTENT
controller = tk.Frame(self.frame, bg="#474756", width=0.9 * 1500, height=200, bd=0,)
controller.pack(side="top", fill="x", padx=20, pady=10)
self.table = Table(self.frame, rows=20, columns=10)
self.table.pack(side="top", fill="both", padx=20, expand=1)
class MainContent(tk.Frame):
# Setup main content's stacked-frame
frames = {}
# main_content_classes = [PageOne, PageTwo, PageThree, PageFour, PageFive, PageSix, PageDefault] # << ORIGINAL ONE
main_content_classes = [PageTwo]
def __init__(self, master):
# Create main content's frame
super().__init__(master)
# Place main content's frame in main window
self.place(x=150, y=130, relwidth=0.9, relheight=0.83)
# Create grid inside main content frame
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
# Stacking pages in main content
for FrameClass in MainContent.main_content_classes:
page_name = FrameClass.__name__
frame = FrameClass(self)
frame.grid(row=0, column=0, sticky="nsew")
MainContent.frames[page_name] = frame
class Datalab:
def __init__(self, *args, **kwargs):
main_window = MainWindow()
MainContent(main_window)
main_window.mainloop()
if __name__ == "__main__":
app = Datalab()
我包含一些指向图片的链接(无法直接发布)以说明
默认窗口大小 - 顶部可滚动画布
最大化窗口 - 画布在底部创建了额外的滚动区域(标记为红色:画布)
最大化窗口 - 画布在顶部创建了额外的滚动区域(标记为红色:画布)
提前致谢
答案 0 :(得分:0)
我遇到了同样的问题,发现vsb.get()
方法在窗口中显示所有内容时返回元组(0.0, 1.0)
(滚动区域内的项目最大化,或者不是很多项目)。不知道这个解决方案有多脏,但这对我有用。
鼠标滚轮只有在滚动条可滚动时才会生效:
def mouse_wheel(self, event):
"""
Capture mouse wheel changes to scroll page
"""
if self.vsb.get() != (0.0, 1.0):
self.canvas.yview_scroll(-1 * int(event.delta / 60), "units")