Tix Vs Pmw which is better to use?

Greg McFarlane gregm at iname.com
Tue May 14 03:10:35 EDT 2002


It seems that Cimarron has not read (or did not understand) the Pmw
documentation, otherwise he would have found that none of his
frustrations are due to Pmw itself.  Perhaps the documentation
could be improved? Please let me know.

cimarron+google at taylors.org (Cimarron Taylor) wrote in message news:<29e28c51.0205020305.53cbfd22 at posting.google.com>...
> I have not used Tix, but I have recently started working with Pmw. 
> Overall I'm pretty happy with the result.  First the good things:
> 
> 1. Pmw is easy to use and there are lots of examples!

and documentation!
 
> 2. Pmw has a very nice Notebook widget which makes it easy to create
>    the tab-dialog interface I wanted.

I'm glad it was of use.

> Now for the things which frustrated me:
> 
> 3. Not much thought seems to have been given to making the megawidgets
>    support a consistant interface for reading and writing the data
>    values. you often have to violate encapsulation to do something
>    as mundane as setting the value of a widget.

None of the examples you cite require any use of private members. See below.

>     For example, suppose 
>    I create a Pmw.Counter with the following code
> 
>      counter = Pmw.Counter(
>         parent, labelpos='w', label_text='Number of tests',
>         entryfield_value=10, datatype='numeric',
>         entryfield_validate={'validator':'numeric', 'min':0, 'max':100},
>         increment=10
>       ) 
> 
>    To set the value of the counter later on, I need to invoke the
>    setentry() method on the internal entry widget of the counter:
> 
>      counter._counterEntry.setentry(value)

Do this instead:

  counter.setentry(value)

>    So how did I know to do this?  The answer is, I studied the demos and 
>    the source code and tried lots of things until I found something that 
>    worked for this specific widget.  Now suppose somewhere else I create 
>    a read-only text box with the following code:
> 
>       textbox = Pmw.ScrolledText(
>          parent, borderframe=1, text_padx=5, text_pady=5, 
>          text_wrap='none', vscrollmode='static', hscrollmode='static'
>        )
>       textbox._textbox.configure(state='disabled')

Do this instead:

    textbox.configure(text_state = 'disabled')

Or add this component option when creating the megawidget:

    text_state = 'disabled'

>    I could find no obvious way to make the text box read-only without
>    once again acessing an internal member of the widget.  Also, by trial 
>    and error I have discovered that I can set the text of the widget via
> 
>       textbox._textbox.configure(state='normal')
>       textbox.clear()
>       textbox.settext(value) 
>       textbox._textbox.configure(state='disabled')

This works:

    textbox.settext(value)

 
>    You get the idea.  To me, the most important thing a megawidget must do
>    is manage the value shown to the user and one of the important programming
>    services the megawidget layer should provide is a simple and consistent 
>    way of accessing that value.  Hence I ended up rolling my own adaptor
>    classes for this purpose.  Here is my own Counter:
> 
>       class Counter:
>         "class providing a common get/set interface to Pmw.Counter"
>         def __init__(self, parent, labeltext, init, min, max, incr=1):
>            self.counter = Pmw.Counter(
>              parent, labelpos='w', label_text=labeltext,
>              entryfield_value=init, datatype='numeric',
>              entryfield_validate={'validator':'numeric', 'min':min, 'max':max},
>              increment=incr) 
>            self.counter._counterEntry._entryFieldEntry.config(bg='white')
>         def get(self):
>            return self.counter._counterEntry.get()
>         def set(self, value):
>            return self.counter._counterEntry.setentry(value)

Setting the background could be done with:
        self.counter.configure(entry_background = 'white')
or by adding this component option to the constructor on the previous line:
        entry_background = 'white'

The last two methods could have been written:
    def get(self):
        return self.counter.get()
    def set(self, value):
        return self.counter.setentry(value)

> 
> 4. Pmw has a less-than-useful color abstraction.  The Pmw.Color class 
>    may be useful if you want to change the entire color scheme of an
>    application but it is difficult to use with a single widget.  For example,
>    the Pmw.Color example suggests
> 
> 	defaultPalette = Pmw.Color.getdefaultpalette(parent)
>       normalcolor = Pmw.Color.changebrightness(parent, 'white', 0.85)
> 	Pmw.Color.setscheme(parent, normalcolor)
>        .. create your widget here ..
> 	apply(Pmw.Color.setscheme, (parent,), defaultPalette)
> 
>     but suppose you want only the editable area of the counter to 
>     have a white background and not the entire widget to be white.
>     The code you see above is a dead-end.  To do what I wanted you 
>     will need something like
> 
>       self.counter._counterEntry._entryFieldEntry.config(bg='white')

Pmw.Color was mainly written so that the otherwise difficult task of changing
the color scheme of an entire widget hierarchy was made easier.  It is
relatively easy to change the color of a single widget, see point 3 above.


> 5.  The font system is also a little less than useful.  Suppose you
>     want your text box to use a fixed width font.  Once again you 
>     will need to access the internal member:
> 
>        typewriter = apply(Pmw.logicalfont, ('Typewriter', 0), {})
>        textbox = Pmw.ScrolledText(
>            parent, borderframe=1, text_padx=5, text_pady=5, 
>            text_wrap='none', vscrollmode='static', hscrollmode='static')
>        textbox._textbox.configure(font=typewriter)

Or, more simply:

    textbox.configure(text_font = typewriter)

Or add this component option when creating the megawidget:
    text_font = typewriter

> 6.  Be very careful about which geometry management scheme you choose.
>     If you accidently mix .pack() and .grid(), you may end up with an
>     application which freezes up the first time you resize it (of course,
>     this is probably more of a Tkinter problem than a Pmw one).

You are right. But I found that I only made this mistake once. And it
has nothing to do with Pmw.

Greg



More information about the Python-list mailing list