[Python-checkins] r62591 - in sandbox/trunk/ttk-gsoc: Doc/library/othergui.rst.diff Doc/library/tk.rst.diff Doc/library/ttk.rst Lib/lib-tk/Ttk.py samples/theme_selector.py samples/widget_state.py

guilherme.polo python-checkins at python.org
Wed Apr 30 16:12:08 CEST 2008


Author: guilherme.polo
Date: Wed Apr 30 16:12:07 2008
New Revision: 62591

Log:
Changed method configure of class Style so it accepts arguments to be
passed as:
  foreground="blue"
instead of:
  "-foreground", "blue"

Wrapped some other widgets: Sizegrip, Separator, Radiobutton, 
Menubutton and LabelFrame which are all pretty simple to wrap.

Added initial documentation for Ttk.

Added a diff for Doc/library/othergui.rst which does some minor
corrections in the same sense of the ones at tk.rst.diff

Updated Doc/library/tk.rst.diff so it points to the Ttk documentation
and also changed a part of its text to match the current estate of Tk.


Added:
   sandbox/trunk/ttk-gsoc/Doc/library/othergui.rst.diff
Modified:
   sandbox/trunk/ttk-gsoc/Doc/library/tk.rst.diff
   sandbox/trunk/ttk-gsoc/Doc/library/ttk.rst
   sandbox/trunk/ttk-gsoc/Lib/lib-tk/Ttk.py
   sandbox/trunk/ttk-gsoc/samples/theme_selector.py
   sandbox/trunk/ttk-gsoc/samples/widget_state.py

Added: sandbox/trunk/ttk-gsoc/Doc/library/othergui.rst.diff
==============================================================================
--- (empty file)
+++ sandbox/trunk/ttk-gsoc/Doc/library/othergui.rst.diff	Wed Apr 30 16:12:07 2008
@@ -0,0 +1,18 @@
+Index: Doc/library/othergui.rst
+===================================================================
+--- Doc/library/othergui.rst	(revision 62383)
++++ Doc/library/othergui.rst	(working copy)
+@@ -69,10 +69,9 @@
+       <http://www.amazon.com/exec/obidos/ASIN/1932394621>`_, by Noel Rappin and
+       Robin Dunn.
+ 
+-PyGTK, PyQt, and wxPython, all have a modern look and feel and far more
+-widgets and better documentation than Tkinter. In addition,
+-there are many other GUI toolkits for Python, both cross-platform, and
+-platform-specific. See the `GUI Programming
++PyGTK, PyQt, and wxPython, all have a modern look and feel and more
++widgets than Tkinter. In addition, there are many other GUI toolkits for 
++Python, both cross-platform, and platform-specific. See the `GUI Programming
+ <http://wiki.python.org/moin/GuiProgramming>`_ page in the Python Wiki for a
+ much more complete list, and also for links to documents where the
+ different GUI toolkits are compared.

Modified: sandbox/trunk/ttk-gsoc/Doc/library/tk.rst.diff
==============================================================================
--- sandbox/trunk/ttk-gsoc/Doc/library/tk.rst.diff	(original)
+++ sandbox/trunk/ttk-gsoc/Doc/library/tk.rst.diff	Wed Apr 30 16:12:07 2008
@@ -2,7 +2,30 @@
 ===================================================================
 --- Doc/library/tk.rst	(revision 62383)
 +++ Doc/library/tk.rst	(working copy)
