John,
Thank you for the tips.
I was changing the line-column index to a FLOAT because the search would
return the starting position (pos) of the string, then by making it a
FLOAT and adding the string length I was able to get the end position.
If "red" was on line 1 column 0..
Tbox.tag_add("red", pos, float(pos)+.03)
=
Tbox.tag_add("red", 1.0, 1.3)
It was all I could come up with.
You have convinced me about the re.finditer for this, I think...
Still in the prototyping mode:
def get_position(event):
pos = Tbox.get(1.0, END)
match = [ matchobj.span() for matchobj in
re.finditer("red", pos) ]
print "match ",match #debug to shell
Gives all of START,END pairs just fine. It is the last hint about
line-column indexes that I am have problems with. All of the
documentation I can find about "text.tag_add()" uses line-column for
coordinates.
If I count characters from the beginning how do I know what line the
text is on?
Would you mind making your last hint a bit stronger...
Thanks again!
Dave
John Posner wrote:
On Wed, 30 Dec 2009 12:58:06 -0500, Dave McCormick
<mackrac...@gmail.com> wrote:
Hi All,
I am new to Python and the list so I hope I am posting this
correctly...
I am working on a way to have text automatically formated in a
Tkiniter Text widget and would like some input on my code.
Currently I am using Python 2.5 because the server I use has that
installed. Tkinter is tk8.4.
Most of the time when I type red, blue, or green the code works as
expected. When I copy paste text into the widget the last line is
parsed with part of the previous lines
So I guess the problem is in the "looping"?
Here is my code:
from Tkinter import *
root = Tk()
def get_position(event):
start = 1.0
A couple of problems here: you define "start", but then never use it.
Worse, it looks like you don't understand that a line-column index
into a Tkinter Text widget is a STRING, not a FLOAT.
while 1: pos = Tbox.search("red",END,backwards=TRUE)
I suggest that you use Tbox.get() instead of Tbox.search(), and then
use Python's more powerful text-search tools. More on this below.
if not pos:
break
red = pos + "-1c"
Tbox.tag_add("red", pos, float(pos)+.03)
Tbox.tag_config("red", foreground="red")
You don't want to define the "red" tag every time get_position() is
executed -- that is, every time the user presses a key. Define the
red/green/blue tags just once, right after you create the Text widget.
pos = Tbox.search("blue",END,backwards=TRUE)
if not pos:
break
blue = pos + "-1c"
Tbox.tag_add("blue", pos, float(pos)+.04)
Tbox.tag_config("blue", foreground="blue")
pos = Tbox.search("green",END,backwards=TRUE)
if not pos:
break
green = pos + "-1c"
Tbox.tag_add("green", pos, float(pos)+.05)
Tbox.tag_config("green", foreground="green")
The previous 6 lines are almost identical to the 6 lines that precede
them. This is fine for prototyping, but when you find yourself writing
code like this, think about using a loop or a parameterized function
call. For example, you might write this function:
def insert_color_markup(color):
...
... and then call it as many times as you need to:
insert_color_markup("red")
insert_color_markup("green")
insert_color_markup("blue")
Now, about those text-search tools: the "re" (regular expression)
module include the function "finditer". This is a real power tool,
combining regular expressions and Python iterators -- both of which
can be intimidating to newcomers. But it's just what you want, IMHO. I
hope the following annotated IDLE transcript convinces you:
Python 2.6.4 (r264:75708, Oct 26 2009, 08:23:19) [MSC v.1500 32 bit
(Intel)] on win32
import re
text = """The red ball is red, not green. On other other
... hand, the green ball has both red and blue highlights.
... Thank you.
... """
re.finditer("red", text)
<callable-iterator object at 0x00CC46D0>
... not too exciting, but this is better:
list(re.finditer("red", text))
[<_sre.SRE_Match object at 0x00C01F70>, <_sre.SRE_Match object at
0x00C06E20>, <_sre.
SRE_Match object at 0x00C06E58>]
... this list indicates that we got three hits on the word "red"
[ matchobj.span() for matchobj in re.finditer("red", text) ]
[(4, 7), (16, 19), (77, 80)]
... paydirt: a list of (start,end) pairs for an invocation of
Text.tag_add()
One more hint: forget about the line-column indexes into the contexts
of a Text widget. Just count characters from the beginning, e.g.:
"1.0 + %d chars" % start_position
break
Tbox = Text(root,width=40, height=15, wrap=CHAR)
Tbox.grid(column=0, row=0, sticky=(N+W+E+S))
root.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(0, weight=1)
Tbox.bind("<KeyRelease>", get_position)
Tbox.focus()
root.mainloop()
Thank you,
Dave
I hope this set of hints is helpful, and not too disjointed, terse, or
cryptic. I think this is a cute little app!
-John
--
http://mail.python.org/mailman/listinfo/python-list