From f60a986e2a81cff0f9e4f5612f77fd773e146956 Mon Sep 17 00:00:00 2001 From: Cheryl Sabella Date: Mon, 19 Jun 2017 08:31:42 -0400 Subject: [PATCH 1/4] bpo-25684: ttk.OptionMenu radiobuttons aren't unique between instances of OptionMenu --- Lib/tkinter/ttk.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/tkinter/ttk.py b/Lib/tkinter/ttk.py index cbaad76e0084e1..3ecc004f0e06f6 100644 --- a/Lib/tkinter/ttk.py +++ b/Lib/tkinter/ttk.py @@ -1635,7 +1635,8 @@ def set_menu(self, default=None, *values): menu.delete(0, 'end') for val in values: menu.add_radiobutton(label=val, - command=tkinter._setit(self._variable, val, self._callback)) + command=tkinter._setit(self._variable, val, self._callback), + variable=self._variable) if default: self._variable.set(default) From 81779d218d270661db38974a402c5fbcb07283e1 Mon Sep 17 00:00:00 2001 From: Cheryl Sabella Date: Wed, 21 Jun 2017 15:20:49 -0400 Subject: [PATCH 2/4] bpo-25684: Add unittest --- Lib/tkinter/test/test_ttk/test_extensions.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Lib/tkinter/test/test_ttk/test_extensions.py b/Lib/tkinter/test/test_ttk/test_extensions.py index 218b27fc30ea1b..04868448582eb6 100644 --- a/Lib/tkinter/test/test_ttk/test_extensions.py +++ b/Lib/tkinter/test/test_ttk/test_extensions.py @@ -276,7 +276,25 @@ def test_menu(self): self.assertRaises(tkinter.TclError, optmenu['menu'].invoke, -1) self.assertEqual(optmenu._variable.get(), items[0]) + # check that radiobuttons are unique across instances (bpo25684) + textvar2 = tkinter.StringVar(self.root) + optmenu2 = ttk.OptionMenu(self.root, textvar2, default, *items) + optmenu2.pack() + optmenu2.wait_visibility() + optmenu['menu'].invoke(1) + optmenu2['menu'].invoke(2) + optmenu_radiobutton_name = optmenu['menu'].entrycget(0, 'variable') + optmenu2_radiobutton_name = optmenu2['menu'].entrycget(0, 'variable') + self.assertNotEqual(optmenu_radiobutton_name, + optmenu2_radiobutton_name) + self.assertEqual(self.root.tk.globalgetvar(optmenu_radiobutton_name), + items[1]) + self.assertEqual(self.root.tk.globalgetvar(optmenu2_radiobutton_name), + items[2]) + optmenu.destroy() + del textvar2, optmenu_radiobutton_name, optmenu2_radiobutton_name + optmenu2.destroy() # specifying a callback success = [] From 15e73c25acbe5b6fac190e503773ba34fa0ca1f5 Mon Sep 17 00:00:00 2001 From: Cheryl Sabella Date: Mon, 17 Jul 2017 11:35:52 -0400 Subject: [PATCH 3/4] Move tests and add blurb. --- Lib/tkinter/test/test_ttk/test_extensions.py | 34 ++++++++++++------- .../2017-07-17-11-35-00.bpo-25684.usELVx.rst | 2 ++ 2 files changed, 23 insertions(+), 13 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2017-07-17-11-35-00.bpo-25684.usELVx.rst diff --git a/Lib/tkinter/test/test_ttk/test_extensions.py b/Lib/tkinter/test/test_ttk/test_extensions.py index 04868448582eb6..ec5fab481814b3 100644 --- a/Lib/tkinter/test/test_ttk/test_extensions.py +++ b/Lib/tkinter/test/test_ttk/test_extensions.py @@ -276,9 +276,30 @@ def test_menu(self): self.assertRaises(tkinter.TclError, optmenu['menu'].invoke, -1) self.assertEqual(optmenu._variable.get(), items[0]) + optmenu.destroy() + + # specifying a callback + success = [] + def cb_test(item): + self.assertEqual(item, items[1]) + success.append(True) + optmenu = ttk.OptionMenu(self.root, self.textvar, 'a', command=cb_test, + *items) + optmenu['menu'].invoke(1) + if not success: + self.fail("Menu callback not invoked") + + optmenu.destroy() + + def test_unique_radiobuttons(self): # check that radiobuttons are unique across instances (bpo25684) + items = ('a', 'b', 'c') + default = 'a' + optmenu = ttk.OptionMenu(self.root, self.textvar, default, *items) textvar2 = tkinter.StringVar(self.root) optmenu2 = ttk.OptionMenu(self.root, textvar2, default, *items) + optmenu.pack() + optmenu.wait_visibility() optmenu2.pack() optmenu2.wait_visibility() optmenu['menu'].invoke(1) @@ -296,19 +317,6 @@ def test_menu(self): del textvar2, optmenu_radiobutton_name, optmenu2_radiobutton_name optmenu2.destroy() - # specifying a callback - success = [] - def cb_test(item): - self.assertEqual(item, items[1]) - success.append(True) - optmenu = ttk.OptionMenu(self.root, self.textvar, 'a', command=cb_test, - *items) - optmenu['menu'].invoke(1) - if not success: - self.fail("Menu callback not invoked") - - optmenu.destroy() - tests_gui = (LabeledScaleTest, OptionMenuTest) diff --git a/Misc/NEWS.d/next/Library/2017-07-17-11-35-00.bpo-25684.usELVx.rst b/Misc/NEWS.d/next/Library/2017-07-17-11-35-00.bpo-25684.usELVx.rst new file mode 100644 index 00000000000000..61d6b29cafc3ec --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-07-17-11-35-00.bpo-25684.usELVx.rst @@ -0,0 +1,2 @@ +Change ``ttk.OptionMenu`` radiobuttons to be unique across instances of +``OptionMenu``. From b822ebae3c0cb273b9ff9465b117cd95b5ce48be Mon Sep 17 00:00:00 2001 From: Cheryl Sabella Date: Sun, 30 Jul 2017 08:13:30 -0400 Subject: [PATCH 4/4] Rename test variables per Terry's request. --- Lib/tkinter/test/test_ttk/test_extensions.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Lib/tkinter/test/test_ttk/test_extensions.py b/Lib/tkinter/test/test_ttk/test_extensions.py index ec5fab481814b3..a45f882bb00d48 100644 --- a/Lib/tkinter/test/test_ttk/test_extensions.py +++ b/Lib/tkinter/test/test_ttk/test_extensions.py @@ -304,17 +304,16 @@ def test_unique_radiobuttons(self): optmenu2.wait_visibility() optmenu['menu'].invoke(1) optmenu2['menu'].invoke(2) - optmenu_radiobutton_name = optmenu['menu'].entrycget(0, 'variable') - optmenu2_radiobutton_name = optmenu2['menu'].entrycget(0, 'variable') - self.assertNotEqual(optmenu_radiobutton_name, - optmenu2_radiobutton_name) - self.assertEqual(self.root.tk.globalgetvar(optmenu_radiobutton_name), + optmenu_stringvar_name = optmenu['menu'].entrycget(0, 'variable') + optmenu2_stringvar_name = optmenu2['menu'].entrycget(0, 'variable') + self.assertNotEqual(optmenu_stringvar_name, + optmenu2_stringvar_name) + self.assertEqual(self.root.tk.globalgetvar(optmenu_stringvar_name), items[1]) - self.assertEqual(self.root.tk.globalgetvar(optmenu2_radiobutton_name), + self.assertEqual(self.root.tk.globalgetvar(optmenu2_stringvar_name), items[2]) optmenu.destroy() - del textvar2, optmenu_radiobutton_name, optmenu2_radiobutton_name optmenu2.destroy()