mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 11:49:12 +00:00 
			
		
		
		
	Issue #15861: tkinter now correctly works with lists and tuples containing
strings with whitespaces, backslashes or unbalanced braces.
This commit is contained in:
		
						commit
						1e2b7ee3e8
					
				
					 5 changed files with 123 additions and 81 deletions
				
			
		| 
						 | 
					@ -40,6 +40,7 @@ import warnings
 | 
				
			||||||
import _tkinter # If this fails your Python may not be configured for Tk
 | 
					import _tkinter # If this fails your Python may not be configured for Tk
 | 
				
			||||||
TclError = _tkinter.TclError
 | 
					TclError = _tkinter.TclError
 | 
				
			||||||
from tkinter.constants import *
 | 
					from tkinter.constants import *
 | 
				
			||||||
 | 
					import re
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
wantobjects = 1
 | 
					wantobjects = 1
 | 
				
			||||||
| 
						 | 
					@ -52,6 +53,34 @@ WRITABLE = _tkinter.WRITABLE
 | 
				
			||||||
EXCEPTION = _tkinter.EXCEPTION
 | 
					EXCEPTION = _tkinter.EXCEPTION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_magic_re = re.compile(r'([\\{}])')
 | 
				
			||||||
 | 
					_space_re = re.compile(r'([\s])', re.ASCII)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def _join(value):
 | 
				
			||||||
 | 
					    """Internal function."""
 | 
				
			||||||
 | 
					    return ' '.join(map(_stringify, value))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def _stringify(value):
 | 
				
			||||||
 | 
					    """Internal function."""
 | 
				
			||||||
 | 
					    if isinstance(value, (list, tuple)):
 | 
				
			||||||
 | 
					        if len(value) == 1:
 | 
				
			||||||
 | 
					            value = _stringify(value[0])
 | 
				
			||||||
 | 
					            if value[0] == '{':
 | 
				
			||||||
 | 
					                value = '{%s}' % value
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            value = '{%s}' % _join(value)
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        value = str(value)
 | 
				
			||||||
 | 
					        if not value:
 | 
				
			||||||
 | 
					            value = '{}'
 | 
				
			||||||
 | 
					        elif _magic_re.search(value):
 | 
				
			||||||
 | 
					            # add '\' before special characters and spaces
 | 
				
			||||||
 | 
					            value = _magic_re.sub(r'\\\1', value)
 | 
				
			||||||
 | 
					            value = _space_re.sub(r'\\\1', value)
 | 
				
			||||||
 | 
					        elif value[0] == '"' or _space_re.search(value):
 | 
				
			||||||
 | 
					            value = '{%s}' % value
 | 
				
			||||||
 | 
					    return value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _flatten(seq):
 | 
					def _flatten(seq):
 | 
				
			||||||
    """Internal function."""
 | 
					    """Internal function."""
 | 
				
			||||||
    res = ()
 | 
					    res = ()
 | 
				
			||||||
