Reputation: 327
I understand ScrolledText is constructed as a Text object (but has a scrollbar attached together in a frame). But the following code throws an error when the window is closed and the printText()
method is called:
import Tkinter as tk
import ttk
import ScrolledText as st
class tkGui(object):
def printText(self, event):
print "It works!"
self.mText.get("1.0", 'end-1c')
def __init__(self, window):
# create widgets
self.frame=tk.Frame(window)
self.mText = st.ScrolledText(self.frame)
self.mText.bind('<Destroy>',self.printText)
# place widgets
self.frame.pack()
self.mText.pack()
window = tk.Tk()
app = tkGui(window)
window.mainloop()
The error:
[...]
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 3077, in get
return self.tk.call(self._w, 'get', index1, index2)
TclError: invalid command name ".140506094171344.140506094172280.140506094172496"
What am I doing wrong?
Upvotes: 0
Views: 2783
Reputation: 5261
Once you destroy the main window, all its sub-widgets are destroyed, and you can't access them. (This is not technically correct, as Bryan Oakley's answer points out, but it's how I think about it. Trying to work with the widgets after destruction is problematical, at best.)
You need to use wm_protocol
http://nullege.com/codes/search/Tkinter.Tk.wm_protocol
import Tkinter as tk
import ttk
import ScrolledText as st
class tkGui(object):
def printText(self):
print "It works!"
self.mText.get("1.0", 'end-1c')
self.window.destroy()
def __init__(self, window):
# create widgets
self.window = window
self.frame=tk.Frame(window)
self.mText = st.ScrolledText(self.frame)
#self.mText.bind('<Destroy>',self.printText)
window.wm_protocol("WM_DELETE_WINDOW", self.printText)
# place widgets
self.frame.pack()
self.mText.pack()
window = tk.Tk()
app = tkGui(window)
window.mainloop()
There are a couple of changes here. I removed the event
parameter from printText
and added a call to self.window.destroy
. Note that I had to add the self.window
attribute to make this call. The basic change is using wm_protocol instead of binding to the event; the others are necessary consequences.
Upvotes: 2
Reputation: 385950
You should not assume you can get data out of a widget when handling the <Destroy>
event for that widget.
From the official documentation:
When the Destroy event is delivered to a widget, it is in a “half-dead” state: the widget still exists, but most operations on it will fail.
Upvotes: 2