Tkinter problem while using the text widget

113 Views Asked by At

I have this code to make each text "clickleable", from the Text() widget that has tkinter. However, when I run the program and click over one text I get this error message witch each corresponding text line:

_tkinter.TclError: bad text index "This is the first string." _tkinter.TclError: bad text index "This is the second string." _tkinter.TclError: bad text index "This is the third string."

If anyone may now a way to solve the issue, I be forever grateful. Here is the complete code:

import tkinter as tk

def text_click(event):
    index = text_widget.tag_names(tk.CURRENT)[0]
    clicked_text = text_widget.get(index)
    print(clicked_text)

# Create the main window
window = tk.Tk()

# Create a Text widget
text_widget = tk.Text(window, wrap="word")
text_widget.pack()

# List of strings
texto = ["This is the first string.", "This is the second string.", "This is the third string."]

# Insert each string from the list
for string in texto:
    text_widget.insert(tk.END, string + "\n")

    # Apply a tag to each inserted string
    tag_start = f"{text_widget.index(tk.END)}-{len(string) - 1}c"
    tag_end = f"{text_widget.index(tk.END)}-1c"
    text_widget.tag_add(string, tag_start, tag_end)

    # Bind the click event to the tag
    text_widget.tag_bind(string, "<Button-1>", text_click)

# Make the text widget read-only
text_widget.configure(state="disabled")

# Start the tkinter event loop
window.mainloop()

I am expecting to print the text of each line when clicked over it.

2

There are 2 best solutions below

0
Ake On BEST ANSWER

You can modify your text_click function like this:

def text_click(event):
    index = text_widget.index(tk.CURRENT)
    clicked_text = text_widget.get(index + " linestart", index + " lineend")
    print(clicked_text)

This retrieves the index of the clicked text using text_widget.index(tk.CURRENT), then it uses that index to retrieve the actual text by adding the appropriate linestart and lineend modifiers to the index.

3
Bryan Oakley On

If you print out index, you'll see it's the string in the error: "This is the first string.". That is not a valid index. An index needs to be something like line.character or @x,y, and a few other special strings (eg: "end", "current", etc).

I am expecting to print the text of each line when clicked over it.

You can use an index of the form @x,y, and you can use the x and y attributes of the event to create that index. Another alternative is to use the index "current" which represents the character closest to the mouse.

You can use "linestart" and "lineend" to translate that index to the start and end of the line.

Example:

def text_click(event):
    start_index = text_widget.index(f"@{event.x},{event.y} linestart")
    end_index = text_widget.index(f"@{event.x},{event.y} lineend")
    clicked_text = text_widget.get(start_index, end_index)
    print(clicked_text)