mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	gh-43457: Tkinter: fix design flaws in wm_attributes() (GH-111404)
* When called with a single argument to get a value, it allow to omit the minus prefix. * It can be called with keyword arguments to set attributes. * w.wm_attributes(return_python_dict=True) returns a dict instead of a tuple (it will be the default in future). * Setting wantobjects to 0 no longer affects the result.
This commit is contained in:
		
							parent
							
								
									992446dd5b
								
							
						
					
					
						commit
						b4ba0f73d6
					
				
					 6 changed files with 104 additions and 19 deletions
				
			
		|  | @ -421,6 +421,15 @@ tkinter | ||||||
|   :meth:`!tk_busy_current`, and :meth:`!tk_busy_status`. |   :meth:`!tk_busy_current`, and :meth:`!tk_busy_status`. | ||||||
|   (Contributed by Miguel, klappnase and Serhiy Storchaka in :gh:`72684`.) |   (Contributed by Miguel, klappnase and Serhiy Storchaka in :gh:`72684`.) | ||||||
| 
 | 
 | ||||||
|  | * The :mod:`tkinter` widget method :meth:`!wm_attributes` now accepts | ||||||
|  |   the attribute name without the minus prefix to get window attributes, | ||||||
|  |   e.g. ``w.wm_attributes('alpha')`` and allows to specify attributes and | ||||||
|  |   values to set as keyword arguments, e.g. ``w.wm_attributes(alpha=0.5)``. | ||||||
|  |   Add new optional keyword-only parameter *return_python_dict*: calling | ||||||
|  |   ``w.wm_attributes(return_python_dict=True)`` returns the attributes as | ||||||
|  |   a dict instead of a tuple. | ||||||
|  |   (Contributed by Serhiy Storchaka in :gh:`43457`.) | ||||||
|  | 
 | ||||||
| * Add support of the "vsapi" element type in | * Add support of the "vsapi" element type in | ||||||
|   the :meth:`~tkinter.ttk.Style.element_create` method of |   the :meth:`~tkinter.ttk.Style.element_create` method of | ||||||
|   :class:`tkinter.ttk.Style`. |   :class:`tkinter.ttk.Style`. | ||||||
|  |  | ||||||
|  | @ -14,7 +14,7 @@ def setUpClass(cls): | ||||||
|         # Some window managers can maximize new windows. |         # Some window managers can maximize new windows. | ||||||
|         cls.root.wm_state('normal') |         cls.root.wm_state('normal') | ||||||
|         try: |         try: | ||||||
|             cls.root.wm_attributes('-zoomed', False) |             cls.root.wm_attributes(zoomed=False) | ||||||
|         except tkinter.TclError: |         except tkinter.TclError: | ||||||
|             pass |             pass | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -437,6 +437,61 @@ def test_info_patchlevel(self): | ||||||
|         self.assertTrue(str(vi).startswith(f'{vi.major}.{vi.minor}')) |         self.assertTrue(str(vi).startswith(f'{vi.major}.{vi.minor}')) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | class WmTest(AbstractTkTest, unittest.TestCase): | ||||||
|  | 
 | ||||||
|  |     def test_wm_attribute(self): | ||||||
|  |         w = self.root | ||||||
|  |         attributes = w.wm_attributes(return_python_dict=True) | ||||||
|  |         self.assertIsInstance(attributes, dict) | ||||||
|  |         attributes2 = w.wm_attributes() | ||||||
|  |         self.assertIsInstance(attributes2, tuple) | ||||||
|  |         self.assertEqual(attributes2[::2], | ||||||
|  |                          tuple('-' + k for k in attributes)) | ||||||
|  |         self.assertEqual(attributes2[1::2], tuple(attributes.values())) | ||||||
|  |         # silently deprecated | ||||||
|  |         attributes3 = w.wm_attributes(None) | ||||||
|  |         if self.wantobjects: | ||||||
|  |             self.assertEqual(attributes3, attributes2) | ||||||
|  |         else: | ||||||
|  |             self.assertIsInstance(attributes3, str) | ||||||
|  | 
 | ||||||
|  |         for name in attributes: | ||||||
|  |             self.assertEqual(w.wm_attributes(name), attributes[name]) | ||||||
|  |         # silently deprecated | ||||||
|  |         for name in attributes: | ||||||
|  |             self.assertEqual(w.wm_attributes('-' + name), attributes[name]) | ||||||
|  | 
 | ||||||
|  |         self.assertIn('alpha', attributes) | ||||||
|  |         self.assertIn('fullscreen', attributes) | ||||||
|  |         self.assertIn('topmost', attributes) | ||||||
|  |         if w._windowingsystem == "win32": | ||||||
|  |             self.assertIn('disabled', attributes) | ||||||
|  |             self.assertIn('toolwindow', attributes) | ||||||
|  |             self.assertIn('transparentcolor', attributes) | ||||||
|  |         if w._windowingsystem == "aqua": | ||||||
|  |             self.assertIn('modified', attributes) | ||||||
|  |             self.assertIn('notify', attributes) | ||||||
|  |             self.assertIn('titlepath', attributes) | ||||||
|  |             self.assertIn('transparent', attributes) | ||||||
|  |         if w._windowingsystem == "x11": | ||||||
|  |             self.assertIn('type', attributes) | ||||||
|  |             self.assertIn('zoomed', attributes) | ||||||
|  | 
 | ||||||
