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.
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.
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.