tkinter使用canvas时如何让所有按钮自动适配最大按钮的统一尺寸
解决方案
疑问1:是否值得实现自动适配最大文本的效果
如果你的按钮文本固定、长度差异始终在2个字符以内,直接手动给所有按钮统一设置width参数即可,成本极低,没必要额外做自动适配。如果后续有动态修改按钮文本、多语言适配的需求,自动适配逻辑一次编写后续不用反复调整,还是值得投入的。
疑问2:为什么cget('width')返回0,怎么拿实际宽度
cget('width')获取的是你手动给按钮设置的宽度属性值,你没手动设置的话默认值就是0,它不会返回自动计算的实际渲染宽度- 按钮的实际渲染宽度需要等控件完成布局渲染后才能获取,你可以调用
update_idletasks()方法强制触发Tkinter完成所有未执行的布局渲染任务,之后用winfo_reqwidth()方法获取控件自动计算的所需宽度,或者winfo_width()获取实际渲染的像素宽度
疑问3:Canvas上的Frame能不能设透明
Tkinter原生的Frame控件不支持透明度设置,放在Canvas上一定会遮挡背景,这个方案不可行。
具体实现代码
我们可以在按钮创建完成后强制触发渲染,拿到所有按钮的最大宽度,再统一给所有按钮设置相同宽度即可,修改后的可运行代码如下:
from tkinter import * class ThreeButtonMenu(): def __init__(self, button1_text, button2_text, button3_text, image_height = 600, image_width = 500, bg_input = 'space_background.png'): self.root = Tk() HxW = str(image_height)+'x'+str(image_width) self.root.geometry(HxW) self.root.maxsize(image_height,image_width) self.root.minsize(image_height,image_width) self.root.title('Guess') # 背景图存为实例属性避免被垃圾回收 self.bg = PhotoImage(file=bg_input) background_canvas = Canvas(self.root, width = 600, height=500) background_canvas.pack(fill="both", expand=True) background_canvas.create_image(0,0, image=self.bg, anchor='nw') button1 = Button(self.root, text=button1_text, font = ('Lato',28)) button2 = Button(self.root, text=button2_text, font = ('Lato',28)) button3 = Button(self.root, text=button3_text, font = ('Lato',28), command = self.root.destroy) # 强制触发渲染计算尺寸 self.root.update_idletasks() # 获取所有按钮的最大宽度 max_width = max(button1.winfo_reqwidth(), button2.winfo_reqwidth(), button3.winfo_reqwidth()) # 创建window时指定统一宽度,自动拉伸按钮 button1_window = background_canvas.create_window(300,45, anchor=N, window=button1, width=max_width) button2_window = background_canvas.create_window(300,160, anchor=N, window=button2, width=max_width) button3_window = background_canvas.create_window(300,275, anchor=N, window=button3, width=max_width) self.root.mainloop() start_menu = ThreeButtonMenu('Start Game', 'Leaderboard', 'Quit')
内容的提问来源于stack exchange,提问作者Cewu00
相关产品推荐
相关产品推荐

