无法将小部件打包到兄弟姐妹的顶层

时间:2013-08-07 14:40:24

标签: tcl tk

我正在尝试pack(或place)一个小部件,它是另一个顶层内的根{4}的子级,是.本身的一个孩子。也就是说,

.

但是,我发现此代码几乎有效:

% toplevel .tl
.tl
% frame .f
.f
% pack .f -in .tl
can't pack .f inside .tl

我说差不多,因为% frame .tl .tl % frame .f .f % pack .f -in .tl % wm manage .tl 不可见。这有点奇怪,因为如果我在.f内放一个按钮,例如

.f

我看到几何管理器保留的空白区域,但没有可见的小部件。

我确定我做错了什么,但我不知道是什么和为什么,button .f.b -text FooBar pack .f.b packgrid手册页没有帮助。


编辑:有关我正在做的事情的一些细节

我正在尝试构建一个snit小部件,它可以自动创建一些顶级创建内容。我通常做的一件事是在我创建的每个顶层中放置一个place,并使用ttk::frame命令对其进行管理。

我的snidget总是应该这样做,但是我想从用户角度隐藏它,这样对实现的任何更改都不会破坏现有代码。

简单的方法就是这个

pack ... -fill both -expand true

但是用户必须知道snit::widget Toplevel { hulltype toplevel component f constructor {args} { set f [ttk::frame $self.f -padding 2] pack $f -fill both -expand 1 $self configurelist $args } } 组件,并创建其他小部件作为它的子项。

所以,我尝试了另一种解决方案:我使用f小部件作为船体类型,然后构建船体的兄弟顶部,并尝试将船体放入顶部。< / p>

我尝试的代码类似于以下内容:

ttk::frame

如果它按预期工作,用户可以这样写:

snit::widget Toplevel {
    hulltype ttk::frame
    component tl

    constructor {args} {
        set segments [split $self .]
        set wname [join [lreplace $segments end end _[lindex $segments end]] .]

        set tl [frame $wname -width 100 -height 100]
        pack $self -in $tl -fill both -expand 1
        wm manage $tl

        $self configurelist $args
    }
}

并使用snidget在顶层% Toplevel .t .t % button .t.b -text Foobar .t.b % pack .t.b 内部获得一个按钮。

2 个答案:

答案 0 :(得分:1)

你想要做的事是不可能的,Marco。所有小部件必须是其顶级容器的子级。

答案 1 :(得分:1)

除了toplevels 之外的小部件按严格的包含层次排列;小部件.foo包含小部件.foo.bar,小部件又包含.foo.bar.grill等.Toplevel小部件实际上是根窗口的所有子节点。

你可以做两件事来改变它。

  1. 您可以使用wm manage(需要8.5或更高版本)将标准框架窗口小部件转换为顶层窗口,并使用wm forget来转换它(您还必须重新设置{ {1}} / re - pack它也是。 (我认为这不支持OSX / Aqua。)

    grid
    frame .foo
    # Define its contents...
    wm manage .foo
    

    这是一对有用的操作,用于制作像工具栏一样的撕开窗口。在Tk小部件演示中甚至还有一个演示。

  2. 您可以在创建时将框架(或顶层)转换为容器窗口小部件(在创建选项中将# Later... wm forget .foo pack .foo 选项设置为true;以后无法完成)。然后,您可以获取窗口小部件的ID(使用-container)并在创建时告诉顶层 ,以通过winfo id选项将该小部件ID用作其父级。 / p>

    -use

    请注意,在这种情况下,在Unix / X11上,这些ID可以传递给其他进程并使用,而不需要实际引用由Tk创建的窗口。 (某些应用程序也可以反过来,将自己嵌入由Tk定义的ID给出的窗口中。)在Windows和OSX / Aqua上,ID只能保证在单个进程中工作。

  3. 我不知道你想要执行的操作是否可以通过这两种可能的操作完成;你不太清楚你正在尝试做什么的更高层次的观点。它们不能很好地混合,因为frame .foo -container 1 set id [winfo id .foo] toplevel .bar -use $id -container只是创建时选项,并且随后是只读的,并且您无法更改名称层次结构(在创建后完全修复) )。真正复杂的东西可能要求你退后一步并正式定义一个模型,你有多个小部件布局是视图。