Executing a function on clicking specific Tkinter Label() text

58 Views Asked by At

I'm creating a Spellcheck application using Python and Tkinter's ScrolledText(). User input is spellchecked every time the spacebar is hit. The wrongly spelled words are highlighted in red, and a label shows suggested corrections for a specific word when that word is hovered over and clicked in the ScrolledText(). (Courtesy: @OysterShucker)

What I want: I want the misspelt word to be replaced with the corrected word when the corrected word is clicked on in the label. I'm using NLTK corpus to check for spelling and Textblob's Word() to suggest corrections.

I'm not quite sure how to do this on a Tkinter Label.

This is where I'm at so far:

import nltk
from nltk.corpus import words
from nltk.corpus import wordnet
import re
import tkinter as tk
from tkinter.scrolledtext import ScrolledText
import string
from textblob import Word


nltk.download("words")
nltk.download("wordnet")
w= words.words()+list(wordnet.words())
w.append("typing")
word_set= set(w) #set of correctly spelled words from NLTK corpus
root= tk.Tk()
root.geometry("600x600")
text= ScrolledText(root, font = ("Arial", 14))

label = tk.Label(root, text="")

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

wrong_words= []
def check(self):
    global wrong_words
    #get mark
    mark = text.mark_previous('lpos')

    #get characters from mark to just before last space or return
    word = text.get("lpos", f'{tk.INSERT}-1c')

    #if that word is not in the word list, tag it
    if not (re.sub("[^\w]", "", word.lower()) in word_set):
        text.tag_add('misspelled', "lpos", f'{tk.INSERT}-1c')
        if word[-1] in string.punctuation:
            word = word[0:len(word)-1]
        wrong_words.append(word)
        print(wrong_words)  #
        

    #move mark to caret position
    text.mark_set('lpos', tk.INSERT)

#check on return and space
for key in ('Return', 'space'):
    text.bind(f"<KeyRelease-{key}>", check)
    
text.pack()


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 wrong_words:
        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")
    blob_word= Word(word)
    result = blob_word.spellcheck()
    label_word= ""
    for el in result:
        label_word +=el[0]+"\n"
        
    label.configure(text="Did you mean: "+"\n"+label_word)  ##This is a label whose text I want to keybind to a function that replaces corresponding misspelt word with selected correction


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

#init mark at first position with gravity set to left so it wont move as you type
text.mark_set('lpos', "1.0") 
text.mark_gravity('lpos', tk.LEFT)

#make 1 tag and reuse it
text.tag_configure('misspelled', foreground= "red")

root.mainloop()


Code Output (when the word "Heppy" is clicked on) Heppy is clicked

0

There are 0 best solutions below