| 
						 | 
					@ -1089,7 +1118,7 @@ class Misc:
 | 
				
			||||||
                        if isinstance(item, int):
 | 
					                        if isinstance(item, int):
 | 
				
			||||||
                            nv.append(str(item))
 | 
					                            nv.append(str(item))
 | 
				
			||||||
                        elif isinstance(item, str):
 | 
					                        elif isinstance(item, str):
 | 
				
			||||||
                            nv.append(('{%s}' if ' ' in item else '%s') % item)
 | 
					                            nv.append(_stringify(item))
 | 
				
			||||||
                        else:
 | 
					                        else:
 | 
				
			||||||
                            break
 | 
					                            break
 | 
				
			||||||
                    else:
 | 
					                    else:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,13 +49,17 @@ class InternalFunctionsTest(unittest.TestCase):
 | 
				
			||||||
            ttk._format_optdict({'test': {'left': 'as is'}}),
 | 
					            ttk._format_optdict({'test': {'left': 'as is'}}),
 | 
				
			||||||
            {'-test': {'left': 'as is'}})
 | 
					            {'-test': {'left': 'as is'}})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # check script formatting and untouched value(s)
 | 
					        # check script formatting
 | 
				
			||||||
        check_against(
 | 
					        check_against(
 | 
				
			||||||
            ttk._format_optdict(
 | 
					            ttk._format_optdict(
 | 
				
			||||||
                {'test': [1, -1, '', '2m', 0], 'nochange1': 3,
 | 
					                {'test': [1, -1, '', '2m', 0], 'test2': 3,
 | 
				
			||||||
                 'nochange2': 'abc def'}, script=True),
 | 
					                 'test3': '', 'test4': 'abc def',
 | 
				
			||||||
            {'-test': '{1 -1 {} 2m 0}', '-nochange1': 3,
 | 
					                 'test5': '"abc"', 'test6': '{}',
 | 
				
			||||||
             '-nochange2': 'abc def' })
 | 
					                 'test7': '} -spam {'}, script=True),
 | 
				
			||||||
 | 
					            {'-test': '{1 -1 {} 2m 0}', '-test2': '3',
 | 
				
			||||||
 | 
					             '-test3': '{}', '-test4': '{abc def}',
 | 
				
			||||||
 | 
					             '-test5': '{"abc"}', '-test6': r'\{\}',
 | 
				
			||||||
 | 
					             '-test7': r'\}\ -spam\ \{'})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        opts = {'αβγ': True, 'á': False}
 | 
					        opts = {'αβγ': True, 'á': False}
 | 
				
			||||||
        orig_opts = opts.copy()
 | 
					        orig_opts = opts.copy()
 | 
				
			||||||
