]> granicus.if.org Git - python/commitdiff
Issue #21402: tkinter.ttk now works when default root window is not set.
authorSerhiy Storchaka <storchaka@gmail.com>
Wed, 28 May 2014 15:38:27 +0000 (18:38 +0300)
committerSerhiy Storchaka <storchaka@gmail.com>
Wed, 28 May 2014 15:38:27 +0000 (18:38 +0300)
Lib/tkinter/test/test_ttk/test_functions.py
Lib/tkinter/ttk.py
Misc/NEWS

index 1986e660264b4afeb4a5d956e8aca67edd196d3e..8dd87533ff59be64d267270f2f34db00469833d4 100644 (file)
@@ -1,7 +1,19 @@
 # -*- encoding: utf-8 -*-
 import unittest
+import tkinter
 from tkinter import ttk
 
+class MockTkApp:
+
+    def splitlist(self, arg):
+        if isinstance(arg, tuple):
+            return arg
+        return arg.split(':')
+
+    def wantobjects(self):
+        return True
+
+
 class MockTclObj(object):
     typename = 'test'
 
@@ -352,20 +364,22 @@ class InternalFunctionsTest(unittest.TestCase):
 
 
     def test_list_from_layouttuple(self):
+        tk = MockTkApp()
+
         # empty layout tuple
-        self.assertFalse(ttk._list_from_layouttuple(()))
+        self.assertFalse(ttk._list_from_layouttuple(tk, ()))
 
         # shortest layout tuple
