Combobox 梳棉机中的Tcl/Tk LstBox宽度

Combobox 梳棉机中的Tcl/Tk LstBox宽度,combobox,tcl,tk,Combobox,Tcl,Tk,如何在组合框中配置listbox组件宽度,使其适合最长的条目? 小部件宽度本身(条目组件)可能很短,但我正在寻找一种方法来配置listbox组件,使其比条目宽度更宽……这是可能的,但必须进行一些黑客攻击;) 您可以在combobox.tcl中找到combobox的实现(在我的例子中是/usr/share/tcltk/tk8.5/ttk/combobox.tcl。如果您有一个combobox,您会看到它 set cb [ttk::combobox .cb -state readonly] 并调用

如何在组合框中配置listbox组件宽度,使其适合最长的条目?
小部件宽度本身(条目组件)可能很短,但我正在寻找一种方法来配置listbox组件,使其比条目宽度更宽……

这是可能的,但必须进行一些黑客攻击;)

您可以在
combobox.tcl
中找到combobox的实现(在我的例子中是
/usr/share/tcltk/tk8.5/ttk/combobox.tcl
。如果您有一个combobox,您会看到它

set cb [ttk::combobox .cb -state readonly]
并调用它,它将创建以下内部小部件结构:

$cb.popdown.f.l
popdown
是当您单击组合框、
f
一个框架和包含您的值的实际列表框时弹出的顶层。要适合最长的条目,您需要修改
popdown
顶层的几何图形

我们试图通过将调整大小脚本绑定到组合框上的
按钮按下
事件来实现此目的,但是,这不起作用,因为默认情况下,绑定按以下顺序处理(输出
放置[bindtags$cb]
):

因此,首先处理小部件(
.cb
)上的事件,然后处理类(
TCombobox
)上的事件,然后处理顶层(
),最后处理绑定到所有小部件的事件。 这意味着,当我们单击组合框时,首先会执行调整大小脚本,但是,
弹出菜单
顶层仍然存在,因为它只会在处理类事件时创建

解决方案是切换小部件和类的事件处理顺序:

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}"                            
}
然后对每个字符串使用
font-measure
命令([2])来确定适合所有条目所需的像素。别忘了添加一点填充以获得更好的外观,并确保滚动条不会与文本重叠

NB:为了避免各种令人讨厌的东西,请确保在您尝试修改它之前,这个内部小部件结构已经就位,
ttk::combobox
的实现可能会改变,然后您的程序将不再工作!


[1]

[2]

也许水平滚动条是一个简单的解决方法(尽管没有完美大小的选择列表那么好)。
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}"                            
}
$cb.popdown.f.l cget -font