如何在组合框中配置列表框组件宽度,以使其适合最长条目?小部件宽度本身(条目组件)可能很短,但我正在寻找一种方法来将列表框组件配置为比条目更宽......
1 回答
这是可能的,但并非没有一点黑客行为;)
您可以在combobox.tcl
(在我的情况下)中找到组合框的实现/usr/share/tcltk/tk8.5/ttk/combobox.tcl
。在那里您会看到,如果您有一个组合框
set cb [ttk::combobox .cb -state readonly]
并调用它,它会创建以下内部小部件结构:
$cb.popdown.f.l
popdown
是当您单击组合框、f
框架和l
包含您的值的实际列表框时弹出的顶层。为了适应最长的条目,您需要修改popdown
顶层的几何形状。
我们尝试通过将调整大小脚本绑定到ButtonPress
组合框上的事件来做到这一点,但是,这不起作用,因为默认情况下,绑定按以下顺序处理(输出puts [bindtags $cb]
):
.cb TCombobox . all
因此,首先处理小部件 ( .cb
) 上的事件,然后处理类 ( TCombobox
) 上的事件,然后是顶层 ( .
),最后是绑定到所有小部件的事件。这意味着当我们单击组合框时,首先执行我们的调整大小脚本,然后popdown
顶层确实存在,因为它只会在处理类事件时创建。
解决方案是切换小部件和类的事件处理顺序:
bindtags $cb [list TCombobox $cb . all]
现在它应该可以工作了!下面是一个最小的概念证明:
package require Tk
wm title . "Combobox Listbox resize"
wm geometry . "150x40"
grid columnconfigure . 0 -weight 1
set cb [ttk::combobox .cb -width 20 -state readonly]
grid $cb -row 1 -column 0
set cmd "$cb configure -values {abarsdhresntdaenstdsnthret erstihre reshterhstierht}"
$cb configure -postcommand $cmd
bind $cb <ButtonPress> changeGeomPopdown
bindtags $cb [list TCombobox $cb . all]
proc changeGeomPopdown { } {
global cb
scan [wm geometry $cb.popdown] "%dx%d+%d+%d" w h x y
wm geometry $cb.popdown "300x${h}+${x}+${y}"
}
要获得所需的宽度,您需要询问列表框 [1] 的字体:
$cb.popdown.f.l cget -font
然后font measure
在每个字符串上使用命令 ([2]) 来确定适合所有条目所需的像素。不要忘记添加一些填充以获得更好的外观并确保滚动条不会与您的文本重叠。
注意:为避免各种讨厌的事情,请确保在尝试修改此内部小部件结构之前,它的实现ttk::combobox
可能会更改,然后您的程序将无法运行!
[1] http://www.tcl.tk/man/tcl8.5/TkCmd/listbox.htm#M16
[2] http://www.tcl.tk/man/tcl8.5/TkCmd/font.htm #M10