Pmw new version 2015

Post here if you need help with creating a Graphical User Interface in Python.

Pmw new version 2015

Postby Larz60+ » Sat Sep 10, 2016 9:35 pm


Just an FYI for anyone who hasn't discovered (and likes pmw):

I just discovered that a new version of pmw was released last year, pmw_2_0_1 (took me a while).
I haven't used it lately because I thought it wasn't being supported anymore, but have been playing with it for the past few days.

A version for Python 3.4 is available using pip
Code: Select all
pip install Pmw

Some of the supplied widgets are slick, and make resizing windows easy

I modified one of the examples from Grayson's book to use python 3.4 just for
chuckles, it uses the ScrolledFrame widget (basically a root window, Frame with vertical and
horizontal scrollbars all in one) which would be a good starting point for many applications.

There is also a really great demo (in the tar version) which allows you to trace the tk calls, and show the source
code instantaneously. It's a great time-saver for development.

It's not as voluminous as Qt4, but I think it's probably going to be open for a lot longer. Qt4 seems
to be moving to a commercial product lately.

It's also written 100% in python.

I will be using this at least for a while in my applications.
Code: Select all
from tkinter import *
import Pmw

class App:
    def __init__(self, parent):
        self.parent = parent
        self.row = 0
        self.col = 0
        self.sf = None
        self.frame = None

        self.sf = Pmw.ScrolledFrame(self.parent, labelpos=N, label_text='ScrolledFrame',
                               usehullsize=1, hull_width=400, hull_height=220)
        self.sf.pack(padx=5, pady=3, fill='both', expand=1)

        self.frame = self.sf.interior()

        for i in range(250):

    def addButton(self):
        button = Button(self.frame, text='(%d,%d)' % (self.col, self.row))
        button.grid(row=self.row, column=self.col, sticky='nsew')

        self.frame.grid_rowconfigure(self.row, weight=1)
        self.frame.grid_columnconfigure(self.col, weight=1)

        if self.col == self.row:
            self.col = 0
            self.row = self.row + 1
            self.col = self.col + 1

def main():
    root = Tk()
    app = App(root)

if __name__ == '__main__':

I think if it gets used more, it's life expectancy will be greatly improved.

Posts: 1307
Joined: Thu Apr 03, 2014 4:06 pm

Pmw tickle your interest

Postby Larz60+ » Mon Sep 12, 2016 2:50 am


As I stated in my last post, I have been playing with (and having fun) Pmw version 2_0_1.

The following example is from John Grayson's book 'Python and Tkinter Programming'.
I highly recommend this book if you are going to use Tkinter.

The program is written in python Tkinter & Pmw, and doesn't use images.

Try this out and you could get hooked.

You will need to install Pmw first. I used Python 3.4 on Windows 7

Code: Select all
from tkinter import *
import Pmw
import string

