Andy Maleh <
and...@gmail.com> wrote:
> On Saturday, November 6, 2021 at 3:01:34 PM UTC-4, Rich wrote:
>> Andy Maleh wrote:
>> > Nevermind, I stand corrected. I just tried binding to '<KeyPress>'
>> > directly on the text widget in Python TKinter and it worked!
>> >
>> > I guess it is a Ruby-only issue that I cannot bind to standard events
>> > on the text widget.
>> If so, then it is a bug for the Ruby community.
>> > Well, that just leaves the originally reported issue then.
>> Which is not an issue. Deleting all the text tagged with a tag means
>> the tag is no longer associated with any text in the widget. If you
>> don't retag newly inserted text with that tag, it remains associated
>> with no text in the widget.
>>
>> And if the tag is not associated with any text in the widget, then the
>> bindings on that tag will not fire.
>
> I was able to resolve the Ruby issue by binding events directly on
> the text widget. It turned out Ruby had a special nicety whereby I
> do not have to surround the event by '<>'. Ruby automatically does
> it for me, so I could simply bind to 'KeyPress' instead of
> '<KeyPress>'.
Ah, that would make a difference then.
>
> About the original problem with tag bindings, I actually tried
> retagging on every text change and that didn't work.
>
> The reason is because the 'all' tag covering '1.0' to 'end' already
> covers all text from beginning to end for the past, present ,and
> future of the text widget content. Retagging does nothing to
> alleviate the problem.
Nope. Line numbers added below manually:
01 $ rlwrap wish
02 % text .t
03 .t
04 % pack .t
05 % .t insert end "The quick brown fox jumped over the lazy dog\n"
06 % .t insert end "Mary had a little lamb, it's fleece was white as snow\n"
07 % .t tag add all 0.0 end
08 % .t tag ranges all
09 1.0 4.0
10 % .t delete 0.0 end
11 % .t tag ranges all
12 % .t insert end "The quick brown fox jumped over the lazy dog\n"
13 % .t insert end "Mary had a little lamb, it's fleece was white as snow\n"
14 % .t tag ranges all
15 %
At line 7, a tag named all is added covering the entirety of the text.
The 'tag ranges' command shows it is attached to the text in the
widget.
Line 10 deletes all the text.
Line 11 shows that the 'all' tag is no longer associated to any text
within the widget.
Lines 12 and 13 reinsert the text (I just reused lines 5 and 6).
Line 14 shows that the all tag is unchanged, it is associated with no
text within the widget. To have a tag binding fire that tag must be
associated with some text in the widget. A tag with no text associated
to it will not fire its binding scripts.
> Here is a code example written in Python3 to illustrate:
>
> ```python
> from tkinter import *
> from tkinter import ttk
>
> root = Tk()
>
> text = Text(root)
> text.grid()
> text.insert('1.0', "Some giberish\nMore giberish\nNot well spelled giberish")
> text.tag_add('all', '1.0', 'end')
> def print_info(event):
> print('key press')
> print(event)
>
> def changed(event):
> print('modified')
> text.edit_modified(0)
> text.tag_remove('all', '1.0', 'end')
> text.tag_add('all', '1.0', 'end')
>
> text.bind('<<Modified>>', changed)
> text.tag_bind('all', '<KeyPress>', print_info)
>
> text.edit_modified(0)
>
> root.mainloop()
> ```
And..., if you were to delete all of the text in the widget (by say
'selecting all' and pressing "delete", you will end up with the all tag
not associated with any text. Subsequent typing of text after deleting
on the keyboard will insert untagged text, which will not be associated
to the "all" tag.
Here's another illustration:
$ rlwrap wish
% text .t
.t
% pack .t
% .t insert end "The quick brown fox jumped over the lazy dog\n"
% .t insert end "Mary had a little lamb, it's fleece was white as snow\n"
% .t tag add all 0.0 end
% .t tag configure all -background yellow
% # now type something at the end, it is in yellow
% .t get 0.0 end
The quick brown fox jumped over the lazy dog
Mary had a little lamb, it's fleece was white as snow
this is some new text
% # now delete the text in the widget using select all and delete key
% .t get 0.0 end
% .t tag ranges all
% # now type new text - it will not have a yellow background
% .t get 0.0 end
this is even newer text
% .t tag ranges all
%
The 'yellow' background just makes what is, or is not, tagged very
visible in the text widget.
Deleting everything by selecting all (control+/) and deleting (Delete)
results in an all tag with no ranges. And subsequent typing does not
enter text with a yellow background. That newly typed text is
untagged, because the select all plus delete by the keyboard
disassociated the tag with any text in the widget.