更改TTK组合框的下拉列表框的宽度 [英] Change width of dropdown listbox of a ttk combobox
问题描述
我正在尝试更改为ttk组合框的弹出列表的宽度.设置组合框的宽度还会更改列表框的宽度,从而使部分值不可读.
I am trying to change to width of the popdown list of the ttk Combobox. Setting the width of the Combobox also changes the width of the Listbox, making part of the values unreadable.
我在Tk/Tcl中阅读了此解决方案,但是我对这种语言不熟悉,想解决Python的问题.我尝试更改主题参数,但似乎无济于事.下面是一段示例代码.
I read this solution in Tk/Tcl but I am not familiar with this language and would like to solve the problem with Python. I tried changing the theme parameters but it does not seem to help. Below is a piece of sample code.
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
root.title("testing the combobox")
root.geometry('300x300+50+50')
fruit = ['apples are the best', 'bananas are better']
c = ttk.Combobox(root, values=fruit, width=10)
c.pack()
# Trying to change the width, does not work
c.option_add("*TCombobox*Listbox*Width", 50)
root.mainloop()
这里有人可以帮助我或给我一些指导吗?
Anyone here that can help me out or give me some pointers?
推荐答案
细化爱国者的好答案,以使用派生样式而不是修改 TCombobox
样式获得通用解决方案(但要提防Tk的错误,稍后再讨论).
Elaboration of patthoyts' nice answer to get to an universal solution using a derived style instead of modifying the TCombobox
style (but beware of a Tk bug, more on that later).
基本上,将为每个组合框创建一个具有唯一名称的新样式(我不知道这种组合的扩展方式-也许只在需要的地方应用它才更安全).此外,组合框的值是从小部件本身读取的,并且取值最长的一个:如果插入了短文本,还应进行检查以避免将弹出窗口缩小为小部件.
Basically, a new style with an unique name is created for every combobox (I don't know how this could scale up - maybe it's safer to apply it only where is needed). Also, combobox values are read from the widget itself and the longest one is taken: there's also a check to avoid making the popdown smaller than whe widget, if short text is inserted.
import tkinter as tk
import tkinter.ttk as ttk
import tkinter.font as tkfont
def on_combo_configure(event):
combo = event.widget
style = ttk.Style()
# check if the combobox already has the "postoffest" property
current_combo_style = combo.cget('style') or "TCombobox"
if len(style.lookup(current_combo_style, 'postoffset'))>0:
return
combo_values = combo.cget('values')
if len(combo_values) == 0:
return
longest_value = max(combo_values, key=len)
font = tkfont.nametofont(str(combo.cget('font')))
width = font.measure(longest_value + "0") - event.width
if (width<0):
# no need to make the popdown smaller
return
# create an unique style name using widget's id
unique_name='Combobox{}'.format(combo.winfo_id())
# the new style must inherit from curret widget style (unless it's our custom style!)
if unique_name in current_combo_style:
style_name = current_combo_style
else:
style_name = "{}.{}".format(unique_name, current_combo_style)
style.configure(style_name, postoffset=(0,0,width,0))
combo.configure(style=style_name)
root = tk.Tk()
root.title("testing the combobox")
root.geometry('300x300+50+50')
fruit = ['apples are the best', 'bananas are way more better']
c = ttk.Combobox(root, values=fruit, width=10)
c.bind('<Configure>', on_combo_configure)
c.pack()
c1 = ttk.Combobox(root, values=['shorter','than','widget'], width=15)
c1.bind('<Configure>', on_combo_configure)
c1.pack()
root.mainloop()
但是...
如前所述,Tk Combobox中存在一个错误: postoffest
属性只能从 TCombobox
样式中读取,而不能从派生样式中读取.
But...
As stated before, there's a bug in Tk Combobox: the postoffest
property is read only from the TCombobox
style, not from derived styles.
这可以通过编辑 [python-install-dir] \ tcl \ tk [version] \ ttk \ combobox.tcl
来解决.在PlacePopdown方法中找到以下行:
This can be fixed by editing [python-install-dir]\tcl\tk[version]\ttk\combobox.tcl
; find this line in the PlacePopdown method:
set postoffset [ttk::style lookup TCombobox -postoffset {} {0 0 0 0}]
并替换为:
set style [$cb cget -style]
set postoffset [ttk::style lookup $style -postoffset {} {0 0 0 0}]
或者,等待我的拉动请求被合并并释放.
Or, wait for my pull request to get merged and released.
这篇关于更改TTK组合框的下拉列表框的宽度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!