class SLabel(Frame):
    """ SLabel defines a 2-sided label within a Frame. The
        left hand label has blue letters the right has white letters

    def __init__(self, master, leftl, rightl):
        Frame.__init__(self, master, bg='gray40')
        self.pack(side=LEFT, expand=YES, fill=BOTH)
        Label(self, text=leftl, fg='steelblue1',
              font=("arial", 6, "bold"), width=5, bg='gray40').pack(
            side=LEFT, expand=YES, fill=BOTH)
        Label(self, text=rightl, fg='white',
              font=("arial", 6, "bold"), width=1, bg='gray40').pack(
            side=RIGHT, expand=YES, fill=BOTH)

class Key(Button):
    def __init__(self, master, font=('arial', 8, 'bold'),
                 fg='white', width=5, borderwidth=5, **kw):
        kw['font'] = font
        kw['fg'] = fg
        kw['width'] = width
        kw['borderwidth'] = borderwidth
        # apply(Button.__init__, (self, master), kw)
        Button.__init__(self, master, kw)
        self.pack(side=LEFT, expand=NO, fill=NONE)

class Calculator(Frame):
    def __init__(self, parent=None):
        Frame.__init__(self, bg='gray40')
        self.pack(expand=YES, fill=BOTH)
        self.master.title('Tkinter Toolkit TT-42')
        self.calc = Evaluator()  # This is our evaluator
        self.buildCalculator()  # Build the widgets
        # This is an incomplete dictionary - a good exercise!
        self.actionDict = {'second': self.doThis, 'mode': self.doThis,
                           'delete': self.doThis, 'alpha': self.doThis,
                           'stat': self.doThis, 'math': self.doThis,
                           'matrix': self.doThis, 'program': self.doThis,
                           'vars': self.doThis, 'clear': self.clearall,
                           'sin': self.doThis, 'cos': self.doThis,
                           'tan': self.doThis, 'up': self.doThis,
                           'X1': self.doThis, 'X2': self.doThis,
                           'log': self.doThis, 'ln': self.doThis,
                           'store': self.doThis, 'off': self.turnoff,
                           'neg': self.doThis, 'enter': self.doEnter,
        self.current = ""

    def doThis(self, action):
        print('"%s" has not been implemented' % action)

    def turnoff(self, *args):

    def clearall(self, *args):
        self.current = ""
        self.display.component('text').delete(1.0, END)

    def doEnter(self, *args):
        result = self.calc.runpython(self.current)
        if result:
            self.display.insert(END, '\n')
            self.display.insert(END, '%s\n' % result, 'ans')
        self.current = ""

    def doKeypress(self, event):
        key = event.char
        if not key in ['\b']:
            self.current = self.current + event.char
        if key == '\b':
            self.current = self.current[:-1]

    def keyAction(self, key):
        self.display.insert(END, key)
        self.current = self.current + key

    def evalAction(self, action):
        except KeyError:

    def buildCalculator(self):
        FUN = 1  # Designates a Function
        KEY = 0  # Designates a Key
        KC1 = 'gray30'  # Dark Keys
        KC2 = 'gray50'  # Light Keys
        KC3 = 'steelblue1'  # Light Blue Key
        KC4 = 'steelblue'  # Dark Blue Key
        keys = [
            [('2nd', '', '', KC3, FUN, 'second'),  # Row 1
             ('Mode', 'Quit', '', KC1, FUN, 'mode'),
             ('Del', 'Ins', '', KC1, FUN, 'delete'),
             ('Alpha', 'Lock', '', KC2, FUN, 'alpha'),
             ('Stat', 'List', '', KC1, FUN, 'stat')],
            [('Math', 'Test', 'A', KC1, FUN, 'math'),  # Row 2
             ('Mtrx', 'Angle', 'B', KC1, FUN, 'matrix'),
             ('Prgm', 'Draw', 'C', KC1, FUN, 'program'),
             ('Vars', 'YVars', '', KC1, FUN, 'vars'),
             ('Clr', '', '', KC1, FUN, 'clear')],
            [('X-1', 'Abs', 'D', KC1, FUN, 'X1'),  # Row 3
             ('Sin', 'Sin-1', 'E', KC1, FUN, 'sin'),
             ('Cos', 'Cos-1', 'F', KC1, FUN, 'cos'),
             ('Tan', 'Tan-1', 'G', KC1, FUN, 'tan'),
             ('^', 'PI', 'H', KC1, FUN, 'up')],
            [('X2', 'Root', 'I', KC1, FUN, 'X2'),  # Row 4
             (',', 'EE', 'J', KC1, KEY, ','),
             ('(', '{', 'K', KC1, KEY, '('),
             (')', '}', 'L', KC1, KEY, ')'),
             ('/', '', 'M', KC4, KEY, '/')],
            [('Log', '10x', 'N', KC1, FUN, 'log'),  # Row 5
             ('7', 'Un-1', 'O', KC2, KEY, '7'),
             ('8', 'Vn-1', 'P', KC2, KEY, '8'),
             ('9', 'n', 'Q', KC2, KEY, '9'),
             ('X', '[', 'R', KC4, KEY, '*')],
            [('Ln', 'ex', 'S', KC1, FUN, 'ln'),  # Row 6
             ('4', 'L4', 'T', KC2, KEY, '4'),
             ('5', 'L5', 'U', KC2, KEY, '5'),
             ('6', 'L6', 'V', KC2, KEY, '6'),
             ('-', ']', 'W', KC4, KEY, '-')],
            [('STO', 'RCL', 'X', KC1, FUN, 'store'),  # Row 7
             ('1', 'L1', 'Y', KC2, KEY, '1'),
             ('2', 'L2', 'Z', KC2, KEY, '2'),
             ('3', 'L3', '', KC2, KEY, '3'),
             ('+', 'MEM', '"', KC4, KEY, '+')],
            [('Off', '', '', KC1, FUN, 'off'),  # Row 8
             ('0', '', '', KC2, KEY, '0'),
             ('.', ':', '', KC2, KEY, '.'),
             ('(-)', 'ANS', '?', KC2, FUN, 'neg'),
             ('Enter', 'Entry', '', KC4, FUN, 'enter')]]

        self.display = Pmw.ScrolledText(self, hscrollmode='dynamic',
                                        vscrollmode='dynamic', hull_relief='sunken',
                                        hull_background='gray40', hull_borderwidth=10,
                                        text_background='honeydew4', text_width=16,
                                        text_foreground='black', text_height=6,
                                        text_padx=10, text_pady=10, text_relief='groove',
                                        text_font=('arial', 12, 'bold'))
        self.display.pack(side=TOP, expand=YES, fill=BOTH)
        self.display.tag_config('ans', foreground='white')
        self.display.component('text').bind('<Key>', self.doKeypress)
        self.display.component('text').bind('<Return>', self.doEnter)

        for row in keys:
            rowa = Frame(self, bg='gray40')
            rowb = Frame(self, bg='gray40')
            for p1, p2, p3, color, ktype, func in row:
                if ktype == FUN:
                    a = lambda s=self, a=func: s.evalAction(a)
                    a = lambda s=self, k=func: s.keyAction(k)
                SLabel(rowa, p2, p3)
                Key(rowb, text=p1, bg=color, command=a)
            rowa.pack(side=TOP, expand=YES, fill=BOTH)
            rowb.pack(side=TOP, expand=YES, fill=BOTH)

class Evaluator:
    def __init__(self):
        self.myNameSpace = {}
        self.runpython("from math import *")

    def runpython(self, code):
            return (eval(code, self.myNameSpace, self.myNameSpace))
        except SyntaxError:
                exec(code in self.myNameSpace, self.myNameSpace)
                return 'Error'

if __name__ == '__main__':

Here's a screenshot:

calc2.png screenshot
calc2.png (31.26 KiB) Viewed 721 times

Posts: 1307
Joined: Thu Apr 03, 2014 4:06 pm

Return to GUI

Who is online

Users browsing this forum: No registered users and 3 guests