OptionMenu 修改下拉列表宽度以匹配 OptionMenu 宽度
OptionMenu modify drop down list width to match OptionMenu width
现在我知道已经有一个类似的问题Python Tkinter: OptionMenu modify dropdown list width但是这对我没有帮助。
我正在尝试使 OptionMenu 小部件的下拉菜单的宽度具有响应性。这意味着宽度将始终与 OptionMenu 的宽度相匹配。如下面的代码所示,我尝试了一些方法,但它们不适用于子菜单,它始终保持固定宽度。没有办法改变吗?
import tkinter as tk
root = tk.Tk()
var = tk.StringVar()
var.set('First')
option = tk.OptionMenu(root, var, 'First', 'Second', 'Third')
option.configure(indicatoron = False)
option.pack(expand = True, fill = tk.X)
# Sub-menu config
submenu = option['menu']
submenu.configure(width = 50) # Can't use width
submenu.pack_configure(expand = True, fill = tk.X) # Can't use pack_configure
root.mainloop()
虽然无法明确设置宽度,但如果您确实必须使用 tkinter,则可以添加 hacky 解决方法来填充这些内容。这方面的例子是:
import tkinter as tk
from tkinter import font as tkFont
def resizer(event=None):
print("Resize")
widget = event.widget
menu = widget['menu']
req_width = widget.winfo_width()-10
menu_width = menu.winfo_reqwidth()
cur_label = menu.entrycget(0, "label")
cur_label = cur_label.rstrip() # strip off existing whitespace
font = tkFont.Font() # set font size/family here
resized = False
while not resized:
difsize = req_width - menu_width # check how much we need to add in pixels
tempsize = 0
tempstr = ""
while tempsize < difsize:
tempstr += " " # add spaces into a string one by one
tempsize = font.measure(tempstr) #measure until big enough
menu.entryconfigure(0, label=cur_label + tempstr) # reconfigure label
widget.update_idletasks() # we have to update to get the new size
menu_width = menu.winfo_reqwidth() # check if big enough
cur_label = menu.entrycget(0, "label") # get the current label for if loop needs to repeat
if menu_width >= req_width: # exit loop if big enough
resized = True
root = tk.Tk()
var = tk.StringVar()
var.set('First')
option = tk.OptionMenu(root, var, 'First', 'Second', 'Third')
option.bind("<Configure>", resizer) # every time the button is resized then resize the menu
option.configure(indicatoron = False)
option.pack(expand = True, fill = tk.X)
root.mainloop()
这基本上只是填充第一个菜单项,直到菜单足够大。然而,tkinter 报告的宽度似乎确实存在一些差异,因此我的 req_width = widget.winfo_width()-10
偏移量接近顶部。
然而,这并不总是完美匹配大小,而测试我的 space 似乎需要 3 个像素的宽度,因此它可能随时有 1 或 2 个像素。
现在我知道已经有一个类似的问题Python Tkinter: OptionMenu modify dropdown list width但是这对我没有帮助。
我正在尝试使 OptionMenu 小部件的下拉菜单的宽度具有响应性。这意味着宽度将始终与 OptionMenu 的宽度相匹配。如下面的代码所示,我尝试了一些方法,但它们不适用于子菜单,它始终保持固定宽度。没有办法改变吗?
import tkinter as tk
root = tk.Tk()
var = tk.StringVar()
var.set('First')
option = tk.OptionMenu(root, var, 'First', 'Second', 'Third')
option.configure(indicatoron = False)
option.pack(expand = True, fill = tk.X)
# Sub-menu config
submenu = option['menu']
submenu.configure(width = 50) # Can't use width
submenu.pack_configure(expand = True, fill = tk.X) # Can't use pack_configure
root.mainloop()
虽然无法明确设置宽度,但如果您确实必须使用 tkinter,则可以添加 hacky 解决方法来填充这些内容。这方面的例子是:
import tkinter as tk
from tkinter import font as tkFont
def resizer(event=None):
print("Resize")
widget = event.widget
menu = widget['menu']
req_width = widget.winfo_width()-10
menu_width = menu.winfo_reqwidth()
cur_label = menu.entrycget(0, "label")
cur_label = cur_label.rstrip() # strip off existing whitespace
font = tkFont.Font() # set font size/family here
resized = False
while not resized:
difsize = req_width - menu_width # check how much we need to add in pixels
tempsize = 0
tempstr = ""
while tempsize < difsize:
tempstr += " " # add spaces into a string one by one
tempsize = font.measure(tempstr) #measure until big enough
menu.entryconfigure(0, label=cur_label + tempstr) # reconfigure label
widget.update_idletasks() # we have to update to get the new size
menu_width = menu.winfo_reqwidth() # check if big enough
cur_label = menu.entrycget(0, "label") # get the current label for if loop needs to repeat
if menu_width >= req_width: # exit loop if big enough
resized = True
root = tk.Tk()
var = tk.StringVar()
var.set('First')
option = tk.OptionMenu(root, var, 'First', 'Second', 'Third')
option.bind("<Configure>", resizer) # every time the button is resized then resize the menu
option.configure(indicatoron = False)
option.pack(expand = True, fill = tk.X)
root.mainloop()
这基本上只是填充第一个菜单项,直到菜单足够大。然而,tkinter 报告的宽度似乎确实存在一些差异,因此我的 req_width = widget.winfo_width()-10
偏移量接近顶部。
然而,这并不总是完美匹配大小,而测试我的 space 似乎需要 3 个像素的宽度,因此它可能随时有 1 或 2 个像素。