2

I need to consequently find each matching word add scroll to it in the text box with a button click. This function only finds the first matching word. How can I feed the updated index to a function that is bound to the button?

def find(idx='1.0'):
    text.tag_remove('found', idx, END)
    s = edit.get()
    if s:
        idx = text.search(s, idx, nocase=1,
                          stopindex=END)
        if not idx:
            return None
  
        foundidx = '%s+%dc' % (idx, len(s))

        text.tag_add('found', idx, foundidx)
        text.see(foundidx)

        text.tag_config('found', foreground='red')
        edit.focus_set()

    return foundidx
LetzerWille
  • 5,355
  • 4
  • 23
  • 26
  • 1
    did you [read](https://stackoverflow.com/a/19466754/13629335) ? – Thingamabobs Dec 05 '20 at 17:32
  • @Atlas435, thank you for the link. Now I am able to highlight all the matches in the text. But, since the file is huge, I'd like to be able to go to the each highlighted entry with a button click. And that I haven't figured out yet. – LetzerWille Dec 06 '20 at 00:19

1 Answers1

1

To achive this you need a Text widget and a root that display via widget a example text. I did it with this:

import tkinter as tk

root = tk.Tk()

text = tk.Text(root)
text.pack()
text.insert('1.0','''
Lorem ipsum dolor sit amet, consetetur sadipscing elitr,
sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren,
no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet,
consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.

Lorem ipsum dolor sit amet, consetetur sadipscing elitr,
sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren,
no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet,
consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.

Lorem ipsum dolor sit amet, consetetur sadipscing elitr,
sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren,
no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet,
consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.

Lorem ipsum dolor sit amet, consetetur sadipscing elitr,
sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren,
no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet,
consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.

text by: https://www.loremipsum.de/
''')

after this I followed the instructions of the link out of the comments. And extended it by saveing the positions and the index.

countVar = tk.StringVar()
idxVar = tk.StringVar()
posis = []
def search():
    try:
        if idxVar.get():
            new_idx = float(idxVar.get()+countVar.get())
            pos = text.search('sed', new_idx, 'end', count=countVar)
            text.tag_add('search', pos, '%s + %sc' % (pos, countVar.get()))
            text.tag_configure('search', background='green')
            idxVar.set(pos)
            posis.append(pos)
        else:
            pos = text.search('sed', '1.0', 'end', count=countVar)
            text.tag_add('search', pos, '%s + %sc' % (pos, countVar.get()))
            text.tag_configure('search', background='green')
            idxVar.set(pos)
            posis.append(pos)
    except:
        idxVar.set('1.0')

button = tk.Button(root,text='search',command=search)
button.pack()

At least I used the Text.see method to jump to the points of my posis list:

show = tk.IntVar()
show.set(0)

def see():
    if show.get() <= len(posis)-1:
        pos = show.get()
        text.see(posis[show.get()])
        show.set(pos+1)
    else:
        show.set(0)
        

button2= tk.Button(root,text='see', command=see)
button2.pack()

root.mainloop()

I know this code can be improved by a lot, but it should show the priciple and I used to code it self explanatory. But if there are open questions, let me know and I improve this answer.

Thingamabobs
  • 7,274
  • 5
  • 21
  • 54