tkinter中entry输入框与滚动条重叠、滚动条无法靠右如何解决?
问题原因分析
输入框重叠原因
- Entry组件的
width参数单位是字符宽度而非像素,你设置的width=550对应的实际宽度远大于canvas的580像素宽度,直接撑爆了承载它的entrybox_frame,超出canvas的部分就会和右侧滚动条重叠。 - 代码执行顺序错误,你把
root.mainloop()写在了实例化top_level对象的代码之前,等于界面还没完成组件初始化就进入了事件循环,也会导致布局渲染异常。
滚动条无法紧贴右侧停靠原因
你使用grid布局时没有给root窗口配置列权重,canvas所在的第0列、滚动条所在的第1列默认权重都是0,窗口不会给两列分配额外的拉伸空间,同时滚动条的sticky参数设置错误,垂直滚动条仅需要上下贴紧容器,不需要横向拉伸。
修复方案
- 把Entry的width调整为合理值,比如设置为80(对应约550像素宽度,不会超出canvas范围)
- 调整代码执行顺序,先实例化top_level对象,再启动
root.mainloop() - 给root窗口配置grid列权重:
root.grid_columnconfigure(0, weight=1),让canvas所在列占满除滚动条外的所有横向空间 - 把滚动条的
sticky参数从nse改为ns,保证滚动条仅垂直方向贴满容器 - 若需要canvas随root窗口调整大小,除了配置grid权重之外,还需要给root绑定
<Configure>事件,触发时同步更新canvas的滚动区域、以及canvas内部挂载的frame的宽度,保证内容适配canvas尺寸。
修复后完整代码
from tkinter import * from tkinter import ttk from youtubesearchpython import VideosSearch root = Tk() root.title("Sasta YuTube") root.geometry("600x600") # 配置grid权重,让canvas列占满剩余空间 root.grid_columnconfigure(0, weight=1) root.grid_rowconfigure(0, weight=1) class top_level: def __init__(self,root): self.root = root self.yscroll = ttk.Scrollbar(self.root,orient = VERTICAL) # 滚动条sticky改为ns,仅垂直贴满 self.yscroll.grid(row = 0, column = 1,sticky = "ns") self.my_canvas = Canvas(self.root,yscrollcommand=self.yscroll.set,width = 580,height = 600) self.my_canvas.grid(row = 0,column = 0,sticky = "nsew") self.yscroll.config(command = self.my_canvas.yview) self.entrybox_frame = Frame(root) self.entry_frame_id = self.my_canvas.create_window(0,0,window = self.entrybox_frame,anchor = "nw") self.search_btn = ttk.Button(self.entrybox_frame,text = "search") self.search_btn.pack(side = "bottom",anchor = "w") # entry宽度调整为80字符 self.entry_box = Entry(self.entrybox_frame,width = 80) self.entry_box.pack(side = "top") # 绑定窗口大小变化事件,同步调整canvas内容尺寸 self.root.bind("<Configure>", self.resize_canvas) def resize_canvas(self, event): # 更新内部frame的宽度为canvas宽度 self.my_canvas.itemconfig(self.entry_frame_id, width=self.my_canvas.winfo_width()) # 更新滚动区域 self.my_canvas.config(scrollregion=self.my_canvas.bbox("all")) # 先实例化对象,再启动事件循环 obj = top_level(root) root.mainloop()
内容的提问来源于stack exchange,提问作者siddharth singh
相关产品推荐
相关产品推荐

