[Python-checkins] r62619 - in sandbox/trunk/ttk-gsoc: Doc/library/ttk.rst Lib/lib-tk/Ttk.py

guilherme.polo python-checkins at python.org
Thu May 1 21:30:59 CEST 2008


Author: guilherme.polo
Date: Thu May  1 21:30:58 2008
New Revision: 62619

Log:
ttk::style theme settings has been wrapped, documentation added.

Formatting code used at map method has been moved to the function 
_format_mapdict, and formatting code used at configure method has
been moved to the function _format_confdict. This was done to let
theme_settings reuse this code and perform its job.



Modified:
   sandbox/trunk/ttk-gsoc/Doc/library/ttk.rst
   sandbox/trunk/ttk-gsoc/Lib/lib-tk/Ttk.py

Modified: sandbox/trunk/ttk-gsoc/Doc/library/ttk.rst
==============================================================================
--- sandbox/trunk/ttk-gsoc/Doc/library/ttk.rst	(original)
+++ sandbox/trunk/ttk-gsoc/Doc/library/ttk.rst	Thu May  1 21:30:58 2008
@@ -190,9 +190,9 @@
 
 Each widget is assigned a style, which especifies the set of elements making
 up the widget and how they are arranged, along with dynamic and default
-settings for element options. By default, the style name is the same as
-the widget's class prefixed by a "T", which may be overriden by the widget's 
-style option.
+settings for element options. By default the style name is the same as
+the widget's class prefixed by a "T" (except the root style that is "."), 
+but it may be overriden by the widget's style option.
 
 .. seealso::
 
@@ -305,7 +305,38 @@
    .. method:: theme_create TBD
 
 
-   .. method:: theme_settings TBD
+   .. method:: theme_settings(themeName, settings)
+
+      Temporarily sets the current theme to themeName, apply specified settings and then restore 
+      the previous theme.
+      
+      Each key in *settings* is a style and each value may contain the keys 'configure' and 'map'. 
+      'configure' and 'map' are expected to have the same format as specified by the methods 
+      configure and map respectively.
+      
+      As an example, lets change the Combobox for the default theme a bit::
+
+         import Ttk
+         import Tkinter
+
+         root = Tkinter.Tk()
+
+         style = Ttk.Style()
+         style.theme_settings("default", {
+            "TCombobox": {
+                "configure": {"padding": 5},
+                "map": {
+                    "background": [("active", "green2"), ("!disabled", "green4")],
+                    "fieldbackground": [("!disabled", "green3")],
+                    "foreground": [("focus", "OliveDrab1"), ("!disabled", "OliveDrab2")]
+                }
+            }
+         })
+
+         combo = Ttk.Combobox().pack()
+
+         root.mainloop()
+
 
 
    .. method:: theme_names()
@@ -313,9 +344,9 @@
       Returns a list of all known themes
        
 
-   .. method:: theme_use(themename)
+   .. method:: theme_use(themeName)
 
-      Sets the current theme to themename and refreshes all wigets
+      Sets the current theme to themeName and refreshes all wigets
     
 
 Others new features

Modified: sandbox/trunk/ttk-gsoc/Lib/lib-tk/Ttk.py
==============================================================================
--- sandbox/trunk/ttk-gsoc/Lib/lib-tk/Ttk.py	(original)
+++ sandbox/trunk/ttk-gsoc/Lib/lib-tk/Ttk.py	Thu May  1 21:30:58 2008
@@ -34,14 +34,58 @@
     def f(self):
         loadtk(self)
         if REQUIRE_TILE: 
-            # XXX Maybe I should catch a possible TclError and display a
-            #     Warning telling Ttk won't be available ?
+            # XXX Maybe I should catch a possible TclError and display 
+            #     a Warning telling Ttk won't be available ? Or maye I 
+            #     shouldn't be doing this at all, the users could then 
+            #     write the next line
             self.tk.eval('package require tile')
     
     return f
 
 Tkinter.Tk._loadtk = _loadttk(Tkinter.Tk._loadtk)
 
