can't invoke "event" command: application has been destroyed
Asked Answered
H

2

7

So I was debugging some of my code today and noticed a new message in the output:

can't invoke "event" command:  application has been destroyed
     while executing
"event generate $w <<ThemeChanged>>"
     (procedure "ttk::ThemeChanged" line 6)
    invoked from within
"ttk::ThemeChanged"

I looked at the questions regarding it on SO but they did't relate to this instance of the error. As for the ttk widget, I have not used ttk once in my code, a search for the string "ttk" in my code yields none.

Chunk of code that outputs this:

def GoToEvent(self, controller, driver):

    wait = WebDriverWait(driver, 600)

    var = Vars()
    entertain = var.GetVars("Link")
    if type(entertain) == type(""):
        event = var.GetVars("Event")
        entertain = driver.find_element_by_partial_link_text(event)
    entertain.click()
    try:
        # we have to wait for the page to refresh, the last thing that seems to be updated is the title
        wait.until(EC.title_contains("Entertain"))
    finally:
        # the page is ajaxy so the title is originally this:
        msg = driver.title
        label = tk.Label(self, text=msg, cursor='spinning', font="courier 24", bg="#c63f17")
        label.place(x=self.winfo_width()/2, y=self.winfo_height()/2, anchor="center")
        self.update()   # <--- This is where the problem is
        label.destroy()

This doesn't seem to actually throw any errors, and my code runs absolutely fine. I can't give enough code to replocate the problem as it is just simply too much code before this, but I can tell you all the testing I did if that helps. I debugged this code block and found that adding a breakpoint at label.destroy() would still give this error, but placing one anywhere before and stepping over to label.destroy() would not print this, leading me to believe it was some type of timing error with self.update(), but when I placed time.sleep(5) before and after self.update() the error was still there. So stepping through the code did not show the error but time.sleep() still showed the error. This puzzles me, I don't know why it would be behaving this way, I have been writing this program for 2 weeks and this is the first time this has happened. If no one knows it's fine, the code still runs perfectly, I'm just curious as to what this means and why it is happening. Thanks!

Beginning of code:

# !/usr/bin/python
# coding: utf-8
'''
Created on Jun 23, 2017

@author: jacob    <---------------- Line 6

'''


from selenium import webdriver
#from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait # available since 2.4.0
from selenium.webdriver.support import expected_conditions as EC # available since 2.26.0
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException
import os
import platform
import pwd
import re
import time
#import datetime
from time import strftime
import Tkinter as tk     
import tkFont as tkfont  
from Tkinter import Entry, Menu, Menubutton, Canvas
Huguenot answered 25/7, 2017 at 16:37 Comment(8)
Only an idea, but did you try update_idletasks()?Sauers
The error seems fairly clear: something is triggering a callback after the root window has been destroyed. It's impossible to say what, since the error metions ttk widgets and nowhere in the code you posted do you use ttk widgets.Arella
@Sauers Yes I tried, didn't fix itHuguenot
@Brian Oakly I did post in the code ttk widgets, tk.Label is a ttk widget. And as mentioned it isn't label.destroy, as this error happens before label.destroy is executed.Huguenot
@Huguenot tk.Label should be a tkinter widget not a ttk widget. The only way tk.Label is a ttk widget is if you imported ttk as tk, and that would not be a good idea.Saltigrade
Please provide the code block that contains line 6 of your code. This should help us in figuring out the problem.Saltigrade
Alright, here's line 6, knock yourself out lol. I hope that helps, but I'm about 76.59% sure line 6 isn't the problem. As for the ttk widget, I have not used ttk once in my code, a search for the string "ttk" in my code yields none. This is why I am so confused lol.Huguenot
Found the error! I explain it in detail in the answer I gave, but can anyone explain the actual error? Like I understand what caused the error, but I don't understand why this would throw an error?Huguenot
H
5

So this was a very hard error to find, as debugging never pointed to the right area of code I had to read through the code to try to find something off. So the program gets user input for a keyword, a website is then searched for the events containing this keyword, they are then put into a drop down menu. If there is only one or none occurrence of the keyword then there is no menu displayed and it either clicks the event or it prompts the user with a suggested event that is closest to their keyword. This seemed like the probable area where this error was happening because it only occurred when no menu was displayed. Code from this:

    if (len(options) > 1):

        button6 = tk.Button(selectMenu, text="Enter",
                        cursor='pointinghand', command=lambda: self.GetSelection(str(var.GetVars("Selection")), links, options, selectMenu, controller))  

        msg = "Which one would you like to attend?"
        label = tk.Label(selectMenu, text=msg, font="Helvedica 14")
        label.pack(side='top', pady=10)
        menbutton.pack(side="top", pady=10)        
        button6.pack(pady=10)

        self.Progress()

        selectMenu.attributes('-topmost', True)
        selectMenu.mainloop()
    elif options:
        var.SendVars("selLink", links[0])
        selectMenu.destroy()
        self.Progress()
    else:
        var.SendVars("Link", 'NO-LINK-FOUND')
        selectMenu.destroy()
        self.Progress()

It turns out that this error was caused by a Menubutton being created in a tk window but never reaching the mainloop, even though it was destroyed. The error is thrown when the mainloop of another tk window is reached. So to fix this you move the creation of the Menubutton to a place where it will reach it's mainloop as below.

enter image description here

Huguenot answered 27/7, 2017 at 20:33 Comment(2)
Because of your good answer I added an update() call before calling destroy() on the Tk widget to get rid of that error message in my own code.Walkon
@Walkon I didn't think anyone else would come across this, glad to help!Huguenot
T
0

The ttk::ThemeChanged error is a Tk bug: https://core.tcl-lang.org/tk/info/2958768, https://core.tcl-lang.org/tk/info/310c74ecf440

The bug is a race condition which can be difficult to reproduce. Tk runs on a Tcl “interpreter”; if the root Tk window is destroyed, the interpreter can continue to run, but Tk commands will not be available in that interpreter. ttk::ThemeChanged is something Tk schedules to run as an idle task on occasion. So if the root Tk window is destroyed, then this idle task should be canceled right away; but instead it is not being canceled until the interpreter is deleted, causing an error if this task happens to run.

Although there are workarounds, such as doing update then destroy as mentioned in Mandera’s comment, ideally this bug will be fixed in a future Tcl/Tk release (which Tkinter users then upgrade to).

Talkington answered 25/4, 2023 at 12:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.