summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2022-09-27 11:39:31 (GMT)
committerGitHub <noreply@github.com>2022-09-27 11:39:31 (GMT)
commitdc0a87d9a0cf18fdfc51865a3c1bd2d5ebe9eae9 (patch)
tree72bd3ca17f456c5ab39352ff1219f908009aafe1 /Lib
parent2e315d87ff0e7ac01d532ebb334f7bb8f376bfe6 (diff)
downloadcpython-dc0a87d9a0cf18fdfc51865a3c1bd2d5ebe9eae9.zip
cpython-dc0a87d9a0cf18fdfc51865a3c1bd2d5ebe9eae9.tar.gz
cpython-dc0a87d9a0cf18fdfc51865a3c1bd2d5ebe9eae9.tar.bz2
gh-73588: Fix generation of the default name of tkinter.Checkbutton. (GH-97547)
Previously, checkbuttons in different parent widgets could have the same short name and share the same state if arguments "name" and "variable" are not specified. Now they are globally unique. (cherry picked from commit adbed2d542a815b8175db965742211856b19b52f) Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Diffstat (limited to 'Lib')
-rw-r--r--Lib/tkinter/__init__.py12
-rw-r--r--Lib/tkinter/dialog.py2
-rw-r--r--Lib/tkinter/test/test_tkinter/test_widgets.py26
-rw-r--r--Lib/tkinter/test/test_ttk/test_widgets.py15
-rw-r--r--Lib/tkinter/tix.py2
5 files changed, 54 insertions, 3 deletions
diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py
index b20c16d..c7176e6 100644
--- a/Lib/tkinter/__init__.py
+++ b/Lib/tkinter/__init__.py
@@ -2592,7 +2592,7 @@ class BaseWidget(Misc):
if kw:
cnf = _cnfmerge((cnf, kw))
self.widgetName = widgetName
- BaseWidget._setup(self, master, cnf)
+ self._setup(master, cnf)
if self._tclCommands is None:
self._tclCommands = []
classes = [(k, v) for k, v in cnf.items() if isinstance(k, type)]
@@ -3011,6 +3011,8 @@ class Canvas(Widget, XView, YView):
return self.tk.call(self._w, 'type', tagOrId) or None
+_checkbutton_count = 0
+
class Checkbutton(Widget):
"""Checkbutton widget which is either in on- or off-state."""
@@ -3026,6 +3028,14 @@ class Checkbutton(Widget):
underline, variable, width, wraplength."""
Widget.__init__(self, master, 'checkbutton', cnf, kw)
+ def _setup(self, master, cnf):
+ if not cnf.get('name'):
+ global _checkbutton_count
+ name = self.__class__.__name__.lower()
+ _checkbutton_count += 1
+ cnf['name'] = f'!{name}{_checkbutton_count}'
+ super()._setup(master, cnf)
+
def deselect(self):
"""Put the button in off-state."""
self.tk.call(self._w, 'deselect')
diff --git a/Lib/tkinter/dialog.py b/Lib/tkinter/dialog.py
index 8ae2140..36ae6c2 100644
--- a/Lib/tkinter/dialog.py
+++ b/Lib/tkinter/dialog.py
@@ -11,7 +11,7 @@ class Dialog(Widget):
def __init__(self, master=None, cnf={}, **kw):
cnf = _cnfmerge((cnf, kw))
self.widgetName = '__dialog__'
- Widget._setup(self, master, cnf)
+ self._setup(master, cnf)
self.num = self.tk.getint(
self.tk.call(
'tk_dialog', self._w,
diff --git a/Lib/tkinter/test/test_tkinter/test_widgets.py b/Lib/tkinter/test/test_tkinter/test_widgets.py
index c0b92bf..562f471 100644
--- a/Lib/tkinter/test/test_tkinter/test_widgets.py
+++ b/Lib/tkinter/test/test_tkinter/test_widgets.py
@@ -212,6 +212,32 @@ class CheckbuttonTest(AbstractLabelTest, unittest.TestCase):
widget = self.create()
self.checkParams(widget, 'onvalue', 1, 2.3, '', 'any string')
+ def test_unique_variables(self):
+ frames = []
+ buttons = []
+ for i in range(2):
+ f = tkinter.Frame(self.root)
+ f.pack()
+ frames.append(f)
+ for j in 'AB':
+ b = tkinter.Checkbutton(f, text=j)
+ b.pack()
+ buttons.append(b)
+ variables = [str(b['variable']) for b in buttons]
+ self.assertEqual(len(set(variables)), 4, variables)
+
+ def test_same_name(self):
+ f1 = tkinter.Frame(self.root)
+ f2 = tkinter.Frame(self.root)
+ b1 = tkinter.Checkbutton(f1, name='test', text='Test1')
+ b2 = tkinter.Checkbutton(f2, name='test', text='Test2')
+
+ v = tkinter.IntVar(self.root, name='test')
+ b1.select()
+ self.assertEqual(v.get(), 1)
+ b2.deselect()
+ self.assertEqual(v.get(), 0)
+
@add_standard_options(StandardOptionsTests)
class RadiobuttonTest(AbstractLabelTest, unittest.TestCase):
diff --git a/Lib/tkinter/test/test_ttk/test_widgets.py b/Lib/tkinter/test/test_ttk/test_widgets.py
index 1cb7e74..c314296 100644
--- a/Lib/tkinter/test/test_ttk/test_widgets.py
+++ b/Lib/tkinter/test/test_ttk/test_widgets.py
@@ -275,6 +275,21 @@ class CheckbuttonTest(AbstractLabelTest, unittest.TestCase):
self.assertEqual(cbtn['offvalue'],
cbtn.tk.globalgetvar(cbtn['variable']))
+ def test_unique_variables(self):
+ frames = []
+ buttons = []
+ for i in range(2):
+ f = ttk.Frame(self.root)
+ f.pack()
+ frames.append(f)
+ for j in 'AB':
+ b = ttk.Checkbutton(f, text=j)
+ b.pack()
+ buttons.append(b)
+ variables = [str(b['variable']) for b in buttons]
+ print(variables)
+ self.assertEqual(len(set(variables)), 4, variables)
+
@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
class EntryTest(AbstractWidgetTest, unittest.TestCase):
diff --git a/Lib/tkinter/tix.py b/Lib/tkinter/tix.py
index 44ecae1..ce21826 100644
--- a/Lib/tkinter/tix.py
+++ b/Lib/tkinter/tix.py
@@ -310,7 +310,7 @@ class TixWidget(tkinter.Widget):
del cnf[k]
self.widgetName = widgetName
- Widget._setup(self, master, cnf)
+ self._setup(master, cnf)
# If widgetName is None, this is a dummy creation call where the
# corresponding Tk widget has already been created by Tix