Why is the creation order of widgets important?

匿名 (未验证) 提交于 2019-12-03 10:10:24

问题:

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.

回答1:

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:

raise .top .root

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:

panedwindow .root -orient vertical -showhandle true -background red frame .root.top -background blue -width 100 -height 100 frame .root.bot -background green -width 100 -height 100 .root add .root.top .root.bot

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.



回答2:

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.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!