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()