| 
						 | 
					@ -69,6 +73,32 @@ class InternalFunctionsTest(unittest.TestCase):
 | 
				
			||||||
            ttk._format_optdict(
 | 
					            ttk._format_optdict(
 | 
				
			||||||
                {'option': ('one two', 'three')}),
 | 
					                {'option': ('one two', 'three')}),
 | 
				
			||||||
            {'-option': '{one two} three'})
 | 
					            {'-option': '{one two} three'})
 | 
				
			||||||
 | 
					        check_against(
 | 
				
			||||||
 | 
					            ttk._format_optdict(
 | 
				
			||||||
 | 
					                {'option': ('one\ttwo', 'three')}),
 | 
				
			||||||
 | 
					            {'-option': '{one\ttwo} three'})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # passing empty strings inside a tuple/list
 | 
				
			||||||
 | 
					        check_against(
 | 
				
			||||||
 | 
					            ttk._format_optdict(
 | 
				
			||||||
 | 
					                {'option': ('', 'one')}),
 | 
				
			||||||
 | 
					            {'-option': '{} one'})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # passing values with braces inside a tuple/list
 | 
				
			||||||
 | 
					        check_against(
 | 
				
			||||||
 | 
					            ttk._format_optdict(
 | 
				
			||||||
 | 
					                {'option': ('one} {two', 'three')}),
 | 
				
			||||||
 | 
					            {'-option': r'one\}\ \{two three'})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # passing quoted strings inside a tuple/list
 | 
				
			||||||
 | 
					        check_against(
 | 
				
			||||||
 | 
					            ttk._format_optdict(
 | 
				
			||||||
 | 
					                {'option': ('"one"', 'two')}),
 | 
				
			||||||
 | 
					            {'-option': '{"one"} two'})
 | 
				
			||||||
 | 
					        check_against(
 | 
				
			||||||
 | 
					            ttk._format_optdict(
 | 
				
			||||||
 | 
					                {'option': ('{one}', 'two')}),
 | 
				
			||||||
 | 
					            {'-option': r'\{one\} two'})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # ignore an option
 | 
					        # ignore an option
 | 
				
			||||||
        amount_opts = len(ttk._format_optdict(opts, ignore=('á'))) / 2
 | 
					        amount_opts = len(ttk._format_optdict(opts, ignore=('á'))) / 2
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -189,6 +189,14 @@ class ComboboxTest(unittest.TestCase):
 | 
				
			||||||
        self.combo.configure(values=[1, '', 2])
 | 
					        self.combo.configure(values=[1, '', 2])
 | 
				
			||||||
        self.assertEqual(self.combo['values'], ('1', '', '2'))
 | 
					        self.assertEqual(self.combo['values'], ('1', '', '2'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # testing values with spaces
 | 
				
			||||||
 | 
					        self.combo['values'] = ['a b', 'a\tb', 'a\nb']
 | 
				
			||||||
 | 
					        self.assertEqual(self.combo['values'], ('a b', 'a\tb', 'a\nb'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # testing values with special characters
 | 
				
			||||||
 | 
					        self.combo['values'] = [r'a\tb', '"a"', '} {']
 | 
				
			||||||
 | 
					        self.assertEqual(self.combo['values'], (r'a\tb', '"a"', '} {'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # out of range
 | 
					        # out of range
 | 
				
			||||||
        self.assertRaises(tkinter.TclError, self.combo.current,
 | 
					        self.assertRaises(tkinter.TclError, self.combo.current,
 | 
				
			||||||
            len(self.combo['values']))
 | 
					            len(self.combo['values']))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,8 +26,7 @@ __all__ = ["Button", "Checkbutton", "Combobox", "Entry", "Frame", "Label",
 | 
				
			||||||
           "tclobjs_to_py", "setup_master"]
 | 
					           "tclobjs_to_py", "setup_master"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import tkinter
 | 
					import tkinter
 | 
				
			||||||
 | 
					from tkinter import _flatten, _join, _stringify
 | 
				
			||||||
_flatten = tkinter._flatten
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Verify if Tk is new enough to not need the Tile package
 | 
					# Verify if Tk is new enough to not need the Tile package
 | 
				
			||||||
_REQUIRE_TILE = True if tkinter.TkVersion < 8.5 else False
 | 
					_REQUIRE_TILE = True if tkinter.TkVersion < 8.5 else False
 | 
				
			||||||
| 
						 | 
					@ -47,40 +46,55 @@ def _load_tile(master):
 | 
				
			||||||
        master.tk.eval('package require tile') # TclError may be raised here
 | 
					        master.tk.eval('package require tile') # TclError may be raised here
 | 
				
			||||||
        master._tile_loaded = True
 | 
					        master._tile_loaded = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def _format_optvalue(value, script=False):
 | 
				
			||||||
 | 
					    """Internal function."""
 | 
				
			||||||
 | 
					    if script:
 | 
				
			||||||
 | 
					        # if caller passes a Tcl script to tk.call, all the values need to
 | 
				
			||||||
 | 
					        # be grouped into words (arguments to a command in Tcl dialect)
 | 
				
			||||||
 | 
					        value = _stringify(value)
 | 
				
			||||||
 | 
					    elif isinstance(value, (list, tuple)):
 | 
				
			||||||
 | 
					        value = _join(value)
 | 
				
			||||||
 | 
					    return value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _format_optdict(optdict, script=False, ignore=None):
 | 
					def _format_optdict(optdict, script=False, ignore=None):
 | 
				
			||||||
    """Formats optdict to a tuple to pass it to tk.call.
 | 
					    """Formats optdict to a tuple to pass it to tk.call.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    E.g. (script=False):
 | 
					    E.g. (script=False):
 | 
				
			||||||
      {'foreground': 'blue', 'padding': [1, 2, 3, 4]} returns:
 | 
					      {'foreground': 'blue', 'padding': [1, 2, 3, 4]} returns:
 | 
				
			||||||
      ('-foreground', 'blue', '-padding', '1 2 3 4')"""
 | 
					      ('-foreground', 'blue', '-padding', '1 2 3 4')"""
 | 
				
			||||||
    format = "%s" if not script else "{%s}"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    opts = []
 | 
					    opts = []
 | 
				
			||||||
    for opt, value in optdict.items():
 | 
					    for opt, value in optdict.items():
 | 
				
			||||||
        if ignore and opt in ignore:
 | 
					        if not ignore or opt not in ignore:
 | 
				
			||||||
            continue
 | 
					            opts.append("-%s" % opt)
 | 
				
			||||||
 | 
					            if value is not None:
 | 
				
			||||||
 | 
					                opts.append(_format_optvalue(value, script))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if isinstance(value, (list, tuple)):
 | 
					 | 
				
			||||||
            v = []
 | 
					 | 
				
			||||||
            for val in value:
 | 
					 | 
				
			||||||
                if isinstance(val, str):
 | 
					 | 
				
			||||||
                    v.append(str(val) if val else '{}')
 | 
					 | 
				
			||||||
                else:
 | 
					 | 
				
			||||||
                    v.append(str(val))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            # format v according to the script option, but also check for
 | 
					 | 
				
			||||||
            # space in any value in v in order to group them correctly
 | 
					 | 
				
			||||||
            value = format % ' '.join(
 | 
					 | 
				
			||||||
                ('{%s}' if ' ' in val else '%s') % val for val in v)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if script and value == '':
 | 
					 | 
				
			||||||
            value = '{}' # empty string in Python is equivalent to {} in Tcl
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        opts.append(("-%s" % opt, value))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Remember: _flatten skips over None
 | 
					 | 
				
			||||||
    return _flatten(opts)
 | 
					    return _flatten(opts)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def _mapdict_values(items):
 | 
				
			||||||
 | 
					    # each value in mapdict is expected to be a sequence, where each item
 | 
				
			||||||
 | 
					    # is another sequence containing a state (or several) and a value
 | 
				
			||||||
 | 
					    # E.g. (script=False):
 | 
				
			||||||
 | 
					    #   [('active', 'selected', 'grey'), ('focus', [1, 2, 3, 4])]
 | 
				
			||||||
 | 
					    #   returns:
 | 
				
			||||||
 | 
					    #   ['active selected', 'grey', 'focus', [1, 2, 3, 4]]
 | 
				
			||||||
 | 
					    opt_val = []
 | 
				
			||||||
 | 
					    for *state, val in items:
 | 
				
			||||||
 | 
					        # hacks for bakward compatibility
 | 
				
			||||||
 | 
					        state[0] # raise IndexError if empty
 | 
				
			||||||
 | 
					        if len(state) == 1:
 | 
				
			||||||
 | 
					            # if it is empty (something that evaluates to False), then
 | 
				
			||||||
 | 
					            # format it to Tcl code to denote the "normal" state
 | 
				
			||||||
 | 
					            state = state[0] or ''
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            # group multiple states
 | 
				
			||||||
 | 
					            state = ' '.join(state) # raise TypeError if not str
 | 
				
			||||||
 | 
					        opt_val.append(state)
 | 
				
			||||||
 | 
					        if val is not None:
 | 
				
			||||||
 | 
					            opt_val.append(val)
 | 
				
			||||||
 | 
					    return opt_val
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _format_mapdict(mapdict, script=False):
 | 
					def _format_mapdict(mapdict, script=False):
 | 
				
			||||||
    """Formats mapdict to pass it to tk.call.
 | 
					    """Formats mapdict to pass it to tk.call.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -90,32 +104,11 @@ def _format_mapdict(mapdict, script=False):
 | 
				
			||||||
      returns:
 | 
					      returns:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      ('-expand', '{active selected} grey focus {1, 2, 3, 4}')"""
 | 
					      ('-expand', '{active selected} grey focus {1, 2, 3, 4}')"""
 | 
				
			||||||
    # if caller passes a Tcl script to tk.call, all the values need to
 | 
					 | 
				
			||||||
    # be grouped into words (arguments to a command in Tcl dialect)
 | 
					 | 
				
			||||||
    format = "%s" if not script else "{%s}"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    opts = []
 | 
					    opts = []
 | 
				
			||||||
    for opt, value in mapdict.items():
 | 
					    for opt, value in mapdict.items():
 | 
				
			||||||
 | 
					        opts.extend(("-%s" % opt,
 | 
				
			||||||
        opt_val = []
 | 
					                     _format_optvalue(_mapdict_values(value), script)))
 | 
				
			||||||
        # each value in mapdict is expected to be a sequence, where each item
 | 
					 | 
				
			||||||
        # is another sequence containing a state (or several) and a value
 | 
					 | 
				
			||||||
        for statespec in value:
 | 
					 | 
				
			||||||
            state, val = statespec[:-1], statespec[-1]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if len(state) > 1: # group multiple states
 | 
					 | 
				
			||||||
                state = "{%s}" % ' '.join(state)
 | 
					 | 
				
			||||||
            else: # single state
 | 
					 | 
				
			||||||
                # if it is empty (something that evaluates to False), then
 | 
					 | 
				
			||||||
                # format it to Tcl code to denote the "normal" state
 | 
					 | 
				
			||||||
                state = state[0] or '{}'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if isinstance(val, (list, tuple)): # val needs to be grouped
 | 
					 | 
				
			||||||
                val = "{%s}" % ' '.join(map(str, val))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            opt_val.append("%s %s" % (state, val))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        opts.append(("-%s" % opt, format % ' '.join(opt_val)))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return _flatten(opts)
 | 
					    return _flatten(opts)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -129,7 +122,7 @@ def _format_elemcreate(etype, script=False, *args, **kw):
 | 
				
			||||||
            iname = args[0]
 | 
					            iname = args[0]
 | 
				
			||||||
            # next args, if any, are statespec/value pairs which is almost
 | 
					            # next args, if any, are statespec/value pairs which is almost
 | 
				
			||||||
            # a mapdict, but we just need the value
 | 
					            # a mapdict, but we just need the value
 | 
				
			||||||
            imagespec = _format_mapdict({None: args[1:]})[1]
 | 
					            imagespec = _join(_mapdict_values(args[1:]))
 | 
				
			||||||
            spec = "%s %s" % (iname, imagespec)
 | 
					            spec = "%s %s" % (iname, imagespec)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
| 
						 | 
					@ -138,7 +131,7 @@ def _format_elemcreate(etype, script=False, *args, **kw):
 | 
				
			||||||
            # themed styles on Windows XP and Vista.
 | 
					            # themed styles on Windows XP and Vista.
 | 
				
			||||||
            # Availability: Tk 8.6, Windows XP and Vista.
 | 
					            # Availability: Tk 8.6, Windows XP and Vista.
 | 
				
			||||||
            class_name, part_id = args[:2]
 | 
					            class_name, part_id = args[:2]
 | 
				
			||||||
            statemap = _format_mapdict({None: args[2:]})[1]
 | 
					            statemap = _join(_mapdict_values(args[2:]))
 | 
				
			||||||
            spec = "%s %s %s" % (class_name, part_id, statemap)
 | 
					            spec = "%s %s %s" % (class_name, part_id, statemap)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        opts = _format_optdict(kw, script)
 | 
					        opts = _format_optdict(kw, script)
 | 
				
			||||||
| 
						 | 
					@ -148,11 +141,11 @@ def _format_elemcreate(etype, script=False, *args, **kw):
 | 
				
			||||||
        # otherwise it will clone {} (empty element)
 | 
					        # otherwise it will clone {} (empty element)
 | 
				
			||||||
        spec = args[0] # theme name
 | 
					        spec = args[0] # theme name
 | 
				
			||||||
        if len(args) > 1: # elementfrom specified
 | 
					        if len(args) > 1: # elementfrom specified
 | 
				
			||||||
            opts = (args[1], )
 | 
					            opts = (_format_optvalue(args[1], script),)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if script:
 | 
					    if script:
 | 
				
			||||||
        spec = '{%s}' % spec
 | 
					        spec = '{%s}' % spec
 | 
				
			||||||
        opts = ' '.join(map(str, opts))
 | 
					        opts = ' '.join(opts)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return spec, opts
 | 
					    return spec, opts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -189,7 +182,7 @@ def _format_layoutlist(layout, indent=0, indent_size=2):
 | 
				
			||||||
    for layout_elem in layout:
 | 
					    for layout_elem in layout:
 | 
				
			||||||
        elem, opts = layout_elem
 | 
					        elem, opts = layout_elem
 | 
				
			||||||
        opts = opts or {}
 | 
					        opts = opts or {}
 | 
				
			||||||
        fopts = ' '.join(map(str, _format_optdict(opts, True, "children")))
 | 
					        fopts = ' '.join(_format_optdict(opts, True, ("children",)))
 | 
				
			||||||
        head = "%s%s%s" % (' ' * indent, elem, (" %s" % fopts) if fopts else '')
 | 
					        head = "%s%s%s" % (' ' * indent, elem, (" %s" % fopts) if fopts else '')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if "children" in opts:
 | 
					        if "children" in opts:
 | 
				
			||||||
| 
						 | 
					@ -215,11 +208,11 @@ def _script_from_settings(settings):
 | 
				
			||||||
    for name, opts in settings.items():
 | 
					    for name, opts in settings.items():
 | 
				
			||||||
        # will format specific keys according to Tcl code
 | 
					        # will format specific keys according to Tcl code
 | 
				
			||||||
        if opts.get('configure'): # format 'configure'
 | 
					        if opts.get('configure'): # format 'configure'
 | 
				
			||||||
            s = ' '.join(map(str, _format_optdict(opts['configure'], True)))
 | 
					            s = ' '.join(_format_optdict(opts['configure'], True))
 | 
				
			||||||
            script.append("ttk::style configure %s %s;" % (name, s))
 | 
					            script.append("ttk::style configure %s %s;" % (name, s))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if opts.get('map'): # format 'map'
 | 
					        if opts.get('map'): # format 'map'
 | 
				
			||||||
            s = ' '.join(map(str, _format_mapdict(opts['map'], True)))
 | 
					            s = ' '.join(_format_mapdict(opts['map'], True))
 | 
				
			||||||
            script.append("ttk::style map %s %s;" % (name, s))
 | 
					            script.append("ttk::style map %s %s;" % (name, s))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if 'layout' in opts: # format 'layout' which may be empty
 | 
					        if 'layout' in opts: # format 'layout' which may be empty
 | 
				
			||||||
| 
						 | 
					@ -706,30 +699,9 @@ class Combobox(Entry):
 | 
				
			||||||
            exportselection, justify, height, postcommand, state,
 | 
					            exportselection, justify, height, postcommand, state,
 | 
				
			||||||
            textvariable, values, width
 | 
					            textvariable, values, width
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        # The "values" option may need special formatting, so leave to
 | 
					 | 
				
			||||||
        # _format_optdict the responsibility to format it
 | 
					 | 
				
			||||||
        if "values" in kw:
 | 
					 | 
				
			||||||
            kw["values"] = _format_optdict({'v': kw["values"]})[1]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Entry.__init__(self, master, "ttk::combobox", **kw)
 | 
					        Entry.__init__(self, master, "ttk::combobox", **kw)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __setitem__(self, item, value):
 | 
					 | 
				
			||||||
        if item == "values":
 | 
					 | 
				
			||||||
            value = _format_optdict({item: value})[1]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Entry.__setitem__(self, item, value)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def configure(self, cnf=None, **kw):
 | 
					 | 
				
			||||||
        """Custom Combobox configure, created to properly format the values
 | 
					 | 
				
			||||||
        option."""
 | 
					 | 
				
			||||||
        if "values" in kw:
 | 
					 | 
				
			||||||
            kw["values"] = _format_optdict({'v': kw["values"]})[1]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return Entry.configure(self, cnf, **kw)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def current(self, newindex=None):
 | 
					    def current(self, newindex=None):
 | 
				
			||||||
        """If newindex is supplied, sets the combobox value to the
 | 
					        """If newindex is supplied, sets the combobox value to the
 | 
				
			||||||
        element at position newindex in the list of values. Otherwise,
 | 
					        element at position newindex in the list of values. Otherwise,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -150,6 +150,9 @@ Core and Builtins
 | 
				
			||||||
Library
 | 
					Library
 | 
				
			||||||
-------
 | 
					-------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Issue #15861: tkinter now correctly works with lists and tuples containing
 | 
				
			||||||
 | 
					  strings with whitespaces, backslashes or unbalanced braces.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- Issue #10527: Use poll() instead of select() for multiprocessing pipes.
 | 
					- Issue #10527: Use poll() instead of select() for multiprocessing pipes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- Issue #9720: zipfile now writes correct local headers for files larger than
 | 
					- Issue #9720: zipfile now writes correct local headers for files larger than
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue