Game with username entry using tkinter - python-3.x

I've downloaded a sample snake game from this github and I am desperately trying to modify the code to have an additional username entry window which then displays the username as the game is being played. I'd also hoping to code a leaderboard once I have the current issue sorted out.
My problem is that while the game itself works great as soon as I added the additional code to open the username entry window at the start the window dimension are applied to the game window as well.
Can anyone point out the likely blindingly obvious thing I'm missing here? My code is everything after the comment line.
import tkinter as tk
from random import randint
from PIL import Image, ImageTk
from tkinter import messagebox
MOVE_INCREMENT = 20
MOVES_PER_SECOND = 15
GAME_SPEED = 1000 // MOVES_PER_SECOND
def StartGame():
class Snake(tk.Canvas):
def __init__(self):
super().__init__(
width=600, height=620, background="black", highlightthickness=0
)
self.snake_positions = [(100, 100), (80, 100), (60, 100)]
self.food_position = self.set_new_food_position()
self.direction = "Right"
self.score = 0
self.load_assets()
self.create_objects()
self.bind_all("<Key>", self.on_key_press)
self.pack()
self.after(GAME_SPEED, self.perform_actions)
def load_assets(self):
try:
self.snake_body_image = Image.open("./assets/snake.png")
self.snake_body = ImageTk.PhotoImage(self.snake_body_image)
self.food_image = Image.open("./assets/food.png")
self.food = ImageTk.PhotoImage(self.food_image)
except IOError as error:
print(error)
root.destroy()
def create_objects(self):
self.create_text(
45, 12, text=f"Score: {self.score}", tag="score", fill="#fff", font=(10)
)
self.create_text(
150, 12, text=f"Username: {username}", tag="username", fill="#fff", font=(10)
)
for x_position, y_position in self.snake_positions:
self.create_image(
x_position, y_position, image=self.snake_body, tag="snake"
)
self.create_image(*self.food_position, image=self.food, tag="food")
self.create_rectangle(7, 27, 593, 613, outline="#525d69")
def check_collisions(self):
head_x_position, head_y_position = self.snake_positions[0]
return (
head_x_position in (0, 600)
or head_y_position in (20, 620)
or (head_x_position, head_y_position) in self.snake_positions[1:]
)
def check_food_collision(self):
if self.snake_positions[0] == self.food_position:
self.score += 1
self.snake_positions.append(self.snake_positions[-1])
self.create_image(
*self.snake_positions[-1], image=self.snake_body, tag="snake"
)
self.food_position = self.set_new_food_position()
self.coords(self.find_withtag("food"), *self.food_position)
score = self.find_withtag("score")
self.itemconfigure(score, text=f"Score: {self.score}", tag="score")
def end_game(self):
self.delete(tk.ALL)
self.create_text(
self.winfo_width() / 2,
self.winfo_height() / 2,
text=f"Game over! You scored {self.score}!",
fill="#fff",
font=("", 10)
)
def move_snake(self):
head_x_position, head_y_position = self.snake_positions[0]
if self.direction == "Left":
new_head_position = (head_x_position - MOVE_INCREMENT, head_y_position)
elif self.direction == "Right":
new_head_position = (head_x_position + MOVE_INCREMENT, head_y_position)
elif self.direction == "Down":
new_head_position = (head_x_position, head_y_position + MOVE_INCREMENT)
elif self.direction == "Up":
new_head_position = (head_x_position, head_y_position - MOVE_INCREMENT)
self.snake_positions = [new_head_position] + self.snake_positions[:-1]
for segment, position in zip(self.find_withtag("snake"), self.snake_positions):
self.coords(segment, position)
def on_key_press(self, e):
new_direction = e.keysym
all_directions = ("Up", "Down", "Left", "Right")
opposites = ({"Up", "Down"}, {"Left", "Right"})
if (
new_direction in all_directions
and {new_direction, self.direction} not in opposites
):
self.direction = new_direction
def perform_actions(self):
if self.check_collisions():
self.end_game()
self.check_food_collision()
self.move_snake()
self.after(GAME_SPEED, self.perform_actions)
def set_new_food_position(self):
while True:
x_position = randint(1, 29) * MOVE_INCREMENT
y_position = randint(3, 30) * MOVE_INCREMENT
food_position = (x_position, y_position)
if food_position not in self.snake_positions:
return food_position
root = tk.Tk()
root.title("Snake")
root.resizable(False, False)
root.tk.call("tk", "scaling", 4.0)
board = Snake()
root.mainloop()
# My code
window = tk.Tk()
window.title("Snake game")
window.geometry('250x120')
Usern_label= tk.Label(window, text="Username: ", font=("Arial Bold", 10))
Usern_label.place(x=10, y=10)
UsernInput = tk.Text(window, bg='White', bd=5, width=15, height=1)
UsernInput.pack
UsernInput.place(x=90, y=10)
username = UsernInput.get("1.0", "end-1c")
if len(username) > 8:
messagebox.showwarning("Invalid username", "Please enter a valid username")
usern_button = tk.Button(window, text='Start Game', bd='5', command=StartGame)
usern_button.place(x=20, y=75)
window.mainloop()

The cause of your problems is just copying the snake code and putting it in a function. You should take the Snake class out of the function. You should only have one instance of Tk, the root window. Therefore this needs to be created first. I've used .withdraw() to hide it until we need it. Then I've used Toplevel to create another window. This is like Tk but doesn't cause problems. Your current user validation does not work as you get and check the value of UsernInput immediately after creating it. Therefore it will always pass as the length of an empty string is less than 8. Instead you need to do the validation in the StartGame function. I've replaced the Text with an Entry because whilst Text would work fine, Entry is much more well suited to what you need (a single line of text).
When the user presses the button it calls StartGame. This validates the input and if it's valid it destroys the username window and shows the root, then does the same setup stuff as before. Although it isn't necessary in this case it's always a good idea to pass a parent widget to every child. In this case the snake canvas will automatically go to the root window but in your original code this is what caused the window size to be wrong as it automatically went in the username window. I've done this by adding the parent parameter to Snake and passing root. Assuming the Snake code all works fine this code should all work. If you want to use the value of username in Snake then you'll want to pass it as a parameter by changing it to def __init__(self, parent, username):. Then after adding something like self.username = username you can use it anywhere in the class.
import tkinter as tk
from random import randint
from PIL import Image, ImageTk
from tkinter import messagebox
MOVE_INCREMENT = 20
MOVES_PER_SECOND = 15
GAME_SPEED = 1000 // MOVES_PER_SECOND
class Snake(tk.Canvas):
def __init__(self, parent):
super().__init__(
parent, width=600, height=620, background="black", highlightthickness=0
)
# Rest of the Snake class code goes here
root = tk.Tk()
root.title("Snake")
root.withdraw() # Hide root window for now
def StartGame():
# Do the validation after the user has pressed the button
# The input has no value if you call it immediately after
username = UsernInput.get() # The get is easier with an Entry
if len(username) > 8:
messagebox.showwarning("Invalid username", "Please enter a valid username")
window.focus() # Go back to the window after showing the warning
else:
window.destroy() # Get rid of the username input
root.deiconify() # Show the root window again
root.tk.call("tk", "scaling", 4.0)
root.resizable(False, False)
board = Snake(root)
window = tk.Toplevel() # Don't use multiple Tk instances
window.title("Snake game")
window.geometry('250x120')
Usern_label= tk.Label(window, text="Username: ", font=("Arial Bold", 10))
Usern_label.place(x=10, y=10)
# It makes more sense to use an entry for what you are doing
UsernInput = tk.Entry(window, bg='White', bd=5, width=15)
UsernInput.place(x=90, y=10)
usern_button = tk.Button(window, text='Start Game', bd='5', command=StartGame)
usern_button.place(x=20, y=75)
root.mainloop()

Related

Tkinter continuously loop main event