-        self.assertEqual(ttk._list_from_layouttuple(('name', )),
+        self.assertEqual(ttk._list_from_layouttuple(tk, ('name', )),
             [('name', {})])
 
         # not so interesting ltuple
         sample_ltuple = ('name', '-option', 'value')
-        self.assertEqual(ttk._list_from_layouttuple(sample_ltuple),
+        self.assertEqual(ttk._list_from_layouttuple(tk, sample_ltuple),
             [('name', {'option': 'value'})])
 
         # empty children
-        self.assertEqual(ttk._list_from_layouttuple(
+        self.assertEqual(ttk._list_from_layouttuple(tk,
             ('something', '-children', ())),
             [('something', {'children': []})]
         )
@@ -378,7 +392,7 @@ class InternalFunctionsTest(unittest.TestCase):
                 )
             )
         )
-        self.assertEqual(ttk._list_from_layouttuple(ltuple),
+        self.assertEqual(ttk._list_from_layouttuple(tk, ltuple),
             [('name', {'option': 'niceone', 'children':
                 [('otherone', {'otheropt': 'othervalue', 'children':
                     [('child', {})]
@@ -387,29 +401,37 @@ class InternalFunctionsTest(unittest.TestCase):
         )
 
         # bad tuples
-        self.assertRaises(ValueError, ttk._list_from_layouttuple,
+        self.assertRaises(ValueError, ttk._list_from_layouttuple, tk,
             ('name', 'no_minus'))
-        self.assertRaises(ValueError, ttk._list_from_layouttuple,
+        self.assertRaises(ValueError, ttk._list_from_layouttuple, tk,
             ('name', 'no_minus', 'value'))
-        self.assertRaises(ValueError, ttk._list_from_layouttuple,
+        self.assertRaises(ValueError, ttk._list_from_layouttuple, tk,
             ('something', '-children')) # no children
-        import tkinter
-        if not tkinter._default_root or tkinter._default_root.wantobjects():
-            self.assertRaises(ValueError, ttk._list_from_layouttuple,
-                ('something', '-children', 'value')) # invalid children
+        self.assertRaises(ValueError, ttk._list_from_layouttuple, tk,
+            ('something', '-children', 'value')) # invalid children
 
 
     def test_val_or_dict(self):
-        def func(opt, val=None):
+        def func(res, opt=None, val=None):
+            if opt is None:
+                return res
             if val is None:
                 return "test val"
             return (opt, val)
 
-        options = {'test': None}
-        self.assertEqual(ttk._val_or_dict(options, func), "test val")
+        tk = MockTkApp()
+        tk.call = func
+
+        self.assertEqual(ttk._val_or_dict(tk, {}, '-test:3'),
+                         {'test': '3'})
+        self.assertEqual(ttk._val_or_dict(tk, {}, ('-test', 3)),
+                         {'test': 3})
+
+        self.assertEqual(ttk._val_or_dict(tk, {'test': None}, 'x:y'),
+                         'test val')
 
-        options = {'test': 3}
-        self.assertEqual(ttk._val_or_dict(options, func), options)
+        self.assertEqual(ttk._val_or_dict(tk, {'test': 3}, 'x:y'),
+                         {'test': 3})
 
 
     def test_convert_stringval(self):
index ca9027374d56a3b280a8bf1b408b122325189a24..81f909c98450172ee4319f90ce3d2ed61f337506 100644 (file)
@@ -272,7 +272,7 @@ def _list_from_statespec(stuple):
     it = iter(nval)
     return [_flatten(spec) for spec in zip(it, it)]
 
-def _list_from_layouttuple(ltuple):
+def _list_from_layouttuple(tk, ltuple):
     """Construct a list from the tuple returned by ttk::layout, this is
     somewhat the reverse of _format_layoutlist."""
     res = []
@@ -293,17 +293,16 @@ def _list_from_layouttuple(ltuple):
             indx += 2
 
             if opt == 'children':
-                if (tkinter._default_root and
-                    not tkinter._default_root.wantobjects()):
-                    val = tkinter._default_root.splitlist(val)
-                val = _list_from_layouttuple(val)
+                if not tk.wantobjects():
+                    val = tk.splitlist(val)
+                val = _list_from_layouttuple(tk, val)
 
             opts[opt] = val
 
     return res
 
-def _val_or_dict(options, func, *args):
-    """Format options then call func with args and options and return
+def _val_or_dict(tk, options, *args):
+    """Format options then call Tk command with args and options and return
     the appropriate result.
 
     If no option is specified, a dict is returned. If a option is
@@ -311,14 +310,12 @@ def _val_or_dict(options, func, *args):
     Otherwise, the function just sets the passed options and the caller
     shouldn't be expecting a return value anyway."""
     options = _format_optdict(options)
-    res = func(*(args + options))
+    res = tk.call(*(args + options))
 
     if len(options) % 2: # option specified without a value, return its value
         return res
 
-    if tkinter._default_root:
-        res = tkinter._default_root.splitlist(res)
-    return _dict_from_tcltuple(res)
+    return _dict_from_tcltuple(tk.splitlist(res))
 
 def _convert_stringval(value):
     """Converts a value to, hopefully, a more appropriate Python object."""
@@ -396,7 +393,7 @@ class Style(object):
         a sequence identifying the value for that option."""
         if query_opt is not None:
             kw[query_opt] = None
-        return _val_or_dict(kw, self.tk.call, self._name, "configure", style)
+        return _val_or_dict(self.tk, kw, self._name, "configure", style)
 
 
     def map(self, style, query_opt=None, **kw):
@@ -466,7 +463,7 @@ class Style(object):
             lspec = "null" # could be any other word, but this may make sense
                            # when calling layout(style) later
 
-        return _list_from_layouttuple(self.tk.splitlist(
+        return _list_from_layouttuple(self.tk, self.tk.splitlist(
             self.tk.call(self._name, "layout", style, lspec)))
 
 
@@ -907,7 +904,7 @@ class Notebook(Widget):
         options to the corresponding values."""
         if option is not None:
             kw[option] = None
-        return _val_or_dict(kw, self.tk.call, self._w, "tab", tab_id)
+        return _val_or_dict(self.tk, kw, self._w, "tab", tab_id)
 
 
     def tabs(self):
@@ -984,7 +981,7 @@ class Panedwindow(Widget, tkinter.PanedWindow):
         Otherwise, sets the options to the corresponding values."""
         if option is not None:
             kw[option] = None
-        return _val_or_dict(kw, self.tk.call, self._w, "pane", pane)
+        return _val_or_dict(self.tk, kw, self._w, "pane", pane)
 
 
     def sashpos(self, index, newpos=None):
@@ -1223,7 +1220,7 @@ class Treeview(Widget, tkinter.XView, tkinter.YView):
         Otherwise, sets the options to the corresponding values."""
         if option is not None:
             kw[option] = None
-        return _val_or_dict(kw, self.tk.call, self._w, "column", column)
+        return _val_or_dict(self.tk, kw, self._w, "column", column)
 
 
     def delete(self, *items):
@@ -1282,7 +1279,7 @@ class Treeview(Widget, tkinter.XView, tkinter.YView):
         if option is not None:
             kw[option] = None
 
-        return _val_or_dict(kw, self.tk.call, self._w, 'heading', column)
+        return _val_or_dict(self.tk, kw, self._w, 'heading', column)
 
 
     def identify(self, component, x, y):
@@ -1361,7 +1358,7 @@ class Treeview(Widget, tkinter.XView, tkinter.YView):
         values as given by kw."""
         if option is not None:
             kw[option] = None
-        return _val_or_dict(kw, self.tk.call, self._w, "item", item)
+        return _val_or_dict(self.tk, kw, self._w, "item", item)
 
 
     def move(self, item, parent, index):
@@ -1456,7 +1453,7 @@ class Treeview(Widget, tkinter.XView, tkinter.YView):
         values for the given tagname."""
         if option is not None:
             kw[option] = None
-        return _val_or_dict(kw, self.tk.call, self._w, "tag", "configure",
+        return _val_or_dict(self.tk, kw, self._w, "tag", "configure",
             tagname)
 
 
index f82d3c565c5d7a799c2629774c7b42c14eeaad99..51210308ac348e64e8f2e9603ecb903190c368e0 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -18,6 +18,8 @@ Core and Builtins
 Library
 -------
 
+- Issue #21402: tkinter.ttk now works when default root window is not set.
+
 - Issue #10203: sqlite3.Row now truly supports sequence protocol.  In particulr
   it supports reverse() and negative indices.  Original patch by Claudiu Popa.