Home > Software engineering >  Tkinter text that executes functions on click, highlights when cursor hovers
Tkinter text that executes functions on click, highlights when cursor hovers

Time:05-29

What I`m using: Tkinter

What I want: to create a text with keywords that will be highlighted when the cursor hovers over them, and to execute the function bound to them when you click on it. In the future I plan to bind additional information to these words

How it looks for me for now: the closest thing I've found is how to call functions when hovering over and clicking on text in a Label using bind() function (like bind("<Enter>", red_text)). But this way I have no way to change one specific word. In addition, if it turns out that the only way to do what I want is to create individual Labels for each of the sentences and keywords, and then posit them as well, then I'm not sure how to make it simpler

For what I need it and what I expect to see: I want to be able to write fiction text, in which later, will be identified keywords. These keywords, when activated, will offer pre-created answer options for them

A bit more illustrative example:

Text: Hello, world!, where the main text is displayed like non-bold and italic, and keyword the opposite - bold and non-italic. Fonts is white

Keyword: "world" - bound with functions that change and return the original color (depending on whether the cursor points to it) and a more complex function, when clicked, that offers answer choices in a separate window (which initially contains the standard answers)

Answer options before pressing the keyword:

1. Hi!

And after:

1. What world?
2. The world is me?
3. Who are you talking to?

CodePudding user response:

You can create a binding on <Motion> to call a function whenever the mouse moves. In the callback you can find the index of the character under the cursor using an index like "@x,y", and from that you can get the word.

You can then add a tag on that word, set some marks to help you find the word in a callback, and have a binding on the tag that calls a function when the widget is clicked.

Here's an example:

import tkinter as tk

root = tk.Tk()

text = tk.Text(root, width=80, height=10)
label = tk.Label(root, text="")

label.pack(side="bottom", fill="y")
text.pack(fill="both", expand=True)

text.tag_configure("keyword", background="black", foreground="white")
text.insert("end", "Hello, world!\nThis has another hidden keyword\n")

keywords = ["world", "another"]
def hover(event):
    text = event.widget
    keyword_start = text.index(f"@{event.x},{event.y} wordstart")
    keyword_end = text.index(f"@{event.x},{event.y} wordend")
    word = text.get(keyword_start, keyword_end)

    text.tag_remove("keyword", "1.0", "end")

    if word in keywords:
        text.mark_set("keyword_start", keyword_start)
        text.mark_set("keyword_end", keyword_end)
        text.tag_add("keyword", keyword_start, keyword_end)

def keyword_click(event):
    text = event.widget
    word = text.get("keyword_start", "keyword_end")
    label.configure(text=f"you clicked on the word '{word}'")

text.bind("<Motion>", hover)
text.tag_bind("keyword", "<1>", keyword_click)

root.mainloop()

screenshot after clicking on 'hello'

  • Related