I'm making a trivia game where data is from www.opentdb.com. I want it to continually loop through the main program after it tells you whether your answer is correct or not. (clicking an answer and shows green label but will stay at that screen). I would like it to wait a few seconds and have tried using .after(3000, main()) but do not know how to reset the screen and repeat.Im sorry if this sounds very confusing. Thank you for your assistance :)
from tkinter import *
import trivia
import html
t = trivia.Trivia()
root = Tk()
root.geometry("1366x768")
root.configure(bg='#4dc4ff')
root.iconbitmap("icon.ico")
root.title("Trivia Party!")
frame = Frame(root, bg='#4dc4ff')
class Buttons:
def __init__(self, text):
self.text = html.unescape(text) # remove html entities
self.correct_label = Label(root, text="Correct!", font=("Arial", 30), background="#98FB98", width=20, height=2) # green correct label
def reveal_answer(self):
if self.text == t.return_correct_answer(): # if its the right answer
self.correct_label.pack(pady=175)
frame.destroy()
else:
self.correct_label.config(text="Incorrect", background="#ff6347")
self.correct_label.pack(pady=175)
Label(root, background="#4dc4ff", text=("The correct answer was: " + t.return_correct_answer()),
font=("Arial", 40)).pack()
frame.destroy()
def create(self):
Button(frame, text=self.text, borderwidth=0, highlightbackground="#00abff", font=("Helvetica", 30),
command=self.reveal_answer).pack(side=LEFT, expand=YES)
frame.pack(fill=BOTH, expand=YES)
buttons = []
question = Label(frame, text=html.unescape(t.return_question()), font=("Arial", 25), height=3, bg="#00abff").pack(fill=X)
for i in t.all_answers: # t.all_answers is pulling all of the multiple choice answers ie "coke", "pepsi" "sprite"
buttons.append(Buttons(i).create()) # i is the individual answer eg "pepsi" and is making a button
root.mainloop()

Cropping multiple parts of the image and placing on the canvas in Tkinter

I am new to the Tkinter platform so please help me where I'm going wrong.
I have a floorplan image in which I want to cut the objects in it and place it on a canvas screen so that individual objects can be dragged if I want.
I'm able to cut and paste the objects on the screen except the first object. It is not placed on the screen. Can anyone help me?
I am using a Matlab code to identify the objects in the floorplan image. I am attaching the Matlab file.
Is it possible to add the wall to the screen? I have no idea at all. Can anyone suggest how to add the wall?
Here is my code
import tkinter as tk
from tkinter import *
from PIL import Image,ImageTk
from scipy.io import loadmat
root = tk.Tk()
canvas = tk.Canvas(width=800, height=800)
canvas.grid(row=4,column=0,sticky=(N,W,E,S))
#canvas.config(width=100,height=100)
root.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(4, weight=1)
mfile=loadmat('C:\\Users\\User\\Desktop\\tkinter_codes\\obj identification\\ans.mat')
#print(mfile.values())
#print(len(mfile['ans'][0]))
print(mfile.values())
class Example(tk.Frame):
def __init__(self, parent):
self.parent =parent
tk.Frame.__init__(self, parent)
self.canvas = tk.Canvas(width=800, height=800)
self.canvas.grid(row=0,column=0,sticky=(N,W,E,S))
#canvas.pack (expand =1, fill =tk.BOTH)
self.canvas.tag_bind("DnD","<Button-1>")
self._drag_data = {"x": 0, "y": 0, "item": None}
self.canvas.tag_bind("token", "<ButtonPress-1>", self.drag_start)
self.canvas.tag_bind("token", "<ButtonRelease-1>", self.drag_stop)
self.canvas.tag_bind("token", "<B1-Motion>", self.drag)
self.canvas.bind("<ButtonPress-1>", self.on_button_1)
self.iimg=Image.open("C:\\Users\\User\\Desktop\\tkinter_codes\\floorplans\\ROBIN\\Dataset_3rooms\\Cat1_1.jpg")
#iimg=iimg.resize((1000, 800), Image.ANTIALIAS)
self.canvas.img=ImageTk.PhotoImage(self.iimg)
#canvas.img = canvas.img.resize((250, 250), Image.ANTIALIAS)
self.canvas_img=canvas.create_image(0,0,image=self.canvas.img,anchor="nw")
self.mylist=[]
for x in range(len(mfile['ans'][0])):
#canvas.create_rectangle((mfile['ans'][0][x][0][0],mfile['ans'][0][x][0][1],mfile['ans'][0][x][0][0]+mfile['ans'][0][x][0][2],mfile['ans'][0][x][0][1]+mfile['ans'][0][x][0][3]),outline='red',tags=("token","DnD"))
self.im_crop = self.iimg.crop((mfile['ans'][0][x][0][0],mfile['ans'][0][x][0][1],mfile['ans'][0][x][0][0]+mfile['ans'][0][x][0][2],mfile['ans'][0][x][0][1]+mfile['ans'][0][x][0][3]))
self.canvas.im_crop2=ImageTk.PhotoImage(self.im_crop)
self.canvas.create_image(mfile['ans'][0][x][0][0],mfile['ans'][0][x][0][1], image=self.canvas.im_crop2)
#canvas.create_image(1000,1000,image=im_crop2)
#if(x>=0):
self.mylist.append(self.canvas.im_crop2)
#im_crop.show()
#canvas.iiiimg=ImageTk.PhotoImage(im_crop)
#canvas.create_image(150,150,image=canvas.im_crop2)
self.popup = tk.Menu(root, tearoff=0)
#self.popup.add_command(label="delete",command=lambda: self.dele(id))
self.popup.add_command(label="delete",
command=lambda: self.dele(id))
self.popup.add_command(label="add",command= lambda: root.bind("<Button-1>",self.addn))
root.bind("<Button-3>", self.do_popup)
self.canvas.delete(self.canvas_img)
def do_popup(self,event):
# display the popup menu
try:
self.popup.tk_popup(event.x_root, event.y_root, 0)
finally:
# make sure to release the grab (Tk 8.0a1 only)
self.popup.grab_release()
def on_button_1(self, event):
iid = self.canvas.find_enclosed(event.x-150, event.y-150, event.x + 150, event.y + 100)
#iid=canvas.find_closest(event.x, event.y)[0]
self.canvas.itemconfigure("DEL")
self.canvas.dtag("all","DEL")
self.canvas.itemconfigure(iid, tags=("DEL","DnD","token","drag"))
#canvas.unbind("<Button-1>")
def create_token(self, x, y, color):
"""Create a token at the given coordinate in the given color"""
self.canvas.create_rectangle(
x ,
y ,
x + 50,
y + 50,
outline=color,
fill=color,
tags=("token","DnD"),
)
def create_token1(self,x,y,color):
self.canvas.create_rectangle(
x ,
y ,
x + 25,
y + 25,
outline=color,
fill=color,
tags=("token","DnD"),
)
def drag_start(self, event):
"""Begining drag of an object"""
# record the item and its location
self._drag_data["item"] = self.canvas.find_closest(event.x, event.y)[0]
rect=self.canvas.bbox(self._drag_data["item"])
self.canvas.addtag_enclosed("drag",*rect)
print(rect)
self._drag_data["x"] = event.x
self._drag_data["y"] = event.y
def drag_stop(self, event):
"""End drag of an object"""
# reset the drag information
self._drag_data["item"] = None
self._drag_data["x"] = 0
self._drag_data["y"] = 0
self.canvas.dtag("drag","drag")
def drag(self, event):
"""Handle dragging of an object"""
# compute how much the mouse has moved
self.delta_x = event.x - self._drag_data["x"]
self.delta_y = event.y - self._drag_data["y"]
# move the object the appropriate amount
self.canvas.move("drag", self.delta_x, self.delta_y)
# record the new position
self._drag_data["x"] = event.x
self._drag_data["y"] = event.y
def dele(self,id):
#canvas.tag_bind(id,"<Button-1>")
self.canvas.delete("DEL")
def addn(self,event):
canvas.create_rectangle(event.x,event.y,event.x+25,event.y+25,fill='red',tags=("DnD","token"))
root.unbind("<Button-1>")
Example(root) #pack(fill="both", expand=True)
root.mainloop()
This is the Matlab code I am using for identifying objects

How can I put this script in a function?

