pythonpython-3.xtkintertextbox

Tkinter Text widget - Use clicked text in event function


I currently have a a log parser that puts user infomration into a Text widget. If a line that is inserted into the Text widget has a keyword the line will be highlighted blue. If that line is clicked i'd like to use the text from that line in the event function that carries out.

Because I am using the config for my tag to color the line blue, am I not able to also copy the clicked text?

Example of the code:

from tkinter import *


def callback(event):
    window = Toplevel()
    window.overrideredirect(1)
    window.geometry("200x100+{0}+{1}".format(event.x_root-1, event.y_root-12))
    label = Label(window, justify="left", text="Username: value \nLocation: value \nAddress: value \nSecurity Level: value")
    label.grid()
    window.bind("<Leave>", lambda e: window.destroy())

root = Tk()
text = Text(root)
text.insert(END, "Click here", "tag")
text.pack()
text.tag_config("tag", foreground="blue")
text.tag_bind("tag", "<Button-1>", callback)

root.mainloop()

How can I take the username that is clicked and use it in the function? I just want to set the username to a variable and use that, im just missing how to do it.


Solution

  • You can use individual tag for every clicked text and then you can send it as argument to binded function

    import tkinter as tk
    
    
    def callback(event, tag):
        print(event.widget.get('%s.first'%tag, '%s.last'%tag))
    
    root = tk.Tk()
    
    text = tk.Text(root)
    text.pack()
    
    text.tag_config("tag1", foreground="blue")
    text.tag_bind("tag1", "<Button-1>", lambda e:callback(e, "tag1"))
    text.insert('end', "first link", "tag1")
    
    text.insert('end', " other text ")
    
    text.tag_config("tag2", foreground="blue")
    text.tag_bind("tag2", "<Button-1>", lambda e:callback(e, "tag2"))
    text.insert('end', "second link", "tag2")
    
    root.mainloop()
    

    EDIT:

    I found how to convert mouse position and find clicked tag so it doesn't need individual tags.

    Python TKinter get clicked tag in text widget

    import tkinter as tk
    
    
    def callback(event):
        # get the index of the mouse click
        index = event.widget.index("@%s,%s" % (event.x, event.y))
    
        # get the indices of all "tag" tags
        tag_indices = list(event.widget.tag_ranges('tag'))
    
        # iterate them pairwise (start and end index)
        for start, end in zip(tag_indices[0::2], tag_indices[1::2]):
            # check if the tag matches the mouse click index
            if event.widget.compare(start, '<=', index) and event.widget.compare(index, '<', end):
                # return string between tag start and end
                print(start, end, event.widget.get(start, end))
    
    root = tk.Tk()
    
    text = tk.Text(root)
    text.pack()
    
    text.tag_config("tag", foreground="blue")
    text.tag_bind("tag", "<Button-1>", callback)
    
    text.insert('end', "first link", "tag")
    
    text.insert('end', " other text ")
    
    text.insert('end', "second link", "tag")
    
    root.mainloop()