Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

'canvas bbox all' returns wrong value!

Status
Not open for further replies.

tmaslach

Programmer
Mar 13, 2008
3
0
0
US
All,

I have the following working example:

catch { destroy .w }
toplevel .w
canvas .w.cns -relief sunken -background "blue" -yscrollcommand ".w.cns.sbY set"
scrollbar .w.cns.sbY -orient vertical -command ".w.cns yview"
foreach id { 0 1 2 } {
if { 1 } {
frame .w.cns.frm$id
label .w.cns.frm$id.lbl -text "Label $id"
grid .w.cns.frm$id.lbl -row 0 -column 0
entry .w.cns.frm$id.ent -width 8
grid .w.cns.frm$id.ent -row 0 -column 1
} else {
checkbutton .w.cns.frm$id -text "CheckButton $id"
}
.w.cns create window 0 [expr { $id * 25 }] -window .w.cns.frm$id -anchor nw
}
pack .w.cns.sbY -side right
pack .w.cns -fill both
.w.cns configure -scrollregion [.w.cns bbox all]


It's rough looking, but if you look in the canvas box, you'll notice that you can only scroll two thirds of the way down - not all the way down (there are 3 rows of widgets)!

Diagnosing things, I noticed that the canvas' "bbox all" is returning the wrong value. It is returning 1 pixel greater than the y value I use in "create window". If, after executing the above code, I manually call ".w.cns configure -scrollregion [.w.cns bbox all]", "bbox all" returns the correct value and I can scroll through all 3 rows of widgets. I also noticed I can add an "update" call right before the configure call to get it working. Unfortunately, I don't see these as good solutions (discussed more later).

I think I understand the problem here. The label/entry/checkbox is not getting built until after the configure happens when we return to the main messaging loop. This is why the second configure call works when I type it in the console.

"update", on the other hand, forces the messaging loop to be called recursively, which fixes the problem as well. update causes the label/entry/checkbox to be full built and "bbox all" returns the right value. However, update also causes all sorts of problems because I sometimes get the rug pulled out from under me (one example is if the user is quick enough to close the dialog box before update gets hit - not possible in this example, but a problem I have seen in other code misusing update).

Is there a hook I can use for the above example? I know <Configure> will work on building the first time - problem is, that doesn't solve the problem when I want to add something on the fly. Here is some example code:

set id 3
checkbutton .w.cns.frm$id -text "CheckButton $id"
.w.cns create window 0 [expr { $id * 25 }] -window .w.cns.frm$id -anchor nw
.w.cns configure -scrollregion [.w.cns bbox all]

What hook can I use that I can trust in each case? By the way, Configure in my opinion is slightly overkill for this task, since it'll get called many more times than necessary.

Also, is there a better recommended widget? This is a secondary question, since I have no choice but to use canvas for now.

Thanks for any help!
 
Try using wait to delay execution of the configure command. Alternatively, you could use vwait to only execute after some variable gets set but I'm not seeing what variable that would be.

_________________
Bob Rashkin
 
@Bong

Thanks for the response. What does wait and vwait do? Don't they process the messaging loop as well? That would seem to cause the same problem as update then.

One crucial thing I forgot to mention - if I change the if "{ 1 }" to "if { 0 }", things do begin working. It seems that the extra level of indirection (the extra frame that I am adding, which has the widgets in it) is causing all the grief. If I just add the widgets, problem is solved.

Is it not good to have window managers indirectly in a canvas?
 
I've never run into a problem like this so I don't really have an opinion as what might be the root cause.

As to wait, I don't think the execution of the wait causes any processing per se. The interpreter pauses, allowing any processing that is happening in the stack to proceed, I think.

_________________
Bob Rashkin
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top