diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2014-08-17 12:32:42 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2014-08-17 12:32:42 (GMT) |
commit | 0879001f00430a7393ae84a1c6988ac88eb77437 (patch) | |
tree | e247cdb70ca47351e812bc7fcaa6dc3215688b03 /Lib/tkinter/__init__.py | |
parent | 95d5c9d5fff08e883613df42c99c6c8a9dab7733 (diff) | |
parent | 87bbf257ef6e8d1e5876776094db609702ee468a (diff) | |
download | cpython-0879001f00430a7393ae84a1c6988ac88eb77437.zip cpython-0879001f00430a7393ae84a1c6988ac88eb77437.tar.gz cpython-0879001f00430a7393ae84a1c6988ac88eb77437.tar.bz2 |
Issue #22068: Avoided reference loops with Variables and Fonts in Tkinter.
Diffstat (limited to 'Lib/tkinter/__init__.py')
-rw-r--r-- | Lib/tkinter/__init__.py | 34 |
1 files changed, 29 insertions, 5 deletions
diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index 5257cb6..2c64971 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -191,6 +191,7 @@ class Variable: that constrain the type of the value returned from get().""" _default = "" _tk = None + _tclCommands = None def __init__(self, master=None, value=None, name=None): """Construct a variable @@ -209,7 +210,7 @@ class Variable: global _varnum if not master: master = _default_root - self._master = master + self._root = master._root() self._tk = master.tk if name: self._name = name @@ -222,9 +223,15 @@ class Variable: self.initialize(self._default) def __del__(self): """Unset the variable in Tcl.""" - if (self._tk is not None and - self._tk.getboolean(self._tk.call("info", "exists", self._name))): + if self._tk is None: + return + if self._tk.getboolean(self._tk.call("info", "exists", self._name)): self._tk.globalunsetvar(self._name) + if self._tclCommands is not None: + for name in self._tclCommands: + #print '- Tkinter: deleted command', name + self._tk.deletecommand(name) + self._tclCommands = None def __str__(self): """Return the name of the variable in Tcl.""" return self._name @@ -244,7 +251,20 @@ class Variable: Return the name of the callback. """ - cbname = self._master._register(callback) + f = CallWrapper(callback, None, self).__call__ + cbname = repr(id(f)) + try: + callback = callback.__func__ + except AttributeError: + pass + try: + cbname = cbname + callback.__name__ + except AttributeError: + pass + self._tk.createcommand(cbname, f) + if self._tclCommands is None: + self._tclCommands = [] + self._tclCommands.append(cbname) self._tk.call("trace", "variable", self._name, mode, cbname) return cbname trace = trace_variable @@ -255,7 +275,11 @@ class Variable: CBNAME is the name of the callback returned from trace_variable or trace. """ self._tk.call("trace", "vdelete", self._name, mode, cbname) - self._master.deletecommand(cbname) + self._tk.deletecommand(cbname) + try: + self._tclCommands.remove(cbname) + except ValueError: + pass def trace_vinfo(self): """Return all trace callback information.""" return [self._tk.split(x) for x in self._tk.splitlist( |