PYTHON- tkinter ERROR Cant evoke event command - python

I am making a simple program that also incorporates the use of TKinter. The inclusion is to have it copy and paste to my clipboard and also to check the contents of my keyboard. However, without much change from me, the console spits out an error :
can't invoke "event" command: application has been destroyed while executing
"event generate $w <<ThemeChanged>>" (procedure "ttk::ThemeChanged" line 6)
invoke from within "ttk::ThemeChanged"`
My questions:
I do not understand what the error means;
I do not understand how to fix it.
From my understanding, these error usually pop up from the use of matplotlib, which I am not using. The python console still can function after this message but it is annoying and distracting.
here is the code that i think is affecting it.
from Tkinter import Tk
r = Tk()
r.withdraw()
r.clipboard_clear()
r.clipboard_append(finalbib)
r.destroy()
#os.startfile("TEMPPY.py")
clipbardtest=True
while clipbardtest:
r=Tk()
clippytest = r.clipboard_get()
r.destroy()
if clippytest==finalbib:
os.system('cls')
print "Successfully copied to clipboard"
#os.remove("TEMPPY.py")
clipbardtest=False
morebibdef()
else:
time.sleep(1.2)
#os.startfile("TEMPPY.py")
r = Tk()
r.withdraw()
r.clipboard_clear()
r.clipboard_append(finalbib)
r.destroy()

See one of the comments from this question
If you use this in a console script this might lead to an error, that
the .destroy() function will not work ("can't invoke "event" command:
application has been destroyed while executing [...]"). To prevent
this, call r.update() before r.destroy.

The error means that all of the tkinter windows have been destroyed, but that something is trying to generate an event. In order to generate an event you must have a window.

Related

TKinter. Tcl_AsyncDelete: cannot find async handler

I am running tkinter library in the Odoo15 for a specific purpose.
I have created a custom python interpreter to run python code inside odoo.
To handle user inputs i specially designed a concept and via tkinter i am taking inputs from user.
In a code there may be more than one inputs and so i need to open the window more than one time. for example taken one input, Entered, closed window and then repeat the same process till final user input.
So in that case, at some movement my server getting terminated with a runtime error:
Tcl_AsyncDelete: cannot find async handler
Aborted (core dumped)
can anyone guide me how can i resolve this please ?
import tkinter as tk
import gc
root=tk.Tk()
root.geometry('800x200+600+300')
name_var=tk.StringVar()
var_1 = ''
def submit():
name=name_var.get()
global %s
var_1 = name
root.destroy()
name_label = tk.Label(root, text = 'Enter value', font=('calibre',10, 'bold'))
name_entry = tk.Entry(root,textvariable = name_var, font=('calibre',10,'normal'))
sub_btn=tk.Button(root,text = 'Submit', command = submit)
name_label.grid(row=0,column=0)
name_entry.grid(row=0,column=1)
sub_btn.grid(row=2,column=1)
root.mainloop()
when there is a line like value = input("Enter value")
i am replacing that line with the above code to take user input.
Looking forward to hear on this .. thanks
Without a minimal reproducible example it is more of a guessing than an answer.
But due to your request, I'll try my best guess. The information how you code this section below, can be crucial.
In a code there may be more than one inputs
and so i need to open the window more than
one time. for example taken one input,
Entered, closed window and then repeat the
same process till final user input.
If you destroy the root window, the instance of tkinter.Tk() and you try to retrieve the users input (data located in tkinter) of the destroyed instance you could run into trouble. Instead of creating new instances of tkinter.Tk use tkinter.Toplevel. You could hide the root window in many ways. I.e with overrideredirect and transparency.
TL;DR
Make sure you use the same instance of tkinter.Tk() through out the whole session and or connect the new instance with your server and vice versa.
Hope it will work out for you, especially because I don't know about odoo.

error _tkinter.TclError: can't invoke "wm" command: application has been destroyed in tkinter (tk)?

So, I was trying to remake "you are an idiot" virus in python. The way I'm doing this is looping my python script. I tried to make it so that when you try to close a window more popups show up.
It was working the 1st time but, then I started getting this error _tkinter.TclError: can't invoke "wm" command: application has been destroyed, and I can't find a way to fix it. Here is my code for how I'm getting this error.
Also another reason why I need it looped is because I'm using random functions to make the windows appear in random positions.
# On closing function:
def on_closing():
restart()
root.protocol("WM_DELETE_WINDOW", on_closing)
root.title("you are an idiot")
root.mainloop()
# Restart function:
def restart():
os.system("python3 main.py")
Random position functions:
#random values
x = random.randint(100,600)
y = random.randint(200,600)
root.geometry("+{}+{}".format(x,y)) #randomized window position
Your could use the event binding for the Destroy event.
root.bind("<Destroy>", on_closing)
Is the code you shown the main.py?

Using Jupyter notebook - which is best for this tkinter algrithm? quit(), exit(), sys.exit(), or os.exit()?

I am using the Jupyter notebook to write a tkinter algorithm with a lot of "if" statements.
I would like some of these "if" statements to stop running the program (but not stop the tkinter window from running) at certain points without returning to the main flow of the code. I wrote a small sample app (below) to illustrate what I mean.
I have tried using quit(), exit(), sys.exit(), and os.exit(). Both quit() and exit() seem to work okay,They say "Hi" and not "bye", as expected. But I still get some unwanted readout when I close the tkinter window - which I think may be more Jupyters fault than python or tkinter. It usually says, "The kernel appears to have died. It will restart automatically."
The sample script contains each of the commands above, and it uses a comment "#" to toggle the line on and off. The unwanted readout and messages for each case are also commented beside the code in the script.
My concern is whether the unwanted readout could be problematic or even a security threat if I code any further, since some of these if statements will be used in a password protected area. Would I be correct in assuming, if the unwanted messages came from Jupyter, the messages will be benign and transparent once I compile the code to an exe?
My code is below:
import tkinter
from tkinter import *
import tkinter as tk
import sys
import os
def routine ():
x = 0
if x < 1:
print("Hi")
# quit() # Prints Hi and not bye;
# when destroyed, it says Kernel Restarting
# The kernel appears to have died. It will restart automatically.
# exit() # On an apparent level - it seems to do all the same things as quit.
# sys.exit() # Prints Hi
# and then...
# An exception has occurred, use %tb to see the full traceback.
# SystemExit
# Then the entire systems, including the tkinter window,
# locks up and spin doing nothing.
# The close button wont even work.
# os._exit() # Exception in Tkinter callback
# Traceback (most recent call last):
# File "C:\Users\rrr\lib\tkinter\__init__.py", line 1705, in __call__
# return self.func(*args)
# File "<ipython-input-3-c9d340ae6a31>", line 31, in routine
# os._exit()
# TypeError: _exit() missing required argument 'status' (pos 1)
if x > 1:
print("bye...")
root = Tk()
root.geometry("300x200+200+200")
btn1 = Button(root, text ="Run A Routine", command = routine)
btn1.pack(pady = 20, anchor='center')
btn1 = Button(root, text ="Close Window", command = root.destroy)
btn1.pack(pady = 20, anchor='center')
root.mainloop()
I am wondering what you mean by "stop running the program"? Do you mean exit the function/subroutine that you have written? Because if that is the case, you should simply use return to exit the defined routine.
If you want to do something more complex, you may need to remove your .mainloop() call for updating tkinter, and instead use something like the below:
RUN_FLAG = True
while RUN_FLAG:
root.update_idletasks()
root.update()
time.sleep(0.01)
This would allow you to update the global variable RUN_FLAG in your subroutine and use that to move beyond your tkinter and then finish your script.
Also, side note; Running tkinter in Jupyter is a bit odd, in my opinion. If your solution gets much more extensive, you'd probably get better performance from a standard python script. I recommend "PyCharm" by JetBrains as an IDE.
Angus B: I liked your thought on using return, which I didnt know I could do - because I am still too new at programming. But it seems to work like I wanted it. The code below demonstrates what I mean.
If you ran it as it is, then it would stop at the return command in line 7, and it would print "Hi A" to the command line.
But if you commented out Line 7, then it would print
"Hi A"
"Hi B"
I dont quite understand the difference between using return versus using exit or quit, but return seems to do more of what I want. I will continue to study it. Thank you for your response. :)
For the record, my question may not have been cutting edge research, but it is a bit different and it has been answered. We can continue to discuss it, if you like.
import tkinter
def routine (x):
if x == "A":
print("Hi A1")
return
if x == "B":
print("Hi B")
if x == "A":
print("Hi A2")
root = Tk()
root.geometry("300x200+200+200")
btn1 = Button(root, text ="Run A Routine", command = lambda: routine("A"))
btn1.pack(pady = 20, anchor='center')
btn1 = Button(root, text ="Close Window", command = root.destroy)
btn1.pack(pady = 20, anchor='center')
root.mainloop()

How to prevent Tkinter root window from taking over focus?

I'm writing a program where most of user interaction happens in Windows Command line, however I use Tkinter for some File and Directory selection dialogs.
When I start up program by clicking .py file (In IDLE the problem doesn't occur), command line is launched and when Tk root window is instantiated, it takes over the focus from command line, even if I withdraw it.
This behaviour requires extra action from user to focus back on command line window.
Here is some code sample to reproduce the problem.
from tkinter import Tk
root_window = Tk()
root_window.withdraw()
name = input("Enter your name:\n")
print("Nice to meet you, " + name)
How do I keep Windows Command line in focus?
Strange enough, now your example works for me in the intended way - even though, ten minutes ago, it showed the problem you have reported. The only other thing I tried out inbetween was to add a latency to the withdraw call:
root_window.after(1, lambda: root_window.withdraw())
It seemed to also work as intended with a latency argument of zero, but now I am not sure what exactly changed the behaviour.

Why does Tkinter label crash the window python

Python Tkinter label cause window to say not responding when i use it more than once in 5 seconds or so.
Here is my code i am calling it with the variable data which is just a basic string
def print_data(data):
L1 = Tkinter.Label(app, text="You: " + data)
L1.pack()
I solved the issue i was running the script externally to my main script. I was calling the print data script without calling mainloop(). Thanks everyone :)

Categories