Python Tkinter:如何在 <Destroy> 事件回调中从 ScrolledText 小部件获取文本?
Python Tkinter: how to get text from ScrolledText widget on <Destroy> event callback?
我知道 ScrolledText 是作为一个 Text 对象构造的(但有一个滚动条附加在一个框架中)。但是下面的代码在关闭window并调用printText()
方法时会抛出错误:
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()
错误:
[...]
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"
我做错了什么?
您不应该假设在处理小部件的 <Destroy>
事件时可以从小部件中获取数据。
来自官方文档:
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.
一旦你销毁了主要的window,它的所有子部件都会被销毁,你将无法访问它们。 (这在技术上是不正确的,正如 Bryan Oakley 的回答所指出的,但这是我的想法。在破坏后尝试使用小部件充其量是有问题的。)
您需要使用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()
这里有一些变化。我从 printText
中删除了 event
参数并添加了对 self.window.destroy
的调用。请注意,我必须添加 self.window
属性才能进行此调用。基本更改是使用 wm_protocol 而不是绑定到事件;其他都是必然结果。
我知道 ScrolledText 是作为一个 Text 对象构造的(但有一个滚动条附加在一个框架中)。但是下面的代码在关闭window并调用printText()
方法时会抛出错误:
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()
错误:
[...]
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"
我做错了什么?
您不应该假设在处理小部件的 <Destroy>
事件时可以从小部件中获取数据。
来自官方文档:
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.
一旦你销毁了主要的window,它的所有子部件都会被销毁,你将无法访问它们。 (这在技术上是不正确的,正如 Bryan Oakley 的回答所指出的,但这是我的想法。在破坏后尝试使用小部件充其量是有问题的。)
您需要使用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()
这里有一些变化。我从 printText
中删除了 event
参数并添加了对 self.window.destroy
的调用。请注意,我必须添加 self.window
属性才能进行此调用。基本更改是使用 wm_protocol 而不是绑定到事件;其他都是必然结果。