-@@ -30,6 +30,7 @@
+@@ -12,7 +12,8 @@
+ 
+ Tk/Tcl has long been an integral part of Python.  It provides a robust and
+ platform independent windowing toolkit, that is available to Python programmers
+-using the :mod:`Tkinter` module, and its extension, the :mod:`Tix` module.
++using the :mod:`Tkinter` module, its extension, the :mod:`Tix` module and
++the :mod:`Ttk` module for using themed widgets.
+ 
+ The :mod:`Tkinter` module is a thin object-oriented layer on top of Tcl/Tk. To
+ use :mod:`Tkinter`, you don't need to write Tcl code, but you will need to
+@@ -22,14 +23,16 @@
+ mechanism which allows Python and Tcl to interact.
+ 
+ :mod:`Tkinter`'s chief virtues are that it is fast, and that it usually comes
+-bundled with Python. Although it has been used to create some very good
+-applications, including IDLE, it has weak documentation and an outdated look and
+-feel. For more modern, better documented, and much more extensive GUI
+-libraries, see the :ref:`other-gui-packages` section.
++bundled with Python, but it has the fame of having an outdated look and feel.
++Tk 8.5 has improved a lot on look and feel, so this is not entirely true 
++anymore, nevertheless, there are many other GUI libraries that you could be
++be interested in. For more information about alternatives, see the 
++:ref:`other-gui-packages` section.
+ 
  .. toctree::
     
     tkinter.rst

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	Wed Apr 30 16:12:07 2008
@@ -1,11 +1,190 @@
-:mod:`Ttk` --- Empty
-====================
+:mod:`Ttk` --- Tk themed widgets
+================================
 
 .. module:: Ttk
-   :synposis: Empty
+   :synopsis: Tk themed widget set
 .. sectionauthor:: Guilherme Polo <ggpolo at gmail.com>
 
 
 .. index:: single: Ttk
 