I want to display a text first and remove it after a second, and keep the software running during this time (that is, preventing the loop) and getting the text and display it repeatedly.
I want this to be in the form of a function
I want to display the text with each key and the text operation is in a function
import keyboard
import pynput
import tkinter, win32api, win32con, pywintypes
def printer(text):
label = tkinter.Label(text=text, font=('Times New Roman','16'), fg='white', bg='blue')
label.master.overrideredirect(True)
label.master.geometry("+0+0")
label.master.lift()
label.master.wm_attributes("-topmost", True)
label.master.wm_attributes("-disabled", True)
label.master.wm_attributes("-transparentcolor", "blue")
hWindow = pywintypes.HANDLE(int(label.master.frame(), 16))
exStyle = win32con.WS_EX_COMPOSITED | win32con.WS_EX_LAYERED | win32con.WS_EX_NOACTIVATE | win32con.WS_EX_TOPMOST | win32con.WS_EX_TRANSPARENT
win32api.SetWindowLong(hWindow, win32con.GWL_EXSTYLE, exStyle)
label.pack()
label.after(1000, lambda:label.config(text=''))
label.mainloop()
pressedList = ''
def on_press(key):
global pressedList
try:
pressedKey = key.char # single-char keys
except:
pressedKey = key.name # other keys
pressedList += pressedKey
if pressedList.rfind('a')+len('a') == len(pressedList) and pressedList[pressedList.rfind('a'):] == 'a':
printer('a')
elif pressedList.rfind('f1')+len('f1') == len(pressedList) and pressedList[pressedList.rfind('f1'):] == 'f1' and pressedKey == 'f1':
printer('f1')
else:
printer('pass')
pass
lis = pynput.keyboard.Listener(on_press=on_press)
lis.start()
lis.join()
You probably do not need to mix tkinter with other events listeners; binding a keypress to a tkinter window will do what you require:
import tkinter as tk
def display_key(e=None):
if e is not None:
tv.set(e.keysym)
root.after(1000, display_key)
else:
tv.set('-')
root = tk.Tk()
root.geometry('300x200')
tv = tk.StringVar()
tv.set('-')
label = tk.Label(root, textvariable=tv)
label.config(font=("Courier", 144))
label.pack(expand=True, fill='both')
root.bind('<Key>', display_key)
root.mainloop()

tkinter packs in wrong window

I am creating the simonsays game and separating into 3 files. The table.py file contains:
from tkinter import *
import random
class Table:
def __init__(self, parent):
self.parent = parent
self.canvas = Canvas(self.parent, height=400, width=400) #tk.
self.canvas.pack()
self.dark = {'r':'darkred', 'g':'darkgreen', 'b':'darkblue', 'y':'darkgoldenrod'}
self.light = {'r':'red', 'g':'green', 'b':'blue', 'y':'goldenrod'}
self.squares = {'r':self.canvas.create_rectangle(0, 0, 200, 200,
fill='darkred', outline='darkred'),
'g':self.canvas.create_rectangle(200, 0, 400, 200,
fill='darkgreen', outline='darkgreen'),
'b':self.canvas.create_rectangle(0, 200, 200, 400,
fill='darkblue', outline='darkblue'),
'y':self.canvas.create_rectangle(200, 200, 400, 400,
fill='darkgoldenrod', outline='darkgoldenrod')}
self.status = Label(text='Good luck!')
self.status.pack(side=BOTTOM, fill=X)
The player file basically has some methods on how the game should work. When I start the main_menu file(the one below) everything is running smoothly besides one thing. The status bar which is a label from the table file (which should be in the window of the game) is packed in the main_menu window. What is the reason for that? (I am still a beginner so dont be too harsh if it is stupid mistake ^_^ and thanks in advance)
from tkinter import *
from table import Table
from player import Player
class Window():
def __init__(self, master):
self.master = master
self.master.geometry('300x100')
self.master.title('Simon says')
self.label1 = Label(self.master, text = 'Welcome to the simon says game', fg='red').pack()
self.button1 = Button(self.master, text = 'Start game',fg = 'blue', command =self.start_game).pack()
self.button2 = Button(self.master, text = 'Quit game',fg = 'blue', command =self.quit_game).pack()
def start_game(self):
root2 = Toplevel(self.master)
table = Table(root2)
player = Player(table)
def quit_game(self):
self.master.destroy()
def main():
root = Tk()
my_main_menu= Window(root)
root.mainloop()
if __name__ == '__main__':
main()
Side question is there a simple function in tkinter to use a picture for a background for the main menu?

Tkinter Text widget tag_add does not work second time

