This is a similar question so I think I'm in the right forum. I have a tkinter app that counts 'steps' for something. After about 2 billion +1 additions (close to the size of a maximum 32-bit int), the count displayed in an Entry widget stops being user accessible -- can't focus the cursor in the displayed value and can't select some or all the characters of the value. If I restart the app and preset ('Update') the count to 1999999999 before starting, it still take 2 billion steps or more for this problem to manifest. Below is a stripped down app that shows this problem on 64-bit Windows 10 and on a Raspberry Pi 4. (Original script was replaced. See comments. 17Jan2021)
from tkinter import * #python3
start = False
count = 0
def startCount():
global start
start = True
countUp()
def stopCount():
global start
start = False
eVal.set(count)
def get_eVal():
global count
count = int(eVal.get())
def countUp():
global count, start
count += 1
if count % 1000 == 0:
eVal.set(count)
if start:
on.after_idle(countUp)
root = Tk()
eVal = StringVar()
frame = Frame(root)
on = Button(frame, text='Start', command=startCount)
off = Button(frame, text='Stop', command=stopCount)
updt = Button(frame, text='Update', command=get_eVal)
entry = Entry(frame, textvariable=eVal, width=20, justify=RIGHT)
on.pack(side=LEFT)
off.pack(side=LEFT, padx=(8,4), pady=6)
updt.pack(side=LEFT, padx=(4,8))
entry.pack(side=LEFT)
frame.pack()
mainloop()
So far in my bigger app, when this problem happens, ALL Entry widgets become inaccessible to the user. Is this a known tkinter problem? Are there any easy fixes?
I know I shouldn't answer my own question but I think I now have answers that may be important to others seeing this problem. I did quite a bit of research both here and elsewhere before asking. If I had found any answers, I wouldn't have bothered the community. The question was simply to confirm if anyone else had seen this problem. I didn't receive any 'yes' or 'no' comments or answers. Instead, the question was down counted. How does one show research made before asking a question? I think the question was very clear. And the answer is certainly important to me.
I also asked if there were any easy fixes - workarounds one might use to overcome the problem. Well here goes. On Windows the following script still shows anomalous display behavior, but at least the script still works, allows copying the Entry value during counting, and doesn't delay the work (countUp) any more than it has to.
from tkinter import * #python3
start = False
count = 0
def startCount():
global start
start = True
countUp()
def stopCount():
global start
start = False
eVal.set(count)
def get_eVal():
global count
count = int(eVal.get())
def countUp():
global count, start
count += 1
if count % 1000 == 0:
eVal.set(count)
if start:
root.update_idletasks()
root.after(0, countUp)
root = Tk()
eVal = StringVar()
frame = Frame(root)
on = Button(frame, text='Start', command=startCount)
off = Button(frame, text='Stop', command=stopCount)
updt = Button(frame, text='Update', command=get_eVal)
entry = Entry(frame, textvariable=eVal, width=20, justify=RIGHT)
on.pack(side=LEFT)
off.pack(side=LEFT, padx=(8,4), pady=6)
updt.pack(side=LEFT, padx=(4,8))
entry.pack(side=LEFT)
frame.pack()
root.mainloop()
The anomolous behavior is that your desktop can display two blinking cursors (sorry the vertical bars aren't blinking in this image) and selections in the Entry persist even when the app doesn't have focus. BUT, the script still functions.
I am testing this second script now which dares to use .update. I will comment later on whether it is a functioning workaround.
from tkinter import * # python3
start = False
count = 0
quit = False
def startCount():
global start
start = True
def stopCount():
global start
start = False
eVal.set(count)
def get_eVal():
global count
count = int(eVal.get())
def countUp():
global count
count += 1
if count % 1000 == 0:
eVal.set(count)
root = Tk()
eVal = StringVar()
frame = Frame(root)
on = Button(frame, text='Start', command=startCount)
off = Button(frame, text='Stop', command=stopCount)
updt = Button(frame, text='Update', command=get_eVal)
entry = Entry(frame, textvariable=eVal, width=20, justify=RIGHT)
on.pack(side=LEFT)
off.pack(side=LEFT, padx=(8,4), pady=6)
updt.pack(side=LEFT, padx=(4,8))
entry.pack(side=LEFT)
frame.pack()
while quit == False:
if start:
countUp()
try:
root.update_idletasks()
root.update()
except:
break