-Booh!
+The :mod:`Ttk` module provides access to the Tk themed widget set, which
+has been introduced in Tk 8.5. If you do not have Python compiled against
+Tk 8.5 you may still use this module as long as you have Tile installed and
+you will also miss other features of the new Tk, like anti-aliased font
+rendering under X11, window transparency (on X11 you will need a compositing 
+window manager), and others.
+
+The basic idea of :mod:`Ttk` is to separate, to the extent possible, the code 
+implementing a widget's behavior from the code implementing its appearance. 
+
+
+.. seealso::
+
+   `Tk Widget Styling Support <http://www.tcl.tk/cgi-bin/tct/tip/48>`_
+      The document which brought up theming support for Tk
+
+
+Using Ttk
+---------
+
+Basically to use Ttk you have to import its module::
+
+   import Ttk
+
+But if you already have some code that does::
+
+   from Tkinter import *
+
+You may optionally want to use::
+
+   from Tkinter import *
+   from Ttk import *
+
+So several :mod:`Ttk` widgets (:class:`Button`, :class:`Entry`, :class:`Frame`,
+:class:`Label`, :class:`LabelFrame`, :class:`Menubutton`, :class:`PanedWindow`,
+:class:`Radiobutton`, :class:`Scrollbar`) will automatically substitute the Tk 
+widgets. 
+
+This has the direct benefit of using the new widgets which gives better
+look & feel across platforms, but you should be aware that they are not 
+totally compatible. The main difference you will find out is that widget 
+options such as "-fg", "-bg" and others related to widget styling are no 
+longer present in Ttk widgets, instead you will have to use Ttk :class:`Style` 
+to achieve same (or better) styling.
+
+
+Ttk Widgets
+-----------
+
+Ttk comes with 16 widgets, where 10 of these already existed in Tkinter:
+:class:`Button`, :class:`Checkbutton`, :class:`Entry`, :class:`Frame`, :
+class:`Label`, :class:`LabelFrame`, :class:`Menubutton`, :class:`PanedWindow`, 
+:class:`Radiobutton` and :class:`Scrollbar`. The others 6 are new:
+:class:`Combobox`, :class:`Notebook`, :class:`Progressbar`, :class:`Separator`,
+:class:`Sizegrip` and :class:`Treeview`. And all them are subclasses of 
+:class:`Widget`.
+
+Like it was told before, you will notice look & feel changes aswell changes
+in the styling code. To demonstrate the latter, a simple example follows.
+
+Tk code::
+
+   l1 = Tkinter.Label(text="Test", fg="black", bg="white")
+   l2 = Tkinter.Label(text="Test", fg="black", bg="white")
+
+Ttk code::
+
+   style = Ttk.Style()
+   style.configure("BW.TButton", foreground="black", background="white")
+
+   l1 = Ttk.Label(text="Test", style="BW.TButton")
+   l2 = Ttk.Label(text="Test", style="BW.TButton")
+
+
+.. class:: Widget
+
+   Accepts the following options:
+
+   +-----------+--------------------------------------------------------------+
+   | Option    | Description                                                  |
+   +===========+==============================================================+
+   | class     | Specifies the window class. The class is used when querying  |
+   |           | the option database for the window's other options, to       |
+   |           | determine the default bindtags for the window, and to select |
+   |           | the widget's default layout and style. This is a read-only   |
+   |           | which may only be specified when the window is created       |
+   +-----------+--------------------------------------------------------------+
+   | cursor    | Specifies the mouse cursor to be used for the widget. If set |
+   |           | to the emptry string (the default), the cursor is inherited  |
+   |           | for the parent widget.                                       |
+   +-----------+--------------------------------------------------------------+
+   | takefocus | Determines wheter the window accepts the focus during        |
+   |           | keyboard traversal. 0, 1 or an empty is return. If 0 is      |
+   |           | returned, it means that the window should be skipped entirely|
+   |           | during keyboard traversal. If 1, it means that the window    |
+   |           | should receive the input focus as long as it is viewable. And|
+   |           | an empty string means that the traversal scripts make the    |
+   |           | decision about whether or not to focus on the window.        |
+   +-----------+--------------------------------------------------------------+
+   | style     | May be used to specify a custom widget style                 |
+   +-----------+--------------------------------------------------------------+
+
+   And the new methods:
+
+   .. method:: instate(statespec[, callback=None], *args]])
+
+      Test the widget's state. If a callback is not specified, returns 1
+      if the widget state matches statespec and 0 otherwise. If callback
+      is specified then it is called with args if widget state matches 
+      statespec.
+
+
+   .. method:: state([statespec=None])
+
+      Modify or inquire widget state. If statespec is specified, sets the
+      widget state according to it and return a new statespec indicating
+      which flags were changed. If statespec is not especified, returns
+      a list of the currently-enabled state flags.
+
+
+Widget States
+^^^^^^^^^^^^^
+
+   The widget state is a bitmap of independent state flags.
+
+   +------------+-------------------------------------------------------------+
+   | flag       | description                                                 |
+   +============+=============================================================+
+   | active     | The mouse cursor is over the widget and pressing a mouse    |
+   |            | button will cause soem action to occur                      |
+   +------------+-------------------------------------------------------------+
+   | disabled   | Widget is disabled under program control                    |
+   +------------+-------------------------------------------------------------+
+   | focus      | Widget has keyboard focus                                   |
+   +------------+-------------------------------------------------------------+
+   | pressed    | Widget is being pressed                                     |
+   +------------+-------------------------------------------------------------+
+   | selected   | "On", "true", or "current" for things like Checkbuttons and |
+   |            | radiobuttons                                                |
+   +------------+-------------------------------------------------------------+
+   | background | Windows and Mac have a notion of an "active" or foreground  |
+   |            | window. The *background* state is set for widgets in a      |
+   |            | background window, and cleared for those in the foreground  |
+   |            | window                                                      |
+   +------------+-------------------------------------------------------------+
+   | readonly   | Widget should not allow user mofidication                   |
+   +------------+-------------------------------------------------------------+
+   | alternate  | A widget-specific alternate display format                  |
+   +------------+-------------------------------------------------------------+
+   | invalid    | The widget's value is invalid                               |
+   +------------+-------------------------------------------------------------+
+
+   A state specification is a list of state names, optionally prefixed with an
+   exclamation point indicating that the bit is off.
+
+
+New Widgets
+^^^^^^^^^^^
+
+:class:`Combobox`, :class:`Notebook`, :class:`Progressbar`, :class:`Separator`, :class:`Sizegrip` and :class:`Treeview`.
+
+.. class:: Combobox
+.. class:: Notebook
+.. class:: Progressbar
+.. class:: Separator
+.. class:: Sizegrip
+.. class:: Treeview
+
+
+Ttk Styling
+-----------
+
+
+.. class:: Style
+
+
+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	Wed Apr 30 16:12:07 2008
@@ -16,8 +16,10 @@
 
 __author__ = "Guilherme Polo <ggpolo at gmail.com>"
 