I am writing my first python app for the last 20 years. I have a problem with the tag_add() function of the Tkinter Text widget. Adding a tag just works the first time, but not the second time. I checked with tag_names() if my tag got deleted on unchecking the "Highlight Errors" checkbutton. And it is deleted. It is even re-added on checking the checkbutton again, but the text is not colored on second attempt.
Anyone an idea?
As its the first python code for years, do you have feedback to the way I have implemented and structured it? (Sorry cant get away from CamelCase)
Thanks in advance
SLi
from Tkinter import Tk, BOTH, END, N, W, S, TOP, BOTTOM, INSERT, LEFT, RIGHT, SUNKEN, RAISED, X, Y, PanedWindow, Frame, LabelFrame, Scrollbar, Checkbutton, Entry, Button, Label, Text, Menu, IntVar
from ScrolledText import ScrolledText
class Application(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.initializeUiVariables()
self.doWindowSetup()
self.createWidgets()
self.doColorSetup()
def doWindowSetup(self):
self.parent.title('PACE Client Log Viewer')
self.screenWidth = self.parent.winfo_screenwidth()
self.screenHeight = self.parent.winfo_screenheight()
desiredWindowWidth = (self.screenWidth * 1.0)
desiredWindowHeight = (self.screenHeight * 1.0)
x = (self.screenWidth / 2) - (desiredWindowWidth / 2)
y = (self.screenHeight / 2) - (desiredWindowHeight / 2)
self.parent.geometry('%dx%d+%d+%d' % (desiredWindowWidth, desiredWindowHeight, x, y))
def initializeUiVariables(self):
self.fontSize = 12
self.highlightErrors = IntVar()
def createWidgets(self):
panedWindow = PanedWindow(sashrelief=RAISED)
panedWindow.pack(fill=BOTH, expand=1)
self.wText = ScrolledText(panedWindow)
self.wText.config(font=("consolas", self.fontSize))
self.wText.pack(side=LEFT, fill=BOTH, expand=True)
panedWindow.add(self.wText, minsize=(self.screenWidth * 0.75))
self.wText.insert(END, "2018-09-28 11:15:03 GMT - my.app.id (ERROR): Class:CertChecker:error: No certificate loaded. Load certificate before continuing.\n2018-09-28 11:15:07 GMT - my.app.id (INFO): Class:PerformInitialization: begin - version 0.3.10")
frameToolbar = Frame(panedWindow, padx=10)
frameToolbar.pack(side=LEFT, fill=BOTH, expand=True)
panedWindow.add(frameToolbar)
# Highlight Options
frameHighlightOptions = LabelFrame(frameToolbar, text="Highlight", padx=5, pady=5)
frameHighlightOptions.pack(side=TOP, fill=BOTH)
cbErrors = Checkbutton(frameHighlightOptions, text="Errors", anchor=W, padx=5, justify=LEFT, variable=self.highlightErrors, command=self.onHighlightErrors)
cbErrors.pack(side=TOP, fill=X)
def doColorSetup(self):
self.wText.tag_config("highlightError", background="#EE2C2C", foreground="#FFFFFF") # red
def onHighlightErrors(self):
if self.highlightErrors.get() == 0:
self.wText.tag_delete("highlightError")
else:
self.highlightRow("error", "highlightError")
def highlightRow(self, pattern, tag):
self.highlightPattern(pattern, tag, True)
def highlightPattern(self, pattern, tag, highlightRow=False):
start = self.wText.index("1.0")
end = self.wText.index(END)
self.wText.mark_set("matchStart", start)
self.wText.mark_set("matchEnd", start)
self.wText.mark_set("searchLimit", end)
count = IntVar()
while True:
index = self.wText.search(pattern, "matchEnd","searchLimit", count=count, regexp=True, nocase=True)
if index == "": break
if count.get() == 0: break # degenerate pattern which matches zero-length strings
if highlightRow:
row, col = index.split('.')
self.wText.mark_set("matchStart", "%s.%s" % (int(row), 0))
else:
self.wText.mark_set("matchStart", index)
if highlightRow:
lineEndIndex = self.wText.search("\n", index, "searchLimit", count=count, regexp=False, nocase=False)
row, col = lineEndIndex.split('.')
self.wText.mark_set("matchEnd", lineEndIndex)
else:
self.wText.mark_set("matchEnd", "%s+%sc" % (index, count.get()))
self.wText.tag_add(tag, "matchStart", "matchEnd")
def main():
root = Tk()
ex = Application(root)
root.mainloop()
if __name__ == '__main__':
main()
When you delete the tag, you destroy all of the information associated with that tag. The next time you add the tag it has no colors associate with it, so you can't see the tag.
Instead of deleting the tag, you should just remove it from the text.
Replace this:
self.wText.tag_delete("highlightError")
... with this:
self.wText.tag_remove("highlightError", "1.0", "end")

Resources