|  |         w.wm_attributes(alpha=0.5) | ||||||
|  |         self.assertEqual(w.wm_attributes('alpha'), | ||||||
|  |                          0.5 if self.wantobjects else '0.5') | ||||||
|  |         w.wm_attributes(alpha=1.0) | ||||||
|  |         self.assertEqual(w.wm_attributes('alpha'), | ||||||
|  |                          1.0 if self.wantobjects else '1.0') | ||||||
|  |         # silently deprecated | ||||||
|  |         w.wm_attributes('-alpha', 0.5) | ||||||
|  |         self.assertEqual(w.wm_attributes('alpha'), | ||||||
|  |                          0.5 if self.wantobjects else '0.5') | ||||||
|  |         w.wm_attributes(alpha=1.0) | ||||||
|  |         self.assertEqual(w.wm_attributes('alpha'), | ||||||
|  |                          1.0 if self.wantobjects else '1.0') | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| class BindTest(AbstractTkTest, unittest.TestCase): | class BindTest(AbstractTkTest, unittest.TestCase): | ||||||
| 
 | 
 | ||||||
|     def setUp(self): |     def setUp(self): | ||||||
|  |  | ||||||
|  | @ -2108,26 +2108,39 @@ def wm_aspect(self, | ||||||
| 
 | 
 | ||||||
|     aspect = wm_aspect |     aspect = wm_aspect | ||||||
| 
 | 
 | ||||||
|     def wm_attributes(self, *args): |     def wm_attributes(self, *args, return_python_dict=False, **kwargs): | ||||||
|         """This subcommand returns or sets platform specific attributes |         """Return or sets platform specific attributes. | ||||||
| 
 | 
 | ||||||
|         The first form returns a list of the platform specific flags and |         When called with a single argument return_python_dict=True, | ||||||
|         their values. The second form returns the value for the specific |         return a dict of the platform specific attributes and their values. | ||||||
|         option. The third form sets one or more of the values. The values |         When called without arguments or with a single argument | ||||||
|         are as follows: |         return_python_dict=False, return a tuple containing intermixed | ||||||
|  |         attribute names with the minus prefix and their values. | ||||||
| 
 | 
 | ||||||
|         On Windows, -disabled gets or sets whether the window is in a |         When called with a single string value, return the value for the | ||||||
|         disabled state. -toolwindow gets or sets the style of the window |         specific option.  When called with keyword arguments, set the | ||||||
|         to toolwindow (as defined in the MSDN). -topmost gets or sets |         corresponding attributes. | ||||||
|         whether this is a topmost window (displays above all other |  | ||||||
|         windows). |  | ||||||
| 
 |  | ||||||
|         On Macintosh, XXXXX |  | ||||||
| 
 |  | ||||||
|         On Unix, there are currently no special attribute values. |  | ||||||
|         """ |         """ | ||||||
|         args = ('wm', 'attributes', self._w) + args |         if not kwargs: | ||||||
|         return self.tk.call(args) |             if not args: | ||||||
|  |                 res = self.tk.call('wm', 'attributes', self._w) | ||||||
|  |                 if return_python_dict: | ||||||
|  |                     return _splitdict(self.tk, res) | ||||||
|  |                 else: | ||||||
|  |                     return self.tk.splitlist(res) | ||||||
|  |             if len(args) == 1 and args[0] is not None: | ||||||
|  |                 option = args[0] | ||||||
|  |                 if option[0] == '-': | ||||||
|  |                     # TODO: deprecate | ||||||
|  |                     option = option[1:] | ||||||
|  |                 return self.tk.call('wm', 'attributes', self._w, '-' + option) | ||||||
|  |             # TODO: deprecate | ||||||
|  |             return self.tk.call('wm', 'attributes', self._w, *args) | ||||||
|  |         elif args: | ||||||
|  |             raise TypeError('wm_attribute() options have been specified as ' | ||||||
|  |                             'positional and keyword arguments') | ||||||
|  |         else: | ||||||
|  |             self.tk.call('wm', 'attributes', self._w, *self._options(kwargs)) | ||||||
| 
 | 
 | ||||||
|     attributes = wm_attributes |     attributes = wm_attributes | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -262,7 +262,7 @@ def _setup_dialog(w): | ||||||
|         w.tk.call("::tk::unsupported::MacWindowStyle", "style", |         w.tk.call("::tk::unsupported::MacWindowStyle", "style", | ||||||
|                   w, "moveableModal", "") |                   w, "moveableModal", "") | ||||||
|     elif w._windowingsystem == "x11": |     elif w._windowingsystem == "x11": | ||||||
|         w.wm_attributes("-type", "dialog") |         w.wm_attributes(type="dialog") | ||||||
| 
 | 
 | ||||||
| # -------------------------------------------------------------------- | # -------------------------------------------------------------------- | ||||||
| # convenience dialogues | # convenience dialogues | ||||||
|  |  | ||||||
|  | @ -0,0 +1,8 @@ | ||||||
|  | Fix the :mod:`tkinter` widget method :meth:`!wm_attributes`. It now | ||||||
|  | accepts the attribute name without the minus prefix to get window attributes | ||||||
|  | and allows to specify attributes and values to set as keyword arguments. | ||||||
|  | Add new optional keyword argument *return_python_dict*: calling | ||||||
|  | ``w.wm_attributes(return_python_dict=True)`` returns the attributes as | ||||||
|  | a dict instead of a tuple. | ||||||
|  | Calling ``w.wm_attributes()`` now returns a tuple instead of string if | ||||||
|  | *wantobjects* was set to 0. | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Serhiy Storchaka
						Serhiy Storchaka