-__all__ = ["Button", "Checkbutton", "Combobox", "Entry", "Frame", "Label", 
-           "Style", "Widget"]
+__all__ = ["Button", "Checkbutton", "Combobox", "Entry", "Frame", 
+           "Label", "LabelFrame", "Menubutton", "Notebook", "PanedWindow", 
+           "Progressbar", "Radiobutton", "Scrollbar", "Separator", 
+           "Sizegrip", "Treeview", "Style"]
 
 import Tkinter
 
@@ -31,7 +33,9 @@
     # Ttk is available for use, or not.
     def f(self):
         loadtk(self)
-        if REQUIRE_TILE:
+        if REQUIRE_TILE: 
+            # XXX Maybe I should catch a possible TclError and display a
+            #     Warning telling Ttk won't be available ?
             self.tk.eval('package require tile')
     
     return f
@@ -51,12 +55,16 @@
 
         self.tk = master.tk
 
-    def configure(self, style, *args):
+    def configure(self, style, **kw):
         """Sets the default value of the especified option(s) in style."""
-        return self.tk.call(self._name, "configure", style, *args)
+        opts = [("-%s" % opt, value) for opt, value in kw.iteritems()]
+        opts = Tkinter._flatten(opts)
+
+        return self.tk.call(self._name, "configure", style, *opts)
 
 
     def map(self, style, statespec):
+        # XXX Missing docstring
         self.tk.call(self._name, "map", style, statespec)
 
 
@@ -123,10 +131,14 @@
         raise NotImplementedError
 
 
-    def theme_settings(self, themename, script):
-        """Temporarily sets the current theme to themename, evaluate 
+    def theme_settings(self, themeName, script):
+        """Temporarily sets the current theme to themeName, evaluate 
         script, then restore the previous theme."""
-        raise NotImplementedError
+        # 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.
+        self.tk.call(self._name, "theme", "settings", themeName, script)
 
 
     def theme_names(self):
@@ -165,6 +177,9 @@
         Tkinter.Widget.__init__(self, master, widgetName, cnf, kw, extra)
 
 
+    # XXX statespec is said to be a list of state names, but right now both
+    #     functions expects and returns (state method) a string with the states.
+
     def instate(self, statespec, callback=None, *args):
         """Test the widget's state. 
         
@@ -228,10 +243,10 @@
 
     def invoke(self):
         """Toggles between the selected and deselected states and 
-        invoke the associated command. If the widget is currently 
-        selected, sets the option variable to the option offvalue 
-        option and deselects the widget; otherwise, sets the option
-        variable to the option onvalue.
+        invokes the associated command. If the widget is currently 
+        selected, sets the option variable to the offvalue option 
+        and deselects the widget; otherwise, sets the option variable 
+        to the option onvalue.
 
         Returns the result of the associated command."""
         return self.tk.call(self._w, "invoke")
