Am 02.01.2015 um 15:50 schrieb Francois Vogel:
> nemethi a écrit le 02/01/2015 13:03 :
>> What you wrote about the "two unexpected things" above might be the
>> expected behavior. From the "text" man page, section "EMBEDDED
>> WINDOWS", option "-create script":
>>
>> "... If the annotation's window should ever be deleted, script will be
>> evaluated again the next time the annotation is displayed."
>
> Yes I had read that line too before writing.
>
> I thought that it means that when the embedded window gets undisplayed,
> e.g. because it is off screen, or obscured by another item, or out of
> the visible part of the text, then the -create window will be run again
> when the embedded window needs to be displayed again (i.e. when it's
> again visible on screen).
>
> Another interpretation is that this sentence seems to say that any
> attempt to delete the embedded window will run the -create script again
> if the embedded window index position is still on screen? Isn't this
> unexpected? Why such a behavior?
> That means that "destroy.t.l" cannot be used to remove an embedded
> window from a text widget since it:
> 1. runs the -create script again
> 2. has no effect with respect to removing the window from the text
> widget.
>
> Well, why not after all...
>
This is yet another text widget story. Consider the following simple
script:
pack [text .t -height 5] -expand yes -fill both
proc createLabel line {
set w .t.l$line
if {![winfo exists $w]} {
puts "creating label $w"
label $w -text "Label $line"
}
return $w
}
for {set line 1} {$line <= 10} {incr line} {
.t window create $line.0 -create [list createLabel $line]
.t insert end \n
}
after 2000 {
puts "\n2 seconds later:"
for {set line 1} {$line <= 10} {incr line} {
destroy .t.l$line
}
}
On my Linux box, with Tk 8.5 and 8.6, I get the output:
creating label .t.l1
creating label .t.l2
creating label .t.l3
creating label .t.l4
creating label .t.l5
creating label .t.l6
creating label .t.l7
creating label .t.l8
creating label .t.l9
creating label .t.l10
2 seconds later:
creating label .t.l1
creating label .t.l2
creating label .t.l3
creating label .t.l4
creating label .t.l5
creating label .t.l6
creating label .t.l7
creating label .t.l8
creating label .t.l9
creating label .t.l10
Actually, the text widget (of height 5) can only display 4 lines
(because the embedded labels make the lines a bit higher). For this
reason, IMHO it is a bug that all 10 labels get created (and recreated).
With Tk 8.4, only 4 labels are created. IMO, this is the correct behavior:
creating label .t.l1
creating label .t.l2
creating label .t.l3
creating label .t.l4
2 seconds later:
creating label .t.l1
creating label .t.l2
creating label .t.l3
creating label .t.l4
I had reported this bug in October 2006 (item #1581955), as follows:
In Tk 8.5, the text widget command
<path> window create <index> -create <script>
doesn't behave as expected. From the man page:
"... this script will be evaluated when the annotation
is about to be displayed on the screen. ... If the
annotation's window should ever be deleted, script will
be evaluated again the next time the annotation is
displayed."
In earlier Tk versions, the window's creation was
delayed indeed as specified in the man page, i.e.,
until effectively displaying it on the screen. This
was a very useful feature, allowing the creation of a
large number of embedded windows, of which only a few
had to really exist. For example, whenever vertical
scrolling or anything else made it necessary to update
the view, it was possible to destroy the windows
embedded into the other lines. A very effective way to
save resources and avoid problems related to keyboard
navigation with the Tab key (which becomes awfully slow
in the presence of a large number of windows).
In Tk 8.5, the "-create" option behaves basically like
"-window". The [window names] subcommand returns the
names of *all* embedded windows, and it is quite easy
to see that all of these really exist. Any attempt to
delete some of them fails, because they are immediately
recreated, contrary to what is stated in the documentation.
---
Comment By: Csaba Nemethi (nemethi)
Date: 2009-10-20 14:25
Message:
Any chance to see this annoying bug fixed in the near future?
---
Comment By: Donal K. Fellows (dkf)
Date: 2010-01-05 01:11
Message:
Bluntly, there's not much chance of fixing this unless we can find
someone who really groks the (now horrendously complex) text widget code
in enough detail. My suspicion/hunch is that it'll be hard to fix
because we now need the dimensions of the embedded windows much earlier
so that we can get smooth scrolling right.
---
Comment By: Francois VOGEL (fvogelnew1)
Date: 2012-05-17 13:22
Message:
Test script:
pack [text .t]
for {set i 1} {$i < 100} {incr i} {
.t insert end $i\t$i--$i--$i--$i--$i\n
}
proc cremwin {} {
puts "NOW running the -create script"
return [entry .t.e2]
}
# create embedded window out of the currently visible area
# In Tk 8.5 the message displays as soon as we hit enter
# on next line - BUG
# In Tk 8.4 the message displays only when scrolling down
# so that line 50 becomes visible - OK
.t window create 50.5 -create cremwin
From the above I conclude that this problem is probably very hard to
solve. For Tablelist I found the following workaround: Immediately
after invoking "window create", I apply an elided tag to the respective
text position. This prevents the embedded window from being effectively
created. Then, whenever the visible portion of the tablelist's body
text widget changes, I remove that tag from the embedded windows of the
currently visible lines (this will trigger the respective creation
scripts), apply it to the other embedded windows, and destroy the
latters (again, due to that elided tag, the windows just deleted won't
get recreated). Not really the fine English art, but it does the trick.
Now, what should be the next step regarding this bug report (submitted
over 8 years ago)? If it would really need too much work to restore the
behavior known from Tk 8.4 and earlier, I think the man page should be
corrected accordingly and extended by the following 3 comments:
1) Eliding an embedded window immediately after scheduling it for
creation via "window create" will prevent it from being effectively created.
2) Uneliding an elided embedded window will automatically trigger the
associated creation script.
3) After destroying an elided embedded window, the latter won't get
automatically recreated.
Just a possible way towards closing that bug item.