summaryrefslogtreecommitdiffstats
path: root/Lib/tkinter
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2024-05-06 17:12:51 (GMT)
committerGitHub <noreply@github.com>2024-05-06 17:12:51 (GMT)
commit1ff626ebda465931ff3e4922e8e87d586eb6244c (patch)
tree9398cac06485d2da705e16985f1c4d64f3de42ef /Lib/tkinter
parent417dd3aca7bb910691d34e54fee108d7bbc627d3 (diff)
downloadcpython-1ff626ebda465931ff3e4922e8e87d586eb6244c.zip
cpython-1ff626ebda465931ff3e4922e8e87d586eb6244c.tar.gz
cpython-1ff626ebda465931ff3e4922e8e87d586eb6244c.tar.bz2
gh-71592: Add ability to trace Tcl commands executed by Tkinter (GH-118291)
This is an experimental feature, for internal use. Setting tkinter._debug = True before creating the root window enables printing every executed Tcl command (or a Tcl command equivalent to the used Tcl C API). This will help to convert a Tkinter example into Tcl script to check whether the issue is caused by Tkinter or exists in the underlying Tcl/Tk library.
Diffstat (limited to 'Lib/tkinter')
-rw-r--r--Lib/tkinter/__init__.py19
1 files changed, 15 insertions, 4 deletions
diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py
index 5031085..dc6ee9a 100644
--- a/Lib/tkinter/__init__.py
+++ b/Lib/tkinter/__init__.py
@@ -41,6 +41,7 @@ from tkinter.constants import *
import re
wantobjects = 1
+_debug = False # set to True to print executed Tcl/Tk commands
TkVersion = float(_tkinter.TK_VERSION)
TclVersion = float(_tkinter.TCL_VERSION)
@@ -69,7 +70,10 @@ def _stringify(value):
else:
value = '{%s}' % _join(value)
else:
- value = str(value)
+ if isinstance(value, bytes):
+ value = str(value, 'latin1')
+ else:
+ value = str(value)
if not value:
value = '{}'
elif _magic_re.search(value):
@@ -411,7 +415,6 @@ class Variable:
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
@@ -683,7 +686,6 @@ class Misc:
this widget in the Tcl interpreter."""
if self._tclCommands is not None:
for name in self._tclCommands:
- #print '- Tkinter: deleted command', name
self.tk.deletecommand(name)
self._tclCommands = None
@@ -691,7 +693,6 @@ class Misc:
"""Internal function.
Delete the Tcl command provided in NAME."""
- #print '- Tkinter: deleted command', name
self.tk.deletecommand(name)
try:
self._tclCommands.remove(name)
@@ -2450,6 +2451,8 @@ class Tk(Misc, Wm):
baseName = baseName + ext
interactive = False
self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
+ if _debug:
+ self.tk.settrace(_print_command)
if useTk:
self._loadtk()
if not sys.flags.ignore_environment:
@@ -2536,6 +2539,14 @@ class Tk(Misc, Wm):
"Delegate attribute access to the interpreter object"
return getattr(self.tk, attr)
+
+def _print_command(cmd, *, file=sys.stderr):
+ # Print executed Tcl/Tk commands.
+ assert isinstance(cmd, tuple)
+ cmd = _join(cmd)
+ print(cmd, file=file)
+
+
# Ideally, the classes Pack, Place and Grid disappear, the
# pack/place/grid methods are defined on the Widget class, and
# everybody uses w.pack_whatever(...) instead of Pack.whatever(w,