@@ -346,3 +361,116 @@
             relief, text, wraplength
         """
         Widget.__init__(self, master, "ttk::label", cnf, kw)
+
+
+class LabelFrame(Widget):
+    """Ttk Labelframe widget is a container used to group other widgets
+    together. It has an optional label, which may be a plain text string
+    or another widget."""
+
+    def __init__(self, master=None, cnf={}, **kw):
+        """Construct a Ttk Labelframe with parent master.
+
+        STANDARD OPTIONS
+
+            class, cursor, style, takefocus
+
+        WIDGET-SPECIFIC OPTIONS
+            labelanchor, text, underline, padding, labelwidget, width,
+            height
+        """
+        Widget.__init__(self, master, "ttk::labelframe", cnf, kw)
+
+
+class Menubutton(Widget):
+    """Ttk Menubutton widget displays a textual label and/or image, and
+    displays a menu when pressed."""
+
+    def __init__(self, master=None, cnf={}, **kw):
+        """Construct a Ttk Menubutton with parent master.
+
+        STANDARD OPTIONS
+
+            class, compound, cursor, image, state, style, takefocus, 
+            text, textvariable, underline, width
+
+        WIDGET-SPECIFIC OPTIONS
+
+            direction, menu
+        """
+        Widget.__init__(self, master, "ttk::menubutton", cnf, kw)
+
+
+class Notebook(Widget): pass
+
+
+class PanedWindow(Widget): pass
+
+
+class Progressbar(Widget): pass
+
+
+class Radiobutton(Widget):
+    """Ttk Radiobutton widgets are used in groups to show or change a
+    set of mutually-exclusive options."""
+
+    def __init__(self, master=None, cnf={}, **kw):
+        """Construct a Ttk Radiobutton with parent master.
+
+        STANDARD OPTIONS
+
+            class, compound, cursor, image, state, style, takefocus,
+            text, textvariable, underline, width
+
+        WIDGET-SPECIFIC OPTIONS
+
+            command, value, variable
+        """
+        Widget.__init__(self, master, "ttk::radiobutton", cnf, kw)
+
+
+    def invoke(self):
+        """Sets the option variable to the option value, selects the
+        widget, and invokes the associated command.
+
+        Returns the result of the command, or an empty string if
+        no command is specified."""
+        return self.tk.call(self._w, "invoke")
+
+
+class Scrollbar(Widget): pass
+
+
+class Separator(Widget):
+    """Ttk Separator widget displays a horizontal or vertical separator
+    bar."""
+
+    def __init__(self, master=None, cnf={}, **kw):
+        """Construct a Ttk Separator with parent master.
+
+        STANDARD OPTIONS
+
+            class, cursor, style, takefocus
+
+        WIDGET-SPECIFIC OPTIONS
+
+            orient
+        """
+        Widget.__init__(self, master, "ttk::separator", cnf, kw)
+
+
+class Sizegrip(Widget):
+    """Ttk Sizegrip allows the user to resize the containing toplevel
+    window by pressing and dragging the grip."""
+
+    def __init__(self, master=None, cnf={}, **kw):
+        """Construct a Ttk Sizegrip with parent master.
+
+        STANDARD OPTIONS
+            
+            class, cursor, state, style, takefocus
+        """
+        Widget.__init__(self, master, "ttk::sizegrip", cnf, kw)
+
+
+class Treeview(Widget): pass

Modified: sandbox/trunk/ttk-gsoc/samples/theme_selector.py
==============================================================================
--- sandbox/trunk/ttk-gsoc/samples/theme_selector.py	(original)
+++ sandbox/trunk/ttk-gsoc/samples/theme_selector.py	Wed Apr 30 16:12:07 2008
@@ -14,7 +14,7 @@
         self.style = Ttk.Style()
 
         # XXX Ideally I wouldn't want to create a Tkinter.IntVar to make
-        #     it work with Checkbutton variable option.
+        #     it works with Checkbutton variable option.
         self.theme_autochange = Tkinter.IntVar(self, 0)
         self._setup_widgets()
 
@@ -35,7 +35,7 @@
         self.themes_combo.bind("<<ComboboxSelected>>", self._theme_sel_changed)
 
         change_btn = Ttk.Button(self, text='Change Theme', 
-            command=self._change_theme) # XXX how can I set Ttk Button height?
+            command=self._change_theme)
        
         theme_change_checkbtn = Ttk.Checkbutton(self, 
             text="Change themes when combobox item is activated", 

Modified: sandbox/trunk/ttk-gsoc/samples/widget_state.py
==============================================================================
--- sandbox/trunk/ttk-gsoc/samples/widget_state.py	(original)
+++ sandbox/trunk/ttk-gsoc/samples/widget_state.py	Wed Apr 30 16:12:07 2008
@@ -33,8 +33,8 @@
         self._setup_widgets()
 
     def _set_font(self, extra=0):
-        self.style.configure("TButton", "-font", 
-            "%s -%d" % (self.font_family, self.base_font_size + extra))
+        self.style.configure("TButton", font="%s -%d" % (self.font_family, 
+            self.base_font_size + extra))
 
     def _new_state(self, widget, newtext):
         widget = self.nametowidget(widget)


More information about the Python-checkins mailing list