Tkinter带滚动条、画布和按钮的框架问题:滚动条失效
解决Tkinter Canvas滚动条无法滚动按钮的问题
嗨,我来帮你搞定这个滚动条的问题!你的代码里有几个关键细节没处理到位,导致滚动条显示了但没法驱动按钮滚动。我帮你调整了代码,现在就能正常滚动啦:
import tkinter as tk import tkinter.font as tkFont from PIL import Image, ImageTk def frontpage(): #1. window setup root = tk.Tk() root.title("Title") screenWidth = root.winfo_screenwidth() screenHeight = root.winfo_screenheight() w = 1200 h = 680 x = (screenWidth - w) / 2 y = (screenHeight - h ) / 4 root.geometry("%dx%d+%d+%d" % (w,h,x,y)) #2. window background image = Image.open("secondpage/sec.gif") yellowstone = ImageTk.PhotoImage(image) label = tk.Label(root,image=yellowstone) label.pack() #3.frame with canvas and scrollbar canvas_frame = tk.Frame(root) #frame set up canvas_frame.place(x=150,y=95) canvas_frame_scrollbar = tk.Scrollbar(canvas_frame) #scrollbar set up canvas_frame_scrollbar.pack(side=tk.RIGHT,fill=tk.Y) # 关键改动1:Canvas和Scrollbar绑定滚动命令 canvas = tk.Canvas(canvas_frame, width=898, height=490,bd=0,bg='#f9ca7c', yscrollcommand=canvas_frame_scrollbar.set) canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) canvas_frame_scrollbar.config(command=canvas.yview) # 关键改动2:创建Canvas内部的Frame,所有按钮都放在这里 inner_frame = tk.Frame(canvas, bg='#f9ca7c') canvas.create_window((0, 0), window=inner_frame, anchor="nw") # 关键改动3:绑定事件让Canvas自动更新滚动范围 def on_frame_configure(event): canvas.configure(scrollregion=canvas.bbox("all")) inner_frame.bind("<Configure>", on_frame_configure) #4.button design # button picture size=100*100 person_name_font= tkFont.Font(size=5, weight="bold") #font design front_p1_pic = tk.PhotoImage(file="secondpage/p1.gif") # button image # 关键改动4:按钮的父组件改成inner_frame front_p1 = tk.Button(inner_frame,image= front_p1_pic,compound=tk.TOP,font= person_name_font) front_p2 = tk.Button(inner_frame,image= front_p1_pic,compound=tk.TOP,font= person_name_font) # 多添加几个按钮方便测试滚动 front_p3 = tk.Button(inner_frame,image= front_p1_pic,compound=tk.TOP,font= person_name_font) front_p4 = tk.Button(inner_frame,image= front_p1_pic,compound=tk.TOP,font= person_name_font) front_p5 = tk.Button(inner_frame,image= front_p1_pic,compound=tk.TOP,font= person_name_font) front_p6 = tk.Button(inner_frame,image= front_p1_pic,compound=tk.TOP,font= person_name_font) front_p7 = tk.Button(inner_frame,image= front_p1_pic,compound=tk.TOP,font= person_name_font) front_p8 = tk.Button(inner_frame,image= front_p1_pic,compound=tk.TOP,font= person_name_font) #4-1.button place front_p1.place(x=56,y=30,width=100,height=100) front_p2.place(x=232,y=30,width=100,height=100) front_p3.place(x=408,y=30,width=100,height=100) front_p4.place(x=584,y=30,width=100,height=100) front_p5.place(x=760,y=30,width=100,height=100) front_p6.place(x=56,y=160,width=100,height=100) front_p7.place(x=232,y=160,width=100,height=100) front_p8.place(x=408,y=160,width=100,height=100) root.mainloop() frontpage()
关键改动说明:
- 绑定滚动条与Canvas:给Canvas设置
yscrollcommand=canvas_frame_scrollbar.set,同时给滚动条设置command=canvas.yview,这样两者就能联动起来,拖动滚动条时Canvas会滚动视图。 - 创建内部承载Frame:Canvas本身不能直接管理多个组件的布局滚动,需要在Canvas内部创建一个Frame,把所有按钮都放在这个Frame里,然后用
canvas.create_window把这个Frame添加到Canvas中。 - 自动更新滚动范围:绑定内部Frame的
<Configure>事件,每次Frame的尺寸变化(比如添加更多按钮),就更新Canvas的scrollregion,让滚动条能识别到可滚动的范围。 - 调整按钮的父组件:把按钮的父容器从
canvas_frame改成内部的inner_frame,这样按钮才属于Canvas可滚动的内容区域。
我还额外加了几个按钮方便你测试滚动效果,你可以根据自己的需求调整按钮的数量和布局~
内容的提问来源于stack exchange,提问作者Tini
相关产品推荐
相关产品推荐