+def _format_confdict(confdict):
+    """Formats confdict to pass it to tk.call.
+    
+    E.g.: 
+      {'foreground': 'blue'} returns:
+      ('-foreground', 'blue')"""
+    opts = [("-%s" % opt, value) for opt, value in confdict.iteritems()]
+    return Tkinter._flatten(opts)
+
+def _format_mapdict(mapdict, script=False):
+    """Formats mapdict to pass it to tk.call.
+    
+    E.g.:
+      {'background': [('active", 'white'), ('focus', 'blue')]} returns:
+      ('-background', 'active white focus blue')"""
+
+    opts = []
+
+    for opt, value in mapdict.iteritems():
+
+        opt_val = []
+        # each value in mapdict is expected to be a sequence, where each item
+        # is a another sequence containg a state (or several) and a value 
+        # for it
+        for state, val in value:
+            if not isinstance(state, basestring):
+                # lets believe it is a sequence and format these multiple 
+                # states according to Tk documentation
+                state = "{%s}" % ' '.join(state) 
+
+            opt_val.append("%s %s" % (state, val))
+
+        if script: 
+            # theme_settings passes a Tcl script to tk.call, so it needs
+            # a Tcl formatting
+            opts.append(("-%s" % opt, "[list %s]" % ' '.join(opt_val)))
+        else:
+            opts.append(("-%s" % opt, ' '.join(opt_val)))
+
+    return Tkinter._flatten(opts)
+
+
 class Style(object):
     """Manipulate style database."""
    
@@ -56,36 +100,24 @@
         self.tk = master.tk
 
     def configure(self, style, **kw):
-        """Sets the default value of the specified option(s) in style."""
-        opts = [("-%s" % opt, value) for opt, value in kw.iteritems()]
-        opts = Tkinter._flatten(opts)
-
+        """Sets the default value of the specified option(s) in style.
+        
+        Each key in kw is an option and each value is a string identifying
+        the value for that option."""
+        opts = _format_confdict(kw)
         return self.tk.call(self._name, "configure", style, *opts)
 
 
     def map(self, style, **kw):
-        """Sets dynamic values of the specified option(s) in given style."""
-        opts = []
-
-        # format kw to pass it to tk
-        for opt, value in kw.iteritems():
-
-            opt_val = []
-            # each value in kw is expected to be a sequence, where each item
-            # is a another sequence containg a state (or several) and a value 
-            # for it
-            for state, val in value:
-                if not isinstance(state, basestring):
-                    # lets believe it is a sequence and format these multiple 
-                    # states according to Tk documentation
-                    state = "{%s}" % ' '.join(state) 
-
-                opt_val.append("%s %s" % (state, val))
-
-            opts.append(("-%s" % opt, ' '.join(opt_val)))
-
-        opts = Tkinter._flatten(opts)
-        self.tk.call(self._name, "map", style, *opts)
+        """Sets dynamic values of the specified option(s) in given style.
+        
+        Each key in kw is an option and each value should be a sequence. 
+        Each of these sequences have to have a state, or a group of states,
+        and a value, grouped in yet another sequence. Note that a group of 
+        states is expected to be a sequence, otherwise a single string 
+        should be passed as state."""
+        opts = _format_mapdict(kw)
+        return self.tk.call(self._name, "map", style, *opts)
 
 
     def lookup(self, style, option, state=None, default=None):
@@ -149,17 +181,33 @@
         return self.tk.call(self._name, "element", "options", element)
 
 
-    def theme_create(self, themename, **kw):
+    def theme_create(self, themeName, **kw):
         raise NotImplementedError
 
 
-    def theme_settings(self, themeName, script):
-        """Temporarily sets the current theme to themeName, evaluate 
-        script, then restore the previous theme."""
-        # XXX script may define styles and elements, but it also accepts
-        #     arbitrary Tcl code. It may be more interesting to check
-        #     what are the uses here and change this method so it 
-        #     resembles more like Python code than Tcl code.
+    def theme_settings(self, themeName, settings):
+        """Temporarily sets the current theme to themeName, apply specified
+        settings and then restore the previous theme.
+
+        Each key in settings is a style and each value may contain the 
+        keys 'configure' and 'map'. 'configure' and 'map' are expected to 
+        have the same format as specified by the methods configure and map 
+        respectively."""
+        script = []
+        # a script will be generated according to settings passed, which
+        # will then be evaluated by Tcl
+        for name, opts in settings.iteritems():
+            # format 'configure' according to Tcl code
+            if opts.get('configure'):
+                s = ' '.join(map(str, _format_confdict(opts['configure'])))
+                script.append("%s configure %s %s;" % (self._name, name, s))
+
+            # format 'map' according to Tcl code
+            if opts.get('map'):
+                s = ' '.join(map(str, _format_mapdict(opts['map'], True)))
+                script.append("%s map %s %s;" % (self._name, name, s))
+
+        script = '\n'.join(script)
         self.tk.call(self._name, "theme", "settings", themeName, script)
 
 
@@ -168,9 +216,9 @@
         return self.tk.call(self._name, "theme", "names")
 
 
-    def theme_use(self, themename):
-        """Sets the current theme to themename and refreshes all widgets."""
-        self.tk.call(self._name, "theme", "use", themename)
+    def theme_use(self, themeName):
+        """Sets the current theme to themeName and refreshes all widgets."""
+        self.tk.call(self._name, "theme", "use", themeName)
 
 
 class Widget(Tkinter.Widget):


More information about the Python-checkins mailing list