为什么小部件的创建顺序很重要?
下面的代码工作正常。 它显示一个 panedwindow
,顶部有一个蓝色框,下面有一个绿色框:
panedwindow .root -orient vertical -showhandle true -background red
frame .top -background blue -width 100 -height 100
frame .bot -background green -width 100 -height 100
.root add .top .bot
pack .root -expand true -fill both
但是,当我向下移动 panedwindow
命令时,一切都停止工作。 顶部的蓝色框未显示。 相反,panedwindow
本身的红色会闪闪发光:
frame .top -background blue -width 100 -height 100
panedwindow .root -orient vertical -showhandle true -background red
frame .bot -background green -width 100 -height 100
.root add .top .bot
pack .root -expand true -fill both
为什么会发生这种情况? panedwindow
真的只能管理在它之后创建的小部件吗? 我在打包程序中看到了类似的行为,它会拒绝将小部件 -in
打包到稍后出现的小部件中。
The following code works fine. It displays a panedwindow
, with a blue box on top and a green box below:
panedwindow .root -orient vertical -showhandle true -background red
frame .top -background blue -width 100 -height 100
frame .bot -background green -width 100 -height 100
.root add .top .bot
pack .root -expand true -fill both
However, when I move the panedwindow
command down, things stop working. The top, blue box is not shown. Instead, the red of the panedwindow
itself shines through:
frame .top -background blue -width 100 -height 100
panedwindow .root -orient vertical -showhandle true -background red
frame .bot -background green -width 100 -height 100
.root add .top .bot
pack .root -expand true -fill both
Why does this happen? Can a panedwindow
really only manage widgets that were created after it? I've seen similar behavior with the packer, where it will refuse to pack widgets -in
widgets that came later.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
正如马特指出的,这一切都与堆叠顺序有关。 堆叠顺序只是应用程序中小部件的“z 坐标”——您可以将其视为除了屏幕上的自然 x 和 y 坐标之外,还有另一个垂直于小部件平面的轴。屏幕。 所有的小部件都沿着这个轴放置在某个地方。 您在屏幕上实际看到的图像是沿该轴“展平”所有小部件的结果。 任何小部件在 x 和 y 平面上重叠的地方,您在该位置看到的就是堆叠顺序较高的小部件。
Tk 中小部件的默认堆叠顺序由它们的创建顺序决定。 它创建的小部件越早,它在堆叠顺序中的位置就越低 - 想象屏幕本身位于 z 坐标零,并且从屏幕向您传递的值不断增加。 创建的第一个小部件的堆叠顺序为零,第二个小部件的堆叠顺序为 1,依此类推。
解决问题的最简单的解决方案就是按正确的顺序创建小部件,但是
如果您执意要按照显示的顺序创建小部件,则可以稍后手动更改堆叠顺序,以确保小部件按照您想要的顺序堆叠。 例如,要将蓝色框架再次置于顶部,您可以添加:
这告诉 Tk 更改
.top
的堆叠顺序,使其位于.root
的“上方” >。当我使用窗格窗口小部件时,我倾向于让它管理子小部件 - 对我来说,它在概念上只是一个具有额外行为的框架,并且由于我使用框架将相关小部件分组在一起,因此我以相同的方式使用窗格窗口。 此策略还巧妙地回避了堆叠顺序的问题,因为它要求您首先创建窗格窗口 - 您必须这样做,因为在创建小部件本身之前您无法创建小部件的子级。 因此,我会像这样修改您的示例:
对我来说,这使得
.root
和.root.top
和.root.bot
之间存在关系清除:两个框架位于窗格窗口“内部”。 自然的堆叠顺序恰好是正确的,每个人都很高兴。It's all to do with stacking order, as Matt noted. Stacking order is just the "z-coordinate" for widgets in your app — you can think of it as if in addition to the natural x and y coordinates you have on the screen, there is another axis that is perpendicular to the plane of the screen. All the widgets lay somewhere along this axis. The image you actually see on screen is the result of "flattening" all the widgets together along that axis. Anywhere that widgets overlap in the x and y plane, the widget that is higher in the stacking order is what you see at that location.
The default stacking order of widgets in Tk is determined by their creation order. The earlier the widget it created, the lower it is in the stacking order — think of the screen itself being at z-coordinate zero, with increasing values coming towards you from the screen. The first widget created has stacking order zero, the second has one, etc.
The easiest solution to your problem is just to create the widgets in the right order, but
if you are dead set on creating the widgets in the order you've shown, you can manually change the stacking order later, to ensure the widgets are stacked in the order you want. For example, to bring your blue frame to the top again, you could add:
This tells Tk to change the stacking order of
.top
so that it is "above".root
.When I use the paned window widget, I tend to have it manage child widgets — to me, it is conceptually just a frame with extra behaviors, and since I use frames to group related widgets together, I use the paned window the same way. This policy also neatly sidesteps the question of stacking order since it requires that you have created the paned window first — you must, because you can't create children of a widget until the widget itself is created. Thus I would modify your example like this:
To me, this makes the relationship between
.root
and.root.top
and.root.bot
clear: the two frame are "inside" the paned window. The natural stacking order happens to be the correct one, and everybody is happy.哇,我已经有一段时间没有考虑过 Tcl/Tk 了。 感谢您的记忆之旅。 :)
根据这个链接,同级小部件的默认堆叠顺序是它们创建的顺序,而不是它们的包装顺序。 本质上,.top、.bot 和 .root 都是彼此的同级,因为它们在小部件层次结构中处于同一级别,即它们都“挂”在同一个父级上(在本例中为“.”)。 我希望如果您将 panedwindow 命令再向下移动一行,您也不会看到绿色框。 我认为,如果您将 .top 和 .bot 分别重命名为 .root.top 和 .root.bot,可能会解决您所看到的问题,因为这将使它们成为 .root 父级的子级。
希望这可以帮助。
Wow, it's been a while since I've even thought about Tcl/Tk. Thanks for the trip down memory lane. :)
According to this link, the default stacking order of sibling widgets is the order in which they were created, not the order they are packed. In essence, .top, .bot, and .root are all siblings of each other because they are at the same level in the widget hierarchy, i.e., they all 'hang' off the same parent ('.' in this case). I expect if you move the panedwindow command down one more line, you won't see the green box either. I think if you were to rename .top and .bot to .root.top and .root.bot, respectively, that might fix the issue you're seeing because that would make them children of the .root parent.
Hope this helps.