././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609388376.7883995 Pmw-2.1/0000775000175000017500000000000000000000000012346 5ustar00gregmgregm00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609388376.7883995 Pmw-2.1/PKG-INFO0000775000175000017500000000172500000000000013453 0ustar00gregmgregm00000000000000Metadata-Version: 1.1 Name: Pmw Version: 2.1 Summary: Python Megawidgets Home-page: http://pmw.sourceforge.net/ Author: Telstra Corporation Limited, Australia Author-email: UNKNOWN License: BSD Description: Pmw is a toolkit for building high-level compound widgets, or megawidgets, constructed using other widgets as component parts. It promotes consistent look and feel within and between graphical applications, is highly configurable to your needs and is easy to use. Platform: UNKNOWN Classifier: Development Status :: beta Classifier: Environment :: Console Classifier: Intended Audience :: End Users/Desktop Classifier: Intended Audience :: Developers Classifier: Intended Audience :: System Administrators Classifier: License :: BSD Classifier: Operating System :: MacOS :: MacOS X Classifier: Operating System :: Microsoft :: Windows Classifier: Operating System :: POSIX Classifier: Programming Language :: Python Classifier: Topic :: GUI ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609388377.4204135 Pmw-2.1/Pmw/0000775000175000017500000000000000000000000013111 5ustar00gregmgregm00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9431188 Pmw-2.1/Pmw/Pmw_1_3_3/0000775000175000017500000000000000000000000014540 5ustar00gregmgregm00000000000000././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1609332343.907118 Pmw-2.1/Pmw/Pmw_1_3_3/__init__.py0000664000175000017500000000010300000000000016643 0ustar00gregmgregm00000000000000# File to allow this directory to be treated as a python package. ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9111183 Pmw-2.1/Pmw/Pmw_1_3_3/bin/0000775000175000017500000000000000000000000015310 5ustar00gregmgregm00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9111183 Pmw-2.1/Pmw/Pmw_1_3_3/bin/bundlepmw.py0000664000175000017500000001053300000000000017661 0ustar00gregmgregm00000000000000#!/usr/bin/env python # Helper script when freezing Pmw applications. It concatenates all # Pmw megawidget files into a single file, 'Pmw.py', in the current # directory. The script must be called with one argument, being the # path to the 'lib' directory of the required version of Pmw. # To freeze a Pmw application, you will also need to copy the # following files to the application directory before freezing: # # PmwBlt.py PmwColor.py import os import re import string import sys # The order of these files is significant. Files which reference # other files must appear later. Files may be deleted if they are not # used. files = [ 'Dialog', 'TimeFuncs', 'Balloon', 'ButtonBox', 'EntryField', 'Group', 'LabeledWidget', 'MainMenuBar', 'MenuBar', 'MessageBar', 'MessageDialog', 'NoteBook', 'OptionMenu', 'PanedWidget', 'PromptDialog', 'RadioSelect', 'ScrolledCanvas', 'ScrolledField', 'ScrolledFrame', 'ScrolledListBox', 'ScrolledText', 'HistoryText', 'SelectionDialog', 'TextDialog', 'TimeCounter', 'AboutDialog', 'ComboBox', 'ComboBoxDialog', 'Counter', 'CounterDialog', ] # Set this to 0 if you do not use any of the Pmw.Color functions: needColor = 1 # Set this to 0 if you do not use any of the Pmw.Blt functions: needBlt = 1 def expandLinks(path): if not os.path.isabs(path): path = os.path.join(os.getcwd(), path) while 1: if not os.path.islink(path): break dir = os.path.dirname(path) path = os.path.join(dir, os.readlink(path)) return path def mungeFile(file): # Read the file and modify it so that it can be bundled with the # other Pmw files. file = 'Pmw' + file + '.py' text = open(os.path.join(srcdir, file)).read() text = re.sub(r'import Pmw\b', '', text) text = re.sub('INITOPT = Pmw.INITOPT', '', text) text = re.sub(r'\bPmw\.', '', text) text = '\n' + ('#' * 70) + '\n' + '### File: ' + file + '\n' + text return text # Work out which version is being bundled. file = sys.argv[0] file = os.path.normpath(file) file = expandLinks(file) dir = os.path.dirname(file) dir = expandLinks(dir) dir = os.path.dirname(dir) dir = expandLinks(dir) dir = os.path.basename(dir) version = string.replace(dir[4:], '_', '.') # Code to import the Color module. colorCode = """ import PmwColor Color = PmwColor del PmwColor """ # Code to import the Blt module. bltCode = """ import PmwBlt Blt = PmwBlt del PmwBlt """ # Code used when not linking with PmwBlt.py. ignoreBltCode = """ _bltImported = 1 _bltbusyOK = 0 """ # Code to define the functions normally supplied by the dynamic loader. extraCode = """ ### Loader functions: _VERSION = '%s' def setversion(version): if version != _VERSION: raise ValueError, 'Dynamic versioning not available' def setalphaversions(*alpha_versions): if alpha_versions != (): raise ValueError, 'Dynamic versioning not available' def version(alpha = 0): if alpha: return () else: return _VERSION def installedversions(alpha = 0): if alpha: return () else: return (_VERSION,) """ if '-noblt' in sys.argv: sys.argv.remove('-noblt') needBlt = 0 if '-nocolor' in sys.argv: sys.argv.remove('-nocolor') needColor = 0 if len(sys.argv) != 2: print 'usage: bundlepmw.py [-noblt] [-nocolor] /path/to/Pmw/Pmw_X_X_X/lib' sys.exit() srcdir = sys.argv[1] if os.path.exists('Pmw.py'): print 'Pmw.py already exists. Remove it and try again.' sys.exit() outfile = open('Pmw.py', 'w') if needColor: outfile.write(colorCode) if needBlt: outfile.write(bltCode) outfile.write(extraCode % version) # Specially handle PmwBase.py file: text = mungeFile('Base') text = re.sub('import PmwLogicalFont', '', text) text = re.sub('PmwLogicalFont._font_initialise', '_font_initialise', text) outfile.write(text) if not needBlt: outfile.write(ignoreBltCode) files.append('LogicalFont') for file in files: text = mungeFile(file) outfile.write(text) print '' print ' Pmw.py has been created.' if needColor or needBlt: print ' Before running freeze, also copy the following file(s):' if needBlt: print ' ' + os.path.join(srcdir, 'PmwBlt.py') if needColor: print ' ' + os.path.join(srcdir, 'PmwColor.py') ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9111183 Pmw-2.1/Pmw/Pmw_1_3_3/contrib/0000775000175000017500000000000000000000000016200 5ustar00gregmgregm00000000000000././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1609332343.907118 Pmw-2.1/Pmw/Pmw_1_3_3/contrib/DirBrowser.py0000664000175000017500000003007200000000000020636 0ustar00gregmgregm00000000000000# # FILE: DirBrowser.py # # DESCRIPTION: # This file provides a generic Directory browser selection widget. # # AUTHOR: MontaVista Software, Inc. # # Copyright 2001 MontaVista Software Inc. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 2 of the License, or (at your # option) any later version. # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN # NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 675 Mass Ave, Cambridge, MA 02139, USA. # import os import Tkinter import Pmw class DirBrowserDialog(Pmw.MegaToplevel): def __init__(self, parent = None, **kw): cwd = os.getcwd() # Define the megawidget options. INITOPT = Pmw.INITOPT optiondefs = ( ('path', cwd, None), ('hidedotfiles', 1, INITOPT), ('label', None, INITOPT), #('labelmargin', 0, INITOPT), #('labelpos', None, INITOPT), ('borderx', 20, INITOPT), ('bordery', 20, INITOPT), ) self.defineoptions(kw, optiondefs) # Initialise the base class (after defining the options). Pmw.MegaToplevel.__init__(self, parent) interior = self.interior() self.childframe = self.createcomponent('childframe', (), None, Tkinter.Frame, (interior,), borderwidth = 1, relief = 'raised', ) self.childframe.pack(expand = 1, fill = 'both', ) self.labelframe = self.createcomponent('labelframe', (), None, Tkinter.Frame, (self.childframe,), borderwidth = 2, relief = 'groove', ) self.labelframe.pack(padx = 10, pady = 10, expand = 1, fill = 'both') if self['label']: self.label = self.createcomponent('label', (), None, Tkinter.Label, (self.childframe,), text = self['label'], ) self.label.place(x = (10 + self['borderx']), y = 10, anchor = 'w') self.workframe = self.createcomponent('workframe', (), None, Tkinter.Frame, (self.labelframe,), #borderwidth = 2, #relief = 'groove', ) self.workframe.pack(padx = self['borderx'], pady = self['bordery'], expand = 1, fill = 'both', ) self.buttonframe = self.createcomponent('buttonframe', (), None, Tkinter.Frame, (interior,), borderwidth = 1, relief = 'raised', ) self.buttonframe.pack(expand = 0, fill = 'x', ) self.optbox = self.createcomponent('optbox', (), None, Pmw.OptionMenu, (self.workframe,), command = self.setpath, ) self.optbox.bind('', self._setMinimumSize) self.listbox = self.createcomponent('listbox', (), None, Pmw.ScrolledListBox, (self.workframe,), dblclickcommand = self._select, ) path = self['path'] self.entry = self.createcomponent('entryfield', (), None, Pmw.EntryField, (self.workframe,), value = path, command = self.enteredpath, labelpos = 'nw', label_text = 'Current Path:', ) #self.createlabel(self.workframe, childCols = 1, childRows = 3) self.buttonbox = self.createcomponent('buttonbox', (), None, Pmw.ButtonBox, (self.buttonframe,), ) self.buttonbox.add('OK', text = 'OK', command = self.okbutton) self.buttonbox.add('Cancel', text = 'Cancel', command = self.cancelbutton) self.buttonbox.add('New Directory', text = 'New Directory', command = self.newdirbutton) self.buttonbox.alignbuttons() self.buttonbox.pack(expand = 1, fill = 'x') self.optbox.grid(row = 2, column = 2, sticky = 'ew') self.listbox.grid(row = 3, column = 2, sticky = 'news') self.entry.grid(row = 5, column = 2, sticky = 'ew') self.workframe.grid_rowconfigure(3, weight = 1) self.workframe.grid_rowconfigure(4, minsize = 20) self.workframe.grid_columnconfigure(2, weight = 1) self.setpath(self['path']) # Check keywords and initialise options. self.initialiseoptions() def setpath(self, path): path = os.path.abspath(os.path.expanduser(path)) if os.path.isfile(path): path = os.path.dirname(path) dirlist = [] hidedotfiles = self['hidedotfiles'] try: posix = (os.name == 'posix') for entry in os.listdir(path): entryPath = path + '/' + entry if hidedotfiles and entry[0] == '.': # skip dot files if desired continue if not os.path.isdir(entryPath): # skip files continue if not os.access(entryPath, os.R_OK | os.X_OK): # skip directories we can't enter any way continue dirlist.append(entry) except: self.entry.setentry(self['path']) return self.entry.setentry(path) self['path'] = path dirlist.sort() if path != '/': dirlist.insert(0, '..') self.listbox.setlist(dirlist) pathlist = [] while path != '/': pathlist.append(path) path = os.path.dirname(path) pathlist.append('/') self.optbox.setitems(pathlist, 0) def _setMinimumSize(self, event): # If the optionmenu changes width, make sure it does not # shrink later. owidth = self.optbox.winfo_width() self.workframe.grid_columnconfigure(2, minsize = owidth) def _select(self): sel = self.listbox.getcurselection() if self['path'] == '/': self['path'] = '' if len(sel) > 0: if sel[0] == '..': self.setpath(os.path.dirname(self['path'])) else: self.setpath(self['path'] + '/' + sel[0]) def getcurpath(self): return self['path'] def enteredpath(self): self.setpath(self.entry.get()) def okbutton(self): self.deactivate(self['path']) def cancelbutton(self): self.deactivate(None) def newdirbutton(self): CreateDirectoryPopup(self.interior(), self['path']) self.setpath(self['path']) class CreateDirectoryPopup: def __init__(self, parent, path): self.path = path self.parent = parent self.newdirpopup = Pmw.PromptDialog(parent, buttons = ('OK', 'Cancel'), defaultbutton = 'OK', title = 'New Directory', entryfield_labelpos = 'nw', label_text = 'Enter new directory name for:\n%s'%self.path, command = self._buttonpress ) self.newdirpopup.activate() def _buttonpress(self, button): if button == 'OK': newdirname = self.newdirpopup.get() dirlist = os.listdir(self.path) if newdirname in dirlist: ErrorPopup(self.parent, 'Error: "%s", already exists as a file or directory.'%newdirname) else: try: os.mkdir(self.path + '/' + newdirname) except: ErrorPopup(self.parent, 'Error: Could not create directory: "%s"'%newdirname) else: self.newdirpopup.deactivate() else: self.newdirpopup.deactivate() def ErrorPopup(parent, message): error = Pmw.MessageDialog(parent, title = 'Error', message_text = message, defaultbutton = 0, ) error.activate() if __name__ == '__main__': rootWin = Tkinter.Tk() Pmw.initialise() rootWin.title('Directory Browser Dialog Demo') def buildBrowser(): # Create the hierarchical directory browser widget dirBrowserDialog = DirBrowserDialog(rootWin, #labelpos = 'nw', label = 'Select a directory', title = 'Directory Selector', #path = '~', #hidedotfiles = 0, ) dir = dirBrowserDialog.activate() print 'Selected Directory:', dir dirButton = Tkinter.Button(rootWin, text="Browser", command=buildBrowser) dirButton.pack(side = 'left', padx = 10, pady = 10) exitButton = Tkinter.Button(rootWin, text="Quit", command=rootWin.quit) exitButton.pack(side = 'left', padx = 10, pady = 10) rootWin.mainloop() ././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1609332343.907118 Pmw-2.1/Pmw/Pmw_1_3_3/contrib/MCListbox.py0000664000175000017500000007077600000000000020437 0ustar00gregmgregm00000000000000# # FILE: MCListbox.py # # DESCRIPTION: # This file provides a generic Multi-Column Listbox widget. It is derived # from a heavily hacked version of Pmw.ScrolledFrame # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 2 of the License, or (at your # option) any later version. # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN # NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 675 Mass Ave, Cambridge, MA 02139, USA. # import string import Tkinter import Pmw class MultiColumnListbox(Pmw.MegaWidget): def __init__(self, parent = None, **kw): colors = Pmw.Color.getdefaultpalette(parent) # Define the megawidget options. INITOPT = Pmw.INITOPT optiondefs = ( #('borderframe', 1, INITOPT), ('horizflex', 'fixed', self._horizflex), ('horizfraction', 0.05, INITOPT), ('hscrollmode', 'dynamic', self._hscrollMode), ('labelmargin', 0, INITOPT), ('labelpos', None, INITOPT), ('scrollmargin', 2, INITOPT), ('usehullsize', 0, INITOPT), ('vertflex', 'fixed', self._vertflex), ('vertfraction', 0.05, INITOPT), ('vscrollmode', 'dynamic', self._vscrollMode), ('labellist', None, INITOPT), ('selectbackground', colors['selectBackground'], INITOPT), ('selectforeground', colors['selectForeground'], INITOPT), ('background', colors['background'], INITOPT), ('foreground', colors['foreground'], INITOPT), ('command', None, None), ('dblclickcommand', None, None), ) self.defineoptions(kw, optiondefs) # Initialise the base class (after defining the options). Pmw.MegaWidget.__init__(self, parent) self._numcolumns = len(self['labellist']) self._columnlabels = self['labellist'] self._lineid = 0 self._numrows = 0 self._lineitemframes = [] self._lineitems = [] self._lineitemdata = {} self._labelframe = {} self._cursel = [] # Create the components. self.origInterior = Pmw.MegaWidget.interior(self) if self['usehullsize']: self.origInterior.grid_propagate(0) # Create a frame widget to act as the border of the clipper. self._borderframe = self.createcomponent('borderframe', (), None, Tkinter.Frame, (self.origInterior,), relief = 'sunken', borderwidth = 2, ) self._borderframe.grid(row = 2, column = 2, rowspan = 2, sticky = 'news') # Create the clipping windows. self._hclipper = self.createcomponent('hclipper', (), None, Tkinter.Frame, (self._borderframe,), width = 400, height = 300, ) self._hclipper.pack(fill = 'both', expand = 1) self._hsframe = self.createcomponent('hsframe', (), None, Tkinter.Frame, (self._hclipper,), ) self._vclipper = self.createcomponent('vclipper', (), None, Tkinter.Frame, (self._hsframe,), #width = 400, #height = 300, highlightthickness = 0, borderwidth = 0, ) self._vclipper.grid(row = 1, column = 0, columnspan = self._numcolumns, sticky = 'news')#, expand = 1) self._hsframe.grid_rowconfigure(1, weight = 1)#, minsize = 300) gridcolumn = 0 for labeltext in self._columnlabels: lframe = self.createcomponent(labeltext+'frame', (), None, Tkinter.Frame, (self._hsframe,), borderwidth = 1, relief = 'raised', ) label = self.createcomponent(labeltext, (), None, Tkinter.Label, (lframe,), text = labeltext, ) label.pack(expand = 0, fill = 'y', side = 'left') lframe.grid(row = 0, column = gridcolumn, sticky = 'ews') self._labelframe[labeltext] = lframe #lframe.update() #print lframe.winfo_reqwidth() self._hsframe.grid_columnconfigure(gridcolumn, weight = 1) gridcolumn = gridcolumn + 1 lframe.update() self._labelheight = lframe.winfo_reqheight() self.origInterior.grid_rowconfigure(2, minsize = self._labelheight + 2) self.origInterior.grid_rowconfigure(3, weight = 1, minsize = 0) self.origInterior.grid_columnconfigure(2, weight = 1, minsize = 0) # Create the horizontal scrollbar self._horizScrollbar = self.createcomponent('horizscrollbar', (), 'Scrollbar', Tkinter.Scrollbar, (self.origInterior,), orient='horizontal', command=self._xview ) # Create the vertical scrollbar self._vertScrollbar = self.createcomponent('vertscrollbar', (), 'Scrollbar', Tkinter.Scrollbar, (self.origInterior,), #(self._hclipper,), orient='vertical', command=self._yview ) self.createlabel(self.origInterior, childCols = 3, childRows = 4) # Initialise instance variables. self._horizScrollbarOn = 0 self._vertScrollbarOn = 0 self.scrollTimer = None self._scrollRecurse = 0 self._horizScrollbarNeeded = 0 self._vertScrollbarNeeded = 0 self.startX = 0 self.startY = 0 self._flexoptions = ('fixed', 'expand', 'shrink', 'elastic') # Create a frame in the clipper to contain the widgets to be # scrolled. self._vsframe = self.createcomponent('vsframe', (), None, Tkinter.Frame, (self._vclipper,), #height = 300, #borderwidth = 4, #relief = 'groove', ) # Whenever the clipping window or scrolled frame change size, # update the scrollbars. self._hsframe.bind('', self._reposition) self._vsframe.bind('', self._reposition) self._hclipper.bind('', self._reposition) self._vclipper.bind('', self._reposition) #elf._vsframe.bind('', self._vsframeselect) # Check keywords and initialise options. self.initialiseoptions() def destroy(self): if self.scrollTimer is not None: self.after_cancel(self.scrollTimer) self.scrollTimer = None Pmw.MegaWidget.destroy(self) # ====================================================================== # Public methods. def interior(self): return self._vsframe # Set timer to call real reposition method, so that it is not # called multiple times when many things are reconfigured at the # same time. def reposition(self): if self.scrollTimer is None: self.scrollTimer = self.after_idle(self._scrollBothNow) def insertrow(self, index, rowdata): #if len(rowdata) != self._numcolumns: # raise ValueError, 'Number of items in rowdata does not match number of columns.' if index > self._numrows: index = self._numrows rowframes = {} for columnlabel in self._columnlabels: celldata = rowdata.get(columnlabel) cellframe = self.createcomponent(('cellframeid.%d.%s'%(self._lineid, columnlabel)), (), ('Cellframerowid.%d'%self._lineid), Tkinter.Frame, (self._vsframe,), background = self['background'], #borderwidth = 1, #relief = 'flat' ) cellframe.bind('', self._cellframedblclick) cellframe.bind('', self._cellframeselect) if celldata: cell = self.createcomponent(('cellid.%d.%s'%(self._lineid, columnlabel)), (), ('Cellrowid.%d'%self._lineid), Tkinter.Label, (cellframe,), background = self['background'], foreground = self['foreground'], text = celldata, ) cell.bind('', self._celldblclick) cell.bind('', self._cellselect) cell.pack(expand = 0, fill = 'y', side = 'left', padx = 1, pady = 1) rowframes[columnlabel] = cellframe self._lineitemdata[self._lineid] = rowdata self._lineitems.insert(index, self._lineid) self._lineitemframes.insert(index, rowframes) self._numrows = self._numrows + 1 self._lineid = self._lineid + 1 self._placedata(index) def _placedata(self, index = 0): gridy = index for rowframes in self._lineitemframes[index:]: gridx = 0 for columnlabel in self._columnlabels: rowframes[columnlabel].grid(row = gridy, column = gridx, sticky = 'news') gridx = gridx + 1 gridy = gridy + 1 def addrow(self, rowdata): self.insertrow(self._numrows, rowdata) def delrow(self, index): rowframes = self._lineitemframes.pop(index) for columnlabel in self._columnlabels: rowframes[columnlabel].destroy() self._placedata(index) self._numrows = self._numrows - 1 del self._lineitems[index] if index in self._cursel: self._cursel.remove(index) def curselection(self): # Return a tuple of just one element as this will probably be the # interface used in a future implementation when multiple rows can # be selected at once. return tuple(self._cursel) def getcurselection(self): # Return a tuple of just one row as this will probably be the # interface used in a future implementation when multiple rows can # be selected at once. sellist = [] for sel in self._cursel: sellist.append(self._lineitemdata[self._lineitems[sel]]) return tuple(sellist) # ====================================================================== # Configuration methods. def _hscrollMode(self): # The horizontal scroll mode has been configured. mode = self['hscrollmode'] if mode == 'static': if not self._horizScrollbarOn: self._toggleHorizScrollbar() elif mode == 'dynamic': if self._horizScrollbarNeeded != self._horizScrollbarOn: self._toggleHorizScrollbar() elif mode == 'none': if self._horizScrollbarOn: self._toggleHorizScrollbar() else: message = 'bad hscrollmode option "%s": should be static, dynamic, or none' % mode raise ValueError, message def _vscrollMode(self): # The vertical scroll mode has been configured. mode = self['vscrollmode'] if mode == 'static': if not self._vertScrollbarOn: self._toggleVertScrollbar() elif mode == 'dynamic': if self._vertScrollbarNeeded != self._vertScrollbarOn: self._toggleVertScrollbar() elif mode == 'none': if self._vertScrollbarOn: self._toggleVertScrollbar() else: message = 'bad vscrollmode option "%s": should be static, dynamic, or none' % mode raise ValueError, message def _horizflex(self): # The horizontal flex mode has been configured. flex = self['horizflex'] if flex not in self._flexoptions: message = 'bad horizflex option "%s": should be one of %s' % \ mode, str(self._flexoptions) raise ValueError, message self.reposition() def _vertflex(self): # The vertical flex mode has been configured. flex = self['vertflex'] if flex not in self._flexoptions: message = 'bad vertflex option "%s": should be one of %s' % \ mode, str(self._flexoptions) raise ValueError, message self.reposition() # ====================================================================== # Private methods. def _reposition(self, event): gridx = 0 for col in self._columnlabels: maxwidth = self._labelframe[col].winfo_reqwidth() for row in self._lineitemframes: cellwidth = row[col].winfo_reqwidth() if cellwidth > maxwidth: maxwidth = cellwidth self._hsframe.grid_columnconfigure(gridx, minsize = maxwidth) gridwidth = self._hsframe.grid_bbox(column = gridx, row = 0)[2] if self['horizflex'] in ('expand', 'elastic') and gridwidth > maxwidth: maxwidth = gridwidth self._vsframe.grid_columnconfigure(gridx, minsize = maxwidth) gridx = gridx + 1 self._vclipper.configure(height = self._hclipper.winfo_height() - self._labelheight) self.reposition() # Called when the user clicks in the horizontal scrollbar. # Calculates new position of frame then calls reposition() to # update the frame and the scrollbar. def _xview(self, mode, value, units = None): if mode == 'moveto': frameWidth = self._hsframe.winfo_reqwidth() self.startX = string.atof(value) * float(frameWidth) else: clipperWidth = self._hclipper.winfo_width() if units == 'units': jump = int(clipperWidth * self['horizfraction']) else: jump = clipperWidth if value == '1': self.startX = self.startX + jump else: self.startX = self.startX - jump self.reposition() # Called when the user clicks in the vertical scrollbar. # Calculates new position of frame then calls reposition() to # update the frame and the scrollbar. def _yview(self, mode, value, units = None): if mode == 'moveto': frameHeight = self._vsframe.winfo_reqheight() self.startY = string.atof(value) * float(frameHeight) else: clipperHeight = self._vclipper.winfo_height() if units == 'units': jump = int(clipperHeight * self['vertfraction']) else: jump = clipperHeight if value == '1': self.startY = self.startY + jump else: self.startY = self.startY - jump self.reposition() def _getxview(self): # Horizontal dimension. clipperWidth = self._hclipper.winfo_width() frameWidth = self._hsframe.winfo_reqwidth() if frameWidth <= clipperWidth: # The scrolled frame is smaller than the clipping window. self.startX = 0 endScrollX = 1.0 if self['horizflex'] in ('expand', 'elastic'): relwidth = 1 else: relwidth = '' else: # The scrolled frame is larger than the clipping window. if self['horizflex'] in ('shrink', 'elastic'): self.startX = 0 endScrollX = 1.0 relwidth = 1 else: if self.startX + clipperWidth > frameWidth: self.startX = frameWidth - clipperWidth endScrollX = 1.0 else: if self.startX < 0: self.startX = 0 endScrollX = (self.startX + clipperWidth) / float(frameWidth) relwidth = '' # Position frame relative to clipper. self._hsframe.place(x = -self.startX, relwidth = relwidth) return (self.startX / float(frameWidth), endScrollX) def _getyview(self): # Vertical dimension. clipperHeight = self._vclipper.winfo_height() frameHeight = self._vsframe.winfo_reqheight() if frameHeight <= clipperHeight: # The scrolled frame is smaller than the clipping window. self.startY = 0 endScrollY = 1.0 if self['vertflex'] in ('expand', 'elastic'): relheight = 1 else: relheight = '' else: # The scrolled frame is larger than the clipping window. if self['vertflex'] in ('shrink', 'elastic'): self.startY = 0 endScrollY = 1.0 relheight = 1 else: if self.startY + clipperHeight > frameHeight: self.startY = frameHeight - clipperHeight endScrollY = 1.0 else: if self.startY < 0: self.startY = 0 endScrollY = (self.startY + clipperHeight) / float(frameHeight) relheight = '' # Position frame relative to clipper. self._vsframe.place(y = -self.startY, relheight = relheight) return (self.startY / float(frameHeight), endScrollY) # According to the relative geometries of the frame and the # clipper, reposition the frame within the clipper and reset the # scrollbars. def _scrollBothNow(self): self.scrollTimer = None # Call update_idletasks to make sure that the containing frame # has been resized before we attempt to set the scrollbars. # Otherwise the scrollbars may be mapped/unmapped continuously. self._scrollRecurse = self._scrollRecurse + 1 self.update_idletasks() self._scrollRecurse = self._scrollRecurse - 1 if self._scrollRecurse != 0: return xview = self._getxview() yview = self._getyview() self._horizScrollbar.set(xview[0], xview[1]) self._vertScrollbar.set(yview[0], yview[1]) self._horizScrollbarNeeded = (xview != (0.0, 1.0)) self._vertScrollbarNeeded = (yview != (0.0, 1.0)) # If both horizontal and vertical scrollmodes are dynamic and # currently only one scrollbar is mapped and both should be # toggled, then unmap the mapped scrollbar. This prevents a # continuous mapping and unmapping of the scrollbars. if (self['hscrollmode'] == self['vscrollmode'] == 'dynamic' and self._horizScrollbarNeeded != self._horizScrollbarOn and self._vertScrollbarNeeded != self._vertScrollbarOn and self._vertScrollbarOn != self._horizScrollbarOn): if self._horizScrollbarOn: self._toggleHorizScrollbar() else: self._toggleVertScrollbar() return if self['hscrollmode'] == 'dynamic': if self._horizScrollbarNeeded != self._horizScrollbarOn: self._toggleHorizScrollbar() if self['vscrollmode'] == 'dynamic': if self._vertScrollbarNeeded != self._vertScrollbarOn: self._toggleVertScrollbar() def _toggleHorizScrollbar(self): self._horizScrollbarOn = not self._horizScrollbarOn interior = self.origInterior if self._horizScrollbarOn: self._horizScrollbar.grid(row = 5, column = 2, sticky = 'news') interior.grid_rowconfigure(4, minsize = self['scrollmargin']) else: self._horizScrollbar.grid_forget() interior.grid_rowconfigure(4, minsize = 0) def _toggleVertScrollbar(self): self._vertScrollbarOn = not self._vertScrollbarOn interior = self.origInterior if self._vertScrollbarOn: self._vertScrollbar.grid(row = 3, column = 4, sticky = 'news') interior.grid_columnconfigure(3, minsize = self['scrollmargin']) else: self._vertScrollbar.grid_forget() interior.grid_columnconfigure(3, minsize = 0) # ====================================================================== # Selection methods. #def _vsframeselect(self, event): # print 'vsframe event x: %d y: %d'%(event.x, event.y) # col, row = self._vsframe.grid_location(event.x, event.y) # self._select(col, row) def _cellframeselect(self, event): #print 'cellframe event x: %d y: %d'%(event.x, event.y) x = event.widget.winfo_x() y = event.widget.winfo_y() #col, row = self._vsframe.grid_location(x + event.x, y + event.y) self._select(x + event.x, y + event.y)#(col, row) def _cellselect(self, event): #print 'cell event x: %d y: %d'%(event.x, event.y) lx = event.widget.winfo_x() ly = event.widget.winfo_y() parent = event.widget.pack_info()['in'] fx = parent.winfo_x() fy = parent.winfo_y() #col, row = self._vsframe.grid_location(fx + lx + event.x, fy + ly + event.y) self._select(fx + lx + event.x, fy + ly + event.y)#(col, row) def _select(self, x, y): col, row = self._vsframe.grid_location(x, y) #print 'Clicked on col: %d row: %d'%(col,row) cfg = {} lineid = self._lineitems[row] cfg['Cellrowid.%d_foreground'%lineid] = self['selectforeground'] cfg['Cellrowid.%d_background'%lineid] = self['selectbackground'] cfg['Cellframerowid.%d_background'%lineid] = self['selectbackground'] #cfg['Cellframerowid%d_relief'%row] = 'raised' if self._cursel != []: cursel = self._cursel[0] lineid = self._lineitems[cursel] if cursel != None and cursel != row: cfg['Cellrowid.%d_foreground'%lineid] = self['foreground'] cfg['Cellrowid.%d_background'%lineid] = self['background'] cfg['Cellframerowid.%d_background'%lineid] = self['background'] #cfg['Cellframerowid%d_relief'%cursel] = 'flat' apply(self.configure, (), cfg) self._cursel = [row] cmd = self['command'] if callable(cmd): cmd() def _cellframedblclick(self, event): #print 'double click cell frame' cmd = self['dblclickcommand'] if callable(cmd): cmd() def _celldblclick(self, event): #print 'double click cell' cmd = self['dblclickcommand'] if callable(cmd): cmd() if __name__ == '__main__': rootWin = Tkinter.Tk() Pmw.initialise() rootWin.title('MultiColumnListbox Demo') rootWin.configure(width = 500, height = 300) rootWin.update() def dbl(): print listbox.getcurselection() listbox = MultiColumnListbox(rootWin, #usehullsize = 1, labellist = ('Column 0', 'Column 1', 'Column 2', 'Column 3', 'Column 4', #'Column 5', #'Column 6', #'Column 7', #'Column 8', #'Column 9', ), horizflex = 'expand', #vertflex = 'elastic', dblclickcommand = dbl, ) #print 'start adding item' for i in range(20): r = {} for j in range(5): r[('Column %d'%j)] = 'Really long item name %d'%i listbox.addrow(r) #print 'items added' listbox.pack(expand = 1, fill = 'both', padx = 10, pady = 10) exitButton = Tkinter.Button(rootWin, text="Quit", command=rootWin.quit) exitButton.pack(side = 'left', padx = 10, pady = 10) rootWin.mainloop() ././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1609332343.907118 Pmw-2.1/Pmw/Pmw_1_3_3/contrib/PmwFileDialog.py0000664000175000017500000003476300000000000021252 0ustar00gregmgregm00000000000000# __version__ = '$Id: PmwFileDialog.py,v 1.2 2002/08/23 15:03:35 gregm Exp $' # # Filename dialogs using Pmw # # (C) Rob W.W. Hooft, Nonius BV, 1998 # # Modifications: # # J. Willem M. Nissink, Cambridge Crystallographic Data Centre, 8/2002 # Added optional information pane at top of dialog; if option # 'info' is specified, the text given will be shown (in blue). # Modified example to show both file and directory-type dialog # # No Guarantees. Distribute Freely. # Please send bug-fixes/patches/features to # ################################################################################ import os,fnmatch,time import Tkinter,Pmw #Pmw.setversion("0.8.5") def _errorpop(master,text): d=Pmw.MessageDialog(master, title="Error", message_text=text, buttons=("OK",)) d.component('message').pack(ipadx=15,ipady=15) d.activate() d.destroy() class PmwFileDialog(Pmw.Dialog): """File Dialog using Pmw""" def __init__(self, parent = None, **kw): # Define the megawidget options. optiondefs = ( ('filter', '*', self.newfilter), ('directory', os.getcwd(), self.newdir), ('filename', '', self.newfilename), ('historylen',10, None), ('command', None, None), ('info', None, None), ) self.defineoptions(kw, optiondefs) # Initialise base class (after defining options). Pmw.Dialog.__init__(self, parent) self.withdraw() # Create the components. interior = self.interior() if self['info'] is not None: rowoffset=1 dn = self.infotxt() dn.grid(row=0,column=0,columnspan=2,padx=3,pady=3) else: rowoffset=0 dn = self.mkdn() dn.grid(row=0+rowoffset,column=0,columnspan=2,padx=3,pady=3) del dn # Create the directory list component. dnb = self.mkdnb() dnb.grid(row=1+rowoffset,column=0,sticky='news',padx=3,pady=3) del dnb # Create the filename list component. fnb = self.mkfnb() fnb.grid(row=1+rowoffset,column=1,sticky='news',padx=3,pady=3) del fnb # Create the filter entry ft = self.mkft() ft.grid(row=2+rowoffset,column=0,columnspan=2,padx=3,pady=3) del ft # Create the filename entry fn = self.mkfn() fn.grid(row=3+rowoffset,column=0,columnspan=2,padx=3,pady=3) fn.bind('',self.okbutton) del fn # Buttonbox already exists bb=self.component('buttonbox') bb.add('OK',command=self.okbutton) bb.add('Cancel',command=self.cancelbutton) del bb Pmw.alignlabels([self.component('filename'), self.component('filter'), self.component('dirname')]) def infotxt(self): """ Make information block component at the top """ return self.createcomponent( 'infobox', (), None, Tkinter.Label, (self.interior(),), width=51, relief='groove', foreground='darkblue', justify='left', text=self['info'] ) def mkdn(self): """Make directory name component""" return self.createcomponent( 'dirname', (), None, Pmw.ComboBox, (self.interior(),), entryfield_value=self['directory'], entryfield_entry_width=40, entryfield_validate=self.dirvalidate, selectioncommand=self.setdir, labelpos='w', label_text='Directory:') def mkdnb(self): """Make directory name box""" return self.createcomponent( 'dirnamebox', (), None, Pmw.ScrolledListBox, (self.interior(),), label_text='directories', labelpos='n', hscrollmode='none', dblclickcommand=self.selectdir) def mkft(self): """Make filter""" return self.createcomponent( 'filter', (), None, Pmw.ComboBox, (self.interior(),), entryfield_value=self['filter'], entryfield_entry_width=40, selectioncommand=self.setfilter, labelpos='w', label_text='Filter:') def mkfnb(self): """Make filename list box""" return self.createcomponent( 'filenamebox', (), None, Pmw.ScrolledListBox, (self.interior(),), label_text='files', labelpos='n', hscrollmode='none', selectioncommand=self.singleselectfile, dblclickcommand=self.selectfile) def mkfn(self): """Make file name entry""" return self.createcomponent( 'filename', (), None, Pmw.ComboBox, (self.interior(),), entryfield_value=self['filename'], entryfield_entry_width=40, entryfield_validate=self.filevalidate, selectioncommand=self.setfilename, labelpos='w', label_text='Filename:') def dirvalidate(self,string): if os.path.isdir(string): return Pmw.OK else: return Pmw.PARTIAL def filevalidate(self,string): if string=='': return Pmw.PARTIAL elif os.path.isfile(string): return Pmw.OK elif os.path.exists(string): return Pmw.PARTIAL else: return Pmw.OK def okbutton(self): """OK action: user thinks he has input valid data and wants to proceed. This is also called by in the filename entry""" fn=self.component('filename').get() self.setfilename(fn) if self.validate(fn): self.canceled=0 self.deactivate() def cancelbutton(self): """Cancel the operation""" self.canceled=1 self.deactivate() def tidy(self,w,v): """Insert text v into the entry and at the top of the list of the combobox w, remove duplicates""" if not v: return entry=w.component('entry') entry.delete(0,'end') entry.insert(0,v) list=w.component('scrolledlist') list.insert(0,v) index=1 while indexself['historylen']: list.delete(index) else: index=index+1 w.checkentry() def setfilename(self,value): if not value: return value=os.path.join(self['directory'],value) dir,fil=os.path.split(value) self.configure(directory=dir,filename=value) c=self['command'] if callable(c): c() def newfilename(self): """Make sure a newly set filename makes it into the combobox list""" self.tidy(self.component('filename'),self['filename']) def setfilter(self,value): self.configure(filter=value) def newfilter(self): """Make sure a newly set filter makes it into the combobox list""" self.tidy(self.component('filter'),self['filter']) self.fillit() def setdir(self,value): self.configure(directory=value) def newdir(self): """Make sure a newly set dirname makes it into the combobox list""" self.tidy(self.component('dirname'),self['directory']) self.fillit() def singleselectfile(self): """Single click in file listbox. Move file to "filename" combobox""" cs=self.component('filenamebox').curselection() if cs!=(): value=self.component('filenamebox').get(cs) self.setfilename(value) def selectfile(self): """Take the selected file from the filename, normalize it, and OK""" self.singleselectfile() value=self.component('filename').get() self.setfilename(value) if value: self.okbutton() def selectdir(self): """Take selected directory from the dirnamebox into the dirname""" cs=self.component('dirnamebox').curselection() if cs!=(): value=self.component('dirnamebox').get(cs) dir=self['directory'] if not dir: dir=os.getcwd() if value: if value=='..': dir=os.path.split(dir)[0] else: dir=os.path.join(dir,value) self.configure(directory=dir) self.fillit() def askfilename(self,directory=None,filter=None): """The actual client function. Activates the dialog, and returns only after a valid filename has been entered (return value is that filename) or when canceled (return value is None)""" if directory!=None: self.configure(directory=directory) if filter!=None: self.configure(filter=filter) self.fillit() self.canceled=1 # Needed for when user kills dialog window self.activate() if self.canceled: return None else: return self.component('filename').get() lastdir="" lastfilter=None lasttime=0 def fillit(self): """Get the directory list and show it in the two listboxes""" # Do not run unnecesarily if self.lastdir==self['directory'] and self.lastfilter==self['filter'] and self.lasttime>os.stat(self.lastdir)[8]: return self.lastdir=self['directory'] self.lastfilter=self['filter'] self.lasttime=time.time() dir=self['directory'] if not dir: dir=os.getcwd() dirs=['..'] files=[] try: fl=os.listdir(dir) fl.sort() except os.error,arg: if arg[0] in (2,20): return raise for f in fl: if os.path.isdir(os.path.join(dir,f)): dirs.append(f) else: filter=self['filter'] if not filter: filter='*' if fnmatch.fnmatch(f,filter): files.append(f) self.component('filenamebox').setlist(files) self.component('dirnamebox').setlist(dirs) def validate(self,filename): """Validation function. Should return 1 if the filename is valid, 0 if invalid. May pop up dialogs to tell user why. Especially suited to subclasses: i.e. only return 1 if the file does/doesn't exist""" return 1 class PmwDirDialog(PmwFileDialog): """Directory Dialog using Pmw""" def __init__(self, parent = None, **kw): # Define the megawidget options. optiondefs = ( ('directory', os.getcwd(), self.newdir), ('historylen',10, None), ('command', None, None), ('info', None, None), ) self.defineoptions(kw, optiondefs) # Initialise base class (after defining options). Pmw.Dialog.__init__(self, parent) self.withdraw() # Create the components. interior = self.interior() if self['info'] is not None: rowoffset=1 dn = self.infotxt() dn.grid(row=0,column=0,columnspan=2,padx=3,pady=3) else: rowoffset=0 dn = self.mkdn() dn.grid(row=1+rowoffset,column=0,columnspan=2,padx=3,pady=3) dn.bind('',self.okbutton) del dn # Create the directory list component. dnb = self.mkdnb() dnb.grid(row=0+rowoffset,column=0,columnspan=2,sticky='news',padx=3,pady=3) del dnb # Buttonbox already exists bb=self.component('buttonbox') bb.add('OK',command=self.okbutton) bb.add('Cancel',command=self.cancelbutton) del bb lastdir="" def fillit(self): """Get the directory list and show it in the two listboxes""" # Do not run unnecesarily if self.lastdir==self['directory']: return self.lastdir=self['directory'] dir=self['directory'] if not dir: dir=os.getcwd() dirs=['..'] try: fl=os.listdir(dir) fl.sort() except os.error,arg: if arg[0] in (2,20): return raise for f in fl: if os.path.isdir(os.path.join(dir,f)): dirs.append(f) self.component('dirnamebox').setlist(dirs) def okbutton(self): """OK action: user thinks he has input valid data and wants to proceed. This is also called by in the dirname entry""" fn=self.component('dirname').get() self.configure(directory=fn) if self.validate(fn): self.canceled=0 self.deactivate() def askfilename(self,directory=None): """The actual client function. Activates the dialog, and returns only after a valid filename has been entered (return value is that filename) or when canceled (return value is None)""" if directory!=None: self.configure(directory=directory) self.fillit() self.activate() if self.canceled: return None else: return self.component('dirname').get() def dirvalidate(self,string): if os.path.isdir(string): return Pmw.OK elif os.path.exists(string): return Pmw.PARTIAL else: return Pmw.OK def validate(self,filename): """Validation function. Should return 1 if the filename is valid, 0 if invalid. May pop up dialogs to tell user why. Especially suited to subclasses: i.e. only return 1 if the file does/doesn't exist""" if filename=='': _errorpop(self.interior(),"Empty filename") return 0 if os.path.isdir(filename) or not os.path.exists(filename): return 1 else: _errorpop(self.interior(),"This is not a directory") return 0 class PmwExistingFileDialog(PmwFileDialog): def filevalidate(self,string): if os.path.isfile(string): return Pmw.OK else: return Pmw.PARTIAL def validate(self,filename): if os.path.isfile(filename): return 1 elif os.path.exists(filename): _errorpop(self.interior(),"This is not a plain file") return 0 else: _errorpop(self.interior(),"Please select an existing file") return 0 class PmwExistingDirDialog(PmwDirDialog): def dirvalidate(self,string): if os.path.isdir(string): return Pmw.OK else: return Pmw.PARTIAL def validate(self,filename): if os.path.isdir(filename): return 1 elif os.path.exists(filename): _errorpop(self.interior(),"This is not a directory") return 0 else: _errorpop(self.interior(),"Please select an existing directory") if __name__=="__main__": root=Tkinter.Tk() root.withdraw() Pmw.initialise() f0=PmwFileDialog(root) f0.title('File name dialog') n=f0.askfilename() print '\nFilename : ',repr(n),'\n' f1=PmwDirDialog(root,info='This is a directory dialog') f1.title('Directory name dialog') while 1: n=f1.askfilename() if n is None: break print "Dirname : ",repr(n) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9111183 Pmw-2.1/Pmw/Pmw_1_3_3/contrib/PmwFullTimeCounter.py0000664000175000017500000004156200000000000022327 0ustar00gregmgregm00000000000000# Authors: Joe VanAndel, Greg McFarlane and Daniel Michelson import string import sys import time import Tkinter import Pmw class FullTimeCounter(Pmw.MegaWidget): """Up-down counter A TimeCounter is a single-line entry widget with Up and Down arrows which increment and decrement the Time value in the entry. """ def __init__(self, parent = None, **kw): # Define the megawidget options. INITOPT = Pmw.INITOPT optiondefs = ( ('autorepeat', 1, INITOPT), ('buttonaspect', 1.0, INITOPT), ('initwait', 300, INITOPT), ('labelmargin', 0, INITOPT), ('labelpos', None, INITOPT), ('max', '', self._max), ('min', '', self._min), ('padx', 0, INITOPT), ('pady', 0, INITOPT), ('repeatrate', 50, INITOPT), ('value', '', INITOPT), ) self.defineoptions(kw, optiondefs) # Initialise the base class (after defining the options). Pmw.MegaWidget.__init__(self, parent) self.arrowDirection = {} self._flag = 'stopped' self._timerId = None self._createComponents() value = self['value'] if value is None or value == '': now = time.time() value = time.strftime('%Y:%m:%d:%H:%M',time.gmtime(now)) self._setTimeFromStr(value) # Check keywords and initialise options. self.initialiseoptions() def _createComponents(self): # Create the components. interior = self.interior() # If there is no label, put the arrows and the entry directly # into the interior, otherwise create a frame for them. In # either case the border around the arrows and the entry will # be raised (but not around the label). if self['labelpos'] is None: frame = interior else: frame = self.createcomponent('frame', (), None, Tkinter.Frame, (interior,)) frame.grid(column=2, row=2, sticky='nsew') interior.grid_columnconfigure(2, weight=1) interior.grid_rowconfigure(2, weight=1) frame.configure(relief = 'raised', borderwidth = 1) # Create the down arrow buttons. # Create the year down arrow. self._downYearArrowBtn = self.createcomponent('downyeararrow', (), 'Arrow', Tkinter.Canvas, (frame,), width = 16, height = 16, relief = 'raised', borderwidth = 2) self.arrowDirection[self._downYearArrowBtn] = 0 self._downYearArrowBtn.grid(column = 0, row = 2) # Create the month down arrow. self._downMonthArrowBtn = self.createcomponent('downmontharrow', (), 'Arrow', Tkinter.Canvas, (frame,), width = 16, height = 16, relief = 'raised', borderwidth = 2) self.arrowDirection[self._downMonthArrowBtn] = 0 self._downMonthArrowBtn.grid(column = 1, row = 2) # Create the day down arrow. self._downDayArrowBtn = self.createcomponent('downdayarrow', (), 'Arrow', Tkinter.Canvas, (frame,), width = 16, height = 16, relief = 'raised', borderwidth = 2) self.arrowDirection[self._downDayArrowBtn] = 0 self._downDayArrowBtn.grid(column = 2, row = 2) # Create the hour down arrow. self._downHourArrowBtn = self.createcomponent('downhourarrow', (), 'Arrow', Tkinter.Canvas, (frame,), width = 16, height = 16, relief = 'raised', borderwidth = 2) self.arrowDirection[self._downHourArrowBtn] = 0 self._downHourArrowBtn.grid(column = 3, row = 2) # Create the minute down arrow. self._downMinuteArrowBtn = self.createcomponent('downminutearrow', (), 'Arrow', Tkinter.Canvas, (frame,), width = 16, height = 16, relief = 'raised', borderwidth = 2) self.arrowDirection[self._downMinuteArrowBtn] = 0 self._downMinuteArrowBtn.grid(column = 4, row = 2) # Create the entry fields. # Create the year entry field. self._yearCounterEntry = self.createcomponent('yearentryfield', (('yearentry', 'yearentryfield_entry'),), None, Pmw.EntryField, (frame,), validate='integer', entry_width = 4) self._yearCounterEntry.grid(column = 0, row = 1, sticky = 'news') # Create the month entry field. self._monthCounterEntry = self.createcomponent('monthentryfield', (('monthentry', 'monthentryfield_entry'),), None, Pmw.EntryField, (frame,), validate='integer', entry_width = 2) self._monthCounterEntry.grid(column = 1, row = 1, sticky = 'news') # Create the day entry field. self._dayCounterEntry = self.createcomponent('dayentryfield', (('dayentry', 'dayentryfield_entry'),), None, Pmw.EntryField, (frame,), validate='integer', entry_width = 2) self._dayCounterEntry.grid(column = 2, row = 1, sticky = 'news') # Create the hour entry field. self._hourCounterEntry = self.createcomponent('hourentryfield', (('hourentry', 'hourentryfield_entry'),), None, Pmw.EntryField, (frame,), validate='integer', entry_width = 2) self._hourCounterEntry.grid(column = 3, row = 1, sticky = 'news') # Create the minute entry field. self._minuteCounterEntry = self.createcomponent('minuteentryfield', (('minuteentry', 'minuteentryfield_entry'),), None, Pmw.EntryField, (frame,), validate='integer', entry_width = 2) self._minuteCounterEntry.grid(column = 4, row = 1, sticky = 'news') # Create the up arrow buttons. # Create the year up arrow. self._upYearArrowBtn = self.createcomponent('upyeararrow', (), 'Arrow', Tkinter.Canvas, (frame,), width = 16, height = 16, relief = 'raised', borderwidth = 2) self.arrowDirection[self._upYearArrowBtn] = 1 self._upYearArrowBtn.grid(column = 0, row = 0) # Create the month up arrow. self._upMonthArrowBtn = self.createcomponent('upmontharrow', (), 'Arrow', Tkinter.Canvas, (frame,), width = 16, height = 16, relief = 'raised', borderwidth = 2) self.arrowDirection[self._upMonthArrowBtn] = 1 self._upMonthArrowBtn.grid(column = 1, row = 0) # Create the day up arrow. self._upDayArrowBtn = self.createcomponent('updayarrow', (), 'Arrow', Tkinter.Canvas, (frame,), width = 16, height = 16, relief = 'raised', borderwidth = 2) self.arrowDirection[self._upDayArrowBtn] = 1 self._upDayArrowBtn.grid(column = 2, row = 0) # Create the hour up arrow. self._upHourArrowBtn = self.createcomponent('uphourarrow', (), 'Arrow', Tkinter.Canvas, (frame,), width = 16, height = 16, relief = 'raised', borderwidth = 2) self.arrowDirection[self._upHourArrowBtn] = 1 self._upHourArrowBtn.grid(column = 3, row = 0) # Create the minute up arrow. self._upMinuteArrowBtn = self.createcomponent('upminutearrow', (), 'Arrow', Tkinter.Canvas, (frame,), width = 16, height = 16, relief = 'raised', borderwidth = 2) self.arrowDirection[self._upMinuteArrowBtn] = 1 self._upMinuteArrowBtn.grid(column = 4, row = 0) # Make it resize nicely. padx = self['padx'] pady = self['pady'] for col in range(5): # YY, MM, DD, HH, mm frame.grid_columnconfigure(col, weight = 1, pad = padx) frame.grid_rowconfigure(0, pad = pady) frame.grid_rowconfigure(2, pad = pady) frame.grid_rowconfigure(1, weight = 1) # Create the label. self.createlabel(interior) # Set bindings. # Up year self._upYearArrowBtn.bind('', lambda event, s=self,button=self._upYearArrowBtn: s._drawArrow(button, 1)) self._upYearArrowBtn.bind('<1>', lambda event, s=self,button=self._upYearArrowBtn: s._countUp(button)) self._upYearArrowBtn.bind('', lambda event, s=self, button=self._upYearArrowBtn: s._stopUpDown(button)) # Up month self._upMonthArrowBtn.bind('', lambda event, s=self,button=self._upMonthArrowBtn: s._drawArrow(button, 1)) self._upMonthArrowBtn.bind('<1>', lambda event, s=self,button=self._upMonthArrowBtn: s._countUp(button)) self._upMonthArrowBtn.bind('', lambda event, s=self, button=self._upMonthArrowBtn: s._stopUpDown(button)) # Up day self._upDayArrowBtn.bind('', lambda event, s=self,button=self._upDayArrowBtn: s._drawArrow(button, 1)) self._upDayArrowBtn.bind('<1>', lambda event, s=self,button=self._upDayArrowBtn: s._countUp(button)) self._upDayArrowBtn.bind('', lambda event, s=self, button=self._upDayArrowBtn: s._stopUpDown(button)) # Up hour self._upHourArrowBtn.bind('', lambda event, s=self,button=self._upHourArrowBtn: s._drawArrow(button, 1)) self._upHourArrowBtn.bind('<1>', lambda event, s=self,button=self._upHourArrowBtn: s._countUp(button)) self._upHourArrowBtn.bind('', lambda event, s=self, button=self._upHourArrowBtn: s._stopUpDown(button)) # Up minute self._upMinuteArrowBtn.bind('', lambda event, s=self,button=self._upMinuteArrowBtn: s._drawArrow(button, 1)) self._upMinuteArrowBtn.bind('<1>', lambda event, s=self,button=self._upMinuteArrowBtn: s._countUp(button)) self._upMinuteArrowBtn.bind('', lambda event, s=self, button=self._upMinuteArrowBtn: s._stopUpDown(button)) # Down year self._downYearArrowBtn.bind('', lambda event, s=self,button=self._downYearArrowBtn: s._drawArrow(button, 0)) self._downYearArrowBtn.bind('<1>', lambda event, s=self,button=self._downYearArrowBtn: s._countDown(button)) self._downYearArrowBtn.bind('', lambda event, s=self, button=self._downYearArrowBtn: s._stopUpDown(button)) # Down month self._downMonthArrowBtn.bind('', lambda event, s=self,button=self._downMonthArrowBtn: s._drawArrow(button, 0)) self._downMonthArrowBtn.bind('<1>', lambda event, s=self,button=self._downMonthArrowBtn: s._countDown(button)) self._downMonthArrowBtn.bind('', lambda event, s=self, button=self._downMonthArrowBtn: s._stopUpDown(button)) # Down day self._downDayArrowBtn.bind('', lambda event, s=self,button=self._downDayArrowBtn: s._drawArrow(button, 0)) self._downDayArrowBtn.bind('<1>', lambda event, s=self,button=self._downDayArrowBtn: s._countDown(button)) self._downDayArrowBtn.bind('', lambda event, s=self, button=self._downDayArrowBtn: s._stopUpDown(button)) # Down hour self._downHourArrowBtn.bind('', lambda event, s=self,button=self._downHourArrowBtn: s._drawArrow(button, 0)) self._downHourArrowBtn.bind('<1>', lambda event, s=self,button=self._downHourArrowBtn: s._countDown(button)) self._downHourArrowBtn.bind('', lambda event, s=self, button=self._downHourArrowBtn: s._stopUpDown(button)) # Down minute self._downMinuteArrowBtn.bind('', lambda event, s=self,button=self._downMinuteArrowBtn: s._drawArrow(button, 0)) self._downMinuteArrowBtn.bind('<1>', lambda event, s=self,button=self._downMinuteArrowBtn: s._countDown(button)) self._downMinuteArrowBtn.bind('', lambda event, s=self, button=self._downMinuteArrowBtn: s._stopUpDown(button)) self._yearCounterEntry.bind('', self.invoke) self._monthCounterEntry.bind('', self.invoke) self._dayCounterEntry.bind('', self.invoke) self._hourCounterEntry.bind('', self.invoke) self._minuteCounterEntry.bind('', self.invoke) self._yearCounterEntry.bind('', self._resizeArrow) self._monthCounterEntry.bind('', self._resizeArrow) self._dayCounterEntry.bind('', self._resizeArrow) self._hourCounterEntry.bind('', self._resizeArrow) self._minuteCounterEntry.bind('', self._resizeArrow) def _drawArrow(self, arrow, direction): arrow.delete('arrow') fg = self._yearCounterEntry.cget('entry_foreground') bw = (string.atoi(arrow['borderwidth']) + string.atoi(arrow['highlightthickness'])) / 2 h = string.atoi(arrow['height']) + 2 * bw w = string.atoi(arrow['width']) + 2 * bw if direction == 0: # down arrow arrow.create_polygon( 0.25 * w + bw, 0.25 * h + bw, 0.50 * w + bw, 0.75 * h + bw, 0.75 * w + bw, 0.25 * h + bw, fill=fg, tag='arrow') else: arrow.create_polygon( 0.25 * w + bw, 0.75 * h + bw, 0.50 * w + bw, 0.25 * h + bw, 0.75 * w + bw, 0.75 * h + bw, fill=fg, tag='arrow') def _resizeArrow(self, event = None): for btn in (self._upYearArrowBtn, self._upMonthArrowBtn, self._upDayArrowBtn, self._upHourArrowBtn, self._upMinuteArrowBtn, self._downYearArrowBtn, self._downMonthArrowBtn, self._downDayArrowBtn, self._downHourArrowBtn, self._downMinuteArrowBtn): bw = (string.atoi(btn['borderwidth']) + \ string.atoi(btn['highlightthickness'])) newHeight = self._yearCounterEntry.winfo_reqheight() - 2 * bw newWidth = newHeight * self['buttonaspect'] btn.configure(width=newWidth, height=newHeight) self._drawArrow(btn, self.arrowDirection[btn]) def _min(self): self._minVal = None def _max(self): self._maxVal = None def _setTimeFromStr(self, str): list = string.split(str, ':') if len(list) != 5: raise ValueError, 'invalid value: ' + str self._year = string.atoi(list[0]) self._month = string.atoi(list[1]) self._day = string.atoi(list[2]) self._hour = string.atoi(list[3]) self._minute = string.atoi(list[4]) self._setHMS() def getstring(self): return '%04d:%02d:%02d:%02d:%02d' % (self._year, self._month, self._day, self._hour, self._minute) def getint(self): pass def _countUp(self, button): self._relief = self._upYearArrowBtn.cget('relief') button.configure(relief='sunken') if button == self._upYearArrowBtn: datetype = "year" elif button == self._upMonthArrowBtn: datetype = "month" elif button == self._upDayArrowBtn: datetype = "day" elif button == self._upHourArrowBtn: datetype = "hour" elif button == self._upMinuteArrowBtn: datetype = "minute" self._count(1, datetype, 'start') def _countDown(self, button): self._relief = self._downYearArrowBtn.cget('relief') button.configure(relief='sunken') if button == self._downYearArrowBtn: datetype = "year" elif button == self._downMonthArrowBtn: datetype = "month" elif button == self._downDayArrowBtn: datetype = "day" elif button == self._downHourArrowBtn: datetype = "hour" elif button == self._downMinuteArrowBtn: datetype = "minute" self._count(-1, datetype, 'start') def _count(self, factor, datetype, newFlag=None): if newFlag != 'force': if newFlag is not None: self._flag = newFlag if self._flag == 'stopped': return if datetype == "year": self._year = self._year + factor elif datetype == "month": self._month = self._month + factor elif datetype == "day": self._day = self._day + factor elif datetype == "hour": self._hour = self._hour + factor elif datetype == "minute": self._minute = self._minute + factor secs = time.mktime((self._year, self._month, self._day, self._hour, self._minute, 0, 0, 0, -1)) tt = time.localtime(secs) # NOT gmtime! self._year = tt[0] self._month = tt[1] self._day = tt[2] self._hour = tt[3] self._minute = tt[4] self._setHMS() if newFlag != 'force': if self['autorepeat']: if self._flag == 'start': delay = self['initwait'] self._flag = 'running' else: delay = self['repeatrate'] self._timerId = self.after( delay, lambda self=self, factor=factor, datetype=datetype: self._count(factor, datetype, 'running')) def _setHMS(self): self._yearCounterEntry.setentry('%04d' % self._year) self._monthCounterEntry.setentry('%02d' % self._month) self._dayCounterEntry.setentry('%02d' % self._day) self._hourCounterEntry.setentry('%02d' % self._hour) self._minuteCounterEntry.setentry('%02d' % self._minute) def _stopUpDown(self, button): if self._timerId is not None: self.after_cancel(self._timerId) self._timerId = None button.configure(relief=self._relief) self._flag = 'stopped' def invoke(self, event = None): cmd = self['command'] if callable(cmd): cmd() def destroy(self): if self._timerId is not None: self.after_cancel(self._timerId) self._timerId = None Pmw.MegaWidget.destroy(self) if __name__=="__main__": def showString(): stringVal = _time.getstring() print stringVal root = Tkinter.Tk() Pmw.initialise(root) root.title('FullTimeCounter') exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') _time = FullTimeCounter(root, labelpos = 'n', label_text = 'YYYY:MM:DD:HH:mm') _time.pack(fill = 'both', expand = 1, padx=10, pady=5) button = Tkinter.Button(root, text = 'Show', command = showString) button.pack() root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9111183 Pmw-2.1/Pmw/Pmw_1_3_3/contrib/PmwVerticalGauge.py0000664000175000017500000001527700000000000021774 0ustar00gregmgregm00000000000000""" I needed a simple gauge, so I've made on with Pmw. It might be useful for others to use as a base to develop more comples gauges with. Is it worth cleaning up and submitting? cheers and thanks chris Dr. Chris Wright Intensive Care Unit Monash Medical Centre Clayton. VIC Australia """ import sys import Tkinter import Pmw import time if sys.platform == 'win32': # MS-Windows specific fonts label_font = "-family Ariel -size 12" value_font = "-family Ariel -size 12" small_font = "-family {MS Sans Serif} -size 9 -weight bold" header_font = "-family {MS Sans Serif} -weight bold" else: # X-Windows specific fonts label_font = "-*-helvetica-*-r-*-*-*-160-*-*-*-*-*-*" value_font = "-*-courier-*-r-*-*-*-160-*-*-*-*-*-*" small_font = "-*-helvetica-*-r-*-*-*-130-*-*-*-*-*-*" header_font = "-*-helvetica-bold-r-*-*-*-150-*-*-*-*-*-*" class VerticalGauge(Pmw.MegaWidget): """Vertical gauge with actual and desired settings""" def __init__(self, parent = None, **kw): optiondefs = ( ('min', 0, None), ('max', 100, None), ('majortickinterval', 10, None), ('minortickinterval', 5, None), ('units', '', None), ('bg', 'grey', self._backgroundSet), ('actualvalue', 50, self._actualSet), ('desiredvalue', 50, self._desiredSet), ('actualcolour', 'yellow1', None), ('desiredcolour', 'turquoise1', None), ('label', 'Label', None), ) self.defineoptions(kw, optiondefs) Pmw.MegaWidget.__init__(self, parent) interior = self.interior() interior.grid_rowconfigure(1, weight = 1) for r in range(3): interior.grid_columnconfigure(r, weight = 1) self.actuallabel = self.createcomponent('actualLabel', (), None, Tkinter.Label, (interior,), text = '', width = 3, relief = 'sunken', bd = 1, fg = self['actualcolour'], font = value_font) self.actuallabel.grid(sticky = "nswe", row = 0, column = 0) self.label = self.createcomponent('label', (), None, Tkinter.Label, (interior,), text = self['label'], relief = 'raised', font = label_font, fg = 'navy', bd = 2) self.label.grid(sticky = "nsew", row = 0, column = 1) self.desiredlabel = self.createcomponent('desiredLabel', (), None, Tkinter.Label, (interior,), text = '', width = 3, relief = 'sunken', bd = 1, fg = self['desiredcolour'], font = value_font) self.desiredlabel.grid(sticky = "nswe", row = 0, column = 2) self.canvas = self.createcomponent('canvas', (), None, Tkinter.Canvas, (interior,), width = 100, height = 300, bg = 'grey') self.canvas.grid(sticky = "nsew", columnspan = 3, pady = 1) self.canvas.bind("", self._createGaugeAxes) self._createGaugeAxes() self.initialiseoptions() def _createGaugeAxes(self, event = None): min = self['min'] max = self['max'] units = self['units'] majortickinterval = self['majortickinterval'] gauge_range = max - min c = self.canvas c.delete("all") if event: h, w = event.height, event.width else: h = int(c.configure("height")[4]) w = int(c.configure("width")[4]) self.lower = h - 15 self.upper = 15 self.middle = w / 2 c.create_line(self.middle, self.lower, self.middle, self.upper) majortickcount = int((max - min) / majortickinterval) self.axislength = self.lower - self.upper self.majortickdistance = float(self.axislength) / majortickcount self.majortickwidth = w / 5 labeloffset = (w / 4) + 10 for i in range(majortickcount + 1): v = min + i * majortickinterval d = self.lower - i * self.majortickdistance c.create_line(self.middle, d, self.middle + self.majortickwidth, d) c.create_text(self.middle + labeloffset, d, font = small_font, text = str(v)) self._desiredSet(event) self._actualSet(event) def _backgroundSet(self): self.canvas.configure(bg = self['bg']) def _desiredSet(self, event = None): c = self.canvas desired = self['desiredvalue'] desiredcolour = self['desiredcolour'] min = self['min'] max = self['max'] if desired > max: desired = max if desired < min: desired = min gauge_range = max - min c = self.canvas if event: h, w = event.height, event.width else: h = int(c.configure("height")[4]) w = int(c.configure("width")[4]) desired_y = self.lower - (float(desired - min) / gauge_range) * self.axislength try: c.delete('desiredBar') except: pass c.create_line(self.middle - self.majortickwidth, desired_y, self.middle + self.majortickwidth, desired_y, fill = desiredcolour, stipple = 'gray50', width = 10, tag = 'desiredBar') self.desiredlabel.configure(text = desired) def setActual(self, value): self.configure(actualvalue = value) def getActual(self): return self.cget('actualvalue') def _actualSet(self, event = None): c = self.canvas actual = self['actualvalue'] actualcolour = self['actualcolour'] min = self['min'] max = self['max'] if actual > max: actual = max if actual < min: actual = min gauge_range = max - min c = self.canvas if event: h, w = event.height, event.width else: h = int(c.configure("height")[4]) w = int(c.configure("width")[4]) actual_y = self.lower - (float(actual - min) / gauge_range) * self.axislength try: c.delete('actualPointer') except: pass triangle = ((self.middle, actual_y), (self.middle - 1.4 * self.majortickwidth, actual_y - self.majortickwidth / 2), (self.middle - 1.4 * self.majortickwidth, actual_y + self.majortickwidth / 2)) c.create_polygon(triangle, fill = actualcolour, tag = 'actualPointer') self.actuallabel.configure(text = actual) Pmw.forwardmethods(VerticalGauge, Tkinter.Canvas, 'canvas') if __name__ == '__main__': # Initialise Tkinter and Pmw. root = Pmw.initialise() root.title('Pmw VerticalGauge demonstration') def increase(): av = g1.getActual() g1.setActual(av + 1) def decrease(): av = g1.getActual() g1.setActual(av - 1) g1 = VerticalGauge(min = 0, max = 30, actualvalue = 15, desiredvalue = 22, majortickinterval = 2, label = "Pms") g1.grid(sticky = "nsew") root.grid_rowconfigure(0, weight = 1) root.grid_columnconfigure(0, weight = 1) b1 = Tkinter.Button(text = "Increase", command = increase) b1.grid() b2 = Tkinter.Button(text = "Decrease", command = decrease) b2.grid() # Let's go. root.mainloop() ././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1609332343.907118 Pmw-2.1/Pmw/Pmw_1_3_3/contrib/README0000664000175000017500000000076700000000000017072 0ustar00gregmgregm00000000000000This directory contains contributed Pmw megawidgets. DirBrowser.py directory selection dialog MCListbox.py multi-column selectable listbox PmwFileDialog.py file selection dialog PmwFullTimeCounter.py time counter which includes year, month and day PmwVerticalGauge.py a simple gauge indicating a value and a threshold TreeBrowser.py generic hierarchical tree browser Each file can be executed and will display a demo of its megawidget. ././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1609332343.907118 Pmw-2.1/Pmw/Pmw_1_3_3/contrib/TreeBrowser.py0000664000175000017500000007431000000000000021022 0ustar00gregmgregm00000000000000# # FILE: TreeBrowser.py # # DESCRIPTION: # This file provides a generic hierarchical tree browser widget. # # AUTHOR: Steve Kinneberg , # MontaVista Software, Inc. # # Copyright 2001 MontaVista Software Inc. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 2 of the License, or (at your # option) any later version. # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN # NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 675 Mass Ave, Cambridge, MA 02139, USA. # import types import Tkinter import Pmw class _Branching: def __init__(self): # List of branch names self._nodeNames = [] # Map from branch name to branch info # branch Either _LeafNode or _BranchNode widget of the branch # nodetype Either 'TreeNode' or 'LeafNode' self._nodeAttrs = {} def addbranch(self, branchName = None, **kw): kw['indent'] = self['indent'] return apply(self._insertnode, ('tree', branchName, len(self._nodeNames), self._treeRoot), kw) def addleaf(self, leafName = None, **kw): return apply(self._insertnode, ('leaf', leafName, len(self._nodeNames), self._treeRoot), kw) def insertbranch(self, branchName = None, before = 0, **kw): kw['indent'] = self['indent'] return apply(self._insertnode, ('tree', branchName, before, self._treeRoot), kw) def insertleaf(self, leafName = None, before = 0, **kw): return apply(self._insertnode, ('leaf', leafName, before, self._treeRoot), kw) def _insertnode(self, type, nodeName, before, treeRoot, **kw): if 'selectbackground' not in kw.keys(): kw['selectbackground'] = self['selectbackground'] if 'selectforeground' not in kw.keys(): kw['selectforeground'] = self['selectforeground'] if 'background' not in kw.keys(): kw['background'] = self['background'] if 'foreground' not in kw.keys(): kw['foreground'] = self['foreground'] if nodeName == None: nodeName = self._nodeName + ".%d" % (len(self._nodeNames) + 1) if self._nodeAttrs.has_key(nodeName): msg = 'Node "%s" already exists.' % nodeName raise ValueError, msg # Do this early to catch bad spec before creating any items. beforeIndex = self.index(before, 1) attributes = {} last = (beforeIndex == len(self._nodeNames)) if last and len(self._nodeNames) > 0: # set the previous node to not last self._nodeAttrs[self._nodeNames[-1]]['branch']._setlast(0) if(type == 'tree'): node = apply(self.createcomponent, ('branch%d'%len(self._nodeNames), (), None, _BranchNode, self._branchFrame, nodeName, treeRoot, self, last, ), kw) attributes['nodetype'] = 'TreeNode' else: node = apply(self.createcomponent, ('leaf%d'%len(self._nodeNames), (), None, _LeafNode, self._branchFrame, nodeName, treeRoot, self, last, ), kw) attributes['nodetype'] = 'LeafNode' if len(self._nodeNames) == beforeIndex: node.pack(anchor='w') else: bname = self._nodeNames[beforeIndex] battrs = self._nodeAttrs[bname] node.pack(anchor='w', before=battrs['branch']) attributes['branch'] = node self._nodeAttrs[nodeName] = attributes self._nodeNames.insert(beforeIndex, nodeName) self._sizechange() return node def delete(self, *nodes): curSel = self._treeRoot.curselection()[0] for node in nodes: index = self.index(node) name = self._nodeNames.pop(index) dnode = self._nodeAttrs[name]['branch'] del self._nodeAttrs[name] if dnode == curSel: self._treeRoot._unhightlightnode(dnode) dnode.destroy() self._sizechange() def destroy(self): for node in len(self._nodeNames): self.delete(node) Pmw.MegaWidget.destroy(self) def index(self, index, forInsert = 0): if isinstance(index, _LeafNode): index = index._nodeName listLength = len(self._nodeNames) if type(index) == types.IntType: if forInsert and index <= listLength: return index elif not forInsert and index < listLength: return index else: raise ValueError, 'index "%s" is out of range' % index elif type(index) == types.StringType: if index in self._nodeNames: return self._nodeNames.index(index) raise ValueError, 'bad branch or leaf name: %s' % index elif index is Pmw.END: if forInsert: return listLength elif listLength > 0: return listLength - 1 else: raise ValueError, 'TreeNode has no branches' #elif index is Pmw.SELECT: # if listLength == 0: # raise ValueError, 'TreeNode has no branches' # return self._pageNames.index(self.getcurselection()) else: validValues = 'a name, a number, Pmw.END, Pmw.SELECT, or a reference to a TreeBrowser Leaf or Branch' raise ValueError, \ 'bad index "%s": must be %s' % (index, validValues) def getnodenames(self): return self._nodeNames def getnode(self, node): nodeName = self._nodeNames[self.index(node)] return self._nodeAttrs[nodeName]['branch'] class _LeafNode(Pmw.MegaWidget): def __init__(self, parent, nodeName, treeRoot, parentnode, last = 1, **kw): colors = Pmw.Color.getdefaultpalette(parent) self._nodeName = nodeName self._treeRoot = treeRoot self._parentNode = parentnode self._last = last # Define the megawidget options. INITOPT = Pmw.INITOPT optiondefs = ( ('selectbackground', colors['selectBackground'], INITOPT), ('selectforeground', colors['selectForeground'], INITOPT), ('background', colors['background'], INITOPT), ('foreground', colors['foreground'], INITOPT), ('selectcommand', None, None), ('deselectcommand', None, None), ('labelpos', 'e', INITOPT), ('labelmargin', 0, INITOPT), ('label', None, None), ) self.defineoptions(kw, optiondefs) # Initialise the base class (after defining the options). Pmw.MegaWidget.__init__(self, parent) # Create the components interior = self._hull labelpos = self['labelpos'] if self['label'] == None: self._labelWidget = self.createcomponent('labelwidget', (), None, Pmw.LabeledWidget, (interior,), #background = self['background'], #foreground = self['foreground'], ) else: self._labelWidget = self.createcomponent('labelwidget', (), None, Pmw.LabeledWidget, (interior,), label_background = self['background'], label_foreground = self['foreground'], labelpos = labelpos, labelmargin = self['labelmargin'], label_text = self['label'], ) self._labelWidget.component('label').bind('', self._selectevent) self._labelWidget.grid(column = 1, row = 0, sticky = 'w') self._labelWidget.update() self._labelheight = self._labelWidget.winfo_height() self._lineCanvas = self.createcomponent('linecanvas', (), None, Tkinter.Canvas, (interior,), width = self._labelheight, height = self._labelheight, ) self._lineCanvas.grid( column = 0, row = 0, sticky = 'news') self._lineCanvas.update() cw = int(self._lineCanvas['width']) ch = int(self._lineCanvas['height']) self._lineCanvas.create_line(cw/2, ch/2, cw, ch/2, tag='hline') if last: self._lineCanvas.create_line(cw/2, 0, cw/2, ch/2, tag='vline') else: self._lineCanvas.create_line(cw/2, 0, cw/2, ch, tag='vline') # Check keywords and initialise options. self.initialiseoptions() def interior(self): return self._labelWidget.interior() def select(self): self._highlight() def getname(self): return self._nodeName def getlabel(self): return self['label'] def _selectevent(self, event): self._highlight() def _highlight(self): self._treeRoot._highlightnode(self) #self._subHull.configure(background = self._selectbg, relief = 'raised') if self['label'] != None: self._labelWidget.configure(label_background = self['selectbackground']) self._labelWidget.configure(label_foreground = self['selectforeground']) #self._viewButton.configure(background = self._selectbg) cmd = self['selectcommand'] if callable(cmd): cmd(self) def _unhighlight(self): #self._subHull.configure(background = self._bg, relief = 'flat') if self['label'] != None: self._labelWidget.configure(label_background = self['background']) self._labelWidget.configure(label_foreground = self['foreground']) #self._viewButton.configure(background = self._bg) cmd = self['deselectcommand'] if callable(cmd): cmd(self) def _setlast(self, last): self._last = last cw = int(self._lineCanvas['width']) ch = int(self._lineCanvas['height']) if last: self._lineCanvas.create_line(cw/2, 0, cw/2, ch/2, tag='vline') else: self._lineCanvas.create_line(cw/2, 0, cw/2, ch, tag='vline') class _BranchNode(_LeafNode, _Branching): #Pmw.MegaWidget): def __init__(self, parent, nodeName, treeRoot, parentnode, last = 1, **kw): # Define the megawidget options. INITOPT = Pmw.INITOPT optiondefs = ( ('view', 'collapsed', None), ('expandcommand', None, None), ('collapsecommand', None, None), ('indent', 0, INITOPT) ) self.defineoptions(kw, optiondefs) # Initialise the base class (after defining the options). apply(_LeafNode.__init__, (self, parent, nodeName, treeRoot, parentnode, last), kw) _Branching.__init__(self) # Create the components interior = self._hull # Create the expand/collapse button self._viewButton = self.createcomponent('viewbutton', (), None, Tkinter.Canvas, (interior,), background = self['background'], width = self._labelheight - 4, height = self._labelheight - 4, borderwidth = 2, relief = 'raised') self._viewButton.grid(column = 0, row = 0, sticky='se') self._viewButton.bind('', self._showbuttonpress) self._viewButton.bind('', self._toggleview) # The label widget is already created by the base class, however # we do need to make some slight modifications. if self['label'] != None: self._labelWidget.component('label').bind('', self._toggleview) self._labelWidget.grid(column=1, row=0, columnspan = 3, sticky='sw') # A line canvas is already created for us, we just need to make # some slight modifications self._lineCanvas.delete('hline') self._lineCanvas.grid_forget() # Set the minsize of column 1 to control additional branch frame indentation self.grid_columnconfigure(1, minsize = self['indent']) # Create the branch frame that will contain all the branch/leaf nodes self._branchFrame = self.createcomponent('frame', (), None, Tkinter.Frame, (interior,), #borderwidth=2, #relief='ridge', ) self.grid_columnconfigure(2,minsize=0, weight=1) #self.grid_rowconfigure(0,minsize=0) if(self['view'] == 'expanded'): Pmw.drawarrow(self._viewButton, self['foreground'], 'down', 'arrow') self._branchFrame.grid(column = 2, row = 1, sticky='nw') if not self._last: self._branchFrame.update() bh = self._branchFrame.winfo_height() self._lineCanvas.configure(height = bh) self._lineCanvas.grid(column = 0, row = 1, sticky='news') cw = int(self._lineCanvas['width']) ch = int(self._lineCanvas['height']) #self._lineCanvas.create_line(cw/2, 1, cw/2, ch, tag = 'vline') self._lineCanvas.coords('vline', cw/2, 1, cw/2, ch) else: Pmw.drawarrow(self._viewButton, self['foreground'], 'right', 'arrow') self._viewButton.configure(relief = 'raised') # Check keywords and initialise options. self.initialiseoptions() def _showbuttonpress(self, event): self._viewButton.configure(relief = 'sunken') def _toggleview(self, event): self._viewButton.configure(relief = 'sunken') self.select() if(self['view'] == 'expanded'): self.collapsetree() else: self.expandtree() self._viewButton.configure(relief = 'raised') def expandtree(self): if(self['view'] == 'collapsed'): cmd = self['expandcommand'] if cmd is not None: cmd(self) self['view'] = 'expanded' Pmw.drawarrow(self._viewButton, self['foreground'], 'down', 'arrow') self._branchFrame.grid(column = 2, row = 1, sticky='nw') if not self._last: self._branchFrame.update() bh = self._branchFrame.winfo_height() self._lineCanvas.configure(height = bh) self._lineCanvas.grid(column = 0, row = 1, sticky='news') cw = int(self._lineCanvas['width']) ch = int(self._lineCanvas['height']) #self._lineCanvas.create_line( cw/2, 1, cw/2, ch, tag = 'vline') self._lineCanvas.coords('vline', cw/2, 1, cw/2, ch) self._parentNode._sizechange() def collapsetree(self): if(self['view'] == 'expanded'): cmd = self['collapsecommand'] if cmd is not None: cmd(self) self['view'] = 'collapsed' Pmw.drawarrow(self._viewButton, self['foreground'], 'right', 'arrow') self._branchFrame.grid_forget() if not self._last: #self._lineCanvas.delete('vline') self._lineCanvas.grid_forget() self._parentNode._sizechange() def _setlast(self, last): self._last = last if self['view'] == 'expanded': self._branchFrame.update() bh = self._branchFrame.winfo_height() self._lineCanvas.configure(height = bh) cw = int(self._lineCanvas['width']) ch = int(self._lineCanvas['height']) self._lineCanvas.delete('vline') if not last: self._lineCanvas.create_line(cw/2, 1, cw/2, ch, tag='vline') def _sizechange(self): if not self._last and self['view'] == 'expanded': self._branchFrame.update() bh = self._branchFrame.winfo_height() self._lineCanvas.configure(height = bh) if self._lineCanvas.coords('vline')[3] < bh: cw = int(self._lineCanvas['width']) ch = int(self._lineCanvas['height']) #self._lineCanvas.delete('vline') #self._lineCanvas.create_line(cw/2, 1, cw/2, ch, tag='vline') self._lineCanvas.coords('vline', cw/2, 1, cw/2, ch) self._parentNode._sizechange() class TreeBrowser(Pmw.MegaWidget, _Branching): def __init__(self, parent = None, nodeName = '0', **kw): colors = Pmw.Color.getdefaultpalette(parent) # Define the megawidget options. INITOPT = Pmw.INITOPT optiondefs = ( ('indent', 0, INITOPT), ('selectbackground', colors['selectBackground'], INITOPT), ('selectforeground', colors['selectForeground'], INITOPT), ('background', colors['background'], INITOPT), ('foreground', colors['foreground'], INITOPT), #('selectrelief', 'raised', INITOPT), ) self.defineoptions(kw, optiondefs) # Initialise the base class (after defining the options). Pmw.MegaWidget.__init__(self, parent) _Branching.__init__(self) # Create the components interior = self._hull browserFrame = self.createcomponent('frame', (), None, Pmw.ScrolledFrame, (interior,), ) browserFrame.pack(expand = 1, fill='both') self._branchFrame = browserFrame.interior() self._highlightedNode = None self._treeRoot = self self._nodeName = nodeName # Check keywords and initialise options. self.initialiseoptions() def _highlightnode(self, newNode): if self._highlightedNode != newNode: if self._highlightedNode != None: self._highlightedNode._unhighlight() self._highlightedNode = newNode def _unhighlightnode(self): if self._highlightedNode != None: self._highlightedNode._unhighlight() self._highlightedNode = None def curselection(self): retVal = None if self._highlightedNode != None: retVal = (self._highlightedNode, self._highlightedNode._nodeName, self._highlightedNode['label']) return retVal def getname(self): return self._nodeName # The top-level TreeBrowser widget only shows nodes in an expanded view # but still provides collapsetree() and expandtree() methods so that users # don't have to special case the top-level node def collapsetree(self): return def expandtree(self): return def _sizechange(self): return if __name__ == '__main__': rootWin = Tkinter.Tk() Pmw.initialise() rootWin.title('TreeBrowser Demo') # Create the hierarchical tree browser widget treeBrowser = TreeBrowser(rootWin, #selectbackground = "darkgreen", #selectforeground = 'lightgreen', #background = 'green', #indent = 10, ) def printselected(node): selection = treeBrowser.curselection() if selection != None: print "Selected node name:", selection[1], " label:", selection[2] def printdeselected(node): selection = treeBrowser.curselection() if selection != None: print "Deselected node name:", selection[1], " label:", selection[2] def printexpanded(node): print "Expanded node name:", node.getname(), " label:", node.getlabel() def printcollapsed(node): print "Collapsed node name:", node.getname(), " label:", node.getlabel() for i in range(3): # Add a tree node to the top level treeNodeLevel1 = treeBrowser.addbranch(label = 'TreeNode %d'%i, selectcommand = printselected, deselectcommand = printdeselected, expandcommand = printexpanded, collapsecommand = printcollapsed, ) for j in range(3): # Add a tree node to the second level treeNodeLevel2 = treeNodeLevel1.addbranch(label = 'TreeNode %d.%d'%(i,j), #selectforeground = 'yellow', selectcommand = printselected, deselectcommand = printdeselected, expandcommand = printexpanded, collapsecommand = printcollapsed, ) if i == 0 and j == 1: dynamicTreeRootNode = treeNodeLevel1 dynamicTreePosNode = treeNodeLevel2 for item in range((i+1)*(j+1)): # Add a leaf node to the third level leaf = treeNodeLevel2.addleaf(label = "Item %c"%(item+65), #selectbackground = 'blue', selectcommand = printselected, deselectcommand = printdeselected) for item in range(i+1): # Add a leaf node to the top level leaf = treeNodeLevel1.addleaf(label = "Item %c"%(item+65), selectcommand = printselected, deselectcommand = printdeselected) treeNodeLevel1 = treeBrowser.addbranch(label = 'Check Button Label', selectcommand = printselected, deselectcommand = printdeselected, expandcommand = printexpanded, collapsecommand = printcollapsed, ) checkButton = Tkinter.Checkbutton(treeNodeLevel1.interior(), text = 'Da Check Button', relief = 'ridge', command = treeNodeLevel1.select) checkButton.pack() treeNodeLevel1.addleaf(label = 'Labeled Leaf', selectcommand = printselected, deselectcommand = printdeselected) leaf = treeNodeLevel1.addleaf(label = 'Labeled Leaf w/ Checkbutton', selectcommand = printselected, deselectcommand = printdeselected) checkButton = Tkinter.Checkbutton(leaf.interior(), text = 'Da Check Button', relief = 'ridge', command = leaf.select) checkButton.pack() treeNodeLevel1 = treeBrowser.addbranch(selectcommand = printselected, deselectcommand = printdeselected, expandcommand = printexpanded, collapsecommand = printcollapsed, ) checkButton = Tkinter.Checkbutton(treeNodeLevel1.interior(), text = 'Check Button with no label', relief = 'ridge', command = treeNodeLevel1.select) checkButton.pack() treeNodeLevel1 = treeBrowser.addbranch(label = 'Label', selectcommand = printselected, deselectcommand = printdeselected, expandcommand = printexpanded, collapsecommand = printcollapsed, ) # setup dynamic tree node insertion and removal class dynTree: def __init__(self): self.dyn = Tkinter.IntVar() self.dtree = None self.dLeaf = treeBrowser.addleaf(selectcommand = self.dynSelected, deselectcommand = self.dynDeselected) self.dCheckButton = Tkinter.Checkbutton(self.dLeaf.interior(), text = 'Enable Dynamic Tree', variable = self.dyn, command = self.ChkBtnHandler) self.dCheckButton.pack() def dynSelected(self, node): self.dCheckButton.configure(background = self.dLeaf.configure('selectbackground')[4]) printselected(node) def dynDeselected(self, node): self.dCheckButton.configure(background = self.dLeaf.configure('background')[4]) printdeselected(node) def ChkBtnHandler(self): self.dLeaf.select() if self.dyn.get() == 1: self.dtree = dynamicTreeRootNode.insertbranch(label = 'Dynamic Tree Node', selectcommand = printselected, deselectcommand = printdeselected, expandcommand = printexpanded, collapsecommand = printcollapsed, before = dynamicTreePosNode) self.dtree.addleaf(label = 'Dynamic Leaf 1', selectcommand = printselected, deselectcommand = printdeselected) self.dtree.addleaf(label = 'Dynamic Leaf 2', selectcommand = printselected, deselectcommand = printdeselected) else: if self.dtree != None: dynamicTreeRootNode.delete(self.dtree) self.dtree = None foo = dynTree() treeBrowser.pack(expand = 1, fill='both') exitButton = Tkinter.Button(rootWin, text="Quit", command=rootWin.quit) exitButton.pack() rootWin.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9231184 Pmw-2.1/Pmw/Pmw_1_3_3/demos/0000775000175000017500000000000000000000000015647 5ustar00gregmgregm00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9151182 Pmw-2.1/Pmw/Pmw_1_3_3/demos/AboutDialog.py0000664000175000017500000000225600000000000020420 0ustar00gregmgregm00000000000000title = 'Pmw.AboutDialog demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): # Create dialog. Pmw.aboutversion('9.9') Pmw.aboutcopyright('Copyright My Company 1999\nAll rights reserved') Pmw.aboutcontact( 'For information about this application contact:\n' + ' My Help Desk\n' + ' Phone: +61 2 9876 5432\n' + ' email: help@my.company.com.au' ) self.about = Pmw.AboutDialog(parent, applicationname = 'My Application') self.about.withdraw() # Create button to launch the dialog. w = Tkinter.Button(parent, text = 'Show about dialog', command = self.execute) w.pack(padx = 8, pady = 8) def execute(self): self.about.show() ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9111183 Pmw-2.1/Pmw/Pmw_1_3_3/demos/All.py0000664000175000017500000002117200000000000016734 0ustar00gregmgregm00000000000000#!/usr/bin/env python # ------------------------------------------------------------------ # Display a splash screen as quickly as possible (before importing # modules and initialising Pmw). import Tkinter root = Tkinter.Tk(className = 'Demo') root.withdraw() splash = Tkinter.Toplevel() splash.withdraw() splash.title('Welcome to the Pmw demos') text = Tkinter.Label(splash, font=('Helvetica', 16, 'bold'), relief = 'raised', borderwidth = 2, padx=50, pady=50, text = 'Welcome to the Pmw megawidgets demo.\n' '\n' 'In a moment the main window will appear.\n' 'Please enjoy yourself while you wait.\n' 'You may be interested to know that splash screens\n' '(as this window is called) were first devised to draw\n' 'attention away from the fact the certain applications\n' 'are slow to start. They are normally flashier and more\n' 'entertaining than this one. This is a budget model.' ) text.pack(fill = 'both', expand = 1) splash.update_idletasks() width = splash.winfo_reqwidth() height = splash.winfo_reqheight() x = (root.winfo_screenwidth() - width) / 2 - root.winfo_vrootx() y = (root.winfo_screenheight() - height) / 3 - root.winfo_vrooty() if x < 0: x = 0 if y < 0: y = 0 geometry = '%dx%d+%d+%d' % (width, height, x, y) splash.geometry(geometry) splash.update_idletasks() splash.deiconify() root.update() # ------------------------------------------------------------------ # Now crank up the application windows. import imp import os import re import string import sys import types import Tkinter import DemoVersion import Args # Find where the other scripts are, so they can be listed. if __name__ == '__main__': script_name = sys.argv[0] else: script_name = imp.find_module('DemoVersion')[1] script_name = os.path.normpath(script_name) script_name = DemoVersion.expandLinks(script_name) script_dir = os.path.dirname(script_name) script_dir = DemoVersion.expandLinks(script_dir) # Add the '../../..' directory to the path. package_dir = os.path.dirname(script_dir) package_dir = DemoVersion.expandLinks(package_dir) package_dir = os.path.dirname(package_dir) package_dir = DemoVersion.expandLinks(package_dir) package_dir = os.path.dirname(package_dir) package_dir = DemoVersion.expandLinks(package_dir) sys.path[:0] = [package_dir] # Import Pmw after modifying sys.path (it may not be in the default path). import Pmw DemoVersion.setPmwVersion() class Demo(Pmw.MegaWidget): def __init__(self, parent=None, **kw): # Define the megawidget options. optiondefs = () self.defineoptions(kw, optiondefs) # Initialise the base class (after defining the options). Pmw.MegaWidget.__init__(self, parent) # Create the contents. top = self.interior() panes = Pmw.PanedWidget(top, orient = 'horizontal') panes.pack(fill = 'both', expand = 1) panes.add('widgetlist') self._widgetlist = Pmw.ScrolledListBox(panes.pane('widgetlist'), selectioncommand = Pmw.busycallback(self.startDemo), label_text = 'Select a widget:', labelpos = 'nw', vscrollmode = 'dynamic', hscrollmode = 'none', listbox_exportselection = 0) self._widgetlist.pack(fill = 'both', expand = 1, padx = 8) panes.add('info') self._status = Tkinter.Label(panes.pane('info')) self._status.pack(padx = 8, anchor = 'w') self._example = Tkinter.Frame(panes.pane('info'), borderwidth = 2, relief = 'sunken', background = 'white') self._example.pack(fill = 'both', expand = 1, padx = 8) self.buttonBox = Pmw.ButtonBox(top) self.buttonBox.pack(fill = 'x') # Add the buttons and make them all the same width. self._traceText = 'Trace tk calls' self._stopTraceText = 'Stop trace' self.buttonBox.add('Trace', text = self._traceText, command = self.trace) self.buttonBox.add('Code', text = 'Show code', command = self.showCode) self.buttonBox.add('Exit', text = 'Exit', command = root.destroy) self.buttonBox.alignbuttons() # Create the window to display the python code. self.codeWindow = Pmw.TextDialog(parent, title = 'Python source', buttons = ('Dismiss',), scrolledtext_labelpos = 'n', label_text = 'Source') self.codeWindow.withdraw() self.codeWindow.insert('end', '') self.demoName = None self._loadDemos() # Check keywords and initialise options. self.initialiseoptions() def startDemo(self): # Import the selected module and create and instance of the module's # Demo class. sels = self._widgetlist.getcurselection() if len(sels) == 0: print 'No demonstrations to display' return demoName = sels[0] # Ignore if this if it is a sub title. if demoName[0] != ' ': self._widgetlist.bell() return # Strip the leading two spaces. demoName = demoName[2:] # Ignore if this demo is already being shown. if self.demoName == demoName: return self.demoName = demoName self.showStatus('Loading ' + demoName) # Busy cursor self.update_idletasks() for window in self._example.winfo_children(): window.destroy() frame = Tkinter.Frame(self._example) frame.pack(expand = 1) exec 'import ' + demoName # Need to keep a reference to the widget, so that variables, etc # are not deleted. self.widget = eval(demoName + '.Demo(frame)') title = eval(demoName + '.title') self.showStatus(title) if self.codeWindow.state() == 'normal': self.insertCode() def showStatus(self, text): self._status.configure(text = text) def showCode(self): if self.codeWindow.state() != 'normal': if self.demoName is None: print 'No demonstration selected' return self.insertCode() self.codeWindow.show() def insertCode(self): self.codeWindow.clear() fileName = os.path.join(script_dir, self.demoName + '.py') self.codeWindow.importfile(fileName) self.codeWindow.configure(label_text = self.demoName + ' source') def trace(self): text = self.buttonBox.component('Trace').cget('text') if text == self._traceText: self.buttonBox.configure(Trace_text = self._stopTraceText) Pmw.tracetk(root, 1) self.showStatus('Trace will appear on standard output') else: self.buttonBox.configure(Trace_text = self._traceText) Pmw.tracetk(root, 0) self.showStatus('Tk call tracing stopped') def _loadDemos(self): files = os.listdir(script_dir) files.sort() megawidgets = [] others = [] for file in files: if re.search('.py$', file) is not None and \ file not in ['All.py', 'DemoVersion.py', 'Args.py']: demoName = file[:-3] index = string.find(demoName, '_') if index < 0: testattr = demoName else: testattr = demoName[:index] if hasattr(Pmw, testattr): megawidgets.append(demoName) else: others.append(demoName) self._widgetlist.insert('end', 'Megawidget demos:') for name in megawidgets: self._widgetlist.insert('end', ' ' + name) self._widgetlist.insert('end', 'Other demos:') for name in others: self._widgetlist.insert('end', ' ' + name) self._widgetlist.select_set(1) class StdOut: def __init__(self, displayCommand): self.displayCommand = displayCommand self.text = '\n' def write(self, text): if self.text[-1] == '\n': self.text = text else: self.text = self.text + text if self.text[-1] == '\n': text = self.text[:-1] else: text = self.text self.displayCommand(text) if os.name == 'nt': defaultFontSize = 16 else: defaultFontSize = 12 commandLineArgSpecs = ( ('fontscheme', 0, 'scheme', 'fonts to use [eg pmw2] (Tk defaults)'), ('fontsize', 0, 'num', 'size of fonts to use with fontscheme', defaultFontSize), ('stdout', 0, Args.Bool, 'print messages rather than display in label'), ) program = 'All.py' msg = Args.parseArgs(program, sys.argv, commandLineArgSpecs, 0) if msg is not None: print msg sys.exit() size = Args.get('fontsize') fontScheme = Args.get('fontscheme') Pmw.initialise(root, size = size, fontScheme = fontScheme, useTkOptionDb = 1) root.title('Pmw ' + Pmw.version() + ' megawidget demonstration') if size < 18: geometry = '800x550' else: geometry = '1000x700' root.geometry(geometry) demo = Demo(root) demo.pack(fill = 'both', expand = 1) demo.focus() # Redirect standard output from demos to status line (unless -stdout # option given on command line). if not Args.get('stdout'): sys.stdout = StdOut(demo.showStatus) # Start the first demo. demo.startDemo() # Get rid of the splash screen root.deiconify() root.update() splash.destroy() root.mainloop() ././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1609332343.907118 Pmw-2.1/Pmw/Pmw_1_3_3/demos/Args.py0000664000175000017500000001230000000000000017111 0ustar00gregmgregm00000000000000"""Handle command line arguments. This module contains functions to parse and access the arguments given to the program on the command line. """ import types import string import sys # Symbolic constants for the indexes into an argument specifier tuple. NAME = 0 MANDATORY = 1 TYPE = 2 HELP = 3 DEFAULT = 4 SPEC_LENGTH = 5 Bool = [] helpSpec = ( ('help', 0, Bool, 'print help and exit'), ) def parseArgs(title, argv, argSpecs, filesOK): """Parse and check command line arguments. Scan the command line arguments in *argv* according to the argument specifier *argSpecs*. Return **None** if there are no errors in the arguments, otherwise return an error string describing the error. This function must be called to initialise this module. title -- The name of the program. This is used when returning error messages or help text. argv -- A sequence containing the arguments given to the program. Normally **sys.argv**. argSpecs -- A sequence of argument specifiers. Each specifier describes a valid command line argument and consists of 4 or 5 items: - The argument name (without a leading minus sign **-**). - A boolean value, true if the argument is mandatory. - This should be **Args.Bool** if the argument has no option. Otherwise it should be a string describing the option required for this argument. This is used when printing help. - A short string describing the argument. - The default value of the argument. This should only be used for non-mandatory arguments expecting an option. For example: ( ('foreground', 0, 'colour', 'colour of text', 'black'), ('geometry', 0, 'spec', 'geometry of initial window'), ('server', 1, 'ompserver', 'ompserver to connect to'), ('silent', 0, Args.Bool, 'do not sound bell'), ) """ global programName global _fileList errMsg = title + ' command line error: ' programName = argv[0]; argSpecs = helpSpec + argSpecs argSpecDic = {} for spec in argSpecs: arg = spec[NAME] argSpecDic[arg] = spec if len(spec) >= SPEC_LENGTH: set(arg, spec[DEFAULT]) elif spec[TYPE] is Bool: set(arg, 0) else: set(arg, None) knownKeys = argSpecDic.keys() i = 1 _fileList = [] argc = len(argv) while i < argc: arg = argv[i] key = arg[1:] if key in knownKeys: spec = argSpecDic[key] if spec[TYPE] is Bool: set(key, 1) else: i = i + 1 if i >= argc: return errMsg + 'missing argument to \'' + arg + '\' option.' value = argv[i] if len(spec) >= SPEC_LENGTH: try: if type(spec[DEFAULT]) == types.IntType: typeStr = 'integer' value = string.atoi(value) elif type(spec[DEFAULT]) == types.FloatType: typeStr = 'float' value = string.atof(value) except: sys.exc_traceback = None # Clean up object references return errMsg + 'cannot convert string \'' + value + \ '\' to ' + typeStr + ' for option \'-' + key + '\'.' set(key, value) else: _fileList.append(arg) i = i + 1 if get('help'): return _helpString(title, argSpecs) if not filesOK and len(_fileList) > 0: if len(_fileList) == 1: return errMsg + 'unknown option \'' + str(_fileList[0]) + '\'.' else: return errMsg + 'unknown options ' + str(_fileList) + '.' _missing = [] for spec in argSpecs: if spec[MANDATORY] and get(spec[NAME]) is None: _missing.append(spec[NAME]) if len(_missing) == 1: return errMsg + 'required argument \'-' + \ str(_missing[0]) + '\' is missing.' elif len(_missing) > 1: return errMsg + 'required arguments ' + \ str(map(lambda s: '-' + s, _missing)) + ' are missing.' return None def fileList(): return _fileList def _helpString(title, argSpecs): max = 0 for spec in argSpecs: if spec[TYPE] is Bool: width = len(spec[NAME]) + 1 else: width = len(spec[NAME]) + 4 + len(spec[TYPE]) if width > max: max = width rtn = title + ' command line arguments:' format = '\n %-' + str(max) + 's %s' for mandatory in (1, 0): needHeader = 1 for spec in argSpecs: if mandatory and spec[MANDATORY] or not mandatory and not spec[MANDATORY]: if needHeader: if mandatory: rtn = rtn + '\n Mandatory arguments:' else: rtn = rtn + '\n Optional arguments (defaults in parentheses):' needHeader = 0 if spec[TYPE] is Bool: arg = '-%s' % spec[NAME] else: arg = '-%s <%s>' % (spec[NAME], spec[TYPE]) if len(spec) >= SPEC_LENGTH: if type(spec[DEFAULT]) == types.StringType: definition = spec[HELP] + ' (' + spec[DEFAULT] + ')' else: definition = spec[HELP] + ' (' + str(spec[DEFAULT]) + ')' else: definition = spec[HELP] rtn = rtn + format % (arg, definition) return rtn def exists(key): return configDict.has_key(key) def get(key): return configDict[key] def set(key, value): global configDict configDict[key] = value configDict = {} ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9111183 Pmw-2.1/Pmw/Pmw_1_3_3/demos/Balloon.py0000664000175000017500000001446400000000000017620 0ustar00gregmgregm00000000000000title = 'Pmw.Balloon demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): # Create the Balloon. self.balloon = Pmw.Balloon(parent) # Create some widgets and megawidgets with balloon help. frame = Tkinter.Frame(parent) frame.pack(padx = 10, pady = 5) field = Pmw.EntryField(frame, labelpos = 'nw', label_text = 'Command:') field.setentry('mycommand -name foo') field.pack(side = 'left', padx = 10) self.balloon.bind(field, 'Command to\nstart/stop', 'Enter the shell command to control') start = Tkinter.Button(frame, text='Start') start.pack(side='left', padx = 10) self.balloon.bind(start, 'Start the command') stop = Tkinter.Button(frame, text='Stop') stop.pack(side='left', padx = 10) self.balloon.bind(stop, 'Stop the command') self.suicide = Tkinter.Button(frame, text='Kill me soon!', command = self.killButton) self.suicide.pack(side='left', padx = 10) self.balloon.bind(self.suicide, 'Watch this button disappear!') scrolledCanvas = Pmw.ScrolledCanvas(parent, canvas_width = 300, canvas_height = 115, ) scrolledCanvas.pack() canvas = scrolledCanvas.component('canvas') self.canvas = canvas # Create some canvas items and individual help. item = canvas.create_arc(5, 5, 35, 35, fill = 'red', extent = 315) self.balloon.tagbind(canvas, item, 'This is help for\nan arc item') item = canvas.create_bitmap(20, 150, bitmap = 'question') self.balloon.tagbind(canvas, item, 'This is help for\na bitmap') item = canvas.create_line(50, 60, 70, 80, 85, 20, width = 5) self.balloon.tagbind(canvas, item, 'This is help for\na line item') item = canvas.create_text(10, 90, text = 'Canvas items with balloons', anchor = 'nw', font = field.cget('entry_font')) self.balloon.tagbind(canvas, item, 'This is help for\na text item') # Create two canvas items which have the same tag and which use # the same help. canvas.create_rectangle(100, 10, 170, 50, fill = 'aliceblue', tags = 'TAG1') self.bluecircle = canvas.create_oval(110, 30, 160, 80, fill = 'blue', tags = 'TAG1') self.balloon.tagbind(canvas, 'TAG1', 'This is help for the two blue items' + '\n' * 10 + 'It is very, very big.', 'This is help for the two blue items') item = canvas.create_text(180, 10, text = 'Delete', anchor = 'nw', font = field.cget('entry_font')) self.balloon.tagbind(canvas, item, 'After 2 seconds,\ndelete the blue circle') canvas.tag_bind(item, '', self._canvasButtonpress) scrolledCanvas.resizescrollregion() scrolledText = Pmw.ScrolledText(parent, text_width = 32, text_height = 4, text_wrap = 'none', ) scrolledText.pack(pady = 5) text = scrolledText.component('text') self.text = text text.insert('end', 'This is a text widget with ', '', ' balloon', 'TAG1', '\nhelp. Find the ', '', ' text ', 'TAG1', ' tagged with', '', ' help.', 'TAG2', '\n', '', 'Remove tag 1.', 'TAG3', '\nAnother line.\nAnd another', '', ) text.tag_configure('TAG1', borderwidth = 2, relief = 'sunken') text.tag_configure('TAG3', borderwidth = 2, relief = 'raised') self.balloon.tagbind(text, 'TAG1', 'There is one secret\nballoon help.\nCan you find it?') self.balloon.tagbind(text, 'TAG2', 'Well done!\nYou found it!') self.balloon.tagbind(text, 'TAG3', 'After 2 seconds\ndelete the tag') text.tag_bind('TAG3', '', self._textButtonpress) frame = Tkinter.Frame(parent) frame.pack(padx = 10) self.toggleBalloonVar = Tkinter.IntVar() self.toggleBalloonVar.set(1) toggle = Tkinter.Checkbutton(frame, variable = self.toggleBalloonVar, text = 'Balloon help', command = self.toggle) toggle.pack(side = 'left', padx = 10) self.balloon.bind(toggle, 'Toggle balloon help\non and off') self.toggleStatusVar = Tkinter.IntVar() self.toggleStatusVar.set(1) toggle = Tkinter.Checkbutton(frame, variable = self.toggleStatusVar, text = 'Status help', command = self.toggle) toggle.pack(side = 'left', padx = 10) self.balloon.bind(toggle, 'Toggle status help on and off, on and off' + '\n' * 10 + 'It is very, very big, too.', 'Toggle status help on and off') # Create and pack the MessageBar. messageBar = Pmw.MessageBar(parent, entry_width = 40, entry_relief='groove', labelpos = 'w', label_text = 'Status:') messageBar.pack(fill = 'x', expand = 1, padx = 10, pady = 5) # Configure the balloon to display its status messages in the # message bar. self.balloon.configure(statuscommand = messageBar.helpmessage) def toggle(self): if self.toggleBalloonVar.get(): if self.toggleStatusVar.get(): self.balloon.configure(state = 'both') else: self.balloon.configure(state = 'balloon') else: if self.toggleStatusVar.get(): self.balloon.configure(state = 'status') else: self.balloon.configure(state = 'none') def killButton(self): # Test for old bug when destroying widgets 1) while the # balloon was up and 2) during the initwait period. print 'Destroying button in 2 seconds' self.suicide.after(2000, self.suicide.destroy) def _canvasButtonpress(self, event): print 'Destroying blue circle in 2 seconds' self.canvas.after(2000, self.deleteBlueCircle) def deleteBlueCircle(self): self.balloon.tagunbind(self.canvas, self.bluecircle) self.canvas.delete(self.bluecircle) def _textButtonpress(self, event): print 'Deleting the text tag in 2 seconds' self.text.after(2000, self.deleteTextTag) def deleteTextTag(self): self.balloon.tagunbind(self.text, 'TAG1') self.text.tag_delete('TAG1') ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root, 12, fontScheme = 'default') root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9151182 Pmw-2.1/Pmw/Pmw_1_3_3/demos/BltGraph.py0000664000175000017500000001617500000000000017736 0ustar00gregmgregm00000000000000title = 'Blt Graph demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import string import Tkinter import Pmw # Simple random number generator. rand = 12345 def random(): global rand rand = (rand * 125) % 2796203 return rand class GraphDemo(Pmw.MegaToplevel): def __init__(self, parent=None, **kw): # Define the megawidget options. optiondefs = ( ('size', 10, Pmw.INITOPT), ) self.defineoptions(kw, optiondefs) # Initialise the base class (after defining the options). Pmw.MegaToplevel.__init__(self, parent) # Create the graph. self.createWidgets() # Check keywords and initialise options. self.initialiseoptions() def createWidgets(self): # Create vectors for use as x and y data points. self._numElements = 7 self._vectorSize = self['size'] self._vector_x = Pmw.Blt.Vector() self._vector_y = [] for y in range(self._numElements): self._vector_y.append(Pmw.Blt.Vector()) for index in range(self._vectorSize): self._vector_x.append(index) for y in range(self._numElements): self._vector_y[y].append(random() % 100) interior = self.interior() controlFrame = Tkinter.Frame(interior) controlFrame.pack(side = 'bottom', fill = 'x', expand = 0) # Create an option menu for the kind of elements to create. elementtype = Pmw.OptionMenu(controlFrame, labelpos = 'nw', label_text = 'Element type', items = ['bars', 'lines', 'mixed', 'none'], command = self._setelementtype, menubutton_width = 8, ) elementtype.pack(side = 'left') # Create an option menu for the barmode option. barmode = Pmw.OptionMenu(controlFrame, labelpos = 'nw', label_text = 'Bar mode', items = ['normal', 'stacked', 'aligned', 'overlap'], command = self._setbarmode, menubutton_width = 8, ) barmode.pack(side = 'left') # Create an option menu for the smooth option. self.smooth = Pmw.OptionMenu(controlFrame, labelpos = 'nw', label_text = 'Smooth', items = ['linear', 'step', 'natural', 'quadratic'], command = self._setsmooth, menubutton_width = 9, ) self.smooth.pack(side = 'left') # Create an option menu to reverse sort the elements. sortelements = Pmw.OptionMenu(controlFrame, labelpos = 'nw', label_text = 'Order', items = ['normal', 'reverse'], command = self._setsortelements, menubutton_width = 8, ) sortelements.pack(side = 'left') # Create an option menu for the bufferelements option. bufferelements = Pmw.OptionMenu(controlFrame, labelpos = 'nw', label_text = 'Buffering', items = ['buffered', 'unbuffered'], command = self._setbufferelements, menubutton_width = 10, ) bufferelements.pack(side = 'left') # Create a button to add a point to the vector. addpoint = Tkinter.Button(controlFrame, text = 'Add point', command = Pmw.busycallback(self._addpoint)) addpoint.pack(side = 'left', fill = 'x', expand = 0) # Create a button to close the window close = Tkinter.Button(controlFrame, text = 'Close', command = Pmw.busycallback(self.destroy)) close.pack(side = 'left', fill = 'x', expand = 0) # Create the graph and its elements. self._graph = Pmw.Blt.Graph(interior) self._graph.pack(expand = 1, fill = 'both') self._graph.yaxis_configure(command=self.yaxisCommand) elementtype.invoke('mixed') bufferelements.invoke('buffered') def yaxisCommand(self, graph, value): try: num = string.atoi(value) return '%d %3d' % (num * 3, num) except ValueError: num = string.atof(value) return '%g %3g' % (num * 3, num) def _setelementtype(self, type): elements = self._graph.element_names() apply(self._graph.element_delete, elements) if type == 'none': return colorList = Pmw.Color.spectrum(self._numElements) for elem in range(self._numElements): if elem == 0: hue = None else: hue = (elem + 1.0) / self._numElements * 6.28318 foreground = colorList[elem] background = Pmw.Color.changebrightness(self, foreground, 0.8) if type == 'mixed': if elem < self._numElements / 2: bar = 0 else: bar = 1 elif type == 'bars': bar = 1 else: bar = 0 if bar: self._graph.bar_create( 'var' + str(elem), xdata=self._vector_x, ydata=self._vector_y[elem], foreground = foreground, background = background) else: self._graph.line_create( 'var' + str(elem), linewidth = 4, xdata=self._vector_x, ydata=self._vector_y[elem], smooth = self.smooth.getcurselection(), color = foreground) def _setbarmode(self, tag): self._graph.configure(barmode = tag) def _setsmooth(self, tag): for element in self._graph.element_show(): if self._graph.element_type(element) == 'line': self._graph.element_configure(element, smooth = tag) def _setbufferelements(self, tag): self._graph.configure(bufferelements = (tag == 'buffered')) def _setsortelements(self, tag): element_list = list(self._graph.element_show()) if len(element_list) > 1: if (tag == 'normal') == (element_list[-1] != 'var0'): element_list.reverse() self._graph.element_show(element_list) def _addpoint(self): self._vector_x.append(self._vectorSize) for y in range(self._numElements): self._vector_y[y].append(random() % 100) self._vectorSize = self._vectorSize + 1 class Demo: def __init__(self, parent): if not Pmw.Blt.haveblt(parent): message = 'Sorry\nThe BLT package has not been\n' + \ 'installed on this system.\n' + \ 'Please install it and try again.' w = Tkinter.Label(parent, text = message) w.pack(padx = 8, pady = 8) return message = 'This is a simple demonstration of the\n' + \ 'BLT graph widget.\n' + \ 'Select the number of points to display and\n' + \ 'click on the button to display the graph.' w = Tkinter.Label(parent, text = message) w.pack(padx = 8, pady = 8) # Create combobox to select number of points to display. self.combo = Pmw.ComboBox(parent, scrolledlist_items = ('10', '25', '50', '100', '300'), entryfield_value = '10') self.combo.pack(padx = 8, pady = 8) # Create button to start blt graph. start = Tkinter.Button(parent, text = 'Show BLT graph', command = Pmw.busycallback(self.showGraphDemo)) start.pack(padx = 8, pady = 8) self.parent = parent def showGraphDemo(self): size = string.atoi(self.combo.get()) demo = GraphDemo(self.parent, size = size) demo.focus() ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9111183 Pmw-2.1/Pmw/Pmw_1_3_3/demos/BltTabset.py0000664000175000017500000000675400000000000020121 0ustar00gregmgregm00000000000000title = 'Blt Tabset demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): if not Pmw.Blt.haveblt(parent): message = 'Sorry\nThe BLT package has not been\n' + \ 'installed on this system.\n' + \ 'Please install it and try again.' w = Tkinter.Label(parent, text = message) w.pack(padx = 8, pady = 8) return self.tabset = Pmw.Blt.Tabset(parent, borderwidth = 0, highlightthickness = 0, selectpad = 0, tiers = 2, ) background = self.tabset.cget('background') self.tabset.configure(selectbackground = background, tabbackground = background, activebackground = background) configurePanel = Tkinter.Frame(self.tabset) sideMenu = Pmw.OptionMenu (configurePanel, labelpos = 'w', label_text = 'Side:', items = ('top', 'bottom', 'left', 'right'), menubutton_width = 10, command = self.changeSide, ) sideMenu.pack(anchor = 'w', padx = 10, pady = 10) rotateMenu = Pmw.ComboBox(configurePanel, labelpos = 'w', label_text = 'Text rotation:', entryfield_validate = 'integer', entry_width = 8, selectioncommand = self.rotateText, scrolledlist_items = (0, 45, 90, 135, 180, 225, 270, 315), ) rotateMenu.pack(side = 'left', padx = 10, pady = 10) rotateMenu.selectitem(0) self.rotateText('0') self.appearancePanel = Tkinter.Label(self.tabset) helpersPanel = Tkinter.Button(self.tabset, text = 'This is a lot\nof help!') self.tabset.insert('end', 'Appearance', 'Configure', 'Helpers', 'Images') self.tabset.tab_configure('Appearance', command = self.appearance_cb, fill = 'both') self.tabset.tab_configure('Configure', window = configurePanel) self.tabset.tab_configure('Images', command = self.images_cb, fill = 'both') self.tabset.tab_configure('Helpers', window = helpersPanel, padx = 100, pady = 150) self.tabset.invoke(1) self.tabset.pack(fill = 'both', expand = 1, padx = 5, pady = 5) self.tabset.focus() def appearance_cb(self): self.appearancePanel.configure( text = 'Don\'t judge a book\nby it\'s cover.') self.tabset.tab_configure('Appearance', window = self.appearancePanel) def images_cb(self): self.appearancePanel.configure(text = 'Beauty is only\nskin deep.') self.tabset.tab_configure('Images', window = self.appearancePanel) def changeSide(self, side): self.tabset.configure(side = side) def rotateText(self, angle): if Pmw.integervalidator(angle) == Pmw.OK: self.tabset.configure(rotate = angle) else: self.tabset.bell() ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1609332343.907118 Pmw-2.1/Pmw/Pmw_1_3_3/demos/ButtonBox.py0000664000175000017500000000300100000000000020137 0ustar00gregmgregm00000000000000title = 'Pmw.ButtonBox demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): # Create and pack the ButtonBox. self.buttonBox = Pmw.ButtonBox(parent, labelpos = 'nw', label_text = 'ButtonBox:', frame_borderwidth = 2, frame_relief = 'groove') self.buttonBox.pack(fill = 'both', expand = 1, padx = 10, pady = 10) # Add some buttons to the ButtonBox. self.buttonBox.add('OK', command = self.ok) self.buttonBox.add('Apply', command = self.apply) self.buttonBox.add('Cancel', command = self.cancel) # Set the default button (the one executed when is hit). self.buttonBox.setdefault('OK') parent.bind('', self._processReturnKey) parent.focus_set() # Make all the buttons the same width. self.buttonBox.alignbuttons() def _processReturnKey(self, event): self.buttonBox.invoke() def ok(self): print 'You clicked on OK' def apply(self): print 'You clicked on Apply' def cancel(self): print 'You clicked on Cancel' ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9111183 Pmw-2.1/Pmw/Pmw_1_3_3/demos/Colors.py0000664000175000017500000000312500000000000017463 0ustar00gregmgregm00000000000000title = 'Colorscheme demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): frame = Tkinter.Frame(parent) frame.pack(fill = 'both', expand = 1) defaultPalette = Pmw.Color.getdefaultpalette(parent) colors = ('red', 'green', 'blue') items = ('Testing', 'More testing', 'a test', 'foo', 'blah') for count in range(len(colors)): color = colors[count] normalcolor = Pmw.Color.changebrightness(parent, color, 0.85) Pmw.Color.setscheme(parent, normalcolor) combo = Pmw.ComboBox(frame, scrolledlist_items = items, entryfield_value = items[0]) combo.grid(sticky='nsew', row = count, column = 0) normalcolor = Pmw.Color.changebrightness(parent, color, 0.35) Pmw.Color.setscheme(parent, normalcolor, foreground = 'white') combo = Pmw.ComboBox(frame, scrolledlist_items = items, entryfield_value = items[0]) combo.grid(sticky='nsew', row = count, column = 1) apply(Pmw.Color.setscheme, (parent,), defaultPalette) #normalcolor = Pmw.Color.changebrightness(parent, 'red', 0.85) #Pmw.Color.setscheme(parent, normalcolor) ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9151182 Pmw-2.1/Pmw/Pmw_1_3_3/demos/ComboBox.py0000664000175000017500000000441600000000000017736 0ustar00gregmgregm00000000000000title = 'Pmw.ComboBox demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): parent.configure(background = 'white') # Create and pack the widget to be configured. self.target = Tkinter.Label(parent, relief = 'sunken', padx = 20, pady = 20, ) self.target.pack(fill = 'x', padx = 8, pady = 8) # Create and pack the simple ComboBox. words = ('Monti', 'Python', 'ik', 'den', 'Holie', 'Grailen', '(Bok)') simple = Pmw.ComboBox(parent, label_text = 'Simple ComboBox:', labelpos = 'nw', selectioncommand = self.changeText, scrolledlist_items = words, dropdown = 0, ) simple.pack(side = 'left', fill = 'both', expand = 1, padx = 8, pady = 8) # Display the first text. first = words[0] simple.selectitem(first) self.changeText(first) # Create and pack the dropdown ComboBox. colours = ('cornsilk1', 'snow1', 'seashell1', 'antiquewhite1', 'bisque1', 'peachpuff1', 'navajowhite1', 'lemonchiffon1', 'ivory1', 'honeydew1', 'lavenderblush1', 'mistyrose1') dropdown = Pmw.ComboBox(parent, label_text = 'Dropdown ComboBox:', labelpos = 'nw', selectioncommand = self.changeColour, scrolledlist_items = colours, ) dropdown.pack(side = 'left', anchor = 'n', fill = 'x', expand = 1, padx = 8, pady = 8) # Display the first colour. first = colours[0] dropdown.selectitem(first) self.changeColour(first) def changeColour(self, colour): print 'Colour: ' + colour self.target.configure(background = colour) def changeText(self, text): print 'Text: ' + text self.target.configure(text = text) ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9111183 Pmw-2.1/Pmw/Pmw_1_3_3/demos/ComboBoxDialog.py0000664000175000017500000000226700000000000021060 0ustar00gregmgregm00000000000000title = 'Pmw.ComboBoxDialog demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): # Create the dialog. self.dialog = Pmw.ComboBoxDialog(parent, title = 'My ComboBoxDialog', buttons = ('OK', 'Cancel'), defaultbutton = 'OK', combobox_labelpos = 'n', label_text = 'What do you think of Pmw?', scrolledlist_items = ('Cool man', 'Cool', 'Good', 'Bad', 'Gross')) self.dialog.withdraw() # Create button to launch the dialog. w = Tkinter.Button(parent, text = 'Show combo box dialog', command = self.doit) w.pack(padx = 8, pady = 8) def doit(self): result = self.dialog.activate() print 'You clicked on', result, self.dialog.get() ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9111183 Pmw-2.1/Pmw/Pmw_1_3_3/demos/ConfigClass.py0000664000175000017500000000374300000000000020423 0ustar00gregmgregm00000000000000title = 'Component python class configuration demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class MyButton(Tkinter.Button): # This is just an ordinary button with special colors. def __init__(self, master=None, cnf={}, **kw): self.__toggle = 0 kw['background'] = 'green' kw['activebackground'] = 'red' apply(Tkinter.Button.__init__, (self, master, cnf), kw) class Demo: def __init__(self, parent): # Create a title label: label = Tkinter.Label(parent, text = 'EntryFields with label components of specified type:') label.pack(fill='x', expand=1, padx=10, pady=5) # Create and pack some EntryFields. entries = [] entry = Pmw.EntryField(parent, labelpos = 'w', label_text = 'Label' ) entry.pack(fill='x', expand=1, padx=10, pady=5) entries.append(entry) entry = Pmw.EntryField(parent, labelpos = 'w', label_pyclass = Tkinter.Button, label_text = 'Button' ) entry.pack(fill='x', expand=1, padx=10, pady=5) entries.append(entry) entry = Pmw.EntryField(parent, labelpos = 'w', label_pyclass = MyButton, label_text = 'Special button' ) entry.pack(fill='x', expand=1, padx=10, pady=5) entries.append(entry) Pmw.alignlabels(entries) # Create and pack a ButtonBox. buttonBox = Pmw.ButtonBox(parent, labelpos = 'nw', label_text = 'ButtonBox:') buttonBox.pack(fill = 'both', expand = 1, padx=10, pady=5) # Add some buttons to the ButtonBox. buttonBox.add('with a') buttonBox.add('special', pyclass = MyButton) buttonBox.add('button') ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9111183 Pmw-2.1/Pmw/Pmw_1_3_3/demos/Counter.py0000664000175000017500000000732200000000000017644 0ustar00gregmgregm00000000000000title = 'Pmw.Counter demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import string import time import Tkinter import Pmw class Demo: def __init__(self, parent): # Need to use long ints here because on the Macintosh the maximum size # of an integer is smaller than the value returned by time.time(). now = (long(time.time()) / 300) * 300 # Create the Counters. self._date = Pmw.Counter(parent, labelpos = 'w', label_text = 'Date (4-digit year):', entryfield_value = time.strftime('%d/%m/%Y', time.localtime(now)), entryfield_command = self.execute, entryfield_validate = {'validator' : 'date', 'format' : 'dmy'}, datatype = {'counter' : 'date', 'format' : 'dmy', 'yyyy' : 1}) self._isodate = Pmw.Counter(parent, labelpos = 'w', label_text = 'ISO-Date (4-digit year):', entryfield_value = time.strftime('%Y-%m-%d', time.localtime(now)), entryfield_command = self.execute, entryfield_validate = {'validator' : 'date', 'format' : 'ymd', 'separator' : '-' }, datatype = {'counter' : 'date', 'format' : 'ymd', 'yyyy' : 1, 'separator' : '-' }) self._time = Pmw.Counter(parent, labelpos = 'w', label_text = 'Time:', entryfield_value = time.strftime('%H:%M:%S', time.localtime(now)), entryfield_validate = {'validator' : 'time', 'min' : '00:00:00', 'max' : '23:59:59', 'minstrict' : 0, 'maxstrict' : 0}, datatype = {'counter' : 'time', 'time24' : 1}, increment=5*60) self._real = Pmw.Counter(parent, labelpos = 'w', label_text = 'Real (with comma)\nand extra\nlabel lines:', label_justify = 'left', entryfield_value = '1,5', datatype = {'counter' : 'real', 'separator' : ','}, entryfield_validate = {'validator' : 'real', 'min' : '-2,0', 'max' : '5,0', 'separator' : ','}, increment = 0.1) self._custom = Pmw.Counter(parent, labelpos = 'w', label_text = 'Custom:', entryfield_value = specialword[:4], datatype = _custom_counter, entryfield_validate = _custom_validate) self._int = Pmw.Counter(parent, labelpos = 'w', label_text = 'Vertical integer:', orient = 'vertical', entry_width = 2, entryfield_value = 50, entryfield_validate = {'validator' : 'integer', 'min' : 0, 'max' : 99} ) counters = (self._date, self._isodate, self._time, self._real, self._custom) Pmw.alignlabels(counters) # Pack them all. for counter in counters: counter.pack(fill='both', expand=1, padx=10, pady=5) self._int.pack(padx=10, pady=5) def execute(self): print 'Return pressed, value is', self._date.get() specialword = 'Monti Python ik den Holie Grailen (Bok)' def _custom_validate(text): if string.find(specialword, text) == 0: return 1 else: return -1 def _custom_counter(text, factor, increment): # increment is ignored here. if string.find(specialword, text) == 0: length = len(text) if factor == 1: if length >= len(specialword): raise ValueError, 'maximum length reached' return specialword[:length + 1] else: if length == 0: raise ValueError, 'empty string' return specialword[:length - 1] else: raise ValueError, 'bad string ' + text ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9151182 Pmw-2.1/Pmw/Pmw_1_3_3/demos/CounterDialog.py0000664000175000017500000000335000000000000020761 0ustar00gregmgregm00000000000000title = 'Pmw.CounterDialog demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import string import Tkinter import Pmw class Demo: def __init__(self, parent): # Create the dialog to prompt for the number of times to ring the bell. self.dialog = Pmw.CounterDialog(parent, label_text = 'Enter the number of times to\n' + \ 'sound the bell (1 to 5)\n', counter_labelpos = 'n', entryfield_value = 2, counter_datatype = 'numeric', entryfield_validate = {'validator' : 'numeric', 'min' : 1, 'max' : 5}, buttons = ('OK', 'Cancel'), defaultbutton = 'OK', title = 'Bell ringing', command = self.execute) self.dialog.withdraw() # Create button to launch the dialog. w = Tkinter.Button(parent, text = 'Show counter dialog', command = self.dialog.activate) w.pack(padx = 8, pady = 8) def execute(self, result): if result is None or result == 'Cancel': print 'Bell ringing cancelled' self.dialog.deactivate() else: count = self.dialog.get() if not self.dialog.valid(): print 'Invalid entry: "' + count + '"' else: print 'Ringing the bell ' + count + ' times' for num in range(string.atoi(count)): if num != 0: self.dialog.after(200) self.dialog.bell() self.dialog.deactivate() ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9111183 Pmw-2.1/Pmw/Pmw_1_3_3/demos/DemoVersion.py0000664000175000017500000000161700000000000020460 0ustar00gregmgregm00000000000000# Set the version of Pmw to use for the demonstrations based on the # directory name. import imp import os import string def expandLinks(path): if not os.path.isabs(path): path = os.path.join(os.getcwd(), path) while 1: if not os.path.islink(path): break dir = os.path.dirname(path) path = os.path.join(dir, os.readlink(path)) return path def setPmwVersion(): file = imp.find_module(__name__)[1] file = os.path.normpath(file) file = expandLinks(file) dir = os.path.dirname(file) dir = expandLinks(dir) dir = os.path.dirname(dir) dir = expandLinks(dir) dir = os.path.basename(dir) version = string.replace(dir[4:], '_', '.') import Pmw if version in Pmw.installedversions(): Pmw.setversion(version) else: print 'No such Pmw version', `version` + '.', print 'Using default version', `Pmw.version()` ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9111183 Pmw-2.1/Pmw/Pmw_1_3_3/demos/Dialog.py0000664000175000017500000000535000000000000017423 0ustar00gregmgregm00000000000000title = 'Pmw.Dialog demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): # Create two buttons to launch the dialog. w = Tkinter.Button(parent, text = 'Show application modal dialog', command = self.showAppModal) w.pack(padx = 8, pady = 8) w = Tkinter.Button(parent, text = 'Show global modal dialog', command = self.showGlobalModal) w.pack(padx = 8, pady = 8) w = Tkinter.Button(parent, text = 'Show dialog with "no grab"', command = self.showDialogNoGrab) w.pack(padx = 8, pady = 8) w = Tkinter.Button(parent, text = 'Show toplevel window which\n' + 'will not get a busy cursor', command = self.showExcludedWindow) w.pack(padx = 8, pady = 8) # Create the dialog. self.dialog = Pmw.Dialog(parent, buttons = ('OK', 'Apply', 'Cancel', 'Help'), defaultbutton = 'OK', title = 'My dialog', command = self.execute) self.dialog.withdraw() # Add some contents to the dialog. w = Tkinter.Label(self.dialog.interior(), text = 'Pmw Dialog\n(put your widgets here)', background = 'black', foreground = 'white', pady = 20) w.pack(expand = 1, fill = 'both', padx = 4, pady = 4) # Create the window excluded from showbusycursor. self.excluded = Pmw.MessageDialog(parent, title = 'I still work', message_text = 'This window will not get\n' + 'a busy cursor when modal dialogs\n' + 'are activated. In addition,\n' + 'you can still interact with\n' + 'this window when a "no grab"\n' + 'modal dialog is displayed.') self.excluded.withdraw() Pmw.setbusycursorattributes(self.excluded.component('hull'), exclude = 1) def showAppModal(self): self.dialog.activate(geometry = 'centerscreenalways') def showGlobalModal(self): self.dialog.activate(globalMode = 1) def showDialogNoGrab(self): self.dialog.activate(globalMode = 'nograb') def showExcludedWindow(self): self.excluded.show() def execute(self, result): print 'You clicked on', result if result not in ('Apply', 'Help'): self.dialog.deactivate(result) ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9111183 Pmw-2.1/Pmw/Pmw_1_3_3/demos/EntryField.py0000664000175000017500000000526000000000000020271 0ustar00gregmgregm00000000000000title = 'Pmw.EntryField demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import time import Tkinter import Pmw class Demo: def __init__(self, parent): # Create and pack the EntryFields. self._any = Pmw.EntryField(parent, labelpos = 'w', label_text = 'Any:', validate = None, command = self.execute) self._real = Pmw.EntryField(parent, labelpos = 'w', value = '55.5', label_text = 'Real (10.0 to 99.0):', validate = {'validator' : 'real', 'min' : 10, 'max' : 99, 'minstrict' : 0}, modifiedcommand = self.changed) self._odd = Pmw.EntryField(parent, labelpos = 'w', label_text = 'Odd length:', validate = self.custom_validate, value = 'ABC') self._date = Pmw.EntryField(parent, labelpos = 'w', label_text = 'Date (in 2000):', value = '2000/2/29', validate = {'validator' : 'date', 'min' : '2000/1/1', 'max' : '2000/12/31', 'minstrict' : 0, 'maxstrict' : 0, 'format' : 'ymd'}, ) now = time.localtime(time.time()) self._date2 = Pmw.EntryField(parent, labelpos = 'w', label_text = 'Date (d.m.y):', value = '%d.%d.%d' % (now[2], now[1], now[0]), validate = {'validator' : 'date', 'format' : 'dmy', 'separator' : '.'}, ) self._time = Pmw.EntryField(parent, labelpos = 'w', label_text = 'Time (24hr clock):', value = '8:00:00', validate = {'validator' : 'time', 'min' : '00:00:00', 'max' : '23:59:59', 'minstrict' : 0, 'maxstrict' : 0}, ) self._comma = Pmw.EntryField(parent, labelpos = 'w', label_text = 'Real (with comma):', value = '123,456', validate = {'validator' : 'real', 'separator' : ','}, ) entries = (self._any, self._real, self._odd, self._date, self._date2, self._time, self._comma) for entry in entries: entry.pack(fill='x', expand=1, padx=10, pady=5) Pmw.alignlabels(entries) self._any.component('entry').focus_set() def changed(self): print 'Text changed, value is', self._real.getvalue() def execute(self): print 'Return pressed, value is', self._any.getvalue() # This implements a custom validation routine. It simply checks # if the string is of odd length. def custom_validate(self, text): print 'text:', text if len(text) % 2 == 0: return -1 else: return 1 ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9151182 Pmw-2.1/Pmw/Pmw_1_3_3/demos/ErrorHandling.py0000664000175000017500000000221200000000000020754 0ustar00gregmgregm00000000000000title = 'Pmw error handling demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import string import Tkinter import Pmw class Demo: def __init__(self, parent): # Create two buttons to generate errors. w = Tkinter.Button(parent, text = 'Click here to generate\n' + 'an error in a command callback.', command = self.execute) w.pack(padx = 8, pady = 8) w = Tkinter.Button(parent, text = 'Click here to generate\n' + 'an error in a callback called\nfrom an event binding.') w.pack(padx = 8, pady = 8) w.bind('', self.execute) w.bind('', self.execute) def execute(self, event = None): self._error() def _error(self): # Divide by zero 1/0 ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9111183 Pmw-2.1/Pmw/Pmw_1_3_3/demos/ExampleDemo.py0000664000175000017500000000145700000000000020430 0ustar00gregmgregm00000000000000title = 'Pmw.EXAMPLE demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): # Create and pack the EXAMPLEs. self.widget1 = Pmw.Counter(parent) self.widget1.setentry('1') self.widget1.pack() self.widget2 = Pmw.Counter(parent, increment = 10) self.widget2.setentry('100') self.widget2.pack() ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9111183 Pmw-2.1/Pmw/Pmw_1_3_3/demos/Grid.py0000664000175000017500000000252600000000000017113 0ustar00gregmgregm00000000000000title = 'Grid geometry manager demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): frame = Tkinter.Frame(parent) frame.pack(fill = 'both', expand = 1) button = {} for num in range(0, 10): button[num] = Tkinter.Button(frame, text = 'Button ' + str(num)) button[0].grid(column=0, row=0, rowspan=2, sticky='nsew') button[1].grid(column=1, row=0, columnspan=3, sticky='nsew') button[2].grid(column=1, row=1, rowspan=2, sticky='nsew') button[3].grid(column=2, row=1) button[4].grid(column=3, row=1) button[5].grid(column=0, row=2) button[6].grid(column=0, row=3, columnspan=2, sticky='nsew') button[7].grid(column=2, row=2, columnspan=2, rowspan=2, sticky='nsew') button[8].grid(column=0, row=4) button[9].grid(column=3, row=4, sticky='e') frame.grid_rowconfigure(3, weight=1) frame.grid_columnconfigure(3, weight=1) ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9111183 Pmw-2.1/Pmw/Pmw_1_3_3/demos/Group.py0000664000175000017500000000565600000000000017331 0ustar00gregmgregm00000000000000title = 'Pmw.Group demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): # Create and pack the Groups. w = Pmw.Group(parent, tag_text='label') w.pack(fill = 'both', expand = 1, padx = 6, pady = 6) cw = Tkinter.Label(w.interior(), text = 'A group with the\ndefault Label tag') cw.pack(padx = 2, pady = 2, expand='yes', fill='both') w = Pmw.Group(parent, tag_pyclass = None) w.pack(fill = 'both', expand = 1, padx = 6, pady = 6) cw = Tkinter.Label(w.interior(), text = 'A group\nwithout a tag') cw.pack(padx = 2, pady = 2, expand='yes', fill='both') radiogroups = [] self.var = Tkinter.IntVar() self.var.set(0) radioframe = Tkinter.Frame(parent) w = Pmw.Group(radioframe, tag_pyclass = Tkinter.Radiobutton, tag_text='radiobutton 1', tag_value = 0, tag_variable = self.var) w.pack(fill = 'both', expand = 1, side='left') cw = Tkinter.Frame(w.interior(),width=200,height=20) cw.pack(padx = 2, pady = 2, expand='yes', fill='both') radiogroups.append(w) w = Pmw.Group(radioframe, tag_pyclass = Tkinter.Radiobutton, tag_text='radiobutton 2', tag_font = Pmw.logicalfont('Helvetica', 4), tag_value = 1, tag_variable = self.var) w.pack(fill = 'both', expand = 1, side='left') cw = Tkinter.Frame(w.interior(),width=200,height=20) cw.pack(padx = 2, pady = 2, expand='yes', fill='both') radiogroups.append(w) radioframe.pack(padx = 6, pady = 6, expand='yes', fill='both') Pmw.aligngrouptags(radiogroups) w = Pmw.Group(parent, tag_pyclass = Tkinter.Checkbutton, tag_text='checkbutton', tag_foreground='blue') w.pack(fill = 'both', expand = 1, padx = 6, pady = 6) cw = Tkinter.Frame(w.interior(),width=150,height=20) cw.pack(padx = 2, pady = 2, expand='yes', fill='both') w = Pmw.Group(parent, tag_pyclass = Tkinter.Button, tag_text='Tkinter.Button') w.configure(tag_command = w.toggle) w.pack(fill = 'both', expand = 1, padx = 6, pady = 6) cw = Tkinter.Label(w.interior(), background = 'aliceblue', text = 'A group with\na Button tag!?' ) cw.pack(padx = 2, pady = 2, expand='yes', fill='both') w = Pmw.Group(parent, tag_pyclass = Tkinter.Button, tag_text='Show/Hide') w.configure(tag_command = w.toggle) w.pack(fill = 'both', expand = 1, padx = 6, pady = 6) cw = Tkinter.Label(w.interior(), background = 'aliceblue', text = 'Now you see me.\nNow you don\'t.' ) cw.pack(padx = 2, pady = 2, expand='yes', fill='both') ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9151182 Pmw-2.1/Pmw/Pmw_1_3_3/demos/HistoryText.py0000664000175000017500000000670300000000000020535 0ustar00gregmgregm00000000000000title = 'Pmw.HistoryText demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): # Create and pack the PanedWidget to hold the query and result # windows. # !! panedwidget should automatically size to requested size panedWidget = Pmw.PanedWidget(parent, orient = 'vertical', hull_height = 400, hull_width = 550) panedWidget.add('query', min = 0.05, size = 0.2) panedWidget.add('buttons', min = 0.1, max = 0.1) panedWidget.add('results', min = 0.05) panedWidget.pack(fill = 'both', expand = 1) # Create and pack the HistoryText. self.historyText = Pmw.HistoryText(panedWidget.pane('query'), text_wrap = 'none', text_width = 60, text_height = 10, historycommand = self.statechange, ) self.historyText.pack(fill = 'both', expand = 1) self.historyText.component('text').focus() buttonList = ( [20, None], ['Clear', self.clear], ['Undo', self.historyText.undo], ['Redo', self.historyText.redo], [20, None], ['Prev', self.historyText.prev], ['Next', self.historyText.next], [30, None], ['Execute', Pmw.busycallback(self.executeQuery)], ) self.buttonDict = {} buttonFrame = panedWidget.pane('buttons') for text, cmd in buttonList: if type(text) == type(69): frame = Tkinter.Frame(buttonFrame, width = text) frame.pack(side = 'left') else: button = Tkinter.Button(buttonFrame, text = text, command = cmd) button.pack(side = 'left') self.buttonDict[text] = button for text in ('Prev', 'Next'): self.buttonDict[text].configure(state = 'disabled') self.results = Pmw.ScrolledText(panedWidget.pane('results'), text_wrap = 'none') self.results.pack(fill = 'both', expand = 1) def statechange(self, prevstate, nextstate): self.buttonDict['Prev'].configure(state = prevstate) self.buttonDict['Next'].configure(state = nextstate) def clear(self): self.historyText.delete('1.0', 'end') def addnewlines(self, text): if len(text) == 1: text = text + '\n' if text[-1] != '\n': text = text + '\n' if text[-2] != '\n': text = text + '\n' return text def executeQuery(self): sql = self.historyText.get() self.results.insert('end', 'Query:\n' + self.addnewlines(sql)) self.results.see('end') self.results.update_idletasks() self.historyText.addhistory() results = 'Results:\nfoo' if len(results) > 0: self.results.insert('end', self.addnewlines(results)) self.results.see('end') ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9151182 Pmw-2.1/Pmw/Pmw_1_3_3/demos/LabeledWidget.py0000664000175000017500000000242000000000000020713 0ustar00gregmgregm00000000000000title = 'Pmw.LabeledWidget demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): # Create a frame to put the LabeledWidgets into frame = Tkinter.Frame(parent, background = 'grey90') frame.pack(fill = 'both', expand = 1) # Create and pack the LabeledWidgets. column = 0 row = 0 for pos in ('n', 'nw', 'wn', 'w'): lw = Pmw.LabeledWidget(frame, labelpos = pos, label_text = pos + ' label') lw.component('hull').configure(relief='sunken', borderwidth=2) lw.grid(column=column, row=row, padx=10, pady=10) cw = Tkinter.Button(lw.interior(), text='child\nsite') cw.pack(padx=10, pady=10, expand='yes', fill='both') # Get ready for next grid position. column = column + 1 if column == 2: column = 0 row = row + 1 ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) widget = Demo(root) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack() root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9111183 Pmw-2.1/Pmw/Pmw_1_3_3/demos/LogicalFont.py0000664000175000017500000000522600000000000020427 0ustar00gregmgregm00000000000000title = 'Pmw LogicalFont demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import string import Tkinter import Pmw class Demo: # The fonts to demonstrate. fontList = ( (('Times', 0), {}), (('Helvetica', 0), {}), (('Typewriter', 0), {}), (('Fixed', 0), {}), (('Courier', 0), {}), (('Helvetica', 2), {'slant' : 'italic'}), (('Helvetica', 0), {'size' : 18}), (('Helvetica', 0), {'weight' : 'bold'}), (('Helvetica', 12), {'weight' : 'bold', 'slant' : 'italic'}), (('Typewriter', 0), {'size' : 8, 'weight' : 'bold'}), (('Fixed', 0), {'size' : 8, 'weight' : 'bold'}), (('Times', 0), {'size' : 24, 'weight' : 'bold', 'slant' : 'italic'}), (('Typewriter', 0), {'width' : 'condensed'}), (('Typewriter', -1), {'width' : 'condensed'}), (('Fixed', 0), {'width' : 'condensed'}), (('Fixed', -1), {'width' : 'condensed'}), (('Helvetica', 0), {'weight' : 'bogus'}), ) fontText = [] def __init__(self, parent): self.parent = parent # Create the text to display to the user to represent each font. if Demo.fontText == []: for args, dict in Demo.fontList: text = args[0] if args[1] != 0: text = text + ' ' + str(args[1]) for name, value in dict.items(): text = text + ' ' + name + ': ' + str(value) Demo.fontText.append(text) # Create a listbox to contain the font selections. self.box = Pmw.ScrolledListBox(parent, listbox_selectmode='single', listbox_width = 35, listbox_height = 10, items=Demo.fontText, label_text='Font', labelpos='nw', selectioncommand=self.selectionCommand) self.box.pack(fill = 'both', expand = 1, padx = 10, pady = 10) # Create a label to display the selected font. self.target = Tkinter.Label(parent, text = 'The quick brown fox jumps\nover the lazy dog', relief = 'sunken', padx = 10, pady = 10) self.target.pack(fill = 'both', expand = 1, padx = 10, pady = 10) def selectionCommand(self): sel = self.box.curselection() if len(sel) > 0: args, dict = Demo.fontList[string.atoi(sel[0])] font = apply(Pmw.logicalfont, args, dict) self.target.configure(font = font) print font ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9151182 Pmw-2.1/Pmw/Pmw_1_3_3/demos/MainMenuBar.py0000664000175000017500000001325400000000000020364 0ustar00gregmgregm00000000000000title = 'Pmw.MainMenuBar demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): # Create button to launch the toplevel with main menubar. w = Tkinter.Button(parent, text = 'Show Pmw.MainMenuBar demo', command = lambda parent=parent: MainMenuBarToplevel(parent)) w.pack(padx = 8, pady = 8) class MainMenuBarToplevel: def __init__(self, parent): # Create the toplevel to contain the main menubar. megaToplevel = Pmw.MegaToplevel(parent, title = title) toplevel = megaToplevel.interior() # Create the Balloon for this toplevel. self.balloon = Pmw.Balloon(toplevel) # Create and install the MenuBar. menuBar = Pmw.MainMenuBar(toplevel, balloon = self.balloon) toplevel.configure(menu = menuBar) self.menuBar = menuBar # Add some buttons to the MainMenuBar. menuBar.addmenu('File', 'Close this window or exit') menuBar.addmenuitem('File', 'command', 'Close this window', command = PrintOne('Action: close'), label = 'Close') menuBar.addmenuitem('File', 'separator') menuBar.addmenuitem('File', 'command', 'Exit the application', command = PrintOne('Action: exit'), label = 'Exit') menuBar.addmenu('Edit', 'Cut, copy or paste') menuBar.addmenuitem('Edit', 'command', 'Delete the current selection', command = PrintOne('Action: delete'), label = 'Delete') menuBar.addmenu('Options', 'Set user preferences') menuBar.addmenuitem('Options', 'command', 'Set general preferences', command = PrintOne('Action: general options'), label = 'General...') # Create a checkbutton menu item. self.toggleVar = Tkinter.IntVar() # Initialise the checkbutton to 1: self.toggleVar.set(1) menuBar.addmenuitem('Options', 'checkbutton', 'Toggle me on/off', label = 'Toggle', command = self._toggleMe, variable = self.toggleVar) self._toggleMe() menuBar.addcascademenu('Options', 'Size', 'Set some other preferences', traverseSpec = 'z', tearoff = 1) for size in ('tiny', 'small', 'average', 'big', 'huge'): menuBar.addmenuitem('Size', 'command', 'Set size to ' + size, command = PrintOne('Action: size ' + size), label = size) menuBar.addmenu('Help', 'User manuals', name = 'help') menuBar.addmenuitem('Help', 'command', 'About this application', command = PrintOne('Action: about'), label = 'About...') # Create and pack the main part of the window. self.mainPart = Tkinter.Label(toplevel, text = 'This is the\nmain part of\nthe window', background = 'black', foreground = 'white', padx = 30, pady = 30) self.mainPart.pack(fill = 'both', expand = 1) # Create and pack the MessageBar. self.messageBar = Pmw.MessageBar(toplevel, entry_width = 40, entry_relief='groove', labelpos = 'w', label_text = 'Status:') self.messageBar.pack(fill = 'x', padx = 10, pady = 10) self.messageBar.message('state', 'Balloon/status help not working properly - Tk menubar bug') buttonBox = Pmw.ButtonBox(toplevel) buttonBox.pack(fill = 'x') buttonBox.add('Disable\nall', command = menuBar.disableall) buttonBox.add('Enable\nall', command = menuBar.enableall) buttonBox.add('Create\nmenu', command = self.add) buttonBox.add('Delete\nmenu', command = self.delete) buttonBox.add('Create\nitem', command = self.additem) buttonBox.add('Delete\nitem', command = self.deleteitem) # Configure the balloon to displays its status messages in the # message bar. self.balloon.configure(statuscommand = self.messageBar.helpmessage) self.testMenuList = [] def _toggleMe(self): print 'Toggle value:', self.toggleVar.get() def add(self): if len(self.testMenuList) == 0: num = 0 else: num = self.testMenuList[-1] num = num + 1 name = 'Menu%d' % num self.testMenuList.append(num) self.menuBar.addmenu(name, 'This is ' + name) def delete(self): if len(self.testMenuList) == 0: self.menuBar.bell() else: num = self.testMenuList[0] name = 'Menu%d' % num del self.testMenuList[0] self.menuBar.deletemenu(name) def additem(self): if len(self.testMenuList) == 0: self.menuBar.bell() else: num = self.testMenuList[-1] menuName = 'Menu%d' % num menu = self.menuBar.component(menuName) if menu.index('end') is None: label = 'item X' else: label = menu.entrycget('end', 'label') + 'X' self.menuBar.addmenuitem(menuName, 'command', 'Help for ' + label, command = PrintOne('Action: ' + menuName + ': ' + label), label = label) def deleteitem(self): if len(self.testMenuList) == 0: self.menuBar.bell() else: num = self.testMenuList[-1] menuName = 'Menu%d' % num menu = self.menuBar.component(menuName) if menu.index('end') is None: self.menuBar.bell() else: self.menuBar.deletemenuitems(menuName, 0) class PrintOne: def __init__(self, text): self.text = text def __call__(self): print self.text ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9191184 Pmw-2.1/Pmw/Pmw_1_3_3/demos/MenuBar.py0000664000175000017500000001224400000000000017555 0ustar00gregmgregm00000000000000title = 'Pmw.MenuBar demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): # Create the Balloon. self.balloon = Pmw.Balloon(parent) # Create and pack the MenuBar. menuBar = Pmw.MenuBar(parent, hull_relief = 'raised', hull_borderwidth = 1, balloon = self.balloon) menuBar.pack(fill = 'x') self.menuBar = menuBar # Add some buttons to the MenuBar. menuBar.addmenu('File', 'Close this window or exit') menuBar.addmenuitem('File', 'command', 'Close this window', command = PrintOne('Action: close'), label = 'Close') menuBar.addmenuitem('File', 'separator') menuBar.addmenuitem('File', 'command', 'Exit the application', command = PrintOne('Action: exit'), label = 'Exit') menuBar.addmenu('Edit', 'Cut, copy or paste') menuBar.addmenuitem('Edit', 'command', 'Delete the current selection', command = PrintOne('Action: delete'), label = 'Delete') menuBar.addmenu('Options', 'Set user preferences') menuBar.addmenuitem('Options', 'command', 'Set general preferences', command = PrintOne('Action: general options'), label = 'General...') # Create a checkbutton menu item. self.toggleVar = Tkinter.IntVar() # Initialise the checkbutton to 1: self.toggleVar.set(1) menuBar.addmenuitem('Options', 'checkbutton', 'Toggle me on/off', label = 'Toggle', command = self._toggleMe, variable = self.toggleVar) self._toggleMe() menuBar.addcascademenu('Options', 'Size', 'Set some other preferences', traverseSpec = 'z', tearoff = 1) for size in ('tiny', 'small', 'average', 'big', 'huge'): menuBar.addmenuitem('Size', 'command', 'Set size to ' + size, command = PrintOne('Action: size ' + size), label = size) menuBar.addmenu('Help', 'User manuals', side = 'right') menuBar.addmenuitem('Help', 'command', 'About this application', command = PrintOne('Action: about'), label = 'About...') # Create and pack the main part of the window. self.mainPart = Tkinter.Label(parent, text = 'This is the\nmain part of\nthe window', background = 'black', foreground = 'white', padx = 30, pady = 30) self.mainPart.pack(fill = 'both', expand = 1) # Create and pack the MessageBar. self.messageBar = Pmw.MessageBar(parent, entry_width = 40, entry_relief='groove', labelpos = 'w', label_text = 'Status:') self.messageBar.pack(fill = 'x', padx = 10, pady = 10) self.messageBar.message('state', 'OK') buttonBox = Pmw.ButtonBox(parent) buttonBox.pack(fill = 'x') buttonBox.add('Disable\nall', command = menuBar.disableall) buttonBox.add('Enable\nall', command = menuBar.enableall) buttonBox.add('Create\nmenu', command = self.add) buttonBox.add('Delete\nmenu', command = self.delete) buttonBox.add('Create\nitem', command = self.additem) buttonBox.add('Delete\nitem', command = self.deleteitem) # Configure the balloon to displays its status messages in the # message bar. self.balloon.configure(statuscommand = self.messageBar.helpmessage) self.testMenuList = [] def _toggleMe(self): print 'Toggle value:', self.toggleVar.get() def add(self): if len(self.testMenuList) == 0: num = 0 else: num = self.testMenuList[-1] num = num + 1 name = 'Menu%d' % num self.testMenuList.append(num) self.menuBar.addmenu(name, 'This is ' + name) def delete(self): if len(self.testMenuList) == 0: self.menuBar.bell() else: num = self.testMenuList[0] name = 'Menu%d' % num del self.testMenuList[0] self.menuBar.deletemenu(name) def additem(self): if len(self.testMenuList) == 0: self.menuBar.bell() else: num = self.testMenuList[-1] menuName = 'Menu%d' % num menu = self.menuBar.component(menuName + '-menu') if menu.index('end') is None: label = 'item X' else: label = menu.entrycget('end', 'label') + 'X' self.menuBar.addmenuitem(menuName, 'command', 'Help for ' + label, command = PrintOne('Action: ' + menuName + ': ' + label), label = label) def deleteitem(self): if len(self.testMenuList) == 0: self.menuBar.bell() else: num = self.testMenuList[-1] menuName = 'Menu%d' % num menu = self.menuBar.component(menuName + '-menu') if menu.index('end') is None: self.menuBar.bell() else: self.menuBar.deletemenuitems(menuName, 0) class PrintOne: def __init__(self, text): self.text = text def __call__(self): print self.text ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9151182 Pmw-2.1/Pmw/Pmw_1_3_3/demos/MessageBar.py0000664000175000017500000000473100000000000020237 0ustar00gregmgregm00000000000000title = 'Pmw.MessageBar demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): # Create and pack the MessageBar. self._messagebar = Pmw.MessageBar(parent, entry_width = 40, entry_relief='groove', labelpos = 'w', label_text = 'Status:') self._messagebar.pack(side = 'bottom', fill = 'x', expand = 1, padx = 10, pady = 10) # Create and pack the ScrolledListBox to change the MessageBar. self.box = Pmw.ScrolledListBox(parent, listbox_selectmode='single', items=('state', 'help', 'userevent', 'systemevent', 'usererror', 'systemerror', 'busy',), label_text='Message type', labelpos='n', selectioncommand=self.selectionCommand) self.box.pack(fill = 'both', expand = 'yes', padx = 10, pady = 10) self._index = 0 self._stateCounter = 0 def selectionCommand(self): sels = self.box.getcurselection() if len(sels) > 0: self._index = self._index + 1 messagetype = sels[0] if messagetype == 'state': self._stateCounter = (self._stateCounter + 1) % 3 text = stateMessages[self._stateCounter] if text != '': text = text + ' (' + messagetype + ')' self._messagebar.message('state', text) else: text = messages[messagetype] text = text + ' (' + messagetype + ')' self._messagebar.message(messagetype, text) if messagetype == 'busy': Pmw.showbusycursor() self.box.after(2000) Pmw.hidebusycursor() self._messagebar.resetmessages('busy') text = 'All files successfully removed' text = text + ' (userevent)' self._messagebar.message('userevent', text) messages = { 'help': 'Save current file', 'userevent': 'Saving file "foo"', 'busy': 'Busy deleting all files from file system ...', 'systemevent': 'File "foo" saved', 'usererror': 'Invalid file name "foo/bar"', 'systemerror': 'Failed to save file: file system full', } stateMessages = { 0: '', 1: 'Database is down', 2: 'Waiting for reply from database', } ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9111183 Pmw-2.1/Pmw/Pmw_1_3_3/demos/MessageDialog.py0000664000175000017500000000603300000000000020727 0ustar00gregmgregm00000000000000title = 'Pmw.MessageDialog demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): self.parent = parent # Create dialog 1. self.dialog1 = Pmw.MessageDialog(parent, title = 'Simple message dialog', defaultbutton = 0, message_text = 'A simple message dialog\nwith no callback.') self.dialog1.iconname('Simple message dialog') self.dialog1.withdraw() # Create dialog 2. self.dialog2 = Pmw.MessageDialog(parent, title = 'Bell ringing dialog', message_text = 'This message dialog\nwill ring the bell ' + 'when\nyou click on the buttons.', iconpos = 'w', icon_bitmap = 'error', command = self.execute2, buttons = ('One', 'Two', 'Three', 'Close')) self.dialog2.iconname('Bell ringing dialog') self.dialog2.withdraw() # Create dialog 3. self.dialog3 = Pmw.MessageDialog(parent, title = 'Vertical button dialog', message_text = 'This message dialog\nhas the buttons on the\n' + 'right hand side.', buttonboxpos = 'e', iconpos = 'n', icon_bitmap = 'warning', buttons = ('Goodbye', 'Au revoir', 'Sayonara', 'Close'), defaultbutton = 'Close') self.dialog3.iconname('Vertical button dialog') self.dialog3.withdraw() # Create some buttons to launch the dialogs. w = Tkinter.Button(parent, text = 'Simple dialog', command = lambda self = self: self.dialog1.activate(geometry = 'first+100+100')) w.pack(padx = 8, pady = 8) w = Tkinter.Button(parent, text = 'Bell ringing dialog', command = self.dialog2.activate) w.pack(padx = 8, pady = 8) w = Tkinter.Button(parent, text = 'Vertical buttons', command = self.dialog3.activate) w.pack(padx = 8, pady = 8) w = Tkinter.Button(parent, text = 'On the fly dialog', command = self._createOnTheFly) w.pack(padx = 8, pady = 8) def execute2(self, result): print 'You clicked on', result if result is None: self.dialog2.deactivate(result) elif result == 'Close': self.dialog2.deactivate(result) else: for count in range({'One': 1, 'Two': 2, 'Three': 3}[result]): if count != 0: self.dialog2.after(200) self.dialog2.bell() def _createOnTheFly(self): dialog = Pmw.MessageDialog(self.parent, title = 'On the fly dialog', defaultbutton = 0, buttons = ('OK', 'Apply', 'Cancel', 'Help'), message_text = 'This dialog was created when you clicked ' + 'on the button.') dialog.iconname('Simple message dialog') result = dialog.activate() print 'You selected', result ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9151182 Pmw-2.1/Pmw/Pmw_1_3_3/demos/MessageInfo.py0000664000175000017500000000566000000000000020430 0ustar00gregmgregm00000000000000title = 'Pmw toplevel megawidget demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class MessageInfo(Pmw.MegaToplevel): # Demo Pmw toplevel megawidget. def __init__(self, parent=None, **kw): # Define the megawidget options. optiondefs = () self.defineoptions(kw, optiondefs) # Initialise the base class (after defining the options). Pmw.MegaToplevel.__init__(self, parent) # Create the components. interior = self.interior() self._dismiss = self.createcomponent('dismiss', (), None, Tkinter.Button, (interior,), text = 'Dismiss', command = self.goodbye) self._dismiss.pack(side = 'bottom', pady = 4) self._separator = self.createcomponent('separator', (), None, Tkinter.Frame, (interior,), height = 2, borderwidth = 1, relief = 'sunken') self._separator.pack(side = 'bottom', fill = 'x', pady = 4) self._icon = self.createcomponent('icon', (), None, Tkinter.Label, (interior,)) self._icon.pack(side = 'left', padx = 8, pady = 8) self._infoFrame = self.createcomponent('infoframe', (), None, Tkinter.Frame, (interior,)) self._infoFrame.pack( side = 'left', fill = 'both', expand = 1, padx = 4, pady = 4) self._message = self.createcomponent('message', (), None, Tkinter.Label, (interior,)) self._message.pack(expand = 1, fill = 'both', padx = 10, pady = 10) self.bind('', self.goodbye) # Check keywords and initialise options. self.initialiseoptions() def goodbye(self, event = None): self.destroy() class Demo: def __init__(self, parent): # Create button to launch the megawidget. self.button = Tkinter.Button(parent, command = self.showMessageInfo, text = 'Show toplevel megawidget') self.button.pack(padx = 8, pady = 8) self.count = 0 self.parent = parent def showMessageInfo(self): bitmaps = ('warning', 'hourglass', 'error', 'info', 'gray25', 'gray50', 'question', 'questhead') bitmap = bitmaps[self.count % len(bitmaps)] message = 'This is a demonstration of\na megawidget.\n' + \ 'It contains a configurable\nmessage area and bitmap.\n' + \ 'This instance is displaying\nthe "' + bitmap + '" bitmap.' # Make the toplevel window a child of this window, so that it # is destroyed when the demo is destroyed. MessageInfo(self.parent, message_text = message, icon_bitmap = bitmap) self.count = self.count + 1 if self.count == 1: self.button.configure(text = 'Show another\ntoplevel megawidget') ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9191184 Pmw-2.1/Pmw/Pmw_1_3_3/demos/MultiLineLabel.py0000664000175000017500000000435500000000000021072 0ustar00gregmgregm00000000000000title = 'Multi-line label demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import string import Tkinter import Pmw class Demo: def __init__(self, parent): frame = Tkinter.Frame(parent, background = '#eeeeee') frame.pack(fill = 'both', expand = 1, padx = 5, pady = 5) stickys = ('n', 's', 'e', 'w', 'ns', 'ew', 'ne', 'nw', 'se', 'sw', 'nsw', 'nse', 'new', 'sew', 'nsew',) widgets = [] row = 0 column = 0 # Choose one megawidget class to demonstrate: cls = Pmw.EntryField # cls = Pmw.Counter # cls = Pmw.ComboBox # cls = Pmw.LabeledWidget # cls = Pmw.MessageBar for sticky in stickys: dict = {} dict['sticky'] = sticky dict['labelpos'] = 'w' dict['label_text'] = '1\n' + sticky + ':\n3' if cls == Pmw.EntryField: dict['value'] = sticky dict['entry_width'] = 6 if cls == Pmw.Counter or cls == Pmw.ComboBox: dict['entryfield_value'] = sticky dict['entry_width'] = 6 widget = apply(cls, (frame,), dict) if cls == Pmw.LabeledWidget: f = Tkinter.Button(widget.interior(), text = sticky) f.pack(fill = 'both', expand = 1) if cls == Pmw.MessageBar: widget.message('state', sticky) widget.grid(column=column, row=row, sticky='ew', padx = 10, pady = 5) frame.grid_columnconfigure(column, weight=1) frame.grid_rowconfigure(row, weight=1) widgets.append(widget) if row < 4: row = row + 1 else: row = 0 column = column + 1 Pmw.alignlabels(widgets, sticky = 'e') ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9151182 Pmw-2.1/Pmw/Pmw_1_3_3/demos/NestedDialogs.py0000664000175000017500000000370700000000000020755 0ustar00gregmgregm00000000000000title = 'Modal dialog nesting demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): # Create button to launch the dialog. w = Tkinter.Button(parent, text = 'Show first dialog', command = self.showFirstDialog) w.pack(padx = 8, pady = 8) self.timerId = None self.dialog1 = Pmw.MessageDialog(parent, message_text = 'This is the first modal dialog.\n' + 'You can see how dialogs nest by\n' + 'clicking on the "Next" button.', title = 'Dialog 1', buttons = ('Next', 'Cancel'), defaultbutton = 'Next', command = self.next_dialog) self.dialog1.withdraw() self.dialog2 = Pmw.Dialog(self.dialog1.interior(), title = 'Dialog 2', buttons = ('Cancel',), deactivatecommand = self.cancelTimer, defaultbutton = 'Cancel') self.dialog2.withdraw() w = Tkinter.Label(self.dialog2.interior(), text = 'This is the second modal dialog.\n' + 'It will automatically disappear shortly') w.pack(padx = 10, pady = 10) def showFirstDialog(self): self.dialog1.activate() def cancelTimer(self): if self.timerId is not None: self.dialog2.after_cancel(self.timerId) self.timerId = None def deactivateSecond(self): self.timerId = None self.dialog2.deactivate() def next_dialog(self, result): if result != 'Next': self.dialog1.deactivate() return self.timerId = self.dialog2.after(3000, self.deactivateSecond) self.dialog2.activate() ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9111183 Pmw-2.1/Pmw/Pmw_1_3_3/demos/NoteBook.py0000664000175000017500000000335300000000000017745 0ustar00gregmgregm00000000000000title = 'Pmw.NoteBook demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): # Create and pack the NoteBook. notebook = Pmw.NoteBook(parent) notebook.pack(fill = 'both', expand = 1, padx = 10, pady = 10) # Add the "Appearance" page to the notebook. page = notebook.add('Appearance') notebook.tab('Appearance').focus_set() # Create the "Toolbar" contents of the page. group = Pmw.Group(page, tag_text = 'Toolbar') group.pack(fill = 'both', expand = 1, padx = 10, pady = 10) b1 = Tkinter.Checkbutton(group.interior(), text = 'Show toolbar') b1.grid(row = 0, column = 0) b2 = Tkinter.Checkbutton(group.interior(), text = 'Toolbar tips') b2.grid(row = 0, column = 1) # Create the "Startup" contents of the page. group = Pmw.Group(page, tag_text = 'Startup') group.pack(fill = 'both', expand = 1, padx = 10, pady = 10) home = Pmw.EntryField(group.interior(), labelpos = 'w', label_text = 'Home page location:') home.pack(fill = 'x', padx = 20, pady = 10) # Add two more empty pages. page = notebook.add('Helpers') page = notebook.add('Images') notebook.setnaturalsize() ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) widget = Demo(root) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack() root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9151182 Pmw-2.1/Pmw/Pmw_1_3_3/demos/NoteBook_2.py0000664000175000017500000002057600000000000020174 0ustar00gregmgregm00000000000000title = 'Pmw.NoteBook demonstration (more complex)' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent, withTabs = 1): # Repeat random number sequence for each run. self.rand = 12345 # Default demo is to display a tabbed notebook. self.withTabs = withTabs # Create a frame to put everything in self.mainframe = Tkinter.Frame(parent) self.mainframe.pack(fill = 'both', expand = 1) # Find current default colors button = Tkinter.Button() defaultbg = button.cget('background') defaultfg = button.cget('foreground') button.destroy() # Create the list of colors to cycle through self.colorList = [] self.colorList.append((defaultbg, defaultfg)) self.colorIndex = 0 for color in Pmw.Color.spectrum(6, 1.5, 1.0, 1.0, 1): bg = Pmw.Color.changebrightness(self.mainframe, color, 0.85) self.colorList.append((bg, 'black')) bg = Pmw.Color.changebrightness(self.mainframe, color, 0.55) self.colorList.append((bg, 'white')) # Set the color to the current default Pmw.Color.changecolor(self.mainframe, defaultbg, foreground = defaultfg) defaultPalette = Pmw.Color.getdefaultpalette(self.mainframe) Pmw.Color.setscheme(self.mainframe, defaultbg, foreground = defaultfg) # Create the notebook, but don't pack it yet. if self.withTabs: tabpos = 'n' else: tabpos = None self.notebook = Pmw.NoteBook(self.mainframe, tabpos = tabpos, createcommand = PrintOne('Create'), lowercommand = PrintOne('Lower'), raisecommand = PrintOne('Raise'), hull_width = 300, hull_height = 200, ) # Create a buttonbox to configure the notebook and pack it first. buttonbox = Pmw.ButtonBox(self.mainframe) buttonbox.pack(side = 'bottom', fill = 'x') # Add some buttons to the buttonbox to configure the notebook. buttonbox.add('Insert\npage', command = self.insertpage) buttonbox.add('Delete\npage', command = self.deletepage) buttonbox.add('Add\nbutton', command = self.addbutton) buttonbox.add('Change\ncolor', command = self.changecolor) buttonbox.add('Natural\nsize', command = self.notebook.setnaturalsize) if not self.withTabs: # Create the selection widget to select the page in the notebook. self.optionmenu = Pmw.OptionMenu(self.mainframe, menubutton_width = 10, command = self.notebook.selectpage ) self.optionmenu.pack(side = 'left', padx = 10) # Pack the notebook last so that the buttonbox does not disappear # when the window is made smaller. self.notebook.pack(fill = 'both', expand = 1, padx = 5, pady = 5) # Populate some pages of the notebook. page = self.notebook.add('tmp') self.notebook.delete('tmp') page = self.notebook.add('Appearance') if self.withTabs: self.notebook.tab('Appearance').focus_set() button = Tkinter.Button(page, text = 'Welcome\nto\nthe\nAppearance\npage') button.pack(expand = 1) page = self.notebook.add('Fonts') button = Tkinter.Button(page, text = 'This is a very very very very wide Fonts page') button.pack(expand = 1) page = self.notebook.insert('Applications', before = 'Fonts') button = Tkinter.Button(page, text = 'This is the Applications page') button.pack(expand = 1) # Initialise the first page and the initial colour. if not self.withTabs: self.optionmenu.setitems(self.notebook.pagenames()) apply(Pmw.Color.setscheme, (self.mainframe,), defaultPalette) self.pageCounter = 0 def insertpage(self): # Create a page at a random position defaultPalette = Pmw.Color.getdefaultpalette(self.mainframe) bg, fg = self.colorList[self.colorIndex] Pmw.Color.setscheme(self.mainframe, bg, foreground = fg) self.pageCounter = self.pageCounter + 1 before = self.randomchoice(self.notebook.pagenames() + [Pmw.END]) pageName = 'page%d' % self.pageCounter if self.pageCounter % 5 == 0: tab_text = pageName + '\nline two' else: tab_text = pageName classes = (None, Tkinter.Button, Tkinter.Label, Tkinter.Checkbutton) cls = self.randomchoice((None,) + classes) if cls is None: print 'Adding', pageName, 'as a frame with a button' if self.withTabs: page = self.notebook.insert(pageName, before, tab_text = tab_text) else: page = self.notebook.insert(pageName, before) button = Tkinter.Button(page, text = 'This is button %d' % self.pageCounter) button.pack(expand = 1) else: print 'Adding', pageName, 'using', cls if self.withTabs: page = self.notebook.insert(pageName, before, tab_text = tab_text, page_pyclass = cls, page_text = 'This is a page using\na %s' % str(cls) ) else: page = self.notebook.insert(pageName, before, page_pyclass = cls, page_text = 'This is a page using\na %s' % str(cls) ) if not self.withTabs: self.optionmenu.setitems( self.notebook.pagenames(), self.notebook.getcurselection()) apply(Pmw.Color.setscheme, (self.mainframe,), defaultPalette) def addbutton(self): # Add a button to a random page. defaultPalette = Pmw.Color.getdefaultpalette(self.mainframe) bg, fg = self.colorList[self.colorIndex] Pmw.Color.setscheme(self.mainframe, bg, foreground = fg) framePages = [] for pageName in self.notebook.pagenames(): page = self.notebook.page(pageName) if page.__class__ == Tkinter.Frame: framePages.append(pageName) if len(framePages) == 0: self.notebook.bell() return pageName = self.randomchoice(framePages) print 'Adding extra button to', pageName page = self.notebook.page(pageName) button = Tkinter.Button(page, text = 'This is an extra button') button.pack(expand = 1) apply(Pmw.Color.setscheme, (self.mainframe,), defaultPalette) def deletepage(self): # Delete a random page pageNames = self.notebook.pagenames() if len(pageNames) == 0: self.notebook.bell() return pageName = self.randomchoice(pageNames) print 'Deleting', pageName self.notebook.delete(pageName) if not self.withTabs: self.optionmenu.setitems( self.notebook.pagenames(), self.notebook.getcurselection()) def changecolor(self): self.colorIndex = self.colorIndex + 1 if self.colorIndex == len(self.colorList): self.colorIndex = 0 bg, fg = self.colorList[self.colorIndex] print 'Changing color to', bg Pmw.Color.changecolor(self.mainframe, bg, foreground = fg) self.notebook.recolorborders() # Simple random number generator. def randomchoice(self, selection): num = len(selection) self.rand = (self.rand * 125) % 2796203 index = self.rand % num return selection[index] class PrintOne: def __init__(self, text): self.text = text def __call__(self, text): print self.text, text ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) widget = Demo(root) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack() root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9191184 Pmw-2.1/Pmw/Pmw_1_3_3/demos/NoteBook_3.py0000664000175000017500000000121000000000000020155 0ustar00gregmgregm00000000000000title = 'Pmw.NoteBook demonstration (with no tabs)' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw # Reuse the NoteBook with tabs demo. import NoteBook_2 class Demo(NoteBook_2.Demo): def __init__(self, parent): NoteBook_2.Demo.__init__(self, parent, withTabs = 0) # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) widget = Demo(root) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack() root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9151182 Pmw-2.1/Pmw/Pmw_1_3_3/demos/OptionMenu.py0000664000175000017500000000377100000000000020326 0ustar00gregmgregm00000000000000title = 'Pmw.OptionMenu demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): # Create and pack the OptionMenu megawidgets. # The first one has a textvariable. self.var = Tkinter.StringVar() self.var.set('steamed') self.method_menu = Pmw.OptionMenu(parent, labelpos = 'w', label_text = 'Choose method:', menubutton_textvariable = self.var, items = ['baked', 'steamed', 'stir fried', 'boiled', 'raw'], menubutton_width = 10, ) self.method_menu.pack(anchor = 'w', padx = 10, pady = 10) self.vege_menu = Pmw.OptionMenu (parent, labelpos = 'w', label_text = 'Choose vegetable:', items = ('broccoli', 'peas', 'carrots', 'pumpkin'), menubutton_width = 10, command = self._printOrder, ) self.vege_menu.pack(anchor = 'w', padx = 10, pady = 10) self.direction_menu = Pmw.OptionMenu (parent, labelpos = 'w', label_text = 'Menu direction:', items = ('flush', 'above', 'below', 'left', 'right'), menubutton_width = 10, command = self._changeDirection, ) self.direction_menu.pack(anchor = 'w', padx = 10, pady = 10) menus = (self.method_menu, self.vege_menu, self.direction_menu) Pmw.alignlabels(menus) def _printOrder(self, vege): # Can use 'self.var.get()' instead of 'getcurselection()'. print 'You have chosen %s %s.' % \ (self.method_menu.getcurselection(), vege) def _changeDirection(self, direction): for menu in (self.method_menu, self.vege_menu, self.direction_menu): menu.configure(menubutton_direction = direction) ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9151182 Pmw-2.1/Pmw/Pmw_1_3_3/demos/PanedWidget.py0000664000175000017500000000654600000000000020427 0ustar00gregmgregm00000000000000title = 'Pmw.PanedWidget demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): # Create a main PanedWidget with a few panes. self.pw = Pmw.PanedWidget(parent, orient='vertical', hull_borderwidth = 1, hull_relief = 'sunken', hull_width=300, hull_height=400) for self.numPanes in range(4): if self.numPanes == 1: name = 'Fixed size' pane = self.pw.add(name, min = .1, max = .1) else: name = 'Pane ' + str(self.numPanes) pane = self.pw.add(name, min = .1, size = .25) label = Tkinter.Label(pane, text = name) label.pack(side = 'left', expand = 1) button = Tkinter.Button(pane, text = 'Delete', command = lambda s=self, n=name: s.deletePane(n)) button.pack(side = 'left', expand = 1) # TODO: add buttons to invoke self.moveOneUp and self.moveOneUp. self.pw.pack(expand = 1, fill='both') buttonBox = Pmw.ButtonBox(parent) buttonBox.pack(fill = 'x') buttonBox.add('Add pane', command = self.addPane) buttonBox.add('Move pane', command = self.move) self.moveSrc = 0 self.moveNewPos = 1 self.moveBack = 0 def move(self): numPanes = len(self.pw.panes()) if numPanes == 0: print 'No panes to move!' return if self.moveSrc >= numPanes: self.moveSrc = numPanes - 1 if self.moveNewPos >= numPanes: self.moveNewPos = numPanes - 1 print 'Moving pane', self.moveSrc, 'to new position', self.moveNewPos self.pw.move(self.moveSrc, self.moveNewPos) self.moveSrc, self.moveNewPos = self.moveNewPos, self.moveSrc if self.moveBack: if self.moveNewPos == numPanes - 1: self.moveNewPos = 0 if self.moveSrc == numPanes - 1: self.moveSrc = 0 else: self.moveSrc = self.moveSrc + 1 else: self.moveNewPos = self.moveNewPos + 1 self.moveBack = not self.moveBack def addPane(self): self.numPanes = self.numPanes + 1 name = 'Pane ' + str(self.numPanes) print 'Adding', name pane = self.pw.add(name, min = .1, size = .25) label = Tkinter.Label(pane, text = name) label.pack(side = 'left', expand = 1) button = Tkinter.Button(pane, text = 'Delete', command = lambda s=self, n=name: s.deletePane(n)) button.pack(side = 'left', expand = 1) self.pw.updatelayout() def deletePane(self, name): print 'Deleting', name self.pw.delete(name) self.pw.updatelayout() def moveOneUp(self, name): self.pw.move(name, name, -1) def moveOneDown(self, name): self.pw.move(name, name, 1) ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9151182 Pmw-2.1/Pmw/Pmw_1_3_3/demos/PanedWidget_2.py0000664000175000017500000000351700000000000020643 0ustar00gregmgregm00000000000000title = 'Pmw.PanedWidget demonstration (pane factory)' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): self.paneCount = 0 # Create a "pane factory". label = Tkinter.Label(parent, pady = 10, text = 'Below is a simple "pane factory".\n' + 'Drag the handle on the left\nto create new panes.') label.pack() self.factory = Pmw.PanedWidget(parent, orient='horizontal', command = self.resize, hull_borderwidth = 1, hull_relief = 'raised', hull_width=300, hull_height=200 ) self.factory.add('starter', size = 0.0) self.factory.add('main') button = Tkinter.Button(self.factory.pane('main'), text = 'Pane\n0') button.pack(expand = 1) self.factory.pack(expand = 1, fill = 'both') def resize(self, list): # Remove any panes less than 2 pixel wide. for i in range(len(list) - 1, 0, -1): if list[i] < 2: self.factory.delete(i) # If the user has dragged the left hand handle, create a new pane. if list[0] > 1: self.paneCount = self.paneCount + 1 # Add a button to the new pane. name = self.factory.panes()[0] text = 'Pane\n' + str(self.paneCount) button = Tkinter.Button(self.factory.pane(name), text = text) button.pack(expand = 1) # Create a new starter pane. name = 'Pane ' + str(self.paneCount) self.factory.insert(name, size=0.0) ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9191184 Pmw-2.1/Pmw/Pmw_1_3_3/demos/PromptDialog.py0000664000175000017500000000354100000000000020625 0ustar00gregmgregm00000000000000title = 'Pmw.PromptDialog demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw # This may demonstrate a bug in Tk. Click on Cancel in the confirm # dialog and then click on OK in the password dialog. Under Solaris # 2.5 and python 1.5, the Cancel button in the confirm dialog is still # displayed active, that is, it has a lighter background. class Demo: def __init__(self, parent): # Create the dialog to prompt for the password. self.dialog = Pmw.PromptDialog(parent, title = 'Password', label_text = 'Password:', entryfield_labelpos = 'n', entry_show = '*', defaultbutton = 0, buttons = ('OK', 'Cancel'), command = self.execute) self.dialog.withdraw() # Create the confirmation dialog. self.confirm = Pmw.MessageDialog( title = 'Are you sure?', message_text = 'Are you really sure?', defaultbutton = 0, buttons = ('OK', 'Cancel')) self.confirm.withdraw() # Create button to launch the dialog. w = Tkinter.Button(parent, text = 'Show prompt dialog', command = self.dialog.activate) w.pack(padx = 8, pady = 8) def execute(self, result): if result is None or result == 'Cancel': print 'Password prompt cancelled' self.dialog.deactivate(result) else: result = self.confirm.activate() if result == 'OK': print 'Password entered ' + self.dialog.get() self.dialog.deactivate() ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9151182 Pmw-2.1/Pmw/Pmw_1_3_3/demos/RadioSelect.py0000664000175000017500000000674700000000000020435 0ustar00gregmgregm00000000000000title = 'Pmw.RadioSelect demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): # Create and pack a horizontal RadioSelect widget. horiz = Pmw.RadioSelect(parent, labelpos = 'w', command = self.callback, label_text = 'Horizontal', frame_borderwidth = 2, frame_relief = 'ridge' ) horiz.pack(fill = 'x', padx = 10, pady = 10) # Add some buttons to the horizontal RadioSelect. for text in ('Fruit', 'Vegetables', 'Cereals', 'Legumes'): horiz.add(text) horiz.invoke('Cereals') # Create and pack a multiple selection RadioSelect widget. self.multiple = Pmw.RadioSelect(parent, labelpos = 'w', command = self.multcallback, label_text = 'Multiple\nselection', frame_borderwidth = 2, frame_relief = 'ridge', selectmode = 'multiple', ) self.multiple.pack(fill = 'x', padx = 10) # Add some buttons to the multiple selection RadioSelect. for text in ('Apricots', 'Eggplant', 'Rice', 'Lentils'): self.multiple.add(text) self.multiple.invoke('Rice') # Create and pack a vertical RadioSelect widget, with checkbuttons. self.checkbuttons = Pmw.RadioSelect(parent, buttontype = 'checkbutton', orient = 'vertical', labelpos = 'w', command = self.checkbuttoncallback, label_text = 'Vertical,\nusing\ncheckbuttons', hull_borderwidth = 2, hull_relief = 'ridge', ) self.checkbuttons.pack(side = 'left', expand = 1, padx = 10, pady = 10) # Add some buttons to the checkbutton RadioSelect. for text in ('Male', 'Female'): self.checkbuttons.add(text) self.checkbuttons.invoke('Male') self.checkbuttons.invoke('Female') # Create and pack a RadioSelect widget, with radiobuttons. radiobuttons = Pmw.RadioSelect(parent, buttontype = 'radiobutton', orient = 'vertical', labelpos = 'w', command = self.callback, label_text = 'Vertical,\nusing\nradiobuttons', hull_borderwidth = 2, hull_relief = 'ridge', ) radiobuttons.pack(side = 'left', expand = 1, padx = 10, pady = 10) # Add some buttons to the radiobutton RadioSelect. for text in ('Male', 'Female', 'Both', 'Neither'): radiobuttons.add(text) radiobuttons.invoke('Both') def callback(self, tag): # This is called whenever the user clicks on a button # in a single select RadioSelect widget. print 'Button', tag, 'was pressed.' def multcallback(self, tag, state): # This is called whenever the user clicks on a button # in the multiple select RadioSelect widget. if state: action = 'pressed.' else: action = 'released.' print 'Button', tag, 'was', action, \ 'Selection:', self.multiple.getcurselection() def checkbuttoncallback(self, tag, state): # This is called whenever the user clicks on a button # in the checkbutton RadioSelect widget. if state: action = 'pressed.' else: action = 'released.' print 'Button', tag, 'was', action, \ 'Selection:', self.checkbuttons.getcurselection() ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9151182 Pmw-2.1/Pmw/Pmw_1_3_3/demos/Resources.py0000664000175000017500000000403600000000000020176 0ustar00gregmgregm00000000000000title = 'Using Tk option database to configure Tk widgets' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import string import Tkinter import Pmw info = """ The Tk widgets contained in this simple megawidget have been configured using the Tk option database. *DemoClass*Listbox.cursor is 'heart' *DemoClass*Entry.cursor is 'hand1' *DemoClass*background is 'pink' *DemoClass*highlightBackground is 'green' *DemoClass*foreground is 'blue' """ class DemoClass(Pmw.MegaWidget): # Demo Pmw megawidget. def __init__(self, parent = None, **kw): # Define the megawidget options. optiondefs = () self.defineoptions(kw, optiondefs) # Initialise the base class (after defining the options). Pmw.MegaWidget.__init__(self, parent) interior = self.interior() listbox = Tkinter.Listbox(interior, height = 12, width = 40) listbox.pack(fill='both', expand='yes') for line in string.split(info, '\n'): listbox.insert('end', line) entry = Tkinter.Entry(interior) entry.pack(fill='y') entry.insert(0, 'Hello, World!') # Check keywords and initialise options. self.initialiseoptions() class Demo: def __init__(self, parent): # Test Tk option database settings. parent.option_add('*DemoClass*Listbox.cursor', 'heart') parent.option_add('*DemoClass*Entry.cursor', 'hand1') parent.option_add('*DemoClass*background', 'pink') parent.option_add('*DemoClass*highlightBackground', 'green') parent.option_add('*DemoClass*foreground', 'blue') # Create and pack the megawidget. demo = DemoClass(parent) demo.pack(fill = 'both', expand = 1) ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9151182 Pmw-2.1/Pmw/Pmw_1_3_3/demos/Resources_Pmw.py0000664000175000017500000000674200000000000021027 0ustar00gregmgregm00000000000000title = 'Using Tk option database to configure Pmw megawidgets' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): self.parent = parent header = Tkinter.Label(parent, text = 'Select some Tk option ' + 'database values from\nthe lists, then click ' + '\'Create dialog\' to create\na MessageDialog with ' + 'these values as defaults.') header.pack(padx = 10, pady = 10) # Create and pack the ComboBoxes to select options. buttons = ( "('OK',)", "('Read', 'Write')", "('OK', 'Cancel')", "('OK', 'Apply', 'Cancel', 'Help')", ) if Tkinter.TkVersion >= 8.4: disabledState = 'readonly' else: disabledState = 'disabled' self._buttons = Pmw.ComboBox(parent, label_text = 'buttons:', labelpos = 'w', entry_state = disabledState, scrolledlist_items = buttons) self._buttons.pack(fill = 'x', expand = 1, padx = 8, pady = 8) self._buttons.selectitem(3) buttonboxpos = ('n', 's', 'e', 'w',) self._buttonboxpos = Pmw.ComboBox(parent, label_text = 'buttonboxpos:', labelpos = 'w', entry_state = disabledState, scrolledlist_items = buttonboxpos) self._buttonboxpos.pack(fill = 'x', expand = 1, padx = 8, pady = 8) self._buttonboxpos.selectitem(2) pad = ('0', '8', '20', '50',) self._pad = Pmw.ComboBox(parent, label_text = 'padx, pady:', labelpos = 'w', entry_state = disabledState, scrolledlist_items = pad) self._pad.pack(fill = 'x', expand = 1, padx = 8, pady = 8) self._pad.selectitem(1) Pmw.alignlabels((self._buttons, self._buttonboxpos, self._pad)) # Create button to launch the dialog. w = Tkinter.Button(parent, text = 'Create dialog', command = self._createDialog) w.pack(padx = 8, pady = 8) self.dialog = None def _createDialog(self): # Set the option database. buttons = self._buttons.get() buttonboxpos = self._buttonboxpos.get() pad = self._pad.get() self.parent.option_add('*MessageDialog.buttons', buttons) self.parent.option_add('*MessageDialog.buttonboxpos', buttonboxpos) self.parent.option_add('*ButtonBox.padx', pad) self.parent.option_add('*ButtonBox.pady', pad) # Create the dialog. if self.dialog is not None: self.dialog.destroy() text = ('This dialog was created by setting the Tk ' + 'option database:\n\n *MessageDialog.buttons: ' + buttons + '\n *MessageDialog.buttonboxpos: ' + buttonboxpos + '\n *ButtonBox.padx: ' + pad + '\n *ButtonBox.pady: ' + pad) self.dialog = Pmw.MessageDialog(self.parent, defaultbutton = 0, title = 'Pmw option database demonstration', message_justify = 'left', message_text = text) self.dialog.iconname('Test dialog') # Return the defaults to normal, otherwise all other demos # will be affected. self.parent.option_add('*MessageDialog.buttons', "('OK',)") self.parent.option_add('*MessageDialog.buttonboxpos', 's') self.parent.option_add('*ButtonBox.padx', 8) self.parent.option_add('*ButtonBox.pady', 8) ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root, useTkOptionDb = 1) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9191184 Pmw-2.1/Pmw/Pmw_1_3_3/demos/ScrolledCanvas.py0000664000175000017500000000715500000000000021134 0ustar00gregmgregm00000000000000title = 'Pmw.ScrolledCanvas demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): # Create the ScrolledCanvas. self.sc = Pmw.ScrolledCanvas(parent, borderframe = 1, labelpos = 'n', label_text = 'ScrolledCanvas', usehullsize = 1, hull_width = 400, hull_height = 300, ) # Create a group widget to contain the scrollmode options. w = Pmw.Group(parent, tag_text='Scroll mode') w.pack(side = 'bottom', padx = 5, pady = 5) hmode = Pmw.OptionMenu(w.interior(), labelpos = 'w', label_text = 'Horizontal:', items = ['none', 'static', 'dynamic'], command = self.sethscrollmode, menubutton_width = 8, ) hmode.pack(side = 'left', padx = 5, pady = 5) hmode.invoke('dynamic') vmode = Pmw.OptionMenu(w.interior(), labelpos = 'w', label_text = 'Vertical:', items = ['none', 'static', 'dynamic'], command = self.setvscrollmode, menubutton_width = 8, ) vmode.pack(side = 'left', padx = 5, pady = 5) vmode.invoke('dynamic') buttonBox = Pmw.ButtonBox(parent) buttonBox.pack(side = 'bottom') buttonBox.add('yview', text = 'Show\nyview', command = self.showYView) buttonBox.add('scroll', text = 'Page\ndown', command = self.pageDown) buttonBox.add('center', text = 'Center', command = self.centerPage) # Pack this last so that the buttons do not get shrunk when # the window is resized. self.sc.pack(padx = 5, pady = 5, fill = 'both', expand = 1) self.sc.component('canvas').bind('<1>', self.addcircle) testEntry = Tkinter.Entry(parent) self.sc.create_line(20, 20, 100, 100) self.sc.create_oval(100, 100, 200, 200, fill = 'green') self.sc.create_text(100, 20, anchor = 'nw', text = 'Click in the canvas\nto draw ovals', font = testEntry.cget('font')) button = Tkinter.Button(self.sc.interior(), text = 'Hello,\nWorld!\nThis\nis\na\nbutton.') self.sc.create_window(200, 200, anchor='nw', window = button) # Set the scroll region of the canvas to include all the items # just created. self.sc.resizescrollregion() self.colours = ('red', 'green', 'blue', 'yellow', 'cyan', 'magenta', 'black', 'white') self.oval_count = 0 self.rand = 12345 def sethscrollmode(self, tag): self.sc.configure(hscrollmode = tag) def setvscrollmode(self, tag): self.sc.configure(vscrollmode = tag) def addcircle(self, event): x = self.sc.canvasx(event.x) y = self.sc.canvasy(event.y) width = 10 + self.random() % 100 height = 10 + self.random() % 100 self.sc.create_oval( x - width, y - height, x + width, y + height, fill = self.colours[self.oval_count]) self.oval_count = (self.oval_count + 1) % len(self.colours) self.sc.resizescrollregion() # Simple random number generator. def random(self): self.rand = (self.rand * 125) % 2796203 return self.rand def showYView(self): print self.sc.yview() def pageDown(self): self.sc.yview('scroll', 1, 'page') def centerPage(self): top, bottom = self.sc.yview() size = bottom - top middle = 0.5 - size / 2 self.sc.yview('moveto', middle) ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9151182 Pmw-2.1/Pmw/Pmw_1_3_3/demos/ScrolledField.py0000664000175000017500000000314400000000000020736 0ustar00gregmgregm00000000000000title = 'Pmw.ScrolledField demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): # Create and pack the ScrolledField. self._field = Pmw.ScrolledField(parent, entry_width = 30, entry_relief='groove', labelpos = 'n', label_text = 'Scroll the field using the\nmiddle mouse button') self._field.pack(fill = 'x', expand = 1, padx = 10, pady = 10) # Create and pack a button to change the ScrolledField. self._button = Tkinter.Button(parent, text = 'Change field', command = self.execute) self._button.pack(padx = 10, pady = 10) self._index = 0 self.execute() def execute(self): self._field.configure(text = lines[self._index % len(lines)]) self._index = self._index + 1 lines = ( 'Alice was beginning to get very tired of sitting by her sister', 'on the bank, and of having nothing to do: once or twice she had', 'peeped into the book her sister was reading, but it had no', 'pictures or conversations in it, "and what is the use of a book,"', 'thought Alice "without pictures or conversation?"', 'Alice\'s Adventures in Wonderland', 'Lewis Carroll', ) ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9151182 Pmw-2.1/Pmw/Pmw_1_3_3/demos/ScrolledFrame.py0000664000175000017500000001065100000000000020746 0ustar00gregmgregm00000000000000title = 'Pmw.ScrolledFrame demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): # Create the ScrolledFrame. self.sf = Pmw.ScrolledFrame(parent, labelpos = 'n', label_text = 'ScrolledFrame', usehullsize = 1, hull_width = 400, hull_height = 220, ) # Create a group widget to contain the flex options. w = Pmw.Group(parent, tag_text='Flex') w.pack(side = 'bottom', padx = 5, pady = 3) hflex = Pmw.OptionMenu(w.interior(), labelpos = 'w', label_text = 'Horizontal:', items = ['fixed', 'expand', 'shrink', 'elastic'], command = self.sethflex, menubutton_width = 8, ) hflex.pack(side = 'left', padx = 5, pady = 3) hflex.invoke('fixed') vflex = Pmw.OptionMenu(w.interior(), labelpos = 'w', label_text = 'Vertical:', items = ['fixed', 'expand', 'shrink', 'elastic'], command = self.setvflex, menubutton_width = 8, ) vflex.pack(side = 'left', padx = 5, pady = 3) vflex.invoke('fixed') # Create a group widget to contain the scrollmode options. w = Pmw.Group(parent, tag_text='Scroll mode') w.pack(side = 'bottom', padx = 5, pady = 0) hmode = Pmw.OptionMenu(w.interior(), labelpos = 'w', label_text = 'Horizontal:', items = ['none', 'static', 'dynamic'], command = self.sethscrollmode, menubutton_width = 8, ) hmode.pack(side = 'left', padx = 5, pady = 3) hmode.invoke('dynamic') vmode = Pmw.OptionMenu(w.interior(), labelpos = 'w', label_text = 'Vertical:', items = ['none', 'static', 'dynamic'], command = self.setvscrollmode, menubutton_width = 8, ) vmode.pack(side = 'left', padx = 5, pady = 3) vmode.invoke('dynamic') self.radio = Pmw.RadioSelect(parent, selectmode = 'multiple', command = self.radioSelected) self.radio.add('center', text = 'Keep centered vertically') self.radio.pack(side = 'bottom') buttonBox = Pmw.ButtonBox(parent) buttonBox.pack(side = 'bottom') buttonBox.add('add', text = 'Add a button', command = self.addButton) buttonBox.add('yview', text = 'Show yview', command = self.showYView) buttonBox.add('scroll', text = 'Page down', command = self.pageDown) # Pack this last so that the buttons do not get shrunk when # the window is resized. self.sf.pack(padx = 5, pady = 3, fill = 'both', expand = 1) self.frame = self.sf.interior() self.row = 0 self.col = 0 for count in range(15): self.addButton() def sethscrollmode(self, tag): self.sf.configure(hscrollmode = tag) def setvscrollmode(self, tag): self.sf.configure(vscrollmode = tag) def sethflex(self, tag): self.sf.configure(horizflex = tag) def setvflex(self, tag): self.sf.configure(vertflex = tag) def addButton(self): button = Tkinter.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.sf.cget('horizflex') == 'expand' or \ self.sf.cget('vertflex') == 'expand': self.sf.reposition() if 'center' in self.radio.getcurselection(): self.sf.update_idletasks() self.centerPage() if self.col == self.row: self.col = 0 self.row = self.row + 1 else: self.col = self.col + 1 def showYView(self): print self.sf.yview() def pageDown(self): self.sf.yview('scroll', 1, 'page') def radioSelected(self, name, state): if state: self.centerPage() def centerPage(self): # Example of how to use the yview() method of Pmw.ScrolledFrame. top, bottom = self.sf.yview() size = bottom - top middle = 0.5 - size / 2 self.sf.yview('moveto', middle) ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': import os if os.name == 'nt': size = 16 else: size = 12 root = Tkinter.Tk() Pmw.initialise(root, size = size, fontScheme = 'pmw2') root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9151182 Pmw-2.1/Pmw/Pmw_1_3_3/demos/ScrolledListBox.py0000664000175000017500000000674000000000000021304 0ustar00gregmgregm00000000000000title = 'Pmw.ScrolledListBox demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): # Create the ScrolledListBox. self.box = Pmw.ScrolledListBox(parent, items=('Sydney', 'Melbourne', 'Brisbane'), labelpos='nw', label_text='Cities', listbox_height = 6, selectioncommand=self.selectionCommand, dblclickcommand=self.defCmd, usehullsize = 1, hull_width = 200, hull_height = 200, ) # Create a group widget to contain the scrollmode options. w = Pmw.Group(parent, tag_text='Scroll mode') w.pack(side = 'bottom', padx = 5, pady = 5) hmode = Pmw.OptionMenu(w.interior(), labelpos = 'w', label_text = 'Horizontal:', items = ['none', 'static', 'dynamic'], command = self.sethscrollmode, menubutton_width = 8, ) hmode.pack(side = 'top', padx = 5, pady = 5) hmode.invoke('dynamic') vmode = Pmw.OptionMenu(w.interior(), labelpos = 'w', label_text = 'Vertical:', items = ['none', 'static', 'dynamic'], command = self.setvscrollmode, menubutton_width = 8, ) vmode.pack(side = 'top', padx = 5, pady = 5) vmode.invoke('dynamic') buttonBox = Pmw.ButtonBox(parent) buttonBox.pack(side = 'bottom') buttonBox.add('yview', text = 'Show\nyview', command = self.showYView) buttonBox.add('scroll', text = 'Page\ndown', command = self.pageDown) buttonBox.add('center', text = 'Center', command = self.centerPage) # Pack this last so that the buttons do not get shrunk when # the window is resized. self.box.pack(fill = 'both', expand = 1, padx = 5, pady = 5) # Do this after packing the scrolled list box, so that the # window does not resize as soon as it appears (because # alignlabels has to do an update_idletasks). Pmw.alignlabels((hmode, vmode)) # Add some more entries to the listbox. items = ('Andamooka', 'Coober Pedy', 'Innamincka', 'Oodnadatta') self.box.setlist(items) self.box.insert(2, 'Wagga Wagga', 'Perth', 'London') self.box.insert('end', 'Darwin', 'Auckland', 'New York') index = list(self.box.get(0, 'end')).index('London') self.box.delete(index) self.box.delete(7, 8) self.box.insert('end', 'Bulli', 'Alice Springs', 'Woy Woy') self.box.insert('end', 'Wallumburrawang', 'Willandra Billabong') def sethscrollmode(self, tag): self.box.configure(hscrollmode = tag) def setvscrollmode(self, tag): self.box.configure(vscrollmode = tag) def selectionCommand(self): sels = self.box.getcurselection() if len(sels) == 0: print 'No selection' else: print 'Selection:', sels[0] def defCmd(self): sels = self.box.getcurselection() if len(sels) == 0: print 'No selection for double click' else: print 'Double click:', sels[0] def showYView(self): print self.box.yview() def pageDown(self): self.box.yview('scroll', 1, 'page') def centerPage(self): top, bottom = self.box.yview() size = bottom - top middle = 0.5 - size / 2 self.box.yview('moveto', middle) ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9191184 Pmw-2.1/Pmw/Pmw_1_3_3/demos/ScrolledText.py0000664000175000017500000000616100000000000020641 0ustar00gregmgregm00000000000000title = 'Pmw.ScrolledText demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import os import math import string import Tkinter import Pmw class Demo: def __init__(self, parent): # Create the ScrolledText with headers. fixedFont = Pmw.logicalfont('Fixed') self.st = Pmw.ScrolledText(parent, # borderframe = 1, labelpos = 'n', label_text='ScrolledText with headers', columnheader = 1, rowheader = 1, rowcolumnheader = 1, usehullsize = 1, hull_width = 400, hull_height = 300, text_wrap='none', text_font = fixedFont, Header_font = fixedFont, Header_foreground = 'blue', rowheader_width = 3, rowcolumnheader_width = 3, text_padx = 4, text_pady = 4, Header_padx = 4, rowheader_pady = 4, ) self.st.pack(padx = 5, pady = 5, fill = 'both', expand = 1) funcs = 'atan cos cosh exp log log10 sin sinh sqrt tan tanh' funcs = string.split(funcs) # Create the header for the row headers self.st.component('rowcolumnheader').insert('end', 'x') # Create the column headers headerLine = '' for column in range(len(funcs)): headerLine = headerLine + ('%-7s ' % (funcs[column],)) headerLine = headerLine[:-3] self.st.component('columnheader').insert('0.0', headerLine) self.st.tag_configure('yellow', background = 'yellow') # Create the data rows and the row headers numRows = 50 tagList = [] for row in range(1, numRows): dataLine = '' x = row / 5.0 for column in range(len(funcs)): value = eval('math.' + funcs[column] + '(' + str(x) + ')') data = str(value)[:7] if value < 0: tag1 = '%d.%d' % (row, len(dataLine)) tag2 = '%d.%d' % (row, len(dataLine) + len(data)) tagList.append(tag1) tagList.append(tag2) data = '%-7s' % (data,) dataLine = dataLine + data + ' ' dataLine = dataLine[:-3] header = '%.1f' % (x,) if row < numRows - 1: dataLine = dataLine + '\n' header = header + '\n' self.st.insert('end', dataLine) self.st.component('rowheader').insert('end', header) apply(self.st.tag_add, ('yellow',) + tuple(tagList)) # Prevent users' modifying text and headers self.st.configure( text_state = 'disabled', Header_state = 'disabled', ) ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9191184 Pmw-2.1/Pmw/Pmw_1_3_3/demos/ScrolledText_2.py0000664000175000017500000000541400000000000021062 0ustar00gregmgregm00000000000000title = 'Pmw.ScrolledText demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import os import Tkinter import Pmw class Demo: def __init__(self, parent): # Create the ScrolledText. self.st = Pmw.ScrolledText(parent, borderframe = 1, labelpos = 'n', label_text='ScrolledText.py', usehullsize = 1, hull_width = 400, hull_height = 300, text_padx = 10, text_pady = 10, text_wrap='none' ) # Create a group widget to contain the scrollmode options. w = Pmw.Group(parent, tag_text='Scroll mode') w.pack(side = 'bottom', padx = 5, pady = 5) hmode = Pmw.OptionMenu(w.interior(), labelpos = 'w', label_text = 'Horizontal:', items = ['none', 'static', 'dynamic'], command = self.sethscrollmode, menubutton_width = 8, ) hmode.pack(side = 'left', padx = 5, pady = 5) hmode.invoke('dynamic') vmode = Pmw.OptionMenu(w.interior(), labelpos = 'w', label_text = 'Vertical:', items = ['none', 'static', 'dynamic'], command = self.setvscrollmode, menubutton_width = 8, ) vmode.pack(side = 'left', padx = 5, pady = 5) vmode.invoke('dynamic') buttonBox = Pmw.ButtonBox(parent) buttonBox.pack(side = 'bottom') buttonBox.add('yview', text = 'Show\nyview', command = self.showYView) buttonBox.add('scroll', text = 'Page\ndown', command = self.pageDown) buttonBox.add('center', text = 'Center', command = self.centerPage) # Pack this last so that the buttons do not get shrunk when # the window is resized. self.st.pack(padx = 5, pady = 5, fill = 'both', expand = 1) # Read this file into the text widget. head, tail = os.path.split(sys.argv[0]) self.st.importfile(os.path.join(head,'ScrolledText.py')) self.st.insert('end', '\nThis demonstrates how to\n' + 'add a window to a text widget: ') counter = Pmw.Counter(self.st.component('text'), entryfield_value = 9999) self.st.window_create('end', window = counter) def sethscrollmode(self, tag): self.st.configure(hscrollmode = tag) def setvscrollmode(self, tag): self.st.configure(vscrollmode = tag) def showYView(self): print self.st.yview() def pageDown(self): self.st.yview('scroll', 1, 'page') def centerPage(self): top, bottom = self.st.yview() size = bottom - top middle = 0.5 - size / 2 self.st.yview('moveto', middle) ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9151182 Pmw-2.1/Pmw/Pmw_1_3_3/demos/SelectionDialog.py0000664000175000017500000000254100000000000021270 0ustar00gregmgregm00000000000000title = 'Pmw.SelectionDialog demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): # Create the dialog. self.dialog = Pmw.SelectionDialog(parent, title = 'My SelectionDialog', buttons = ('OK', 'Cancel'), defaultbutton = 'OK', scrolledlist_labelpos = 'n', label_text = 'What do you think of Pmw?', scrolledlist_items = ('Cool man', 'Cool', 'Good', 'Bad', 'Gross'), command = self.execute) self.dialog.withdraw() # Create button to launch the dialog. w = Tkinter.Button(parent, text = 'Show selection dialog', command = self.dialog.activate) w.pack(padx = 8, pady = 8) def execute(self, result): sels = self.dialog.getcurselection() if len(sels) == 0: print 'You clicked on', result, '(no selection)' else: print 'You clicked on', result, sels[0] self.dialog.deactivate(result) ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9151182 Pmw-2.1/Pmw/Pmw_1_3_3/demos/ShowBusy.py0000664000175000017500000000247100000000000020010 0ustar00gregmgregm00000000000000title = 'Blt busy cursor demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): self.parent = parent if Pmw.Blt.havebltbusy(parent): text = 'Click here to show the\nbusy cursor for one second.' else: text = 'Sorry\n' \ 'Either the BLT package has not\n' \ 'been installed on this system or\n' \ 'it does not support the busy command.\n' \ 'Clicking on this button will pause\n' \ 'for one second but will not display\n' \ 'the busy cursor.' button = Tkinter.Button(parent, text = text, command = Pmw.busycallback(self.sleep, parent.update)) button.pack(padx = 10, pady = 10) entry = Tkinter.Entry(parent, width = 30) entry.insert('end', 'Try to enter some text while busy.') entry.pack(padx = 10, pady = 10) def sleep(self): self.parent.after(1000) ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9231184 Pmw-2.1/Pmw/Pmw_1_3_3/demos/SpecialCounter.py0000664000175000017500000000406300000000000021144 0ustar00gregmgregm00000000000000title = 'Subclassing Pmw.Counter' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import string import time import types import Tkinter import Pmw class LabeledDateCounter(Pmw.Counter): def __init__(self, parent=None , **kw): # Need to use long ints here because on the Macintosh the maximum size # of an integer is smaller than the value returned by time.time(). now = (long(time.time()) / 300) * 300 text = time.strftime('%y/%m/%d', time.localtime(now)) kw['datatype'] = 'date' kw['entryfield_validate'] = 'date' kw['entryfield_value'] = text kw['labelpos'] = 'w' apply(Pmw.Counter.__init__, (self, parent), kw) class LabeledRealCounter(Pmw.Counter): def __init__(self, parent=None , **kw): # Define the validate option dictionary. validate = {'validator' : 'real', 'min' : 0.0, 'max' : 100.0} kw['datatype'] = 'real' kw['entryfield_validate'] = validate kw['entryfield_value'] = 50.0 kw['labelpos'] = 'w' apply(Pmw.Counter.__init__, (self, parent), kw) class Demo: def __init__(self, parent): # Create and pack some LabeledDateCounters and LabeledRealCounter. self._date1 = LabeledDateCounter(parent, label_text = 'Date:') self._date2 = LabeledDateCounter(parent, label_text = 'Another Date:') self._real1 = LabeledRealCounter(parent, label_text = 'Real:') self._real2 = LabeledRealCounter(parent, label_text = 'Another Real:') counters = (self._date1, self._date2, self._real1, self._real2) for counter in counters: counter.pack(fill='x', expand=1, padx=10, pady=5) Pmw.alignlabels(counters) ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9191184 Pmw-2.1/Pmw/Pmw_1_3_3/demos/SpecialEntry.py0000664000175000017500000001071700000000000020631 0ustar00gregmgregm00000000000000title = 'Subclassing Pmw.EntryField' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import string import time import types import Tkinter import Pmw class SpecialEntry(Pmw.EntryField): def __init__(self, parent=None , **kw): kw['extravalidators'] = _myValidators apply(Pmw.EntryField.__init__, (self, parent), kw) self._converter = None def setentry(self, text): # Override Pmw.EntryField.setentry to pass string through # the appropriate converter. val = self['validate'] if type(val) == types.DictionaryType: val = val['validator'] if _converters.has_key(val): text = _converters[val](text, output = 0) Pmw.EntryField.setentry(self, text) def getentry(self): text = self.get() val = self['validate'] if type(val) == types.DictionaryType: val = val['validator'] if _converters.has_key(val): return _converters[val](text, output = 1) else: return text def _date(text): return Pmw.datevalidator(text, 'dmy', '.') def _real(text): return Pmw.realvalidator(text, ',') def _dateconv(text, output = 0): # On output, convert from dd.mm.yy to mm-dd-yy. On input, convert # mm-dd-yy to dd.mm.yy and also from +NN+ or -NN- to date NN days # before or after today. if len(text) == 0: return '' if output: try: d = string.split(text, '.') return d[1] + '-' + d[0] + '-' + d[2] except: return text else: if text[-1] == '+' or text[-1] == '-': text = text[:-1] if text[0] == '+' or text[0] == '-': secondsAhead = string.atoi(text) * 3600 * 24 return time.strftime('%d.%m.%Y', time.localtime(time.time() + secondsAhead)) try: d = string.split(text,'-') return d[1] + '.' + d[0] + '.' + d[2] except: return text def _realconv(text, output = 0): # Convert between DD.DD and DD,DD. if output: index = string.find(text, ',') if index >= 0: return text[:index] + '.' + text[index + 1:] else: return text else: index = string.find(text, '.') if index >= 0: return text[:index] + ',' + text[index + 1:] else: return text _converters = { 'real' : _realconv, 'float8' : _realconv, 'date' : _dateconv } _myValidators = { 'date' : (_date, lambda s: Pmw.datestringtojdn(s, 'dmy', '.')), 'real' : (_real, lambda s: string.atof(_realconv(s, 1))), 'int4' : ('numeric', 'numeric'), 'oid' : ('int4', 'int4'), 'float8' : ('real', 'real'), 'varchar' : ('alphanumeric', 'alphanumeric'), 'text' : ('alphanumeric', 'alphanumeric'), } class Demo: def __init__(self, parent): # Create and pack the SpecialEntry megawidgets. self._any = SpecialEntry(parent, labelpos = 'w', label_text = 'Text (max 10 chars):', validate = {'validator' : 'text', 'max' : 10}, command = self.execute) self._any.setentry('abc') self._int = SpecialEntry(parent, labelpos = 'w', label_text = 'Int4:', validate = 'int4') self._int.setentry(1) self._real = SpecialEntry(parent, labelpos = 'w', label_text = 'Real (max 2,5e+9):', validate = {'validator' : 'real', 'max' : +2.5e+9}, ) self._real.setentry('+2.5e+6') self._date = SpecialEntry(parent, labelpos = 'w', label_text = 'Date (dd.mm.yy):', validate = 'date', modifiedcommand = self.changed ) # Set entry to one week from now, using special intput format. self._date.setentry('+7+') entries = (self._any, self._int, self._real, self._date) for entry in entries: entry.pack(fill='x', expand=1, padx=10, pady=5) Pmw.alignlabels(entries) self._any.component('entry').focus_set() def changed(self): print 'Text changed, converted value is', self._date.getentry() def execute(self): print 'Return pressed, value is', self._any.get() # This implements a custom validation routine. It simply checks # if the string is of odd length. def custom_validate(self, text): print 'text:', text if len(text) % 2 == 0: return -1 else: return 1 ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9151182 Pmw-2.1/Pmw/Pmw_1_3_3/demos/Spectrum.py0000664000175000017500000001242700000000000020031 0ustar00gregmgregm00000000000000title = 'Color spectrum demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import string import Tkinter import Pmw class Demo: def __init__(self, parent): parent = Tkinter.Frame(parent) parent.pack(padx=10, pady=10, fill='both', expand=1) self.width = 350 self.height = 250 self.canvas = Tkinter.Canvas(parent, width = self.width, height = self.height) self.canvas.grid(row = 0, column = 0, columnspan = 2, sticky = 'news') self.numColors = Pmw.EntryField(parent, labelpos = 'w', label_text = 'Number of colors:', entry_width = 5, validate = 'numeric', command = Pmw.busycallback(self.execute)) self.numColors.grid(row = 1, column = 0, sticky = 'ew') self.correction = Pmw.EntryField(parent, labelpos = 'w', label_text = 'Correction:', validate = 'real', entry_width = 5, command = Pmw.busycallback(self.execute)) self.correction.grid(row = 1, column = 1, sticky = 'ew') self.saturation = Pmw.EntryField(parent, labelpos = 'w', label_text = 'Saturation:', validate = 'real', entry_width = 5, command = Pmw.busycallback(self.execute)) self.saturation.grid(row = 2, column = 0, sticky = 'ew') self.intensity = Pmw.EntryField(parent, labelpos = 'w', label_text = 'Intensity:', validate = 'real', entry_width = 5, command = Pmw.busycallback(self.execute)) self.intensity.grid(row = 2, column = 1, sticky = 'ew') self.extraOrange = Pmw.EntryField(parent, labelpos = 'w', label_text = 'Emphasize orange (0 or 1):', validate = {'validator' : 'numeric', 'min' : 0, 'max' : 1}, entry_width = 5, command = Pmw.busycallback(self.execute)) self.extraOrange.grid(row = 3, column = 0, sticky = 'ew') self.text = Pmw.EntryField(parent, labelpos = 'w', label_text = 'Text:', entry_width = 20, command = Pmw.busycallback(self.execute)) self.text.grid(row = 4, column = 0, sticky = 'ew') self.brightness = Pmw.EntryField(parent, labelpos = 'w', label_text = 'Brightness:', validate = 'real', entry_width = 5, command = Pmw.busycallback(self.execute)) self.brightness.grid(row = 3, column = 1, sticky = 'ew') self.radiobuttons = Pmw.RadioSelect(parent, command = Pmw.busycallback(self.radio_cb), ) self.radiobuttons.grid(row = 4, column = 1) self.radiobuttons.add('Use saturation\nand intensity') self.radiobuttons.add('Use\nbrightness') parent.grid_columnconfigure(0, weight = 1) parent.grid_columnconfigure(1, weight = 1) parent.grid_rowconfigure(0, weight = 1) Pmw.alignlabels((self.numColors, self.saturation, self.extraOrange)) Pmw.alignlabels((self.correction, self.intensity, self.brightness)) # Set initial values for all entries. self.numColors.setentry('64') self.correction.setentry('1.0') self.saturation.setentry('1.0') self.intensity.setentry('1.0') self.extraOrange.setentry('1') self.brightness.setentry('0.7') self.text.setentry('This is a test') self.radiobuttons.invoke('Use saturation\nand intensity') self.execute() def radio_cb(self, value): self.execute() def execute(self): try: numColors = string.atoi(self.numColors.get()) correction = string.atof(self.correction.get()) saturation = string.atof(self.saturation.get()) intensity = string.atof(self.intensity.get()) extraOrange = string.atof(self.extraOrange.get()) brightness = string.atof(self.brightness.get()) except ValueError: self.numColors.bell() return if numColors <= 0: self.numColors.bell() return self.canvas.delete('all') colorList = Pmw.Color.spectrum( numColors, correction, saturation, intensity, extraOrange) extent = 360.0 / numColors useBrightness = \ (self.radiobuttons.getcurselection() == 'Use\nbrightness') if numColors == 1: # Special case circle, since create_arc does not work when # extent is 360. background = colorList[0] if useBrightness: background = Pmw.Color.changebrightness( self.canvas, background, brightness) self.canvas.create_oval(10, 10, self.width - 10, self.height - 10, fill = background, outline = background) for index in range(numColors): start = index * extent - extent / 2 background = colorList[index] if useBrightness: background = Pmw.Color.changebrightness( self.canvas, background, brightness) self.canvas.create_arc(10, 10, self.width - 10, self.height - 10, start = start, extent = extent, fill = background, outline = background) text = self.text.get() self.canvas.create_text(self.width / 2, self.height / 3, text = text) self.canvas.create_text(self.width / 2, self.height / 2, text = text) self.canvas.create_text(self.width / 2, 2 * self.height / 3, text = text) ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9191184 Pmw-2.1/Pmw/Pmw_1_3_3/demos/SpeedTest.py0000664000175000017500000000325700000000000020130 0ustar00gregmgregm00000000000000title = 'Test of the speed of creating Pmw megawidgets' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import time import Tkinter import Pmw class Demo: def __init__(self, parent): self.parent = parent message = 'This is a test of the time\n' + \ 'it takes to create 20 Pmw\nEntryField megawidgets.\n' + \ 'Click on the button to create them.' w = Tkinter.Label(parent, text = message) w.pack(padx = 8, pady = 8) # Create button to run speed test. w = Tkinter.Button(parent, text = 'Create 20 EntryFields', command = self.createEntries) w.pack(padx = 8, pady = 8) def createEntries(self): entryTop = Tkinter.Toplevel(self.parent) startClock = time.clock() fields = [] for num in range(20): field = Pmw.EntryField(entryTop, labelpos = 'w', label_text='*' + ('*' * num), hull_background = 'lightsteelblue', label_background = 'lightsteelblue', hull_highlightbackground = 'lightsteelblue', label_highlightbackground = 'lightsteelblue', entry_highlightbackground = 'lightsteelblue', entry_background = 'aliceblue') field.pack() fields.append(field) Pmw.alignlabels(fields) print 'Time to create 20 EntryFields:', \ time.clock() - startClock, 'seconds' ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9231184 Pmw-2.1/Pmw/Pmw_1_3_3/demos/SubClassing.py0000664000175000017500000000725300000000000020445 0ustar00gregmgregm00000000000000title = 'More examples of subclassing' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class ExtraMethods(Pmw.EntryField): # How to subclass a Pmw megawidget when you only want to add or # override methods. def doubletext(self): self.setvalue(self.getvalue() + ' ' + self.getvalue()) class OverrideInit(Pmw.EntryField): # How to subclass a Pmw megawidget when you want to define # a new __init__ method. def __init__(self, textToAdd, parent = None, **kw): self._textToAdd = textToAdd apply(Pmw.EntryField.__init__, (self, parent), kw) def addtext(self): self.setvalue(self.getvalue() + ' ' + self._textToAdd) class DefaultOptions(Pmw.EntryField): # How to subclass a Pmw megawidget when you only want to set # existing options to new default values. def __init__(self, parent = None, **kw): kw['label_foreground'] = 'blue' kw['entry_background'] = 'white' apply(Pmw.EntryField.__init__, (self, parent), kw) class NewOptions(Pmw.EntryField): # How to subclass a Pmw megawidget when you want to add new options. def __init__(self, parent=None , **kw): # Define the megawidget options. optiondefs = ( ('backgrounds', None, self._backgrounds), ) self.defineoptions(kw, optiondefs) # Initialise the base class (after defining the options). Pmw.EntryField.__init__(self, parent) # Check keywords and initialise options. self.initialiseoptions() def _backgrounds(self): background = self['backgrounds'] Pmw.Color.changecolor(self.component('hull'), background) class Demo: def __init__(self, parent): # Create and pack the megawidgets. self._extraMethod = ExtraMethods(parent, labelpos = 'w', label_text = 'Sub class with extra method:', value = 'Hello' ) self._overrideInit = OverrideInit('Again', parent, labelpos = 'w', label_text = 'Sub class with new __init__ method:', value = 'Hello' ) self._defaultOptions = DefaultOptions(parent, labelpos = 'w', label_text = 'Sub class with new default options:', value = 'Hello' ) self._newOptions = NewOptions(parent, labelpos = 'w', label_text = 'Sub class with new option:', value = 'Hello', backgrounds = 'white', ) entries = (self._extraMethod, self._overrideInit, self._defaultOptions, self._newOptions) for entry in entries: entry.pack(fill='x', expand=1, padx=10, pady=5) Pmw.alignlabels(entries) bb = Pmw.ButtonBox(parent) bb.add('Double text', command = self._doubleText) bb.pack() bb.add('Add text', command = self._addText) bb.pack() bb.add('White', command = self._changeColorWhite) bb.pack() bb.add('Green', command = self._changeColorGreen) bb.pack() def _doubleText(self): self._extraMethod.doubletext() def _addText(self): self._overrideInit.addtext() def _changeColorWhite(self): self._newOptions.configure(backgrounds = 'white') def _changeColorGreen(self): self._newOptions.configure(backgrounds = 'green') ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9191184 Pmw-2.1/Pmw/Pmw_1_3_3/demos/TextDialog.py0000664000175000017500000000400000000000000020257 0ustar00gregmgregm00000000000000title = 'Pmw.TextDialog demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): # Create the dialog. dialog = Pmw.TextDialog(parent, scrolledtext_labelpos = 'n', title = 'My TextDialog', defaultbutton = 0, label_text = 'Lawyer jokes') dialog.withdraw() dialog.insert('end', jokes) dialog.configure(text_state = 'disabled') # Create button to launch the dialog. w = Tkinter.Button(parent, text = 'Show text dialog', command = dialog.activate) w.pack(padx = 8, pady = 8) jokes = """ Q: What do you call 5000 dead lawyers at the bottom of the ocean? A: A good start! Q: How can you tell when a lawyer is lying? A: His lips are moving. Q: Why won't sharks attack lawyers? A: Professional courtesy. Q: What do have when a lawyer is buried up to his neck in sand? A: Not enough sand. Q: How do you get a lawyer out of a tree? A: Cut the rope. Q: What is the definition of a shame (as in "that's a shame")? A: When a bus load of lawyers goes off a cliff. Q: What is the definition of a "crying shame"? A: There was an empty seat. Q: What do you get when you cross the Godfather with a lawyer? A: An offer you can't understand. Q. What do lawyers use as contraceptives? A. Their personalities. Q. What's brown and black and looks good on a lawyer? A. A doberman. Q. Why are lawyers buried 12 feet underground? A. Deep down their good. Q. What's the difference between a catfish and a lawyer? A. One's a slimy scum-sucking scavenger, the other is just a fish. """ ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9151182 Pmw-2.1/Pmw/Pmw_1_3_3/demos/TextDisplay.py0000664000175000017500000000422400000000000020475 0ustar00gregmgregm00000000000000title = 'Demonstration of how to create a megawidget' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class TextDisplay(Pmw.MegaWidget): # Demo Pmw megawidget. def __init__(self, parent = None, **kw): # Define the megawidget options. optiondefs = () self.defineoptions(kw, optiondefs) # Initialise the base class (after defining the options). Pmw.MegaWidget.__init__(self, parent) # Create the components. interior = self.interior() self._text = self.createcomponent('text', (), None, Tkinter.Text, (interior,), state = 'disabled') self._text.pack(side='left', fill='both', expand='yes') self._scrollbar = self.createcomponent('scrollbar', (), None, Tkinter.Scrollbar, (interior,), command = self._text.yview) self._scrollbar.pack(side='right', fill='y') self._text.configure(yscrollcommand = self._scrollbar.set) # Check keywords and initialise options. self.initialiseoptions() def display(self, info): self._text.configure(state = 'normal') self._text.delete('1.0', 'end') self._text.insert('1.0', info) self._text.configure(state = 'disabled') def append(self, info): self._text.configure(state = 'normal') self._text.insert('end', info) self._text.configure(state = 'disabled') class Demo: def __init__(self, parent): # Create and pack the megawidget. text = TextDisplay(parent, text_background = 'aliceblue', text_width = 40, text_height = 10, text_wrap = 'none', ) text.pack(fill = 'both', expand = 1) text.display('This is an example of a simple Pmw megawidget.\n\n' + 'Public attributes of the Tkinter module:\n\n') for name in dir(Tkinter): if name[0] != '_': text.append(' ' + name + '\n') ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9191184 Pmw-2.1/Pmw/Pmw_1_3_3/demos/TimeCounter.py0000664000175000017500000000174100000000000020462 0ustar00gregmgregm00000000000000title = 'Pmw.TimeCounter demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import string import Tkinter import Pmw class Demo: def __init__(self, parent): self._time = Pmw.TimeCounter(parent, labelpos = 'w', label_text = 'HH:MM:SS', min = '00:00:00', max = '23:59:59') self._time.pack(padx=10, pady=5) button = Tkinter.Button(parent, text = 'Show', command = self.show) button.pack() def show(self): stringVal = self._time.getstring() intVal = self._time.getint() print stringVal + ' (' + str(intVal) + ')' ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9231184 Pmw-2.1/Pmw/Pmw_1_3_3/demos/WidgetDestroy.py0000664000175000017500000000175000000000000021021 0ustar00gregmgregm00000000000000title = 'Demonstration of Pmw megawidget destruction' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): # Create and pack an EntryField. self.entryfield = Pmw.EntryField(parent, command = self.execute, value = 'Press to destroy me', entry_width = 30) self.entryfield.pack(fill='x', expand=1, padx=10, pady=5) self.entryfield.component('entry').focus_set() def execute(self): print 'Return pressed, destroying EntryField.' self.entryfield.destroy() ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9391186 Pmw-2.1/Pmw/Pmw_1_3_3/doc/0000775000175000017500000000000000000000000015305 5ustar00gregmgregm00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9191184 Pmw-2.1/Pmw/Pmw_1_3_3/doc/AboutDialog.gif0000664000175000017500000001000100000000000020156 0ustar00gregmgregm00000000000000GIF87az`w`0;,zh^.I8ͻ`("Dbylp,ZipH,Ȥrl:(ԗ)جvzpzUhznW~o2(tT 8&ďuͮԎғבƎȄʢ웷ﯵنд/>[xl]rAL4ED f80=eG0F4KrPP:d0s@ŗ 7߽yCE4i$*͞jqPJѦR*2lQWhPʺ*VeXZѹ`@s!ۖےj[dKPDOcm98Ü/*XK18Ec\A-Fj饘ftNjJ*ꨤejꪬꪩRꫴj뭀ƺ%hZ)k,z6hF+If&vp 6+n.+:K2jo,0lf kmG0Wg,/!qef¬fm,s+<+b<7t:s`~@'s/sxIsټ\<ۼ5S_0l2V%nKPCqM1ecu;ڃ -#Q3|4ߌڍk͈G9璇 Ԇw9̨On N脣-x퍧{ˎN9t]x屏 _+ݺ_s-^oOx͔g>Ӧ>?'O* (ZL`' f ̠0n A(Npo&LaHn.Q(6!sP>dt? 1eCSA= g0,eױH^7mlI\3,/y+]W=-ꬌK:t5&}гbҾ'1]Ɨ< " C0 .c#4869GG|YUk"'ZNRʲ.]0)aJu oD鐖B]3ӤH;󚩖=BX|eI T7k R*74qlk+IɳuļFU8[m[(Q1mhD3 ԑyT(Y]d JEl.;Ӈ> Yh%Tlc./f#U]pu*cZ`>&N+Jҙ` }y;i/\hIݼ&׾--~rOȱ]Gz N^h1]wG5uR٥x\X1!(GeTC;WlF|5l)=@8HWxds)d=V7z`҄9vvouR|G[68=|ցMXhfxHl~4r1_f}u&W+OB#K o7ˇbv~,}H+fEEo!uBmU҈nioѷZӕyx{iftx-z~(9D?O6U(P楅dHdW˜-*URU"GbOc1|eevZXLsHqIHattWxv3eՋTf7XLȂfpą$٤^cMu h{@xޒi]ؑÑ _dHL i$](g%dXe Ē6YJQp _E|Byԉ@o$(F|\ƀw,)y%zwe3JxEh*:ZEUsEvdרs"xSyA3I*0tYw>4'H 9oku'f}FyuLfi)XswTxVM8*imƌiSPcVY|Iux7qr&YP(Պj{(%t` +}jVLJKH gb{}>ԧO*l›Z_.i/mDU#\.yi ZLڠ*[:㒠z+*"Zy( 9$y.ZEӢ4:@0z:z,6ڣɣ@J,BFzHJLڤNPR:TZVzXZ\ڥ^jy%b:dZfzhjN"C+?9r:/qZxzڧ:+>w:ZtG]¦XʠZ%@fh)j> +Z3:hک_? k*1ԫʩjcFٔ`$sHgԖ{bZ; VpjkaPQ ӮZEȇfښc=i4Z*L<c"**K kQxwr:ʬӃ33ٲ늰&#+vı) < |J"Wd㳶 4kJ7c"N{j(ˢT )VKҩ[,8ˢ,F˫PKM;ni۱R Pmw.AboutDialog reference manual

Pmw.AboutDialog

Name

Pmw.AboutDialog() - window to display version and contact information

Inherits

Pmw.MessageDialog

Description

An about dialog is a dialog window which displays information about the application, such as name, version, copyright and contact details.

The text of the message is constructed from the application name (given by the applicationname option) followed by the values supplied in the most recent calls to Pmw.aboutversion(), Pmw.aboutcopyright() and Pmw.aboutcontact() functions.

The icon of the message defaults to 'info', but may be changed using the icon_bitmap component option.

Options

Options for this megawidget and its base classes are described below.

activatecommand
If this is callable, it will be called whenever the megawidget is activated by a call to activate(). The default is None.

applicationname
Initialisation option. The name of application, to be dispayed in the dialog body and in the window title if the title option is not given. The default is ''.

borderx
Initialisation option. The padding to the left and right of the text message and icon. The default is 20.

bordery
Initialisation option. The padding above and below the text message and icon. The default is 20.

buttonboxpos
Initialisation option. Specifies on which side of the dialog window to place the button box. Must be one of 'n', 's', 'e' or 'w'. The default is 's'.

buttons
This must be a tuple or a list and specifies the names on the buttons in the button box. The default is ('Close',).

command
Specifies a function to call whenever a button in the button box is invoked or the window is deleted by the window manager. The function is called with a single argument, which is the name of the button which was invoked, or None if the window was deleted by the window manager.

If the value of command is not callable, the default behaviour is to deactivate the window if it is active, or withdraw the window if it is not active. If it is deactivated, deactivate() is called with the button name or None as described above. The default is None.

deactivatecommand
If this is callable, it will be called whenever the megawidget is deactivated by a call to deactivate(). The default is None.

defaultbutton
Specifies the default button in the button box. If the <Return> key is hit when the dialog has focus, the default button will be invoked. If defaultbutton is None, there will be no default button and hitting the <Return> key will have no effect. The default is 0.

iconmargin
Initialisation option. The padding between the text message and icon. The default is 20.

iconpos
Initialisation option. Specifies on which side of the text message to place the icon. Must be one of 'n', 's', 'e' or 'w'. The default is 'w'.

master
This is used by the activate() method to control whether the window is made transient during modal dialogs. See the activate() method. The default is 'parent'.

separatorwidth
Initialisation option. If this is greater than 0, a separator line with the specified width will be created between the button box and the child site, as a component named separator. Since the default border of the button box and child site is raised, this option does not usually need to be set for there to be a visual separation between the button box and child site. The default is 0.

title
This is the title that the window manager displays in the title bar of the window. The default is None.

Components

Components created by this megawidget and its base classes are described below.

buttonbox
This is the button box containing the buttons for the dialog. By default it is created with the options (hull_borderwidth = 1, hull_relief = 'raised'). By default, this component is a Pmw.ButtonBox.

dialogchildsite
This is the child site for the dialog, which may be used to specialise the megawidget by creating other widgets within it. By default it is created with the options (borderwidth = 1, relief = 'raised'). By default, this component is a Tkinter.Frame.

hull
This acts as the body for the entire megawidget. Other components are created as children of the hull to further specialise this class. By default, this component is a Tkinter.Toplevel.

icon
If the iconpos option is not None, this component is created to contain the icon label for the dialog. To display a bitmap as an icon, set the icon_bitmap component option to any of the forms acceptable to Tk, such as 'warning' or 'error'. By default, this component is a Tkinter.Label.

message
The label to contain the text message for the dialog. To set the text, use the message_text component option. By default, this component is a Tkinter.Label.

separator
If the separatorwidth initialisation option is non-zero, the separator component is the line dividing the area between the button box and the child site. By default, this component is a Tkinter.Frame.

Methods

This megawidget has no methods of its own. For a description of its inherited methods, see the manual for its base class Pmw.MessageDialog.

Example

The image at the top of this manual is a snapshot of the window (or part of the window) produced by the following code.

class Demo:
    def __init__(self, parent):
        # Create dialog.
        Pmw.aboutversion('9.9')
        Pmw.aboutcopyright('Copyright My Company 1999\nAll rights reserved')
        Pmw.aboutcontact(
            'For information about this application contact:\n' +
            '  My Help Desk\n' +
            '  Phone: +61 2 9876 5432\n' +
            '  email: help@my.company.com.au'
        )
        self.about = Pmw.AboutDialog(parent, applicationname = 'My Application')
        self.about.withdraw()

        # Create button to launch the dialog.
        w = Tkinter.Button(parent, text = 'Show about dialog',
                command = self.execute)
        w.pack(padx = 8, pady = 8)

    def execute(self):
        self.about.show()

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 18 May 2002

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9191184 Pmw-2.1/Pmw/Pmw_1_3_3/doc/Balloon.gif0000664000175000017500000001110000000000000017353 0ustar00gregmgregm00000000000000GIF87a0`N @@ ttt 4@@&{ N0 O @E-9$@@@B},?+9Btt?E-xL{t @<\\7+@Ixt @t\XtBX0@@"X@Kx٘-8 N $_  ||-&x/x @Dtx|А2 @@aa PzN\R``݌8@$`@Dl@HȜyP,z\kx А2 Qk@@8$@tlE-@@`y{Pz ,H*\ȰÇ#JHŋ3jȱǏ ! ɓ(S\ɲ˗0,͛8sSL= JQ?ӧPJJիXjʵׯ_z]z0iI7]˶۷p>=k+ݥfѦ _J @0 ƛ/̦# ⦉ @xѼYB^CQVa闭Y^(4vj.ο {6 zuJȸ}yD[`gY7~AԦ U?=${ _v x!yv搂!H)w z)sVrZ8aʖ]Hb%_(~) wYc8`@.XߏIW]ِj%^L"G6c]I>r'A W9zDߖQJɡzաj'D$vHgsIێH2}eWHetf>bXd{@B*dTBiډi 穖ngh`r&&Qd6ѣ~Fj饨ViJ*vUk멿b듶p:Tf4Ȣ!  J! Ik޾(٦[*[*&PV{M +kp8\SSfeqo1JٿALD =ʍq'U5LsDY%Yܓ77{ʲ T4 !>t 5FZ\L{Fݴ\s,WX'tmv%K_K`%*5Oh;6}ӕe,:'aQJ H)p E,pkx8!n=s(ضzD}nI UW.Є[7? ŽۛFf3En8\I 6L׉ ׶6֯n{UƜ0v],ӌF7q S2'wTdF:h4I!Stț$2n|&79$E[WI\k3dJ-%lU)krʠ-R-aZJR0I-ov@^M1}m/i%!`X)l(M_6)XsOuMpFԨη~T?q (KV|#>$U 8΅24#}(sʼn=1O=?ꑐԚr S4MSX<(ՋiG.rrٍZ±#Gԅ<" 9]d<6QTQadX]iƒV):Ua`IW/gI\Bx26Fz#J>P`tWO REh֎xE^ߩZޭo|垺'ۆj, j=*x|;W\V]U2L5#saƍjt[D֖'%JYڹe1SJ^>$O{-^bտhR;3`SػF0LE̍7 ow%P7<]T_ =N0gHJQnTi@H劓&XN)[ɰ.{`ɴ0hNU2SD@L:Xxγ@f9bpf`LByNt|> wca,+Mјf0A"5΀X,L7yf0 -0/7tmj.fV֗5XGlײjc Y {tVe4Fn6DJlU~?e[Yv+U{'MF-en;O.Őc[0F ghڍv6i]v \oOw+& TF|ڌ/SWodok8T\gxg~ M#D;Ikǧ.Sꑴ:ַ^se :uA:^&pNxϻ.w_O 9vO=zĝrw=|7Ò8.$rM'xHo/r;_|Ⱦ r_Jm'v}~Ww|~x~g "W}_N*Cg(Mǀ~87H~W(qǁ 2,4<4;$&8w37-~/(94X~8HSx7+_4_E;bCGԄPh;ȅVhW}_ӗ{D(Yr HJȆs׀tHxXR;4dʄ5K5'瀗؀v<(s؅ӇNx6QCLFS=bAsA|IyȨwgx2etGVzf8~ug{HjH3 Eҍ&XywWGVՌ8xdИ8f؏8d]Sy ِ IvXNpYyّ d)M(*,#d%K'ْ4Y6yH48@GƓzsY%J7THhft16ْ>YMITYO*32`)X ɖ\9pٖZّDIbR8fkQ]yo)Vi)s9 way)?{Y} )镦9 ɘ G9}%Qj\5陣ɘ隰Y )C؉r)H4_KқyYI ɜyCH"7&V{'&+_iYՙݙYyI ʞ9vw-9$;DM)Dɞ 剞y Jz`wIAzq@ %vZ$#ژɢٙGK fG'h9R*\)\["DNʔd\)h}dxJ!ڣ%@[A*YzڠaRGHCk:dʥ[ڡ  {:s:XETp_*E.I@M䟏:`)4FF(뱪_Z=OJn:~*YKYC!BY#jǺDᗊ)EJ2uJJlQ&yʕZ`Voji*M:ZFGu  {腯 ʮ*{:Lfy ;[]7L*)++[\-5ڱ>kӊpճ?[4FF۴9PR[LEKSZtVVX˵b;dH^[jlkpr;ٶv{xz|۷~;[{۸;[{۹;[{ۺ;[{ۻ;[{țʻۼ;[({؛ڻ۽;[{蛾껾۾+;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9231184 Pmw-2.1/Pmw/Pmw_1_3_3/doc/Balloon.html0000664000175000017500000004061700000000000017571 0ustar00gregmgregm00000000000000 Pmw.Balloon reference manual

Pmw.Balloon

Name

Pmw.Balloon() - display "tool tips" for a number of widgets

Inherits

Pmw.MegaToplevel

Description

A balloon megawidget can be used to give short help messages to the user when they place the mouse over a button or other widget for a short time. It can also be used to display help messages for canvas or text items.

One balloon megawidget can be used to display help for many widgets or items. For each widget or item that requires balloon help, the bind() or bindtag() method is used to specify the help text that should be displayed.

The help message is displayed in a popup balloon window when the mouse remains over the widget or item for a short time. The popup balloon is withdrawn when the mouse leaves the widget or item, or any mouse buttons are pressed.

The position of the popup balloon is configurable and may appear either relative to the widget or item or relative to the position of the mouse.

The popup balloon is displayed without any window manager decorations.

The megawidget can cooperate with a Pmw.MessageBar to display a single-line help message as well as the balloon help.

Options

Options for this megawidget and its base classes are described below.

activatecommand
If this is callable, it will be called whenever the megawidget is activated by a call to activate(). The default is None.

deactivatecommand
If this is callable, it will be called whenever the megawidget is deactivated by a call to deactivate(). The default is None.

initwait
The number of milliseconds delay between when the mouse enters a widget or item and when the popup balloon window should be displayed. The default is 500.

master
This is used by the activate() method to control whether the window is made transient during modal dialogs. See the activate() method. The default is 'parent'.

relmouse
This may be one of 'both', 'x', 'y' or 'none' and indicates that the top left corner of the popup balloon window should be placed relative to the current position of the mouse rather than relative to the bottom left corner of the widget or item (the default). The positioning may be set for the horizontal (x) and vertical (y) axes independently. The default is 'none'.

state
This may be one of 'both', 'balloon', 'status' or 'none' and indicates whether the help message should be displayed in the popup balloon window, in an associated messagebar (via the statuscommand option), or both. The default is 'both'.

statuscommand
This specifies a function to call when the mouse enters a widget or item bound to this balloon megawidget. To configure a Pmw.MessageBar to display help, set this option to the helpmessage method of the messagebar. The default is None.

title
This is the title that the window manager displays in the title bar of the window. The default is None.

xoffset
This specifies the horizontal offset of the position of the left side of the popup balloon window relative the point determined by the relmouse option. The default is 20.

yoffset
This specifies the vertical offset of the position of the top of the popup balloon window relative the point determined by the relmouse option. The default is 1.

Components

Components created by this megawidget and its base classes are described below.

hull
This acts as the body for the entire megawidget. Other components are created as children of the hull to further specialise this class. By default, this component is a Tkinter.Toplevel.

label
This component displays the text of the help message in the popup balloon window. By default it is created with a 'lightyellow' background, a 'black' foreground and is 'left' justified. By default, this component is a Tkinter.Label.

Methods

Only methods specific to this megawidget are described below. For a description of its inherited methods, see the manual for its base class Pmw.MegaToplevel.

bind(widget, balloonHelp, statusHelp = None)
Create bindings for widget so that balloon help and/or status help is displayed when the mouse enters the widget. The balloon help message is given by balloonHelp and the status help message is given by statusHelp. If balloonHelp is None, no balloon is displayed. If statusHelp is not set, it defaults to balloonHelp. Any previous bindings for this widget are removed.

clearstatus()
Clear the text in the associated messagebar by passing None to the statuscommand function.

showstatus(statusHelp)
Set the text in the associated messagebar by passing statusHelp to the statuscommand function.

tagbind(widget, tagOrItem, balloonHelp, statusHelp = None)
Create bindings for the tag or item specified by tagOrItem in the text or canvas widget so that balloon help and/or status help is displayed when the mouse enters the tag or item. The balloon help message is given by balloonHelp and the status help message is given by statusHelp. If balloonHelp is None, no balloon is displayed. If statusHelp is not set, it defaults to balloonHelp. Any previous bindings for this tag or item are removed.

tagunbind(widget, tagOrItem)
Remove the balloon help bindings from the tag or item specified by tagOrItem in the text or canvas widget.

Note that tagunbind() must be called when deleting a canvas item, so that the popup balloon window can be withdrawn if it was triggered by the item. (Unfortunately this can not be automated as is done for widgets since Tk does not support <Destroy> bindings on canvas items, so there is no way that Pmw.Balloon can be notified of the deletion of an item.)

unbind(widget)
Remove the balloon help bindings from widget.

Example

The image at the top of this manual is a snapshot of the window (or part of the window) produced by the following code.

class Demo:
    def __init__(self, parent):
        # Create the Balloon.
        self.balloon = Pmw.Balloon(parent)

        # Create some widgets and megawidgets with balloon help.
        frame = Tkinter.Frame(parent)
        frame.pack(padx = 10, pady = 5)
        field = Pmw.EntryField(frame,
                labelpos = 'nw',
                label_text = 'Command:')
        field.setentry('mycommand -name foo')
        field.pack(side = 'left', padx = 10)
        self.balloon.bind(field, 'Command to\nstart/stop',
                'Enter the shell command to control')

        start = Tkinter.Button(frame, text='Start')
        start.pack(side='left', padx = 10)
        self.balloon.bind(start, 'Start the command')

        stop = Tkinter.Button(frame, text='Stop')
        stop.pack(side='left', padx = 10)
        self.balloon.bind(stop, 'Stop the command')

        self.suicide = Tkinter.Button(frame, text='Kill me soon!',
            command = self.killButton)
        self.suicide.pack(side='left', padx = 10)
        self.balloon.bind(self.suicide, 'Watch this button disappear!')

        scrolledCanvas = Pmw.ScrolledCanvas(parent,
                canvas_width = 300,
                canvas_height = 115,
        )
        scrolledCanvas.pack()
        canvas = scrolledCanvas.component('canvas')
        self.canvas = canvas

        # Create some canvas items and individual help.
        item = canvas.create_arc(5, 5, 35, 35, fill = 'red', extent = 315)
        self.balloon.tagbind(canvas, item, 'This is help for\nan arc item')
        item = canvas.create_bitmap(20, 150, bitmap = 'question')
        self.balloon.tagbind(canvas, item, 'This is help for\na bitmap')
        item = canvas.create_line(50, 60, 70, 80, 85, 20, width = 5)
        self.balloon.tagbind(canvas, item, 'This is help for\na line item')
        item = canvas.create_text(10, 90, text = 'Canvas items with balloons',
                anchor = 'nw', font = field.cget('entry_font'))
        self.balloon.tagbind(canvas, item, 'This is help for\na text item')

        # Create two canvas items which have the same tag and which use
        # the same help.
        canvas.create_rectangle(100, 10, 170, 50, fill = 'aliceblue',
                tags = 'TAG1')
        self.bluecircle = canvas.create_oval(110, 30, 160, 80, fill = 'blue',
                tags = 'TAG1')
        self.balloon.tagbind(canvas, 'TAG1',
                'This is help for the two blue items' + '\n' * 10 +
                    'It is very, very big.',
                'This is help for the two blue items')
        item = canvas.create_text(180, 10, text = 'Delete',
                anchor = 'nw', font = field.cget('entry_font'))
        self.balloon.tagbind(canvas, item,
                'After 2 seconds,\ndelete the blue circle')
        canvas.tag_bind(item, '<ButtonPress>', self._canvasButtonpress)
        scrolledCanvas.resizescrollregion()

        scrolledText = Pmw.ScrolledText(parent,
                text_width = 32,
                text_height = 4,
                text_wrap = 'none',
        )
        scrolledText.pack(pady = 5)
        text = scrolledText.component('text')
        self.text = text

        text.insert('end',
                'This is a text widget with ', '',
                ' balloon', 'TAG1',
                '\nhelp. Find the ', '',
                ' text ', 'TAG1',
                ' tagged with', '',
                ' help.', 'TAG2',
                '\n', '',
                'Remove tag 1.', 'TAG3',
                '\nAnother line.\nAnd another', '',
        )
        text.tag_configure('TAG1', borderwidth = 2, relief = 'sunken')
        text.tag_configure('TAG3', borderwidth = 2, relief = 'raised')

        self.balloon.tagbind(text, 'TAG1',
                'There is one secret\nballoon help.\nCan you find it?')
        self.balloon.tagbind(text, 'TAG2',
                'Well done!\nYou found it!')
        self.balloon.tagbind(text, 'TAG3',
                'After 2 seconds\ndelete the tag')
        text.tag_bind('TAG3', '<ButtonPress>', self._textButtonpress)

        frame = Tkinter.Frame(parent)
        frame.pack(padx = 10)
        self.toggleBalloonVar = Tkinter.IntVar()
        self.toggleBalloonVar.set(1)
        toggle = Tkinter.Checkbutton(frame,
                variable = self.toggleBalloonVar,
                text = 'Balloon help', command = self.toggle)
        toggle.pack(side = 'left', padx = 10)
        self.balloon.bind(toggle, 'Toggle balloon help\non and off')

        self.toggleStatusVar = Tkinter.IntVar()
        self.toggleStatusVar.set(1)
        toggle = Tkinter.Checkbutton(frame,
                variable = self.toggleStatusVar,
                text = 'Status help', command = self.toggle)
        toggle.pack(side = 'left', padx = 10)
        self.balloon.bind(toggle,
                'Toggle status help on and off, on and off' + '\n' * 10 +
                    'It is very, very big, too.',
                'Toggle status help on and off')

        # Create and pack the MessageBar.
        messageBar = Pmw.MessageBar(parent,
                entry_width = 40,
                entry_relief='groove',
                labelpos = 'w',
                label_text = 'Status:')
        messageBar.pack(fill = 'x', expand = 1, padx = 10, pady = 5)

        # Configure the balloon to display its status messages in the
        # message bar.
        self.balloon.configure(statuscommand = messageBar.helpmessage)

    def toggle(self):
        if self.toggleBalloonVar.get():
            if self.toggleStatusVar.get():
                self.balloon.configure(state = 'both')
            else:
                self.balloon.configure(state = 'balloon')
        else:
            if self.toggleStatusVar.get():
                self.balloon.configure(state = 'status')
            else:
                self.balloon.configure(state = 'none')

    def killButton(self):
        # Test for old bug when destroying widgets 1) while the
        # balloon was up and 2) during the initwait period.
        print 'Destroying button in 2 seconds'
        self.suicide.after(2000, self.suicide.destroy)

    def _canvasButtonpress(self, event):
        print 'Destroying blue circle in 2 seconds'
        self.canvas.after(2000, self.deleteBlueCircle)

    def deleteBlueCircle(self):
        self.balloon.tagunbind(self.canvas, self.bluecircle)
        self.canvas.delete(self.bluecircle)

    def _textButtonpress(self, event):
        print 'Deleting the text tag in 2 seconds'
        self.text.after(2000, self.deleteTextTag)

    def deleteTextTag(self):
        self.balloon.tagunbind(self.text, 'TAG1')
        self.text.tag_delete('TAG1')

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 20 May 2002

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9231184 Pmw-2.1/Pmw/Pmw_1_3_3/doc/Blt.html0000664000175000017500000000754200000000000016724 0ustar00gregmgregm00000000000000 Pmw.Blt reference manual

Pmw.Blt

Name

Pmw.Blt - interface to some BLT widgets and commands

Description

This module contains function interfaces to the BLT busy command as well as the classes Pmw.Blt.Vector, Pmw.Blt.Graph, Pmw.Blt.Stripchart and Pmw.Blt.Tabset, which are interfaces to the vector, graph, stripchart and tabset commands of version 2.4 of the BLT extension to Tk. The interfaces are complete except for Pmw.Blt.Vector where several creation options, methods and operations have not been implemented.

The blt graph and barchart widgets are essentially the same and so only the graph widget has been ported. The element_create() method is not implememted for Pmw.Blt.Graph, so instead:

  • to create a line element, use the line_create() method and

  • to create a bar element, use the bar_create() method.

To operate on elements, use the element_*() methods, such as element_bind(), element_activate(), etc.

Note: Full documentation of Pmw.Blt.Graph is available in A User's Guide to Pmw.Blt written by Bjorn Ove Thue and Hans Petter Langtangen. You can also download the full HTML document of the guide for local viewing.

Functions

The following functions are available.

Pmw.Blt.busy_forget(window)
Interface to the BLT busy forget command.

Pmw.Blt.busy_hold(window, cursor = None)
Interface to the BLT busy hold command.

Pmw.Blt.busy_release(window)
Interface to the BLT busy release command.

Pmw.Blt.haveblt(window)
Return true if any commands in the BLT extension are available.

Pmw.Blt.havebltbusy(window)
Return true if the BLT busy command is available.

Pmw.Blt.setBltDisable(window, value)

Pmw.Blt.vector_expr(expression)
Interface to the BLT vector expr command.

Pmw.Blt.vector_names(pattern = None)
Interface to the BLT vector names command.

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 25 May 2002

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9191184 Pmw-2.1/Pmw/Pmw_1_3_3/doc/ButtonBox.gif0000664000175000017500000000170500000000000017723 0ustar00gregmgregm00000000000000GIF87a)Aق,)Aڋ޼H扦ʶ LĢL*̦ JԪ: ܮ N kwGX7XhȘ8(9aI9 H*JYi5j'j*)z+jiLfQ֠l ]<]FKmͅ *|]'ԛMX^ލ+>0Nߧ ?>ka! 'ϡWQb4h!1tPcdB:V>Hæcg.#Pu4gD&ԃ̛E@p5a4f-uѪ @Z_j JZ nSmepVmֵ# ae PCpl8Y-_lL z=vmitrثӇiUY`7\9Td ֋<­%ӈ8ԓO A'R/ /:<c=ǠK72A~/y}8 2(n]ߝ߁e5^8@^u}_g)v0kH`ˉG,F\q^AxuMV,eUG%\JvFH_LZI$LmeiN(UnVnTHb~`y5FS*,m6H:8)fIP :As($faO̺*ęJ^ȩFjl4`K鲃gE4JPʕ2޷"1lfnnnʪT-Ko6{okp®lW/<oNN#g̱!Wq4| @&r*;. s2G#r6ߌs:s> tBMtx;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9191184 Pmw-2.1/Pmw/Pmw_1_3_3/doc/ButtonBox.html0000664000175000017500000002647300000000000020133 0ustar00gregmgregm00000000000000 Pmw.ButtonBox reference manual

Pmw.ButtonBox

Name

Pmw.ButtonBox() - manager megawidget for buttons

Inherits

Pmw.MegaWidget

Description

A button box is a container megawidget which manages a number of buttons. One of these buttons may be specified as the default and it will be displayed with the platform specific appearance for a default button. The buttons may be laid out either horizontally or vertically.

Options

Options for this megawidget and its base classes are described below.

labelmargin
Initialisation option. If the labelpos option is not None, this specifies the distance between the label component and the rest of the megawidget. The default is 0.

labelpos
Initialisation option. Specifies where to place the label component. If not None, it should be a concatenation of one or two of the letters 'n', 's', 'e' and 'w'. The first letter specifies on which side of the megawidget to place the label. If a second letter is specified, it indicates where on that side to place the label. For example, if labelpos is 'w', the label is placed in the center of the left hand side; if it is 'wn', the label is placed at the top of the left hand side; if it is 'ws', the label is placed at the bottom of the left hand side.

If None, a label component is not created. The default is None.

orient
Initialisation option. Specifies the orientation of the button box. This may be 'horizontal' or 'vertical'. The default is 'horizontal'.

padx
Initialisation option. Specifies a padding distance to leave between each button in the x direction and also between the buttons and the outer edge of the button box. The default is 3.

pady
Initialisation option. Specifies a padding distance to leave between each button in the y direction and also between the buttons and the outer edge of the button box. The default is 3.

Components

Components created by this megawidget and its base classes are described below.

frame
If the label component has been created (that is, the labelpos option is not None), the frame component is created to act as the container of the buttons created by the add() and insert() methods. If there is no label component, then no frame component is created and the hull component acts as the container. By default, this component is a Tkinter.Frame.

hull
This acts as the body for the entire megawidget. Other components are created as children of the hull to further specialise this class. By default, this component is a Tkinter.Frame.

label
If the labelpos option is not None, this component is created as a text label for the megawidget. See the labelpos option for details. Note that to set, for example, the text option of the label, you need to use the label_text component option. By default, this component is a Tkinter.Label.

Dynamic components

Button components are created dynamically by the add() and insert() methods. By default, the buttons are of type Tkinter.Button and are created with a component group of Button.

Methods

Only methods specific to this megawidget are described below. For a description of its inherited methods, see the manual for its base class Pmw.MegaWidget.

add(componentName, **kw)
Add a button to the end of the button box as a component named componentName. Any keyword arguments present will be passed to the constructor when creating the button. If the text keyword argument is not given, the text option of the button defaults to componentName. The method returns the component widget.

alignbuttons(when = 'later')
Set the widths of all the buttons to be the same as the width of the widest button. If when is 'later', this will occur when the interpreter next becomes idle, otherwise the resizing will occur immediately.

button(buttonIndex)
Return the button specified by buttonIndex, which may have any of the forms accepted by the index() method.

delete(index)
Delete the button given by index from the button box. index may have any of the forms accepted by the index() method.

index(index, forInsert = 0)
Return the numerical index of the button corresponding to index. This may be specified in any of the following forms:

name
Specifies the button named name.

number
Specifies the button numerically, where 0 corresponds to the left (or top) button.

Pmw.END
Specifies the right (or bottom) button.

Pmw.DEFAULT
Specifies the current default button.

If forInsert is true, Pmw.END returns the number of buttons rather than the index of the last button.

insert(componentName, beforeComponent = 0, **kw)
Add a button to the button box as a component named componentName. The button is added just before the button specified by beforeComponent, which may have any of the forms accepted by the index() method. Any keyword arguments present will be passed to the constructor when creating the button. If the text keyword argument is not given, the text option of the button defaults to componentName. To add a button to the end of the button box, use add(). The method returns the component widget.

invoke(index = Pmw.DEFAULT, noFlash = 0)
Invoke the callback command associated with the button specified by index and return the value returned by the callback. Unless noFlash is true, flash the button to indicate to the user that something happened. index may have any of the forms accepted by the index() method.

numbuttons()
Return the number of buttons in the button box.

setdefault(index)
Set the default button to the button given by index. This causes the specified button to be displayed with the platform specific appearance for a default button. If index is None, there will be no default button. index may have any of the forms accepted by the index() method.

Example

The image at the top of this manual is a snapshot of the window (or part of the window) produced by the following code.

class Demo:
    def __init__(self, parent):
        # Create and pack the ButtonBox.
        self.buttonBox = Pmw.ButtonBox(parent,
                labelpos = 'nw',
                label_text = 'ButtonBox:',
                frame_borderwidth = 2,
                frame_relief = 'groove')
        self.buttonBox.pack(fill = 'both', expand = 1, padx = 10, pady = 10)

        # Add some buttons to the ButtonBox.
        self.buttonBox.add('OK', command = self.ok)
        self.buttonBox.add('Apply', command = self.apply)
        self.buttonBox.add('Cancel', command = self.cancel)

        # Set the default button (the one executed when <Return> is hit).
        self.buttonBox.setdefault('OK')
        parent.bind('<Return>', self._processReturnKey)
        parent.focus_set()

        # Make all the buttons the same width.
        self.buttonBox.alignbuttons()

    def _processReturnKey(self, event):
        self.buttonBox.invoke()

    def ok(self):
        print 'You clicked on OK'

    def apply(self):
        print 'You clicked on Apply'

    def cancel(self):
        print 'You clicked on Cancel'

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 24 May 1998

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9231184 Pmw-2.1/Pmw/Pmw_1_3_3/doc/Color.html0000664000175000017500000003162400000000000017257 0ustar00gregmgregm00000000000000 Pmw.Color reference manual

Pmw.Color

Name

Pmw.Color - contains functions for handling colors and color schemes

Description

This module is a set of functions for manipulating colors and for modifying the color scheme of an application or a widget. Many of the functions in this module take or return colors. These values may represent colors in the following ways:

name
a standard color name, eg 'orange' or '#ffa500'

rgb
a 3-element sequence of red, green and blue intensities each between 0.0 (dark) and 1.0 (light), eg [1.0, 0.6, 0.0].

hsi
a 3-element sequence (hue, saturation, intensity). The value of hue is between 0.0 and 2pi (6.28318) giving a range of colors covering, in order, red, orange, yellow green, cyan, blue, magenta and back to red. The value of saturation is between 0.0 (grey) and 1.0 (brilliant) and the value of intensity is between 0.0 (dark) and 1.0 (bright).

As used in these functions, the brightness of a color is the perceived grey level of the color as registered by the human eye. For example, even though the colors red, blue and yellow have the same intensity (1.0), they have different brightnesses, 0.299, 0.114 and 0.886 respectively, reflecting the different way these colors appear to the eye. The brightness of a color is a value between 0.0 (dark) and 1.0 (bright).

A color scheme is a set of colors defined for each of the default color options in the Tk option database. Color schemes can be used in two ways. Firstly, using Pmw.Color.setscheme(), the Tk option database can be set to the values in the color scheme. This will not have any effect on currently existing widgets, but any new widgets created after setting the options will have these colors as their defaults. Secondly, using Pmw.Color.changecolor() the color scheme can be used to change the colors of a widget and all its child widgets.

A color scheme is specified by defining one or more color options (one of the defined options must be background). Not all options need be specified - if any options are not defined, they are calculated from the other colors. These are the options used by a color scheme, together with their values if not specified:

 background:            (must be specified)
 foreground:            black
 activeForeground:      same as foreground
 insertBackground:      same as foreground
 selectForeground:      same as foreground
 highlightColor:        same as foreground
 disabledForeground:    between fg and bg but closer to bg
 highlightBackground:   same as background
 activeBackground:      a little lighter that bg
 selectBackground:      a little darker that bg
 troughColor:           a little darker that bg
 selectColor:           yellow

There are many functions in this module. As well as Pmw.Color.setscheme() and Pmw.Color.changecolor(), some of the most useful are Pmw.Color.spectrum(), Pmw.Color.changebrightness() and Pmw.Color.getdefaultpalette().

Functions

The following functions are available.

Pmw.Color.average(rgb1, rgb2, fraction)
Return an rgb color fraction of the way "between" the colors rgb1 and rgb2, where fraction must be between 0.0 and 1.0. If fraction is close to 0.0, then the color returned will be close to rgb1. If it is close to 1.0, then the color returned will be close to rgb2. If it is near 0.5, then the color returned will be half way between the two colors.

Pmw.Color.bhi2saturation(brightness, hue, intensity)
Return the saturation of the color represented by brightness, hue and intensity.

Pmw.Color.bordercolors(root, colorName)
Return a tuple (light, dark) of color names that can be used as the light and dark border shadows on a widget where the background is colorName. This is the same method that Tk uses for shadows when drawing reliefs on widget borders. The root argument is only used to query Tk for the rgb values of colorName.

Pmw.Color.changebrightness(root, colorName, brightness)
Find the hue of the color colorName and return a color of this hue with the required brightness. If brightness is None, return the name of color with the given hue and with saturation and intensity both 1.0. The root argument is only used to query Tk for the rgb values of colorName.

Pmw.Color.changecolor(widget, background = None, **kw)
Change the color of widget and all its child widgets according to the color scheme specified by the other arguments. This is done by modifying all of the color options of existing widgets that have the default value. The color options are the lower case versions of those described in the color scheme section. Any options which are different to the previous color scheme (or the defaults, if this is the first call) are not changed.

For example to change a widget to have a red color scheme with a white foreground:

 Pmw.Color.changecolor(widget,
     background = 'red3', foreground = 'white')

The colors of widgets created after this call will not be affected.

Note that widget must be a Tk widget or toplevel. To change the color of a Pmw megawidget, use it's hull component. For example:

 widget = megawidget.component('hull')
 Pmw.Color.changecolor(widget, background = 'red3')

Pmw.Color.correct(rgb, correction)
Return the "corrected" value of rgb. This can be used to correct for dull monitors. If correction is less than 1.0, the color is dulled. If correction is greater than 1.0, the color is brightened.

Pmw.Color.getdefaultpalette(root)
Return a dictionary of the default values of the color options described in the color scheme section.

To do this, a few widgets are created as children of root, their defaults are queried, and then the widgets are destroyed. (Tk supplies no other way to get widget default values.)

Note that root must be a Tk widget or toplevel. To use a Pmw megawidget as the root, use it's hull component. For example:

 root = megawidget.component('hull')
 Pmw.Color.getdefaultpalette(root)

Pmw.Color.hsi2rgb(hue, saturation, intensity)
Return the rgb representation of the color represented by hue, saturation and intensity.

Pmw.Color.hue2name(hue, brightness = None)
Return the name of the color with the specified hue and brightness. If hue is None, return a grey of the requested brightness. Otherwise, the value of hue should be as described above. If brightness is None, return the name of color with the given hue and with saturation and intensity both 1.0.

Pmw.Color.name2rgb(root, colorName, asInt = 0)
Return colorName as an rgb value. If asInt is true, then the elements of the return sequence are in the range 0 to 65535 rather than 0.0 to 1.0. The root argument is only used to query Tk for the rgb values of colorName.

Pmw.Color.rgb2brightness(rgb)
Return the brightness of the color represented by rgb.

Pmw.Color.rgb2hsi(rgb)
Return a tuple (hue, saturation, intensity) corresponding to the color specified by the rgb sequence.

Pmw.Color.rgb2name(rgb)
Return the name of the color represented by rgb as a string of the form '#RRGGBB' suitable for use with Tk color functions.

Pmw.Color.setscheme(root, background = None, **kw)
Set the color scheme for the application by setting default colors (in the Tk option database of the root window of root) according to the color scheme specified by the other arguments. This will affect the initial colours of all widgets created after the call to this function.

For example to initialise an application to have a red color scheme with a white foreground:

 Pmw.Color.setscheme(root,
     background = 'red3', foreground = 'white')

This function does not modify the colors of already existing widgets. Use Pmw.Color.changecolor() to do this.

Note that root must be a Tk widget or toplevel. To use the Tk option database of the root window of a Pmw megawidget, use the megawidget's hull component. For example:

 root = megawidget.component('hull')
 Pmw.Color.setscheme(root, background = 'red3')

Pmw.Color.spectrum(numColors, correction = 1.0, saturation = 1.0, intensity = 1.0, extraOrange = 1, returnHues = 0)
Return a list of numColors different colors making up a spectrum. If extraOrange is false, the colors are evenly spaced by hue from one end of the spectrum (red) to the other (magenta). If extraOrange is true, the hues are not quite evenly spaced - the hues around orange are emphasised, thus preventing the spectrum from appearing to have to many cool hues.

If returnHues is false, the return values are the names of the colors represented by the hues together with saturation and intensity and corrected by correction.

If returnHues is true, the return values are hues.

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 25 May 2002

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9231184 Pmw-2.1/Pmw/Pmw_1_3_3/doc/ComboBox.gif0000664000175000017500000001073500000000000017512 0ustar00gregmgregm00000000000000GIF87axÂouuuڹ,xpI8ͻ`dilp,tmh^|pȤrl:)sJZ( `J5hO =蛵fjh{"t|o&bq40~xj;7+ec~lrºN$ǩŵսĶÄʯDܳ<) FrP_"9l,0E]3q#fB>9ѣ";ʇP#Kpb.OIУ-]nY%ǤKmJ򦼫 uj)F#ʥ֮PŦ^KU0*R-6N2f%,clФ~!(pI>+sHPۮuq8 ӤqcZɣ #_A sݼ>32^/ʛ_/D=,N%=&]ؿϿ'>`& ._~Pfv ($h$v,0?p 8)@)dhB\Xa$ΤJڈ5RXeT^ei֘dyP엦 f2beQ''EAUbRמsPw`٧ 1Z$ʊ~ᚿ EHyu\ 5㖒q {}hzT@R*AꪔgYlJ4Z+r+q1`EaT3jw-2erƫɒ5FndJ;- śd^{)vljKpZ멆wCf0+r,OFm&,k2E\ɿaLS/C0 jCa#>󶿒U4p:+%nd-@-m&y%CdahSsPuS |ni'4ƌtG.S>#IVw./b^4L.{ CnϮ3$/w*|~ܳ扴X73}>߾3KzqWV?O|.E5}/$@}gr~[` &xZ*ctBAeBЀabf ,1̠Xպb|_vr]ALCoFj/]!le [hB/.[ ?豺eK$hL'..~DEM mdj` EF&# $TT1ɯUqAHvvғe)GG/XJ?M ɥCRhWiH"`"PP Ђ!e5i@LjnlMnJS{")?l) p=~ @JP:΂:D%zs/.=*` HCZQ -(;9>0HgJӚD T^H2KT"ifxQhRb'K[JꡪUu)Q@Ԭ`R(NK0d519}$S2v:{6%}>gLhv~p@ hKZ3D]_i93m~|M+ rg}{ Xti'ufvxLUwuFǀ||ht`dV6cΗ| )n~ypH't6xiM{wKz"-Hd{?vfh{1Ax[qY}"gaoZd04u{4ّbw*(bN(ExwxQɘD؁6XVDž)ǍH؍xf/( Jtf} 3xvhɑ]҉ZVpI3rζ5{7Z bY [ljR$ӹxU7-mYx{qhH*_GWs(}ݩs)'yyxdz[Iqih)Y|k6O5¢x㘟dZS%!v~J_ZZ>r\ڎ #5c[I5U_xJu[%T_{:}ZZEWqZ w\\u_j^ޚn:hE\oϵW +*׊լWJTU;G|Uj_!_X+{\b +N Z,*Q'B˯0[ۢQ6{*<{@9;;[ƺeL۴NPT&J{تh눵:rzxמ;O1ǩ1ٟp+Ak[AJY}1ry+ &"=>BA8_#u(~(Z7OKo :5\O;vkfZђ3[ JfzR˶KJ"ʹY˷m;$|y^6:AgϫV{rS \(᫺[ȉ+U˾+˺廫 {Dt Zܽɞej V lK7YZ[dzTyXKZ ikHx *s HdKA{m+Q)JyIa+A ' \;NIO,QvAq$iڡسPѫ& CK}H]ܚCL)qh{a"|dAQ\rFČHl3Ӽ`E[/w4,[n'3lJNQɉ̛O%ʌھzZAXL\ Pmw.ComboBox reference manual

Pmw.ComboBox

Name

Pmw.ComboBox() - dropdown or simple combination box

Inherits

Pmw.MegaWidget

Description

A combobox contains an entry field and an associated scrolled listbox. When an item in the listbox is selected, it is displayed in the entry field. Optionally, the user may also edit the entry field directly.

For a simple combobox, the scrolled listbox is displayed beneath the entry field. For a dropdown combobox (the default), the scrolled listbox is displayed in a window which pops up beneath the entry field when the user clicks on an arrow button on the right of the entry field. Either style allows an optional label.

Options

Options for this megawidget and its base classes are described below.

autoclear
Initialisation option. If both autoclear and history are true, clear the entry field whenever <Return> is pressed, after adding the value to the history list. The default is 0.

buttonaspect
Initialisation option. The width of the arrow button as a proportion of the height. The height of the arrow button is set to the height of the entry widget. The default is 1.0.

dropdown
Initialisation option. Specifies whether the combobox should be dropdown or simple. The default is 1.

fliparrow
Initialisation option. If true, the arrow button is draw upside down when the listbox is being displayed. Used only in dropdown megawidgets. The default is 0.

history
Initialisation option. When <Return> is pressed in the entry field, the current value of the entry field is appended to the listbox if history is true. The default is 1.

labelmargin
Initialisation option. If the labelpos option is not None, this specifies the distance between the label component and the rest of the megawidget. The default is 0.

labelpos
Initialisation option. Specifies where to place the label component. If not None, it should be a concatenation of one or two of the letters 'n', 's', 'e' and 'w'. The first letter specifies on which side of the megawidget to place the label. If a second letter is specified, it indicates where on that side to place the label. For example, if labelpos is 'w', the label is placed in the center of the left hand side; if it is 'wn', the label is placed at the top of the left hand side; if it is 'ws', the label is placed at the bottom of the left hand side.

If None, a label component is not created. The default is None.

listheight
Initialisation option. The height, in pixels, of the dropdown listbox. The default is 200.

selectioncommand
The function to call when an item is selected. If this function takes a long time to run, and you want the entry field to be updated quickly, call update_idletasks() at the beginning of the function. Alternatively, wrap the function using Pmw.busycallback(). The default is None.

sticky
Initialisation option. The default is 'ew'.

unique
Initialisation option. If both unique and history are true, the current value of the entry field is not added to the listbox if it is already in the list. The default is 1.

Components

Components created by this megawidget and its base classes are described below.

arrowbutton
In a dropdown combobox, the button to popup the listbox. By default, this component is a Tkinter.Canvas.

entryfield
The entry field where the current selection is displayed. By default, this component is a Pmw.EntryField.

hull
This acts as the body for the entire megawidget. Other components are created as children of the hull to further specialise this class. By default, this component is a Tkinter.Frame.

label
If the labelpos option is not None, this component is created as a text label for the megawidget. See the labelpos option for details. Note that to set, for example, the text option of the label, you need to use the label_text component option. By default, this component is a Tkinter.Label.

popup
In a dropdown combobox, the dropdown window. By default, this component is a Tkinter.Toplevel.

scrolledlist
The scrolled listbox which displays the items to select. By default, this component is a Pmw.ScrolledListBox.

Component aliases

Sub-components of components of this megawidget may be accessed via the following aliases.

entry
Alias for entryfield_entry.
listbox
Alias for scrolledlist_listbox.

Methods

Only methods specific to this megawidget are described below. For a description of its inherited methods, see the manual for its base class Pmw.MegaWidget. In addition, methods from the following classes are forwarded by this megawidget. Methods from Pmw.ScrolledListBox are forwarded to the scrolledlist component. Methods from Pmw.EntryField are forwarded to the entryfield component. Forwarded methods are searched in the order given.

bbox(index)
This method is explicitly forwarded to the scrolledlist component's bbox() method. Without this explicit forwarding, the bbox() method (aliased to grid_bbox()) of the hull would be invoked, which is probably not what the programmer intended.

clear()
Delete all items from the scrolled listbox and delete all text from the entry widget.

get(first = None, last = None)
This is the same as the get() method of the scrolledlist component, except that if first is None then the value of the entry field is returned.

invoke()
If a dropdown combobox, display the dropdown listbox. In a simple combobox, select the currently selected item in the listbox, call the selectioncommand and return the result.

selectitem(index, setentry = 1)
Select the item in the listbox specified by index which may be either one of the items in the listbox or the integer index of one of the items in the listbox.

If setentry is true, also set the entry field to the selected item.

size()
This method is explicitly forwarded to the scrolledlist component's size() method. Without this explicit forwarding, the size() method (aliased to grid_size()) of the hull would be invoked, which is probably not what the programmer intended.

Example

The image at the top of this manual is a snapshot of the window (or part of the window) produced by the following code.

class Demo:
    def __init__(self, parent):
        parent.configure(background = 'white')

        # Create and pack the widget to be configured.
        self.target = Tkinter.Label(parent,
                relief = 'sunken',
                padx = 20,
                pady = 20,
        )
        self.target.pack(fill = 'x', padx = 8, pady = 8)

        # Create and pack the simple ComboBox.
        words = ('Monti', 'Python', 'ik', 'den', 'Holie', 'Grailen', '(Bok)')
        simple = Pmw.ComboBox(parent,
                label_text = 'Simple ComboBox:',
                labelpos = 'nw',
                selectioncommand = self.changeText,
                scrolledlist_items = words,
                dropdown = 0,
        )
        simple.pack(side = 'left', fill = 'both',
                expand = 1, padx = 8, pady = 8)

        # Display the first text.
        first = words[0]
        simple.selectitem(first)
        self.changeText(first)

        # Create and pack the dropdown ComboBox.
        colours = ('cornsilk1', 'snow1', 'seashell1', 'antiquewhite1',
                'bisque1', 'peachpuff1', 'navajowhite1', 'lemonchiffon1',
                'ivory1', 'honeydew1', 'lavenderblush1', 'mistyrose1')
        dropdown = Pmw.ComboBox(parent,
                label_text = 'Dropdown ComboBox:',
                labelpos = 'nw',
                selectioncommand = self.changeColour,
                scrolledlist_items = colours,
        )
        dropdown.pack(side = 'left', anchor = 'n',
                fill = 'x', expand = 1, padx = 8, pady = 8)

        # Display the first colour.
        first = colours[0]
        dropdown.selectitem(first)
        self.changeColour(first)

    def changeColour(self, colour):
        print 'Colour: ' + colour
        self.target.configure(background = colour)

    def changeText(self, text):
        print 'Text: ' + text
        self.target.configure(text = text)

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 1 November 1998

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9191184 Pmw-2.1/Pmw/Pmw_1_3_3/doc/ComboBoxDialog.gif0000664000175000017500000000664100000000000020633 0ustar00gregmgregm00000000000000GIF87a`w`0;uuu,I-6ͻ`($Qip,O+zxpH,$wTIШtJZ޸re_"GrotcË|jyp0)XB_Ϣ(h& 6Thfv ($hbt'0(&hׄ4<fDi2IǐH6P*PViI#\v%Rdeg p&qisީ#矀fg9hy`腏>*ORjH ĸ)ZYV)fڤjR鉟gt(臮*$bZj误۬I:J;k6:+:nBZ#f+Fҋ{J+;o(*-[<ޛq{-;,^[q|1 LƮ|$|p.<nJnt<t(),CT7M|>LvN_5з:+Twlp먵y\5L{ẅ́/4 MUWBn.J~:O-8;lʝףuN.n߮; o'7G/Agw}s[ϡՋ8![/(?:yտ2zІ5M:x^NY1IP \`CX! fV`;[Ph%p!4g30|-ġkCK6 G?GRs(&̄ˢޢ)r`uA."ɋU4иDOcc7qtr\RxGDqJ{ IBLF:򑐌$>r1vȤ&7Nz (GIRQG*WVJORӣ$ QZ,GTђRԥ @b,D_Je2 dNsh—Ci&4&6M;jpD&9LqdatPbg IL lc9`D; PY2SjCG1[]B!q]d3Ż &" 7}!$DGs/SZXQ4)IUN)L Q%MO9-S9:N γ"j`&2&U U!WrB%EX68 ?mSТ\-#aR*Rx8ב>4X]ĺ:DBl PYǢ6%kZZx:nv\{א4?\.;Nr.M)ʒ<'Op ;mY|:G7NHOҗ;Pԍ~s'5mu!y\ﺋ:gM&)Xaf;xkzdY(l/㝮M{flNpNXڵ,vU{V8㞈x̓uiyx la+ǖyŎ.}ڰ+2}iun{o[ ? O"Kp1/ߏg|z?%~z,[|_g3\jR.^ew{'{EBxez>d/}!]2ES_hF}7@7}Tyy7XĤY{eV0_W}%8UK},@B8DxJ9;%HCLNMRTXS8~X%KG҅^X$`r+thj8=npHQH3tH$cxdz;|؇{xXOkK۷'tG:FqHuhqD!򉂴 T9DbA!S&Ff`ŠBX&d5HXxCxȉC|c׋d,eC{b-k ؂Ȍ3bU#!rN;8((ވ,fX/`JT t6"x︎Ѩ/S$' Ȁwx"8hPDb!9R!(T%ɒ;?.&" DHsSL$H(5ʒhdXNGBlH.b **VlS)rUY67[ɐ`VVi(CE9_VZl , XWYYGc)H#ꈗ"N2-S8Ai;Y^2iߨ (OfY}Ʌ2 $4@(zٌ(e\JsX)y'YAY')"i&I͈ӹ:ٜCJkߩJ"8䩗ሞSGX^HD9~y؟?:-:sĞ ڠʆ:ZY""mڡh`6:$q,)Z;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9271185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/ComboBoxDialog.html0000664000175000017500000002343000000000000021025 0ustar00gregmgregm00000000000000 Pmw.ComboBoxDialog reference manual

Pmw.ComboBoxDialog

Name

Pmw.ComboBoxDialog() - selection dialog displaying a list and an entry field

Inherits

Pmw.Dialog

Description

A combobox dialog is a dialog window which displays a list and an entry field which can be used to prompt the user for a value.

Options

Options for this megawidget and its base classes are described below.

activatecommand
If this is callable, it will be called whenever the megawidget is activated by a call to activate(). The default is None.

borderx
Initialisation option. The padding to the left and right of the combobox. The default is 10.

bordery
Initialisation option. The padding above and below the combobox. The default is 10.

buttonboxpos
Initialisation option. Specifies on which side of the dialog window to place the button box. Must be one of 'n', 's', 'e' or 'w'. The default is 's'.

buttons
This must be a tuple or a list and specifies the names on the buttons in the button box. The default is ('OK',).

command
Specifies a function to call whenever a button in the button box is invoked or the window is deleted by the window manager. The function is called with a single argument, which is the name of the button which was invoked, or None if the window was deleted by the window manager.

If the value of command is not callable, the default behaviour is to deactivate the window if it is active, or withdraw the window if it is not active. If it is deactivated, deactivate() is called with the button name or None as described above. The default is None.

deactivatecommand
If this is callable, it will be called whenever the megawidget is deactivated by a call to deactivate(). The default is None.

defaultbutton
Specifies the default button in the button box. If the <Return> key is hit when the dialog has focus, the default button will be invoked. If defaultbutton is None, there will be no default button and hitting the <Return> key will have no effect. The default is None.

master
This is used by the activate() method to control whether the window is made transient during modal dialogs. See the activate() method. The default is 'parent'.

separatorwidth
Initialisation option. If this is greater than 0, a separator line with the specified width will be created between the button box and the child site, as a component named separator. Since the default border of the button box and child site is raised, this option does not usually need to be set for there to be a visual separation between the button box and child site. The default is 0.

title
This is the title that the window manager displays in the title bar of the window. The default is None.

Components

Components created by this megawidget and its base classes are described below.

buttonbox
This is the button box containing the buttons for the dialog. By default it is created with the options (hull_borderwidth = 1, hull_relief = 'raised'). By default, this component is a Pmw.ButtonBox.

combobox
The combobox for the user to enter a value. By default it is created using the option dropdown = 0. By default, this component is a Pmw.ComboBox.

dialogchildsite
This is the child site for the dialog, which may be used to specialise the megawidget by creating other widgets within it. By default it is created with the options (borderwidth = 1, relief = 'raised'). By default, this component is a Tkinter.Frame.

hull
This acts as the body for the entire megawidget. Other components are created as children of the hull to further specialise this class. By default, this component is a Tkinter.Toplevel.

separator
If the separatorwidth initialisation option is non-zero, the separator component is the line dividing the area between the button box and the child site. By default, this component is a Tkinter.Frame.

Component aliases

Sub-components of components of this megawidget may be accessed via the following aliases.

entry
Alias for combobox_entry.
label
Alias for combobox_label.
listbox
Alias for combobox_listbox.
scrolledlist
Alias for combobox_scrolledlist.

Methods

Only methods specific to this megawidget are described below. For a description of its inherited methods, see the manual for its base class Pmw.Dialog. In addition, methods from the Pmw.ComboBox class are forwarded by this megawidget to the combobox component.

bbox(index)
This method is explicitly forwarded to the combobox component's bbox() method. Without this explicit forwarding, the bbox() method (aliased to grid_bbox()) of the hull would be invoked, which is probably not what the programmer intended.

size()
This method is explicitly forwarded to the combobox component's size() method. Without this explicit forwarding, the size() method (aliased to grid_size()) of the hull would be invoked, which is probably not what the programmer intended.

Example

The image at the top of this manual is a snapshot of the window (or part of the window) produced by the following code.

class Demo:
    def __init__(self, parent):
        # Create the dialog.
        self.dialog = Pmw.ComboBoxDialog(parent,
            title = 'My ComboBoxDialog',
            buttons = ('OK', 'Cancel'),
            defaultbutton = 'OK',
            combobox_labelpos = 'n',
            label_text = 'What do you think of Pmw?',
            scrolledlist_items = ('Cool man', 'Cool', 'Good', 'Bad', 'Gross'))
        self.dialog.withdraw()

        # Create button to launch the dialog.
        w = Tkinter.Button(parent,
                text = 'Show combo box dialog',
                command = self.doit)
        w.pack(padx = 8, pady = 8)

    def doit(self):
        result = self.dialog.activate()
        print 'You clicked on', result, self.dialog.get()

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 18 May 2002

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9231184 Pmw-2.1/Pmw/Pmw_1_3_3/doc/Counter.gif0000664000175000017500000000425200000000000017416 0ustar00gregmgregm00000000000000GIF87anق˙sz,n(0I8ͻ`(dihlp,tmx|pH,l:ШtJZجvzp .#E|N~| npk+m^ipo_i%q Lo ' ,0ѯؿ, $) َ6ZC [g⊈'ho(~H(AsR>e>qLIP(g>[hIӝCBR$իS1&BtΒ&Uk?EB@_+u%TYul29_UJtJ[>)J}<+Z烅ry+,hVڴmzDMfN]lڱlYfj0M+Җ/[>Y+ pҩg75X->==q#ޖtfa]U"7IVv\xė@eͅM֏\Z\vHkށOU`}`}ʃ^CxWbTt=_M]]9G}"UԔաPyhD3i"g`pQPe1 xeq&8ZnLi r7`g9AΘ$&* V9ҋf馜nQL(|驨j*kz뮼ꫥ+k&6F+Vkfv+.akĸ7(a+kP+}Nl' 7G,+Cȿ#Pi@ ,$S Ŋܘq9p,4l8<@ʝ2-1A73T }rґ}tE\`G@d?=4cbK_.DTx s|;-u߀|6I\ FF+];r2-1 <19z̓+WjW`X"ݶe)Pu_}wl:\<ħZ?wCƦ3HMTu"eTQS?,SW#l;71v2-mZs Z0FXT:?AO~ß/G*Nv}P}dḨq Oy dP DBЄD!876ԝP|cjBBpn69[8E⠥6 Y."ڠ:Bύnywy=XÌ~[W@3!or?=qLx9=1,D#o{Pw™!J츒@aQqXt"Jz-D I^rs (!=)q: ) iifyiZH \u6^2d.3TJ̓Mv<M7E $M@S7ǁӒ# ktY C yIn@[1P9S&ɒ4R4l}D*QGt|a pps2A3*[K]R:FR*J5eʪV:PQiǸJֲb*p\/*Wxͫ^< `KMb:d'KZE0f7NaVl &*Dx}MjW[R5-6 TE%JhyQAI-o[e5r#ӷQMUzƭi%O<8l&Y4)FpSp8Zyh$V;CΚ$|;jwuЕ#]H;Җ]X4l4p5ya<0iRyra[{ //Ί*3$^ .nN3HI1Z$`-^pzlXoKb{WNf;ЎMj[[ ;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9191184 Pmw-2.1/Pmw/Pmw_1_3_3/doc/Counter.html0000664000175000017500000004407100000000000017620 0ustar00gregmgregm00000000000000 Pmw.Counter reference manual

Pmw.Counter

Name

Pmw.Counter() - entry field with up and down arrow buttons

Inherits

Pmw.MegaWidget

Description

A counter contains an entry field and two arrow buttons to increment and decrement the value in the entry field. Standard counting types include numbers, times and dates. A user defined counting function may also be supplied for specialised counting. Counting can be used in combination with the entry field's validation. The components may be laid out horizontally or vertically.

Each time an arrow button is pressed the value displayed in the entry field is incremented or decremented by the value of the increment option. If the new value is invalid (according to the entry field's validate option, perhaps due to exceeding minimum or maximum limits), the old value is restored.

When an arrow button is pressed and the value displayed is not an exact multiple of the increment, it is "truncated" up or down to the nearest increment.

Options

Options for this megawidget and its base classes are described below.

autorepeat
If true, the counter will continue to count up or down while an arrow button is held pressed down. The default is 1.

buttonaspect
Initialisation option. Specifies the width of the arrow buttons as a proportion of their height. Values less than 1.0 will produce thin arrow buttons. Values greater than 1.0 will produce fat arrow buttons. The default is 1.0.

datatype
Specifies how the counter should count up and down.

The most general way to specify the datatype option is as a dictionary. The kind of counting is specified by the 'counter' dictionary field, which may be either a function or the name of one of the standard counters described below. If the dictionary does not have a 'counter' field, the field defaults to 'numeric'.

Any other fields in the dictionary are passed on to the counter function as keyword arguments.

If datatype is not a dictionary, then it is equivalent to specifying it as a dictionary with a single 'counter' field. For example, datatype = 'real' is equivalent to datatype = {'counter' : 'real'}.

The standard counters are:

'numeric'
An integer number, as accepted by string.atol().

'integer'
Same as 'numeric'.

'real'
A real number, as accepted by string.atof(). This counter accepts a 'separator' argument, which specifies the character used to represent the decimal point. The default 'separator' is '.'.

'time'
A time specification, as accepted by Pmw.timestringtoseconds(). This counter accepts a 'separator' argument, which specifies the character used to separate the time fields. The default separator is ':'. This counter also accepts a 'time24' argument. If this is true, the time value is converted to a value between '00:00:00' and '23:59:59'. The default is false.

'date'
A date specification, as accepted by Pmw.datestringtojdn(). This counter accepts a 'separator' argument, which specifies the character used to separate the three date fields. The default is '/'. This counter also accepts a 'format' argument, which is passed to Pmw.datestringtojdn() to specify the desired ordering of the fields. The default is 'ymd'. This counter also accepts a 'yyyy' argument. If this is false, the year field will be displayed as the year within the century, otherwise it will be fully displayed. In both cases it will be displayed with at least 2 digits, using leading zeroes. The default is false.

If the 'counter' dictionary field is a function, then it will be called whenever the counter is to be incremented or decremented. The function is called with at least three arguments, the first three being (text, factor, increment), where text is the current contents of the entry field, factor is 1 when incrementing or -1 when decrementing, and increment is the value of the increment megawidget option.

The other arguments are keyword arguments made up of the fields of the datatype dictionary (excluding the 'counter' field).

The counter function should return a string representing the incremented or decremented value. It should raise a ValueError exception if the text is invalid. In this case the bell is rung and the entry text is not changed.

The default for datatype is numeric.

increment
Specifies how many units should be added or subtracted when the counter is incremented or decremented. If the currently displayed value is not a multiple of increment, the value is changed to the next multiple greater or less than the current value.

For the number datatypes, the value of increment is a number. For the 'time' datatype, the value is in seconds. For the 'date' datatype, the value is in days. The default is 1.

initwait
Specifies the initial delay (in milliseconds) before a depressed arrow button automatically starts to repeat counting. The default is 300.

labelmargin
Initialisation option. If the labelpos option is not None, this specifies the distance between the label component and the rest of the megawidget. The default is 0.

labelpos
Initialisation option. Specifies where to place the label component. If not None, it should be a concatenation of one or two of the letters 'n', 's', 'e' and 'w'. The first letter specifies on which side of the megawidget to place the label. If a second letter is specified, it indicates where on that side to place the label. For example, if labelpos is 'w', the label is placed in the center of the left hand side; if it is 'wn', the label is placed at the top of the left hand side; if it is 'ws', the label is placed at the bottom of the left hand side.

If None, a label component is not created. The default is None.

orient
Initialisation option. Specifies whether the arrow buttons should appear to the left and right of the entry field ('horizontal') or above and below ('vertical'). The default is 'horizontal'.

padx
Initialisation option. Specifies a padding distance to leave around the arrow buttons in the x direction. The default is 0.

pady
Initialisation option. Specifies a padding distance to leave around the arrow buttons in the y direction. The default is 0.

repeatrate
Specifies the delay (in milliseconds) between automatic counts while an arrow button is held pressed down. The default is 50.

sticky
Initialisation option. The default is 'ew'.

Components

Components created by this megawidget and its base classes are described below.

downarrow
The arrow button used for decrementing the counter. Depending on the value of orient, it will appear on the left or below the entry field. By default, this component is a Tkinter.Canvas. Its component group is Arrow.

entryfield
The entry field widget where the text is entered, displayed and validated. By default, this component is a Pmw.EntryField.

frame
If the label component has been created (that is, the labelpos option is not None), the frame component is created to act as the container of the entry field and arrow buttons. If there is no label component, then no frame component is created and the hull component acts as the container. In either case the border around the container of the entry field and arrow buttons will be raised (but not around the label). By default, this component is a Tkinter.Frame.

hull
This acts as the body for the entire megawidget. Other components are created as children of the hull to further specialise this class. By default, this component is a Tkinter.Frame.

label
If the labelpos option is not None, this component is created as a text label for the megawidget. See the labelpos option for details. Note that to set, for example, the text option of the label, you need to use the label_text component option. By default, this component is a Tkinter.Label.

uparrow
The arrow button used for incrementing the counter. Depending on the value of orient, it will appear on the right or above the entry field. By default, this component is a Tkinter.Canvas. Its component group is Arrow.

Component aliases

Sub-components of components of this megawidget may be accessed via the following aliases.

entry
Alias for entryfield_entry.

Methods

Only methods specific to this megawidget are described below. For a description of its inherited methods, see the manual for its base class Pmw.MegaWidget. In addition, methods from the Pmw.EntryField class are forwarded by this megawidget to the entryfield component.

decrement()
Decrement the counter once, as if the down arrow had been pressed.

increment()
Increment the counter once, as if the up arrow had been pressed.

Example

The image at the top of this manual is a snapshot of the window (or part of the window) produced by the following code.

class Demo:
    def __init__(self, parent):
        # Need to use long ints here because on the Macintosh the maximum size
        # of an integer is smaller than the value returned by time.time().
        now = (long(time.time()) / 300) * 300

        # Create the Counters.
        self._date = Pmw.Counter(parent,
                labelpos = 'w',
                label_text = 'Date (4-digit year):',
                entryfield_value =
                        time.strftime('%d/%m/%Y', time.localtime(now)),
                entryfield_command = self.execute,
                entryfield_validate = {'validator' : 'date', 'format' : 'dmy'},
                datatype = {'counter' : 'date', 'format' : 'dmy', 'yyyy' : 1})

        self._isodate = Pmw.Counter(parent,
                labelpos = 'w',
                label_text = 'ISO-Date (4-digit year):',
                entryfield_value =
                        time.strftime('%Y-%m-%d', time.localtime(now)),
                entryfield_command = self.execute,
                entryfield_validate = {'validator' : 'date', 'format' : 'ymd',
                        'separator' : '-' },
                datatype = {'counter' : 'date', 'format' : 'ymd', 'yyyy' : 1,
                        'separator' : '-' })

        self._time = Pmw.Counter(parent,
                labelpos = 'w',
                label_text = 'Time:',
                entryfield_value =
                        time.strftime('%H:%M:%S', time.localtime(now)),
                entryfield_validate = {'validator' : 'time',
                        'min' : '00:00:00', 'max' : '23:59:59',
                        'minstrict' : 0, 'maxstrict' : 0},
                datatype = {'counter' : 'time', 'time24' : 1},
                increment=5*60)
        self._real = Pmw.Counter(parent,
                labelpos = 'w',
                label_text = 'Real (with comma)\nand extra\nlabel lines:',
                label_justify = 'left',
                entryfield_value = '1,5',
                datatype = {'counter' : 'real', 'separator' : ','},
                entryfield_validate = {'validator' : 'real',
                        'min' : '-2,0', 'max' : '5,0',
                        'separator' : ','},
                increment = 0.1)
        self._custom = Pmw.Counter(parent,
                labelpos = 'w',
                label_text = 'Custom:',
                entryfield_value = specialword[:4],
                datatype = _custom_counter,
                entryfield_validate = _custom_validate)
        self._int = Pmw.Counter(parent,
                labelpos = 'w',
                label_text = 'Vertical integer:',
                orient = 'vertical',
                entry_width = 2,
                entryfield_value = 50,
                entryfield_validate = {'validator' : 'integer',
                        'min' : 0, 'max' : 99}
        )

        counters = (self._date, self._isodate, self._time, self._real,
                self._custom)
        Pmw.alignlabels(counters)

        # Pack them all.
        for counter in counters:
            counter.pack(fill='both', expand=1, padx=10, pady=5)
        self._int.pack(padx=10, pady=5)

    def execute(self):
        print 'Return pressed, value is', self._date.get()

specialword = 'Monti Python ik den Holie Grailen (Bok)'

def _custom_validate(text):
    if string.find(specialword, text) == 0:
        return 1
    else:
        return -1

def _custom_counter(text, factor, increment):
    # increment is ignored here.
    if string.find(specialword, text) == 0:
        length = len(text)
        if factor == 1:
            if length >= len(specialword):
                raise ValueError, 'maximum length reached'
            return specialword[:length + 1]
        else:
            if length == 0:
                raise ValueError, 'empty string'
            return specialword[:length - 1]
    else:
        raise ValueError, 'bad string ' + text

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 24 May 1998

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9231184 Pmw-2.1/Pmw/Pmw_1_3_3/doc/CounterDialog.gif0000664000175000017500000000532700000000000020542 0ustar00gregmgregm00000000000000GIF87a `w`0;, h^.I8ͻr8hl;Xtmv|pH,:@:ШtJRMFz0SõȲxnL|{V*^y}q2"hx{u~ƿyϡѢӸ|ܧԼ͞澗 w~{vSvi:f*4kÃ8~H1:yA2Cj%{Y$d(l$NY(DJ͚?yb:!j4LZO+&8sf`A$2BXаH#.&7SX(j\bQ*NkTňJaȘ4sɉ-]ٳfP|ѭ M"Lf ۊ ȓ+_{AУKNسkνËO:_Ͼ˟OϿh&ۀ F(Vh|v !%h(߈Y0x"J(8 @sAi i#L6NF)%PNiV\"e`ߗbi&|di&m)qiuީy駏})jh(.腍PR rbFJ zrXz*2(⚥n*@'5,ʩ;Kk;z2RK&[, mזۡ nN+ -F;oo^z!B7 qV/k[g,ƳR| oׂ_Lr⪻7ʰ |&{1L;7="|gtͥ~cGm5-4PKU-a}bo,vx<p37[˪O̭̓+gۼ9Ƽ5D?t:.n{߮|O I̴ zvfM 6"s&ȘC%~tX#-Le?G'qc~I#"_E|$#IRP2?q{$($QΩ|*SUMb|])NŲ%.]nk 0Ib-$LЌ4IjZf6a?'=IrL:v'k. ~%Pջ]8* { O=9|fXҦWfe؂8αw/%x!Fn% K2OB~ ,eR.p2-?I^<.xT>s#Ͷ|3,9syv擀x>π;BЈN4v z4'$IіQ3#LgWЁ֯KܤNt\2/QUEr51)iZ U5nLR=Ku}`װuM\sEzR2PΎc$m{̶hdxwȭ@s'RN7 u{AnҰ]'?ΕxnuSLijo7ޒ" >u[r`"*`g ! cA9}lqC%quxo v8on=t 7&߾2R ߞ >yTXo857J_ně\T=Ru6͝:c8.=-S?D^Oܽ wgM<PO~ =ߪvwx\cmcz:F{h (F9t[jX⁈4jfLVkA(_~,Hd.~4z2%Vg<؃>cB8DX1$JL؄p1N8TX 0|EF؅^G@;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9271185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/CounterDialog.html0000664000175000017500000002413600000000000020740 0ustar00gregmgregm00000000000000 Pmw.CounterDialog reference manual

Pmw.CounterDialog

Name

Pmw.CounterDialog() - selection dialog displaying a counter

Inherits

Pmw.Dialog

Description

A counter dialog is a dialog window which displays a counter which can be used to prompt the user for a value.

Options

Options for this megawidget and its base classes are described below.

activatecommand
If this is callable, it will be called whenever the megawidget is activated by a call to activate(). The default is None.

borderx
Initialisation option. The padding to the left and right of the counter. The default is 20.

bordery
Initialisation option. The padding above and below the counter. The default is 20.

buttonboxpos
Initialisation option. Specifies on which side of the dialog window to place the button box. Must be one of 'n', 's', 'e' or 'w'. The default is 's'.

buttons
This must be a tuple or a list and specifies the names on the buttons in the button box. The default is ('OK',).

command
Specifies a function to call whenever a button in the button box is invoked or the window is deleted by the window manager. The function is called with a single argument, which is the name of the button which was invoked, or None if the window was deleted by the window manager.

If the value of command is not callable, the default behaviour is to deactivate the window if it is active, or withdraw the window if it is not active. If it is deactivated, deactivate() is called with the button name or None as described above. The default is None.

deactivatecommand
If this is callable, it will be called whenever the megawidget is deactivated by a call to deactivate(). The default is None.

defaultbutton
Specifies the default button in the button box. If the <Return> key is hit when the dialog has focus, the default button will be invoked. If defaultbutton is None, there will be no default button and hitting the <Return> key will have no effect. The default is None.

master
This is used by the activate() method to control whether the window is made transient during modal dialogs. See the activate() method. The default is 'parent'.

separatorwidth
Initialisation option. If this is greater than 0, a separator line with the specified width will be created between the button box and the child site, as a component named separator. Since the default border of the button box and child site is raised, this option does not usually need to be set for there to be a visual separation between the button box and child site. The default is 0.

title
This is the title that the window manager displays in the title bar of the window. The default is None.

Components

Components created by this megawidget and its base classes are described below.

buttonbox
This is the button box containing the buttons for the dialog. By default it is created with the options (hull_borderwidth = 1, hull_relief = 'raised'). By default, this component is a Pmw.ButtonBox.

counter
The counter for the user to enter a value. By default, this component is a Pmw.Counter.

dialogchildsite
This is the child site for the dialog, which may be used to specialise the megawidget by creating other widgets within it. By default it is created with the options (borderwidth = 1, relief = 'raised'). By default, this component is a Tkinter.Frame.

hull
This acts as the body for the entire megawidget. Other components are created as children of the hull to further specialise this class. By default, this component is a Tkinter.Toplevel.

separator
If the separatorwidth initialisation option is non-zero, the separator component is the line dividing the area between the button box and the child site. By default, this component is a Tkinter.Frame.

Component aliases

Sub-components of components of this megawidget may be accessed via the following aliases.

entry
Alias for counter_entryfield_entry.
entryfield
Alias for counter_entryfield.
label
Alias for counter_label.

Methods

Only methods specific to this megawidget are described below. For a description of its inherited methods, see the manual for its base class Pmw.Dialog. In addition, methods from the Pmw.Counter class are forwarded by this megawidget to the counter component.

deleteentry(first, last = None)
Delete text from the counter's entry widget. An alias for component('entry').delete().

indexentry(index)
An alias for component('entry').index().

insertentry(index, text)
Insert text into the counter's entry widget. An alias for component('entry').insert().

Example

The image at the top of this manual is a snapshot of the window (or part of the window) produced by the following code.

class Demo:
    def __init__(self, parent):
        # Create the dialog to prompt for the number of times to ring the bell.
        self.dialog = Pmw.CounterDialog(parent,
            label_text = 'Enter the number of times to\n' + \
                    'sound the bell (1 to 5)\n',
            counter_labelpos = 'n',
            entryfield_value = 2,
            counter_datatype = 'numeric',
            entryfield_validate =
                {'validator' : 'numeric', 'min' : 1, 'max' : 5},
            buttons = ('OK', 'Cancel'),
            defaultbutton = 'OK',
            title = 'Bell ringing',
            command = self.execute)
        self.dialog.withdraw()

        # Create button to launch the dialog.
        w = Tkinter.Button(parent, text = 'Show counter dialog',
                command = self.dialog.activate)
        w.pack(padx = 8, pady = 8)

    def execute(self, result):
        if result is None or result == 'Cancel':
            print 'Bell ringing cancelled'
            self.dialog.deactivate()
        else:
            count = self.dialog.get()
            if not self.dialog.valid():
                print 'Invalid entry: "' + count + '"'
            else:
                print 'Ringing the bell ' + count + ' times'
                for num in range(string.atoi(count)):
                    if num != 0:
                        self.dialog.after(200)
                    self.dialog.bell()
                self.dialog.deactivate()

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 18 May 2002

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9231184 Pmw-2.1/Pmw/Pmw_1_3_3/doc/Dialog.gif0000664000175000017500000000545400000000000017203 0ustar00gregmgregm00000000000000GIF87av`w`0;,vhN.I8ͻ`(Dbylp,VZ*ipH,Ȥrl:(ӗجvz0wݨhznxL~wQrw&weuǘʓ̌ҞŌՉ׊&޶䈲ڇb{W+݀[jT4ъ0C tN@!Cz\)Ea)bJds&Q,G!wB\Ka0uR͋Osntʴ#AEUj0%RamTԭ;VHk>ST,8h˖0ܩN|q -73V_pUWϨJSz%WaGn홵*F+isjpQݛУ[uzM29.˽Hy"ǫ_Ͼ@Ͽ(h& G  Vhfv ($h(b0(4h8at@@)DI#hL6Pd]/JΕXf\v`)dihlvIWT)@tix|Λ.R砄j衈&&='F*餔V%I::v駠)jꩨ*q꫰*I뮼꭮*NVy6+Ԛ,fW^,[k-춋s+=KBjolo'L 7찖 ?,Ol1_qo%~mw%\챞ɯ&r*rX#3l 8:LH:?Mt}K GVÌNu`sݲRmvV pئ%3ǽr;ux-CMwlxROMvQ%@ 5ً7θ̄#ݎvmwnKW]5ؤkN9| =8ZӽbުKn{#ۇ:.{=ا"8S;w?݇/'dϮڟ{?&SÅj pt_1 Xēޞ7юk41jT4 o+ 8ܝMM`n7\m U.u0:&x4+k׺| YE fnuR,TgaPqLuEfex80&TL8~^xG Ή^4<:K$Ik^. WpeH&?Y<2cڸ ΃L+5KG+[@Z*|BfCI-f6_fNxLY}7I5V utQ|wLOD3 }zÒH)v&Ѥ=o %ucw Ҭmy:Jw.S߉nt>p)VmC?"9ǧnj#Ҋf+k1'z~#VZFQmاw6.3nw 0FL:<r_=sU]WvVߗϷ)굟رnߧC{E/_7;P{^lzӾwsv=?|=#܃ P}k5Ƹyz=+!~Q}ӟ?ю~w~7a)cA6 XWn'$&}vc0Ȁ8rՁ_"U5&xU%x'~z*+\4hu#Ȃ~{N"[?(FT]uuLh_ՄP3YRXVcOxZ\`R-dTXhXTl؆npr8Vvxxz=8(8؈8haxc ;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9231184 Pmw-2.1/Pmw/Pmw_1_3_3/doc/Dialog.html0000664000175000017500000002370000000000000017374 0ustar00gregmgregm00000000000000 Pmw.Dialog reference manual

Pmw.Dialog

Name

Pmw.Dialog() - toplevel window with button box

Inherits

Pmw.MegaToplevel

Description

A dialog is a toplevel window composed of a button box and a child site area. The child site area can be used to specialise the megawidget by creating other widgets within it. This can be done by using this class directly or by deriving from it.

Options

Options for this megawidget and its base classes are described below.

activatecommand
If this is callable, it will be called whenever the megawidget is activated by a call to activate(). The default is None.

buttonboxpos
Initialisation option. Specifies on which side of the dialog window to place the button box. Must be one of 'n', 's', 'e' or 'w'. The default is 's'.

buttons
This must be a tuple or a list and specifies the names on the buttons in the button box. The default is ('OK',).

command
Specifies a function to call whenever a button in the button box is invoked or the window is deleted by the window manager. The function is called with a single argument, which is the name of the button which was invoked, or None if the window was deleted by the window manager.

If the value of command is not callable, the default behaviour is to deactivate the window if it is active, or withdraw the window if it is not active. If it is deactivated, deactivate() is called with the button name or None as described above. The default is None.

deactivatecommand
If this is callable, it will be called whenever the megawidget is deactivated by a call to deactivate(). The default is None.

defaultbutton
Specifies the default button in the button box. If the <Return> key is hit when the dialog has focus, the default button will be invoked. If defaultbutton is None, there will be no default button and hitting the <Return> key will have no effect. The default is None.

master
This is used by the activate() method to control whether the window is made transient during modal dialogs. See the activate() method. The default is 'parent'.

separatorwidth
Initialisation option. If this is greater than 0, a separator line with the specified width will be created between the button box and the child site, as a component named separator. Since the default border of the button box and child site is raised, this option does not usually need to be set for there to be a visual separation between the button box and child site. The default is 0.

title
This is the title that the window manager displays in the title bar of the window. The default is None.

Components

Components created by this megawidget and its base classes are described below.

buttonbox
This is the button box containing the buttons for the dialog. By default it is created with the options (hull_borderwidth = 1, hull_relief = 'raised'). By default, this component is a Pmw.ButtonBox.

dialogchildsite
This is the child site for the dialog, which may be used to specialise the megawidget by creating other widgets within it. By default it is created with the options (borderwidth = 1, relief = 'raised'). By default, this component is a Tkinter.Frame.

hull
This acts as the body for the entire megawidget. Other components are created as children of the hull to further specialise this class. By default, this component is a Tkinter.Toplevel.

separator
If the separatorwidth initialisation option is non-zero, the separator component is the line dividing the area between the button box and the child site. By default, this component is a Tkinter.Frame.

Methods

Only methods specific to this megawidget are described below. For a description of its inherited methods, see the manual for its base class Pmw.MegaToplevel.

interior()
Return the child site for the dialog. This is the same as component('dialogchildsite').

invoke(index = Pmw.DEFAULT)
Invoke the command specified by the command option as if the button specified by index had been pressed and return the result. index may have any of the forms accepted by the Pmw.ButtonBox index() method.

Example

The image at the top of this manual is a snapshot of the window (or part of the window) produced by the following code.

class Demo:
    def __init__(self, parent):
        # Create two buttons to launch the dialog.
        w = Tkinter.Button(parent, text = 'Show application modal dialog',
                command = self.showAppModal)
        w.pack(padx = 8, pady = 8)

        w = Tkinter.Button(parent, text = 'Show global modal dialog',
                command = self.showGlobalModal)
        w.pack(padx = 8, pady = 8)

        w = Tkinter.Button(parent, text = 'Show dialog with "no grab"',
                command = self.showDialogNoGrab)
        w.pack(padx = 8, pady = 8)

        w = Tkinter.Button(parent, text =
                    'Show toplevel window which\n' +
                    'will not get a busy cursor',
                command = self.showExcludedWindow)
        w.pack(padx = 8, pady = 8)

        # Create the dialog.
        self.dialog = Pmw.Dialog(parent,
            buttons = ('OK', 'Apply', 'Cancel', 'Help'),
            defaultbutton = 'OK',
            title = 'My dialog',
            command = self.execute)
        self.dialog.withdraw()

        # Add some contents to the dialog.
        w = Tkinter.Label(self.dialog.interior(),
            text = 'Pmw Dialog\n(put your widgets here)',
            background = 'black',
            foreground = 'white',
            pady = 20)
        w.pack(expand = 1, fill = 'both', padx = 4, pady = 4)

        # Create the window excluded from showbusycursor.
        self.excluded = Pmw.MessageDialog(parent,
            title = 'I still work',
            message_text =
                'This window will not get\n' +
                'a busy cursor when modal dialogs\n' +
                'are activated.  In addition,\n' +
                'you can still interact with\n' +
                'this window when a "no grab"\n' +
                'modal dialog is displayed.')
        self.excluded.withdraw()
        Pmw.setbusycursorattributes(self.excluded.component('hull'),
            exclude = 1)

    def showAppModal(self):
        self.dialog.activate(geometry = 'centerscreenalways')

    def showGlobalModal(self):
        self.dialog.activate(globalMode = 1)

    def showDialogNoGrab(self):
        self.dialog.activate(globalMode = 'nograb')

    def showExcludedWindow(self):
        self.excluded.show()

    def execute(self, result):
        print 'You clicked on', result
        if result not in ('Apply', 'Help'):
            self.dialog.deactivate(result)

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 18 May 2002

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9231184 Pmw-2.1/Pmw/Pmw_1_3_3/doc/EntryField.gif0000664000175000017500000000427400000000000020050 0ustar00gregmgregm00000000000000GIF87a9ق˙sz,9(0I8ͻ`(dihlp,tmx|pH,Ȥrl:ШtJ جvzxL.Uyn3 ݼ zH~T SR  ~93׏ Ž;ݣ%nX;w\pٶgcְ[}`ѲjB)Cv$h.6% hG!7Vr彔Z2hD4[*"g=:"|TPѭLW8Uz'kfMYlfuؠkt ÊU&CMΑYv LƉE)_іTXl~gTxq.=4k_q-;=sͻ Nk 8μУONسkνËOӫ_Ͼ𑐜OϿQ@h& 6F(߀fvXh(,0(4X%&@)d78CcL6餍!`?h1 ib)=%OifE"MaOoc{<އ/ @J62hMS拉:gCI^>g=,]쓟(?pf \J(e2*W8(XJ.{\q!+ob3 UL`=*㋢;CIUhV68?1խȳb\":ڑf6+02/^vDrdKdJlH&T\QՉ.*P`a29Ф:O3xnVƹr`IZR˥.w^ 0IbL2fvЌ4 iZؼM5wKs7/GC`_ tir&ƈ ߡX 8덍x)+ ~tVh7zDe},,jAJ&4ٞKοNmB\O۠-# rƎsfgΎuj[ζn{;;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9271185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/EntryField.html0000664000175000017500000005524400000000000020252 0ustar00gregmgregm00000000000000 Pmw.EntryField reference manual

Pmw.EntryField

Name

Pmw.EntryField() - entry widget with validation

Inherits

Pmw.MegaWidget

Description

An entry field contains an entry widget with optional validation of various kinds. Built-in validation may be used, such as integer, real, time or date, or an external validation function may be supplied. If valid text is entered, it will be displayed with the normal background. If invalid text is entered, it is not displayed and the previously displayed text is restored. If partially valid text is entered, it will be displayed with a background color to indicate it is in error. An example of partially valid real text is '-.', which may be the first two charactes of the valid string '-.5'. Some validators, such as date, have a relaxed interpretation of partial validity, which allows the user flexibility in how they enter the text.

Validation is performed early, at each keystroke or other event which modifies the text. However, if partially valid text is permitted, the validity of the entered text can be checked just before it is to be used, which is a form of late validation.

Minimum and maximum values may be specified. Some validators also accept other specifications, such as date and time formats and separators.

Validation function return values

Validation is performed by a function which takes as its first argument the entered text and returns one of three standard values, indicating whether the text is valid:

Pmw.OK
The text is valid.

Pmw.ERROR
The text is invalid and is not acceptable for display. In this case the entry will be restored to its previous value.

Pmw.PARTIAL
The text is partially valid and is acceptable for display. In this case the text will be displayed using the errorbackground color.

Options

Options for this megawidget and its base classes are described below.

command
This specifies a function to call whenever the <Return> key is pressed or invoke() is called. The default is None.

errorbackground
Specifies the background color to use when displaying invalid or partially valid text. The default is 'pink'.

extravalidators
This is a dictionary of extra validators. The keys are the names of validators which may be used in a future call to the validate option. Each value in the dictionary is a tuple of (validate_function, stringtovalue_function).

The validate_function is used to implement the validation and the stringtovalue_function is used to convert the entry input into a value which can be compared with the minimum and maximum limits. These functions are as described for the validate option.

If either of these is not given as a function, it is assumed to be the name of one of the other extra validators or one of the standard validators. The alias search is performed when the validate option is configured, not when the extravalidators option is configured or when the validate function is called.

If the name of one of the extra validators is the same as one of the standard validators, the extra validator takes precedence. The default is {}.

invalidcommand
This is executed when invalid text is entered and the text is restored to its previous value (that is, when the validate function returns Pmw.ERROR). It is also called if an attempt is made to set invalid text in a call to setentry(). The default is self.bell.

labelmargin
Initialisation option. If the labelpos option is not None, this specifies the distance between the label component and the rest of the megawidget. The default is 0.

labelpos
Initialisation option. Specifies where to place the label component. If not None, it should be a concatenation of one or two of the letters 'n', 's', 'e' and 'w'. The first letter specifies on which side of the megawidget to place the label. If a second letter is specified, it indicates where on that side to place the label. For example, if labelpos is 'w', the label is placed in the center of the left hand side; if it is 'wn', the label is placed at the top of the left hand side; if it is 'ws', the label is placed at the bottom of the left hand side.

If None, a label component is not created. The default is None.

modifiedcommand
This is called whenever the text of the entry has been changed due to user action or by a call to setentry(). The default is None.

sticky
Initialisation option. The default is 'ew'.

validate
Specifies what kind of validation should be performed on the entry input text.

The most general way to specify the validate option is as a dictionary. The kind of validation is specified by the 'validator' dictionary field, which may be the name of one of the standard validators described below, the name of a validator supplied by the extravalidators option, a function or None. The default is None.

Any other dictionary fields specify other restrictions on the entered values. For all validators, the following fields may be specified:

'min'
Specifies the minimum acceptable value, or None if no minimum checking should be performed. The default is None.

'max'
Specifies the maximum acceptable value, or None if no maximum checking should be performed. The default is None.

'minstrict'
If true, then minimum checking is strictly enforced. Otherwise, the entry input may be less than min, but will be displayed using the errorbackground color. The default is true.

'maxstrict'
If true, then maximum checking is strictly enforced. Otherwise, the entry input may be more than max, but will be displayed using the errorbackground color. The default is true.

If the dictionary contains a 'stringtovalue' field, it overrides the normal stringtovalue function for the validator. The stringtovalue function is described below.

Other fields in the dictionary (apart from the core fields mentioned above) are passed on to the validator and stringtovalue functions as keyword arguments.

If validate is not a dictionary, then it is equivalent to specifying it as a dictionary with a single 'validator' field. For example, validate = 'real' is equivalent to /validate = {'validator' : 'real'}/ and specifies real numbers without any minimum or maximum limits and using '.' as the decimal point character.

The standard validators accepted in the 'validator' field are:

'numeric'
An integer greater than or equal to 0. Digits only. No sign.

'integer'
Any integer (negative, 0 or positive) as accepted by string.atol().

'hexadecimal'
Hex number (with optional leading '0x'), as accepted by string.atol(text, 16).

'real'
A number, with or without a decimal point and optional exponent (e or E), as accepted by string.atof(). This validator accepts a 'separator' argument, which specifies the character used to represent the decimal point. The default 'separator' is '.'.

'alphabetic'
Consisting of the letters 'a-z' and 'A-Z'. In this case, 'min' and 'max' specify limits on the length of the text.

'alphanumeric'
Consisting of the letters 'a-z', 'A-Z' and '0-9'. In this case, 'min' and 'max' specify limits on the length of the text.

'time'
Hours, minutes and seconds, in the format 'HH:MM:SS', as accepted by Pmw.timestringtoseconds(). This validator accepts a 'separator' argument, which specifies the character used to separate the three fields. The default separator is ':'. The time may be negative.

'date'
Day, month and year, as accepted by Pmw.datestringtojdn(). This validator accepts a 'separator' argument, which specifies the character used to separate the three fields. The default is ':'. This validator also accepts a 'format' argument, which is passed to Pmw.datestringtojdn() to specify the desired ordering of the fields. The default is 'ymd'.

If 'validator' is a function, then it will be called whenever the contents of the entry may have changed due to user action or by a call to setentry(). The function is called with at least one argument, the first one being the new text as modified by the user or setentry(). The other arguments are keyword arguments made up of the non-core fields of the validate dictionary.

The validator function should return Pmw.OK, Pmw.ERROR or Pmw.PARTIAL as described above. It should not perform minimum and maximum checking. This is done after the call, if it returns Pmw.OK.

The 'stringtovalue' field in the dictionary may be specified as the name of one of the standard validators, the name of a validator supplied by the extravalidators option, a function or None.

The stringtovalue function is used to convert the entry input into a value which can then be compared with any minimum or maximum values specified for the validator. If the 'min' or 'max' fields are specified as strings, they are converted using the stringtovalue function. The stringtovalue function is called with the same arguments as the validator function. The stringtovalue function for the standard number validators convert the string to a number. Those for the standard alpha validators return the length of the string. Those for the standard 'time' and 'date' validators return the number of seconds and the Julian Day Number, respectively. See Pmw.stringtoreal(), Pmw.timestringtoseconds() and Pmw.datestringtojdn().

If the validator has been specified as a function and no 'stringtovalue' field is given, then it defaults to the standard python len() function.

If 'validator' is None, no validation is performed. However, minimum and maximum checking may be performed, according to the stringtovalue function. For example, to limit the entry text to a maximum of five characters:

 Pmw.EntryField(validate = {'max' : 5})

The validator functions for each of the standard validators can be accessed as:

 Pmw.numericvalidator
 Pmw.integervalidator
 Pmw.hexadecimalvalidator
 Pmw.realvalidator
 Pmw.alphabeticvalidator
 Pmw.alphanumericvalidator
 Pmw.timevalidator
 Pmw.datevalidator

Whenever the validate option is configured, the text currently displayed in the entry widget is revalidated. If it is not valid, the errorbackground color is set and the invalidcommand function is called. However, the displayed text is not modified.

The default for validate is None.

value
Initialisation option. Specifies the initial contents of the entry. If this text is invalid, it will be displayed with the errorbackground color and the invalidcommand function will be called. If both value and entry_textvariable options are specified in the constructor, value will take precedence. The default is ''.

Components

Components created by this megawidget and its base classes are described below.

entry
The widget where the user may enter text. Long text may be scrolled horizontally by dragging with the middle mouse button. By default, this component is a Tkinter.Entry.

hull
This acts as the body for the entire megawidget. Other components are created as children of the hull to further specialise this class. By default, this component is a Tkinter.Frame.

label
If the labelpos option is not None, this component is created as a text label for the megawidget. See the labelpos option for details. Note that to set, for example, the text option of the label, you need to use the label_text component option. By default, this component is a Tkinter.Label.

Methods

Only methods specific to this megawidget are described below. For a description of its inherited methods, see the manual for its base class Pmw.MegaWidget. In addition, methods from the Tkinter.Entry class are forwarded by this megawidget to the entry component.

checkentry()
Check the validity of the current contents of the entry widget and return the result. If the text is not valid, set the background to errorbackground and call the invalidcommand function. If there is a variable specified by the entry_textvariable option, this method should be called after the set() method of the variable is called. If this is not done in this case, the entry widget background will not be set correctly.

clear()
Remove all text from the entry widget. Equivalent to setentry('').

getvalue()
Return the text displayed by the entry.

invoke()
Invoke the command specified by the command option as if the <Return> key had been pressed and return the result.

setentry(text)
Same as setvalue() method.

setvalue(text)
Set the contents of the entry widget to text and carry out validation as if the text had been entered by the user. If the text is invalid, the entry widget will not be changed and the invalidcommand function will be called. Return the validity of text.

valid()
Return true if the contents of the entry widget are valid.

Example

The image at the top of this manual is a snapshot of the window (or part of the window) produced by the following code.

class Demo:
    def __init__(self, parent):
        # Create and pack the EntryFields.
        self._any = Pmw.EntryField(parent,
                labelpos = 'w',
                label_text = 'Any:',
                validate = None,
                command = self.execute)
        self._real = Pmw.EntryField(parent,
                labelpos = 'w',
                value = '55.5',
                label_text = 'Real (10.0 to 99.0):',
                validate = {'validator' : 'real',
                        'min' : 10, 'max' : 99, 'minstrict' : 0},
                modifiedcommand = self.changed)
        self._odd = Pmw.EntryField(parent,
                labelpos = 'w',
                label_text = 'Odd length:',
                validate = self.custom_validate,
                value = 'ABC')
        self._date = Pmw.EntryField(parent,
                labelpos = 'w',
                label_text = 'Date (in 2000):',
                value = '2000/2/29',
                validate = {'validator' : 'date',
                        'min' : '2000/1/1', 'max' : '2000/12/31',
                        'minstrict' : 0, 'maxstrict' : 0,
                        'format' : 'ymd'},
                )
        now = time.localtime(time.time())
        self._date2 = Pmw.EntryField(parent,
                labelpos = 'w',
                label_text = 'Date (d.m.y):',
                value = '%d.%d.%d' % (now[2], now[1], now[0]),
                validate = {'validator' : 'date',
                        'format' : 'dmy', 'separator' : '.'},
                )
        self._time = Pmw.EntryField(parent,
                labelpos = 'w',
                label_text = 'Time (24hr clock):',
                value = '8:00:00',
                validate = {'validator' : 'time',
                        'min' : '00:00:00', 'max' : '23:59:59',
                        'minstrict' : 0, 'maxstrict' : 0},
                )
        self._comma = Pmw.EntryField(parent,
                labelpos = 'w',
                label_text = 'Real (with comma):',
                value = '123,456',
                validate = {'validator' : 'real', 'separator' : ','},
                )

        entries = (self._any, self._real, self._odd, self._date, self._date2,
                self._time, self._comma)

        for entry in entries:
            entry.pack(fill='x', expand=1, padx=10, pady=5)
        Pmw.alignlabels(entries)

        self._any.component('entry').focus_set()

    def changed(self):
        print 'Text changed, value is', self._real.getvalue()

    def execute(self):
        print 'Return pressed, value is', self._any.getvalue()

    # This implements a custom validation routine.  It simply checks
    # if the string is of odd length.
    def custom_validate(self, text):
        print 'text:', text
        if len(text) % 2 == 0:
          return -1
        else:
          return 1

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 22 May 1998

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9231184 Pmw-2.1/Pmw/Pmw_1_3_3/doc/ExampleDemo.py0000664000175000017500000000145700000000000020066 0ustar00gregmgregm00000000000000title = 'Pmw.EXAMPLE demonstration' # Import Pmw from this directory tree. import sys sys.path[:0] = ['../../..'] import Tkinter import Pmw class Demo: def __init__(self, parent): # Create and pack the EXAMPLEs. self.widget1 = Pmw.Counter(parent) self.widget1.setentry('1') self.widget1.pack() self.widget2 = Pmw.Counter(parent, increment = 10) self.widget2.setentry('100') self.widget2.pack() ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Tkinter.Tk() Pmw.initialise(root) root.title(title) exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) exitButton.pack(side = 'bottom') widget = Demo(root) root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9231184 Pmw-2.1/Pmw/Pmw_1_3_3/doc/Group.gif0000664000175000017500000000415500000000000017075 0ustar00gregmgregm00000000000000GIF87aق0`,H0I8ͻ`(dihlp,tmx|pH,Ȥrl:ШtJZجvzxL.hi@~'~/~|Vot Lm;u  ѩ nvpJÂYҚF9qD;"$ȏ$S`A˕0cVxـ̛8O;uIdPC*xҧ&J5TU֓U|^B*,fPYڈ`ӶьƷp'8}z]*m!F/8Tnj͢BC Q0hMN9lư#S{ij͞]udm&lRZ#jxlV`Y}Ue[^[T Y㗯O~oH%YeMGr a o`q/L(j\a n~^%D*<b\D,xcazX=$bTx#E%3S^7xMwȁRJxQ-)hOizG^vYgv[Ws[s1VgY.&8vhv\<i~S=iZJFǦ;j'$#x%i]rjiiQz\b&jC~iOF뗮^Ukmf;.m0nmpn U0ko/c#l' G,Wlgw ,$lc,0\: l8<-# 4BnFt.ʹN?=dfM{2Js^:XVg5VK‰Gq筚ڞy;4JwO6|7#w{xGW^̺fh۸O^"j{~qIFɎķ S]X{S*mMd_bkw}]=G3(yީ磏OȈ11NwvΦ85mo;0V\j=&AM9͇Y4(؛" MW>,W H!Sc&:PJϦH*ZXb1.z` H2hL6pH:x#3d GBMR1A)b T%"37}(d.ռF^ᒖ# 2)MևB( `P`.6% XTJC8V0%L]z ץQt(hIK[Nl*fVIzTa|r*X;f,O V3pFaԬf!LwTs7܌5cM|'2PAFs4IMkj`K/jAUP&YQbJuIhf]7QԂ(K8b\G_Ju[0UM%4=ӡTZ 5F_Z%Rf(*Hgfu|VWVs"kP[:&հ|RW2鄮`,U!U3rZU(WojL@i>ژ3(/ڃf@dmJц*lD7LN+5iEWL)0#gd@qN,ljʺ u=buM1X#p(QE/0ΌU:z֝9v^ESX"co |`Gˈ@5:7c &l;S Ӱ8|<N%bxW(&ًEP1ڊ;\cZb-؍d 9+Eؑd-*M^Kcx=*Qmc])YyXv}9]ٙfiuvy@g'NPF;c']0RҘG7N{ӠGMRԨNWV,;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9231184 Pmw-2.1/Pmw/Pmw_1_3_3/doc/Group.html0000664000175000017500000001733100000000000017274 0ustar00gregmgregm00000000000000 Pmw.Group reference manual

Pmw.Group

Name

Pmw.Group() - frame with ring border and tag

Inherits

Pmw.MegaWidget

Description

This megawidget consists of an interior frame with an exterior ring border and an identifying tag displayed over the top edge of the ring. The programmer can create other widgets within the interior frame.

Options

Options for this megawidget and its base classes are described below.

collapsedheight
Initialisation option. The default is 6.

collapsedsize
Initialisation option. The distance from the bottom of the tag to the bottom of the ring when the groupchildsite is collapsed. The default is 6.

collapsedwidth
Initialisation option. The default is 20.

tagindent
Initialisation option. The distance from the left edge of the ring to the left side of the tag component. The default is 10.

Components

Components created by this megawidget and its base classes are described below.

groupchildsite
The frame which can contain other widgets to be grouped. By default, this component is a Tkinter.Frame.

hull
This acts as the body for the entire megawidget. Other components are created as children of the hull to further specialise this class. By default, this component is a Tkinter.Frame.

ring
This component acts as the enclosing ring around the groupchildsite. The default borderwidth is 2 and the default relief is 'groove'. By default, this component is a Tkinter.Frame.

tag
The identifying tag displayed over the top edge of the enclosing ring. If the pyclass for this component is None, (ie: tag_pyclass = None, then no tag component is created. By default, this component is a Tkinter.Label.

Methods

Only methods specific to this megawidget are described below. For a description of its inherited methods, see the manual for its base class Pmw.MegaWidget.

collapse()
Do not display the groupchildsite component.

expand()
Display the groupchildsite component.

interior()
Return the frame within which the programmer may create widgets. This is the same as component('groupchildsite').

toggle()
Display the groupchildsite component if it is currently hidden and hide it if it is currently displayed.

Example

The image at the top of this manual is a snapshot of the window (or part of the window) produced by the following code.

class Demo:
    def __init__(self, parent):

        # Create and pack the Groups.
        w = Pmw.Group(parent, tag_text='label')
        w.pack(fill = 'both', expand = 1, padx = 6, pady = 6)
        cw = Tkinter.Label(w.interior(),
                text = 'A group with the\ndefault Label tag')
        cw.pack(padx = 2, pady = 2, expand='yes', fill='both')

        w = Pmw.Group(parent, tag_pyclass = None)
        w.pack(fill = 'both', expand = 1, padx = 6, pady = 6)
        cw = Tkinter.Label(w.interior(), text = 'A group\nwithout a tag')
        cw.pack(padx = 2, pady = 2, expand='yes', fill='both')

        radiogroups = []
        self.var = Tkinter.IntVar()
        self.var.set(0)
        radioframe = Tkinter.Frame(parent)
        w = Pmw.Group(radioframe,
                tag_pyclass = Tkinter.Radiobutton,
                tag_text='radiobutton 1',
                tag_value = 0,
                tag_variable = self.var)
        w.pack(fill = 'both', expand = 1, side='left')
        cw = Tkinter.Frame(w.interior(),width=200,height=20)
        cw.pack(padx = 2, pady = 2, expand='yes', fill='both')
        radiogroups.append(w)

        w = Pmw.Group(radioframe,
                tag_pyclass = Tkinter.Radiobutton,
                tag_text='radiobutton 2',
                tag_font = Pmw.logicalfont('Helvetica', 4),
                tag_value = 1,
                tag_variable = self.var)
        w.pack(fill = 'both', expand = 1, side='left')
        cw = Tkinter.Frame(w.interior(),width=200,height=20)
        cw.pack(padx = 2, pady = 2, expand='yes', fill='both')
        radiogroups.append(w)
        radioframe.pack(padx = 6, pady = 6, expand='yes', fill='both')
        Pmw.aligngrouptags(radiogroups)

        w = Pmw.Group(parent,
                tag_pyclass = Tkinter.Checkbutton,
                tag_text='checkbutton',
                tag_foreground='blue')
        w.pack(fill = 'both', expand = 1, padx = 6, pady = 6)
        cw = Tkinter.Frame(w.interior(),width=150,height=20)
        cw.pack(padx = 2, pady = 2, expand='yes', fill='both')

        w = Pmw.Group(parent,
                tag_pyclass = Tkinter.Button,
                tag_text='Tkinter.Button')
        w.configure(tag_command = w.toggle)
        w.pack(fill = 'both', expand = 1, padx = 6, pady = 6)
        cw = Tkinter.Label(w.interior(),
                background = 'aliceblue',
                text = 'A group with\na Button tag!?'
        )
        cw.pack(padx = 2, pady = 2, expand='yes', fill='both')

        w = Pmw.Group(parent,
                tag_pyclass = Tkinter.Button,
                tag_text='Show/Hide')
        w.configure(tag_command = w.toggle)
        w.pack(fill = 'both', expand = 1, padx = 6, pady = 6)
        cw = Tkinter.Label(w.interior(),
                background = 'aliceblue',
                text = 'Now you see me.\nNow you don\'t.'
        )
        cw.pack(padx = 2, pady = 2, expand='yes', fill='both')

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 15 November 1998

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9271185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/HistoryText.gif0000664000175000017500000000440100000000000020301 0ustar00gregmgregm00000000000000GIF87a'+@@xxN @@ttDt 4@@&{ N0O @9$\$@Yoa9@@@\ttD\YE-xL{t @܃7+@Ixt @tXtk\Xlty"TZ<Kx٘-8 N $_ L-&x@x$ @@aa PzN|\<R`x @`<'<݌8@$`\l@89ce/G̹燌9Q[מC\pӵ.L0map~M\7r޽?۶ͳSN::ϫ7^ar}#o=ao4z''ށ&xyuW[tI{؝'v!}u߅gb,h"F\4!Gڍ~Ha#5eLv裁R i}ZB)%5NISehArڹ)r1`|N8\_'ԩ_q\)棐*ƦxJFj饘6ivdm ꨤjDꪬ`bja٣۪A+d /5_"ڷgG(tYm9*'Q2knIJgRYWd%ZB~]j&(JobdozG%Vi;|b&y#ǺG/%kr[Db(/ʬ+\*Y]yW0{e6!D3JTiUgkW+6`k˰--h/Fvll 5\oe Evj-wzwVj]#w`}7.XW3(<[;yx%n;g/0:s kKv⼣2یr^gon6HslP>}׳Wxh^m2[(k=ĄnUs:pU HsE hzp#;%< p{-| GPp5ٖ0l=!QeE<-%:qI|m)ZTUA-zbMW1Me<5Qm|!9Uu;=Qy ɩ>q1$"E2#$' GRY$&7Mr$(G*I4%*WHU $,gJY򖭴%.w_%0O)a$2e2|$)GR&6m#8éqӎ<өN7j|'<(y">}ӊ*P'J<(BЅ !D#ÉRԆ 3Qr*(HM(ґ& JS.}) ])cҴʼ)NӝB>&Pj͡5F=*7o2|*T)թV]'Vέr5^*=vhMZֶp\J׺xͫ^׾ `Mb:_ EIAi;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9271185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/HistoryText.html0000664000175000017500000003737200000000000020515 0ustar00gregmgregm00000000000000 Pmw.HistoryText reference manual

Pmw.HistoryText

Name

Pmw.HistoryText() - text widget with a course-grained form of history

Inherits

Pmw.ScrolledText

Description

A history text is a scrolled text widget with added functionality to maintain a history of each screen and allow editing of prior screens. Here, screen refers to the entire contents of the text widget. This widget does not support a fine-grained history of every change made to the text.

Together with a few buttons and a scrolled text to display the results, a history text can be used as the query-entry part of a simple interactive text-based database query system. When the user enters and executes a query, the query (the entire contents of the text widget) is added to the history list. The user may view previous queries and either execute them again or modify them and execute the new query. If a previously executed query is modified, the user may undo or redo all changes made to the query before the query is executed.

Options

Options for this megawidget and its base classes are described below.

borderframe
Initialisation option. If true, the borderframe component will be created. The default is 0.

columnheader
Initialisation option. If true, the columnheader component will be created. The default is 0.

compressany
See addhistory(). The default is 1.

compresstail
See addhistory(). The default is 1.

historycommand
This is a callback to indicate whether the currently displayed entry in the history list has a previous or next entry. The callback is given two arguments, prevstate and nextstate. If the currently displayed entry is first in the history list, then prevstate is 'disabled', otherwise it is 'normal'. If the currently displayed entry is last in the history list, then nextstate is 'disabled', otherwise it is 'normal'. These values can be used, for example, to modify the state of Next and Previous buttons that call the next() and prev() methods. The default is None.

hscrollmode
The horizontal scroll mode. If 'none', the horizontal scrollbar will never be displayed. If 'static', the scrollbar will always be displayed. If 'dynamic', the scrollbar will be displayed only if necessary. The default is 'dynamic'.

labelmargin
Initialisation option. If the labelpos option is not None, this specifies the distance between the label component and the rest of the megawidget. The default is 0.

labelpos
Initialisation option. Specifies where to place the label component. If not None, it should be a concatenation of one or two of the letters 'n', 's', 'e' and 'w'. The first letter specifies on which side of the megawidget to place the label. If a second letter is specified, it indicates where on that side to place the label. For example, if labelpos is 'w', the label is placed in the center of the left hand side; if it is 'wn', the label is placed at the top of the left hand side; if it is 'ws', the label is placed at the bottom of the left hand side.

If None, a label component is not created. The default is None.

rowcolumnheader
Initialisation option. If true, the rowcolumnheader component will be created. The default is 0.

rowheader
Initialisation option. If true, the rowheader component will be created. The default is 0.

scrollmargin
Initialisation option. The distance between the scrollbars and the text widget. The default is 2.

usehullsize
Initialisation option. If true, the size of the megawidget is determined solely by the width and height options of the hull component.

Otherwise, the size of the megawidget is determined by the width and height of the text component, along with the size and/or existence of the other components, such as the label, the scrollbars and the scrollmargin option. All these affect the overall size of the megawidget. The default is 0.

vscrollmode
The vertical scroll mode. If 'none', the vertical scrollbar will never be displayed. If 'static', the scrollbar will always be displayed. If 'dynamic', the scrollbar will be displayed only if necessary. The default is 'dynamic'.

Components

Components created by this megawidget and its base classes are described below.

borderframe
A frame widget which snuggly fits around the text widget, to give the appearance of a text border. It is created with a border so that the text widget, which is created without a border, looks like it has a border. By default, this component is a Tkinter.Frame.

columnheader
A text widget with a default height of 1 displayed above the main text widget and which scrolls horizontally in sync with the horizontal scrolling of the main text widget. By default, this component is a Tkinter.Text. Its component group is Header.

horizscrollbar
The horizontal scrollbar. By default, this component is a Tkinter.Scrollbar. Its component group is Scrollbar.

hull
This acts as the body for the entire megawidget. Other components are created as children of the hull to further specialise this class. By default, this component is a Tkinter.Frame.

label
If the labelpos option is not None, this component is created as a text label for the megawidget. See the labelpos option for details. Note that to set, for example, the text option of the label, you need to use the label_text component option. By default, this component is a Tkinter.Label.

rowcolumnheader
A text widget displayed to the top left of the main text widget, above the row header and to the left of the column header if they exist. The widget is not scrolled automatically. By default, this component is a Tkinter.Text. Its component group is Header.

rowheader
A text widget displayed to the left of the main text widget and which scrolls vertically in sync with the vertical scrolling of the main text widget. By default, this component is a Tkinter.Text. Its component group is Header.

text
The text widget which is scrolled by the scrollbars. If the borderframe option is true, this is created with a borderwidth of 0 to overcome a known problem with text widgets: if a widget inside a text widget extends across one of the edges of the text widget, then the widget obscures the border of the text widget. Therefore, if the text widget has no border, then this overlapping does not occur. By default, this component is a Tkinter.Text.

vertscrollbar
The vertical scrollbar. By default, this component is a Tkinter.Scrollbar. Its component group is Scrollbar.

Methods

Only methods specific to this megawidget are described below. For a description of its inherited methods, see the manual for its base class Pmw.ScrolledText.

addhistory()
Append the currently displayed text to the history list.

If compressany is true, a new entry will be added to the history list only if the currently displayed entry has changed.

If compresstail is true, a new entry will be added to the history list only if the currently displayed entry has changed or if it is not the last entry in the history list.

gethistory()
Return the history list. Each entry in the list is a 3-tuple. The first item in a history entry is the original text as added by addhistory(). The second item is the edited text (if the user has modified the entry but addhistory() has not yet been called on the text). The third item specifies whether the entry should currently display the original or modified text.

next()
Display the next screen in the history list.

prev()
Display the previous screen in the history list.

redo()
Reverse the effect of undo().

undo()
Undo all changes made since this entry was added to the history list.

Example

The image at the top of this manual is a snapshot of the window (or part of the window) produced by the following code.

class Demo:
    def __init__(self, parent):
        # Create and pack the PanedWidget to hold the query and result
        # windows.
        # !! panedwidget should automatically size to requested size
        panedWidget = Pmw.PanedWidget(parent,
                orient = 'vertical',
                hull_height = 400,
                hull_width = 550)
        panedWidget.add('query', min = 0.05, size = 0.2)
        panedWidget.add('buttons', min = 0.1, max = 0.1)
        panedWidget.add('results', min = 0.05)
        panedWidget.pack(fill = 'both', expand = 1)

        # Create and pack the HistoryText.
        self.historyText = Pmw.HistoryText(panedWidget.pane('query'),
                text_wrap = 'none',
                text_width = 60,
                text_height = 10,
                historycommand = self.statechange,
        )
        self.historyText.pack(fill = 'both', expand = 1)
        self.historyText.component('text').focus()

        buttonList = (
            [20, None],
            ['Clear', self.clear],
            ['Undo', self.historyText.undo],
            ['Redo', self.historyText.redo],
            [20, None],
            ['Prev', self.historyText.prev],
            ['Next', self.historyText.next],
            [30, None],
            ['Execute', Pmw.busycallback(self.executeQuery)],
        )
        self.buttonDict = {}

        buttonFrame = panedWidget.pane('buttons')
        for text, cmd in buttonList:
            if type(text) == type(69):
                frame = Tkinter.Frame(buttonFrame, width = text)
                frame.pack(side = 'left')
            else:
                button = Tkinter.Button(buttonFrame, text = text, command = cmd)
                button.pack(side = 'left')
                self.buttonDict[text] = button

        for text in ('Prev', 'Next'):
            self.buttonDict[text].configure(state = 'disabled')

        self.results = Pmw.ScrolledText(panedWidget.pane('results'), text_wrap = 'none')
        self.results.pack(fill = 'both', expand = 1)

    def statechange(self, prevstate, nextstate):
        self.buttonDict['Prev'].configure(state = prevstate)
        self.buttonDict['Next'].configure(state = nextstate)

    def clear(self):
        self.historyText.delete('1.0', 'end')

    def addnewlines(self, text):
        if len(text) == 1:
            text = text + '\n'
        if text[-1] != '\n':
            text = text + '\n'
        if text[-2] != '\n':
            text = text + '\n'
        return text

    def executeQuery(self):
        sql = self.historyText.get()
        self.results.insert('end', 'Query:\n' + self.addnewlines(sql))
        self.results.see('end')
        self.results.update_idletasks()
        self.historyText.addhistory()
        results = 'Results:\nfoo'
        if len(results) > 0:
            self.results.insert('end', self.addnewlines(results))
        self.results.see('end')

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 20 May 2002

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9231184 Pmw-2.1/Pmw/Pmw_1_3_3/doc/LabeledWidget.gif0000664000175000017500000000157000000000000020473 0ustar00gregmgregm00000000000000GIF87at傂,t80I8ͻ`(dihlp,tmx|@,Ȥrl:sJZ((zxL.]@Vf ~^ۇx|eu}^eosnbfp_cgqzp]œʿ~ÔaǾ٬f hyg`܅s֭x?aS3zi ({qE5N8YDL`#K`ʕ+Oz LR4kn)E<(衡D4)v:5xԩZVw\&V_+&<3ȵlE 7nѹ3T÷߿ ^z^̸1Č3lHZ.E8{dE Yէ1GqdڢmW=etYOJ|ʉ6MYG_ie9FatyhvũG`lZ v"[Պƭ+/T8 GjȆ`4[*FNt-zec+.kn;ݺ+k$;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9231184 Pmw-2.1/Pmw/Pmw_1_3_3/doc/LabeledWidget.html0000664000175000017500000001322100000000000020666 0ustar00gregmgregm00000000000000 Pmw.LabeledWidget reference manual

Pmw.LabeledWidget

Name

Pmw.LabeledWidget() - frame with label

Inherits

Pmw.MegaWidget

Description

This megawidget consists of an interior frame with an associated label which can be positioned on any side of the frame. The programmer can create other widgets within the interior frame.

Options

Options for this megawidget and its base classes are described below.

labelmargin
Initialisation option. If the labelpos option is not None, this specifies the distance between the label component and the rest of the megawidget. The default is 0.

labelpos
Initialisation option. Specifies where to place the label component. If not None, it should be a concatenation of one or two of the letters 'n', 's', 'e' and 'w'. The first letter specifies on which side of the megawidget to place the label. If a second letter is specified, it indicates where on that side to place the label. For example, if labelpos is 'w', the label is placed in the center of the left hand side; if it is 'wn', the label is placed at the top of the left hand side; if it is 'ws', the label is placed at the bottom of the left hand side.

If None, a label component is not created. The default is None.

sticky
Initialisation option. The default is 'nsew'.

Components

Components created by this megawidget and its base classes are described below.

hull
This acts as the body for the entire megawidget. Other components are created as children of the hull to further specialise this class. By default, this component is a Tkinter.Frame.

label
If the labelpos option is not None, this component is created as a text label for the megawidget. See the labelpos option for details. Note that to set, for example, the text option of the label, you need to use the label_text component option. By default, this component is a Tkinter.Label.

labelchildsite
The frame which can contain other widgets to be labelled. By default, this component is a Tkinter.Frame.

Methods

Only methods specific to this megawidget are described below. For a description of its inherited methods, see the manual for its base class Pmw.MegaWidget.

interior()
Return the frame within which the programmer may create widgets. This is the same as component('labelchildsite').

Example

The image at the top of this manual is a snapshot of the window (or part of the window) produced by the following code.

class Demo:
    def __init__(self, parent):

        # Create a frame to put the LabeledWidgets into
        frame = Tkinter.Frame(parent, background = 'grey90')
        frame.pack(fill = 'both', expand = 1)

        # Create and pack the LabeledWidgets.
        column = 0
        row = 0
        for pos in ('n', 'nw', 'wn', 'w'):
            lw = Pmw.LabeledWidget(frame,
                    labelpos = pos,
                    label_text = pos + ' label')
            lw.component('hull').configure(relief='sunken', borderwidth=2)
            lw.grid(column=column, row=row, padx=10, pady=10)
            cw = Tkinter.Button(lw.interior(), text='child\nsite')
            cw.pack(padx=10, pady=10, expand='yes', fill='both')

            # Get ready for next grid position.
            column = column + 1
            if column == 2:
              column = 0
              row = row + 1

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 8 November 1998

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9271185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/MainMenuBar.gif0000664000175000017500000000101100000000000020123 0ustar00gregmgregm00000000000000GIF87aق,ڋ޼ ʶ rj{ Ģ"̦ )ԪMܮ l+v@>96c>߸1y׷0蠖PF(HaW#Xp A: z0Z i zJXkX'7|9II,1);Hm kL )}>p]z̜^{l5r;^*%N[0aPI 7,2dZć03wC1F"~4M%r/j)2YZ+J ./CTiP39* T>ArB]61rV>8BRWe<: `ͧX Qe,"/d i7({1d>- r{! ,gKR~ شkm;(w]Āċ?<̛;=ԫ[=ܻ{;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9271185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/MainMenuBar.html0000664000175000017500000004216600000000000020342 0ustar00gregmgregm00000000000000 Pmw.MainMenuBar reference manual

Pmw.MainMenuBar

Name

Pmw.MainMenuBar() - manager for toplevel native menus

Inherits

Pmw.MegaArchetype

Description

This class is a wrapper for the Tkinter.Menu class. It should be used as the main menu of toplevel windows. The class is similar to Pmw.MenuBar, but should be used when native menus are required. See the Tkinter.Menu documentation for full details.

This class should be created as the child of a Tkinter.Toplevel and should then be specified as the menu associated with the toplevel, using the toplevel's configure() method. For example:

 # Create a Pmw.MegaToplevel.
 megaToplevel = Pmw.MegaToplevel()
 # Get the Tkinter.Toplevel from Pmw.MegaToplevel.
 toplevel = megaToplevel.interior()
 # Create the menu bar for the toplevel.
 menuBar = Pmw.MainMenuBar(toplevel)
 # Configure the toplevel to use the menuBar.
 toplevel.configure(menu = menuBar)

There are methods to add menus, both as toplevel menus and sub-menus, and for adding menu items to the menus. Each menu item may have help text to be displayed by a Pmw.Balloon. Each menu and cascaded menu (sub-menu) is referenced by name which is supplied on creation.

This megawidget is derived from Pmw.MegaArchetype (not Pmw.MegaWidget like most other megawidgets), with the hull class being Tkinter.Menu.

(Note that due to bugs in Tk's menubar functionality, balloon help has not been implemented and status help does not work properly.)

Options

Options for this megawidget and its base classes are described below.

balloon
Specifies a Pmw.Balloon to display the help text for menu items. If None, no help is displayed. If the balloon has an associated Pmw.MessageBar, the help text will also be displayed there.

Due to a bug in some versions of Tk (8.0 and possible others), help text will not be displayed by the balloon. However, help text will be displayed in the balloon's associated messagebar. The default is None.

hotkeys
Initialisation option. If true, keyboard accelerators will be assigned to each menu item. Keyboard accelerators can be used to access the menus without using the mouse. The accelerator character is always one of the alphanumeric characters in the text label of the menu item and is indicated by an underline.

To select a menu, simultaneously press the <Alt> key and the accelerator character indicated on a toplevel menu item. The arrows keys can then be used to select other menus and menu items. To invoke a menu item, press <Return> or press the accelerator character indicated on the menu item.

Each accelerator character will be assigned automatically unless traverseSpec is supplied to the addmenu(), addmenuitem() or addcascademenu() methods. The automatically selected accelerator character for a menu item is the first character in the label text that has not already been used as an accelerator in the menu containing the menu item.

If traverseSpec is given, it must be either an integer or a character. If an integer, it specifies the index of the character in the label text to use as the accelerator character. If a character, it specifies the character to use as the accelerator character. The default is 1.

Components

Components created by this megawidget and its base classes are described below.

hull
The toplevel menu widget. By default, this component is a Tkinter.Menu.

Dynamic components

Menu components are created dynamically by the addmenu() and addcascademenu() methods. By default, these are of type Tkinter.Menu and are created with a component group of Menu.

Methods

Only methods specific to this megawidget are described below. For a description of its inherited methods, see the manual for its base class Pmw.MegaArchetype. In addition, methods from the Tkinter.Menu class are forwarded by this megawidget to the hull component.

addcascademenu(parentMenuName, menuName, statusHelp = '', traverseSpec = None, **kw)
Add a cascade menu (sub-menu) to the menu parentMenuName. The menuName argument must not be the same as any menu already created using the addmenu() or addcascademenu() methods.

A menu item in the parent menu is created (with the add_cascade() method of the parent menu) using all keyword arguments except tearoff and name.

If the label keyword argument is not given, the label option of the menu item defaults to menuName. If the underline keyword argument is not given (and the hotkeys megawidget option is true) the underline option is determined as described under hotkeys and is used to specify the keyboard accelerator.

The statusHelp argument is used as the help string for the menu item. This is displayed using the showstatus() method of the balloon.

The tearoff and name keyword arguments, if present, are passed to the constructor of the menu. See Tkinter.Menu for details of these options. The menu is created as a component named menuName.

addmenu(menuName, balloonHelp, statusHelp = None, traverseSpec = None, **kw)
Add a cascade menu to the toplevel menu. The menuName argument must not be the same as any menu already created using the addmenu() or addcascademenu() methods.

A menu item in the toplevel menu is created (with the add_cascade() method) using all keyword arguments except tearoff and name.

If the label keyword argument is not given, the label option of the menu button defaults to menuName. If the underline keyword argument is not given (and the hotkeys megawidget option is true) the underline option is determined as described under hotkeys and is used to specify the keyboard accelerator.

The statusHelp argument is used as the help string for the menu item. This is displayed using the showstatus() method of the balloon. Currently balloonHelp is not used, due to a bug in Tk version 8.0.

The tearoff and name keyword arguments, if present, are passed to the constructor of the menu. See Tkinter.Menu for details of these options. The menu is created as a component named menuName.

addmenuitem(menuName, itemType, statusHelp = '', traverseSpec = None, **kw)
Add a menu item to the menu menuName. The kind of menu item is given by itemType and may be one of command, separator, checkbutton, radiobutton or cascade (although cascade menus are better added using the addcascademenu() method). Any keyword arguments present will be passed to the menu when creating the menu item. See Tkinter.Menu for the valid options for each item type. In addition, a keyboard accelerator may be automatically given to the item, as described under hotkeys.

When the mouse is moved over the menu item, the helpString will be displayed by the balloon's statuscommand.

deletemenu(menuName)
Delete the menu menuName and all its items. The menu may either be a toplevel menu or a cascade menu.

deletemenuitems(menuName, start, end = None)
Delete menu items from the menu menuName. If end is not given, the start item is deleted. Otherwise all items from start to end are deleted.

disableall()
Disable all toplevel menus.

enableall()
Enable all toplevel menus.

Example

The image at the top of this manual is a snapshot of the window (or part of the window) produced by the following code.

class Demo:
    def __init__(self, parent):
        # Create button to launch the toplevel with main menubar.
        w = Tkinter.Button(parent, text = 'Show Pmw.MainMenuBar demo',
                command = lambda parent=parent: MainMenuBarToplevel(parent))
        w.pack(padx = 8, pady = 8)

class MainMenuBarToplevel:
    def __init__(self, parent):
        # Create the toplevel to contain the main menubar.
        megaToplevel = Pmw.MegaToplevel(parent, title = title)
        toplevel = megaToplevel.interior()

        # Create the Balloon for this toplevel.
        self.balloon = Pmw.Balloon(toplevel)

        # Create and install the MenuBar.
        menuBar = Pmw.MainMenuBar(toplevel,
                balloon = self.balloon)
        toplevel.configure(menu = menuBar)
        self.menuBar = menuBar

        # Add some buttons to the MainMenuBar.
        menuBar.addmenu('File', 'Close this window or exit')
        menuBar.addmenuitem('File', 'command', 'Close this window',
                command = PrintOne('Action: close'),
                label = 'Close')
        menuBar.addmenuitem('File', 'separator')
        menuBar.addmenuitem('File', 'command', 'Exit the application',
                command = PrintOne('Action: exit'),
                label = 'Exit')

        menuBar.addmenu('Edit', 'Cut, copy or paste')
        menuBar.addmenuitem('Edit', 'command', 'Delete the current selection',
                command = PrintOne('Action: delete'),
                label = 'Delete')

        menuBar.addmenu('Options', 'Set user preferences')
        menuBar.addmenuitem('Options', 'command', 'Set general preferences',
                command = PrintOne('Action: general options'),
                label = 'General...')

        # Create a checkbutton menu item.
        self.toggleVar = Tkinter.IntVar()
        # Initialise the checkbutton to 1:
        self.toggleVar.set(1)
        menuBar.addmenuitem('Options', 'checkbutton', 'Toggle me on/off',
                label = 'Toggle',
                command = self._toggleMe,
                variable = self.toggleVar)
        self._toggleMe()

        menuBar.addcascademenu('Options', 'Size',
                'Set some other preferences', traverseSpec = 'z', tearoff = 1)
        for size in ('tiny', 'small', 'average', 'big', 'huge'):
            menuBar.addmenuitem('Size', 'command', 'Set size to ' + size,
                    command = PrintOne('Action: size ' + size),
                    label = size)

        menuBar.addmenu('Help', 'User manuals', name = 'help')
        menuBar.addmenuitem('Help', 'command', 'About this application',
                command = PrintOne('Action: about'),
                label = 'About...')

        # Create and pack the main part of the window.
        self.mainPart = Tkinter.Label(toplevel,
                text = 'This is the\nmain part of\nthe window',
                background = 'black',
                foreground = 'white',
                padx = 30,
                pady = 30)
        self.mainPart.pack(fill = 'both', expand = 1)

        # Create and pack the MessageBar.
        self.messageBar = Pmw.MessageBar(toplevel,
                entry_width = 40,
                entry_relief='groove',
                labelpos = 'w',
                label_text = 'Status:')
        self.messageBar.pack(fill = 'x', padx = 10, pady = 10)
        self.messageBar.message('state',
            'Balloon/status help not working properly - Tk menubar bug')

        buttonBox = Pmw.ButtonBox(toplevel)
        buttonBox.pack(fill = 'x')
        buttonBox.add('Disable\nall', command = menuBar.disableall)
        buttonBox.add('Enable\nall', command = menuBar.enableall)
        buttonBox.add('Create\nmenu', command = self.add)
        buttonBox.add('Delete\nmenu', command = self.delete)
        buttonBox.add('Create\nitem', command = self.additem)
        buttonBox.add('Delete\nitem', command = self.deleteitem)

        # Configure the balloon to displays its status messages in the
        # message bar.
        self.balloon.configure(statuscommand = self.messageBar.helpmessage)

        self.testMenuList = []

    def _toggleMe(self):
        print 'Toggle value:', self.toggleVar.get()

    def add(self):
        if len(self.testMenuList) == 0:
            num = 0
        else:
            num = self.testMenuList[-1]
        num = num + 1
        name = 'Menu%d' % num
        self.testMenuList.append(num)

        self.menuBar.addmenu(name, 'This is ' + name)

    def delete(self):
        if len(self.testMenuList) == 0:
            self.menuBar.bell()
        else:
            num = self.testMenuList[0]
            name = 'Menu%d' % num
            del self.testMenuList[0]
            self.menuBar.deletemenu(name)

    def additem(self):
        if len(self.testMenuList) == 0:
            self.menuBar.bell()
        else:
            num = self.testMenuList[-1]
            menuName = 'Menu%d' % num
            menu = self.menuBar.component(menuName)
            if menu.index('end') is None:
                label = 'item X'
            else:
                label = menu.entrycget('end', 'label') + 'X'
            self.menuBar.addmenuitem(menuName, 'command', 'Help for ' + label,
                    command = PrintOne('Action: ' + menuName + ': ' + label),
                    label = label)
            
    def deleteitem(self):
        if len(self.testMenuList) == 0:
            self.menuBar.bell()
        else:
            num = self.testMenuList[-1]
            menuName = 'Menu%d' % num
            menu = self.menuBar.component(menuName)
            if menu.index('end') is None:
                self.menuBar.bell()
            else:
                self.menuBar.deletemenuitems(menuName, 0)
            
class PrintOne:
    def __init__(self, text):
        self.text = text

    def __call__(self):
        print self.text

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 22 April 2000

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9231184 Pmw-2.1/Pmw/Pmw_1_3_3/doc/MegaArchetype.html0000664000175000017500000005342700000000000020724 0ustar00gregmgregm00000000000000 Pmw.MegaArchetype reference manual

Pmw.MegaArchetype

Name

Pmw.MegaArchetype() - abstract base class for all Pmw megawidgets

Description

This class is the basis for all Pmw megawidgets. It provides methods to manage options and component widgets.

This class is normally used as a base class for other classes. If the hullClass argument is specified, such as in the Pmw.MegaWidget and Pmw.MegaToplevel classes, a container widget is created to act as the parent of all other component widgets. Classes derived from these sub classes create other component widgets and options to implement megawidgets that can be used in applications.

If no hullClass argument is given to the constructor, no container widget is created and only the option configuration functionality is available.

Components

A megawidget is generally made up of other widgets packed within the megawidget's containing widget. These sub-widgets are called the components of the megawidget and are given logical names for easy reference. The component mechanism allows the user of a megawidget to gain controlled access to some of the internals of the megawidget, for example to call a method of a component or to set a component's configuration options.

Sub components: If a component is itself a megawidget containing sub-components, then these sub-components can be referred to using the notation component_subcomponent. For example, Pmw.ComboBox has a component named entryfield which is an instance of Pmw.EntryField, which itself has a Tkinter.Entry component named entry. In the context of the combobox, this entry widget can be referred to as entryfield_entry.

Component aliases: Because the sub-component notation may make component names inconveniently long, components and sub-components can be aliased to simpler names. For example, the entryfield_entry sub-component of Pmw.ComboBox is aliased to simply entry. If there is no conflict in component names, sub-component names are usually aliased to the name of the "leaf" component.

Component groups: Similar components of a megawidget can be given a group name, which allows all components of a group to be referenced using the one group name. For example, the two arrow components of Pmw.Counter have a group name of Arrow. Also, megawidgets that can create an unlimited number of similar components, such as Pmw.ButtonBox, create each of these components with the same group name. By convention, group names begin with a capital letter.

Options

A megawidget defines options which allow the megawidget user to modify the appearance and behaviour of the megawidget. Using the same technique as Tkinter widgets, the values of megawidget options may be set in calls to the constructor and to configure() and the values may be queried by calls to cget() and configure(). Like Tkinter widgets, megawidget options are initialised with default values. Also, if the useTkOptionDb option to Pmw.initialise() has been set, then the Tk option database will be queried to get the initial values. Strings found in the option database are converted to python objects (integer, float, tuple, dictionary, etc) using a restricted eval() call. Anything that is not accepted by eval() is treated as a string.

Inherited options: As well as the options defined in a class, a derived class inherits all options of its base classes. The default value of an option defined by a base class may be modified by the derived class.

Initialisation options: Some megawidget options can only be set in the call to the constructor. These are called initialisation options. Unlike normal configuration options, they cannot be set by calling the configure() method.

Component options: Options of the components of a megawidget can be referred to using the notation component_option. Like the megawidget options, component options can be used in calls to the constructor and to the cget() and configure() methods. For example, the state option of the Tkinter.Text text component of Pmw.ScrolledText may be set by calling

 widget.configure(text_state = 'disabled')

Sub-components, component aliases and component groups may also be combined with options. For example, the state option of the entryfield_entry component of Pmw.ComboBox may be set by calling

 combobox.configure(entryfield_entry_state = 'normal')

Since it has an alias, it is more convenient to use the equivalent form

 combobox.configure(entry_state = 'normal')

Also, the background color of both arrows of Pmw.Counter can be set using the Arrow component group.

 counter.configure(Arrow_background = 'aliceblue')

The pyclass component option

The pyclass component option is a special notation that can be used to specify a non-default python class for a component. This can only be used when the component is being constructed. For a component created during the construction of its parent megawidget, this option must be given to the constructor in the form component_pyclass. For example, to change the python class of the text sub-component of Pmw.TextDialog to a class FontText.Text

 dialog = Pmw.TextDialog(text_pyclass = FontText.Text)

For components created after the construction of the parent megawidget, the pyclass option must be passed into the method which constructs the component. For example, to set the python class of a button in Pmw.ButtonBox to a class MyButton:

 buttonBox.add('special', pyclass = MyButton)

The new python class of the component must support all methods and options that are used by the megawidget when operating on the component. The exact interface required for each component is not documented. You will have to examine the Pmw source code. However, any class derived from the default class of a component can be used as the new class of the component, as long as all of the original methods and options are still supported. For example, any class derived from Tkinter.Text can be used as the class of the text sub-component of Pmw.TextDialog.

The pyclass component option should not be confused with the class option that some of the Tk widgets support. The class option sets the Tk option database class for the widget and is used by Tk to query the database for the default values of the widget's other options. The name pyclass was chosen so that it did not conflict with any known Tk options.

Construction

The constructors of classes derived from this class all accept the same arguments: one positional argument and any number of keyword arguments. The positional argument defaults to None (meaning the root window) and specifies the widget to use as the parent when creating the megawidget's hull component. The keyword arguments define initial values for options. The format for the constructors of derived classes is:

   def __init__(self, parent = None, **kw):

Methods

addoptions(optionDefs)
Add additional options for this megawidget. The optionDefs argument is treated in the same way as for the defineoptions() method.

This method is for use by derived classes. It is only used if a megawidget should conditionally define some options, perhaps depending on the value of other options. Usually, megawidgets unconditionally define all their options in the call to defineoptions() and do not need to use addoptions(). This method must be called after the call to defineoptions() and before the call to initialiseoptions().

cget(option)
Return the current value of option (which should be in the format described in the Options section). This method is also available using object subscripting, for example myWidget['font']. Unlike Tkinter's cget(), which always returns a string, this method returns the same value and type as used when the option was set (except where option is a component option and the component is a Tkinter widget, in which case it returns the string returned by Tcl/Tk).

component(name)
Return the component widget whose name is name. This allows the user of a megawidget to access and configure component widgets directly.

componentaliases()
Return the list of aliases for components. Each item in the list is a tuple whose first item is the name of the alias and whose second item is the name of the component or sub-component it refers to.

componentgroup(name)
Return the group of the component whose name is name or None if it does not have a group.

components()
Return a sorted list of names of the components of this megawidget.

configure(option = None, **kw)
Query or configure the megawidget options.

If no arguments are given, return a tuple consisting of all megawidget options and values, each as a 5-element tuple (name, resourceName, resourceClass, default, value). This is in the same format as the value returned by the standard Tkinter configure() method, except that the resource name is always the same as the option name and the resource class is the option name with the first letter capitalised.

If one argument is given, return the 5 element tuple for option.

Otherwise, set the configuration options specified by the keyword arguments. Each key should be in the format described in the Options section.

createcomponent(componentName, componentAliases, componentGroup, widgetClass, *widgetArgs, **kw)
Create a component widget by calling widgetClass with the arguments given by widgetArgs and any keyword arguments. The componentName argument is the name by which the component will be known and must not contain the underscore, '_', character. The componentGroup argument specifies the group of the component. The componentAliases argument is a sequence of 2-element tuples, whose first item is an alias name and whose second item is the name of the component or sub-component it is to refer to.

If this method is called during megawidget construction, any component options supplied to the megawidget constructor which refer to this component (by componentName or componentGroup) are added to the kw dictionary before calling widgetClass. If the dictionary contains a 'pyclass' key, then this item is removed from the dictionary and the value is used instead of widgetClass. For more details see The pyclass component option section.

This method may be called by derived classes during or after megawidget construction. It returns the instance of the class created.

createlabel(parent, childCols = 1, childRows = 1)
Create a Tkinter.Label component named 'label' in the parent widget. This is a convenience method used by several megawidgets that require an optional label. The widget must have options named labelpos and labelmargin. If labelpos is None, no label is created. Otherwise, a label is created and positioned according to the value of labelpos and labelmargin. The label is added to the parent using the grid() method, with childCols and childRows indicating how many rows and columns the label should span. Note that all other child widgets of the parent must be added to the parent using the grid() method. The createlabel() method may be called by derived classes during megawidget construction.

defineoptions(keywords, optionDefs, dynamicGroups = ())
Create options for this megawidget. The optionDefs argument defines the options. It is a sequence of 3-element tuples, (name, default, callback), where name is the name of the option, default is its default value and callback is the function to call when the value of the option is set by a call to configure(). The keywords argument should be the keyword arguments passed in to the constructor of the megawidget. The user may override the default value of an option by supplying a keyword argument to the constructor.

If any option created by a base class is also defined by optionDefs, then the derived class's default value will take precedence over the base class's. If the callback field is not None, then this will also override the callback set by the base class.

If callback is Pmw.INITOPT, then the option is an initialisation option.

The dynamicGroups argument contains a list of the groups of the components created dynamically by this megawidget. If a group is included in this list, then it not an error if a keyword argument for the group is given to the constructor or to configure(), even when no components with this group have been created.

If defineoptions() is called, it must be called once in the megawidget constructor before the call to the constructor of the base class and there must be a matching call to initialiseoptions() at the end of the constructor.

destroy()
Destroy the hull component widget, if it exists, including all of its children.

destroycomponent(name)
Remove the megawidget component called name. This method may be called by derived classes to destroy a megawidget component. It destroys the component widget and then removes all record of the component from the megawidget.

hulldestroyed()
Return true if the Tk widget corresponding to the hull component has been destroyed.

initialiseoptions(dummy = None)
Check keyword arguments and call option callback functions. This method must be called, at the end of a megawidget constructor, if and only if defineoptions() was also called in the constructor. The dummy argument is not required, but is retained for backwards compatibility.

It checks that all keyword arguments given to the constructor have been used. If not, it raises an error indicating which arguments were unused. A keyword is defined to be used if, during the construction of a megawidget, it is defined in a call to defineoptions() or addoptions() (by the megawidget or one of its base classes), or it references, by name, a component of the megawidget, or it references, by group, at least one component. It also calls the configuration callback function for all options that have a callback.

This method is only effective when called by the constructor of the leaf class, that is, the class in the class hierarchy which first called defineoptions(). For all other classes in the class hierarchy (base classes), the method returns immediately.

interior()
Return the widget framing the interior space in which any children of this megawidget should be created. By default, this returns the hull component widget, if one was created, or None otherwise. A subclass should use the widget returned by interior() as the parent of any components or sub-widgets it creates. Megawidgets which can be further subclassed, such as Pmw.Dialog, should redefine this method to return the widget in which subclasses should create children. The overall containing widget is always available as the hull component.

isinitoption(option)
If option is an initialisation option, return true. Otherwise, return false (the option is a configuration option). The option argument must be an option of this megawidget, not an option of a component. Otherwise an exception is raised.

options()
Return a sorted list of this megawidget's options. Each item in the list is a 3-element tuple, (option, default, isinit), where option is the name of the option, default is its default value and isinit is true if the option is an initialisation option.

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 22 May 1998

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9231184 Pmw-2.1/Pmw/Pmw_1_3_3/doc/MegaToplevel.html0000664000175000017500000002642500000000000020570 0ustar00gregmgregm00000000000000 Pmw.MegaToplevel reference manual

Pmw.MegaToplevel

Name

Pmw.MegaToplevel() - base class for megawidgets within a toplevel

Inherits

Pmw.MegaArchetype

Description

This class creates a megawidget contained within a toplevel window. It may be used directly to create a toplevel megawidget or it may be used as a base class for more specialised toplevel megawidgets, such as Pmw.Dialog. It creates a Tkinter.Toplevel component, named hull, to act as the container of the megawidget. The window class name for the hull widget is set to the most-specific class name for the megawidget. Derived classes specialise this class by creating other widget components as children of the hull widget.

The megawidget may be used as either a normal toplevel window or as a modal dialog. Use show() and withdraw() for normal use and activate() and deactivate() for modal dialog use. If the window is deleted by the window manager while being shown normally, the default behaviour is to destroy the window. If the window is deleted by the window manager while the window is active (ie: when used as a modal dialog), the window is deactivated. Use the userdeletefunc() and usermodaldeletefunc() methods to override these behaviours. Do not call protocol() to set the WM_DELETE_WINDOW window manager protocol directly if you want to use this window as a modal dialog.

The currently active windows form a stack with the most recently activated window at the top of the stack. All mouse and keyboard events are sent to this top window. When it deactivates, the next window in the stack will start to receive events.

Options

Options for this megawidget and its base classes are described below.

activatecommand
If this is callable, it will be called whenever the megawidget is activated by a call to activate(). The default is None.

deactivatecommand
If this is callable, it will be called whenever the megawidget is deactivated by a call to deactivate(). The default is None.

master
This is used by the activate() method to control whether the window is made transient during modal dialogs. See the activate() method. The default is None.

title
This is the title that the window manager displays in the title bar of the window. The default is None.

Components

Components created by this megawidget and its base classes are described below.

hull
This acts as the body for the entire megawidget. Other components are created as children of the hull to further specialise this class. By default, this component is a Tkinter.Toplevel.

Methods

Only methods specific to this megawidget are described below. For a description of its inherited methods, see the manual for its base class Pmw.MegaArchetype. In addition, methods from the Tkinter.Toplevel class are forwarded by this megawidget to the hull component.

activate(globalMode = 0, geometry = 'centerscreenfirst')
Display the window as a modal dialog. This means that all mouse and keyboard events go to this window and no other windows can receive any events. If you do not want to restrict mouse and keyboard events to this window, use the show() method instead.

If the BLT extension to Tk is present, a busy cursor will be displayed on other toplevel windows, using Pmw.showbusycursor().

The activate() method does not return until the deactivate() method is called, when the window is withdrawn, the grab released and the result returned.

If globalMode is false, the window will grab control of the pointer and keyboard, preventing any events from being delivered to any other toplevel windows within the application. If globalMode is true, the grab will prevent events from being delivered to any other toplevel windows regardless of application. Global grabs should be used sparingly, if at all.

If globalMode is 'nograb', then no grab is performed. If BLT is present, this will allow mouse and keyboard events to be received by other windows whose exclude busycursor attribute has been set to true by a call to Pmw.setbusycursorattributes(). Note that if 'nograb' is used and BLT is not present, then all other windows will receive mouse and keyboard events. This is because, in plain Tk, there is no way to specify that two windows (only) receive events. If your application may be used without BLT, then do not use 'nograb'.

When the window is displayed, it is positioned on the screen according to geometry which may be one of:

centerscreenfirst
The window will be centered the first time it is activated. On subsequent activations it will be positioned in the same position as the last time it was displayed, even if it has been moved by the user.

centerscreenalways
The window will be be centered on the screen (halfway across and one third down).

first + spec
It is assumed that the rest of the argument (after 'first') is a standard geometry specification. The window will be positioned using this specification the first time it is activated. On subsequent activations it will be positioned in the same position as the last time it was displayed, even if it has been moved by the user. For example, geometry = first+100+100 will initially display the window at position (100,100). Other calls to activate() will not change the previous position of the window.

spec
This is a standard geometry specification. The window will be be positioned using this specification.

If the BLT Tcl extension library is present, a clock cursor will be displayed until the window is deactivated.

If the activatecommand option is callable, it is called just before the window begins to wait for the result.

If the master option is not None, the window will become a transient window of master, which should be a toplevel window. If master has the special value of 'parent', the master is the toplevel window of the window's parent.

active()
Return true if the megawidget is currently active (that is, activate() is currently waiting for a result to be passed to it by a call to deactivate()).

deactivate(result = None)
This should be called while a call to activate() is waiting. It will withdraw the window, release the grab and cause the activate() call to return with the value of result.

If the deactivatecommand option is callable, it is called just before the deactivate() method returns.

destroy()
Destroy the hull component widget, including all of its children. If the megawidget is currently active, deactivate it.

show(master = None)
Make the window visible. This raises or deiconifies the toplevel window. If the window has previously been shown it will remain in the same position. This means that calling withdraw() then show() will not move the window, whereas calling withdraw() then deiconify() may change the window's position. (This may depend on the behaviour of the window manager.)

userdeletefunc(func = None)
If func is None, return the function that will be called when the window is deleted by the window manager while being displayed normally. If func is not None, set this function to func. By default, the function is self.destroy.

usermodaldeletefunc(func = None)
If func is None, return the function that will be called when the window is deleted by the window manager while it is active (ie: when being used as a modal dialog). If func is not None, set this function to func. By default, the function is self.deactivate.

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 22 May 1998

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9311185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/MegaWidget.html0000664000175000017500000000504500000000000020214 0ustar00gregmgregm00000000000000 Pmw.MegaWidget reference manual

Pmw.MegaWidget

Name

Pmw.MegaWidget() - base class for megawidgets within a frame

Inherits

Pmw.MegaArchetype

Description

This class creates a megawidget contained within a Tkinter.Frame window. The class acts as the base class for megawidgets that are not contained in their own toplevel window, such as Pmw.ButtonBox and Pmw.ComboBox. It creates a Tkinter.Frame component, named hull, to act as the container of the megawidget. The window class name for the hull widget is set to the most-specific class name for the megawidget. Derived classes specialise this class by creating other widget components as children of the hull widget.

Components

Components created by this megawidget and its base classes are described below.

hull
This acts as the body for the entire megawidget. Other components are created as children of the hull to further specialise this class. By default, this component is a Tkinter.Frame.

Methods

This megawidget has no methods of its own. For a description of its inherited methods, see the manual for its base class Pmw.MegaArchetype. In addition, methods from the Tkinter.Frame class are forwarded by this megawidget to the hull component.

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 22 May 1998

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9271185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/MenuBar.gif0000664000175000017500000000101100000000000017316 0ustar00gregmgregm00000000000000GIF87aق,ڋ޼ ʶ rj{ Ģ"̦ )ԪMܮ l+v@>96c>߸1y׷0蠖PF(HaW#Xp A: z0Z i zJXkX'7|9II,1);Hm kL )}>p]z̜^{l5r;^*%N[0aPI 7,2dZć03wC1F"~4M%r/j)2YZ+J ./CTiP39* T>ArB]61rV>8BRWe<: `ͧX Qe,"/d i7({1d>- r{! ,gKR~ شkm;(w]Āċ?<̛;=ԫ[=ܻ{;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9271185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/MenuBar.html0000664000175000017500000004025700000000000017534 0ustar00gregmgregm00000000000000 Pmw.MenuBar reference manual

Pmw.MenuBar

Name

Pmw.MenuBar() - manager megawidget for menu buttons and menus

Inherits

Pmw.MegaWidget

Description

A menu bar is a container megawidget which manages a number of menu buttons and dropdown menus. There are methods to add menu buttons and menus to the menu bar and for adding menu items to the menus. Menu buttons may be added to the left or right of the megawidget. Each menu button and menu item may have help text to be displayed by a Pmw.Balloon. Each menu and cascaded menu (sub-menu) is referenced by name which is supplied on creation.

Options

Options for this megawidget and its base classes are described below.

balloon
Specifies a Pmw.Balloon to display the help text for menu buttons and menu items. If None, no help is displayed. If the balloon has an associated Pmw.MessageBar, the help text will also be displayed there. The default is None.

hotkeys
Initialisation option. If true, keyboard accelerators will be assigned to each menu button and menu item. Keyboard accelerators can be used to access the menus without using the mouse. The accelerator character is always one of the alphanumeric characters in the text label of the menu or menu item and is indicated by an underline.

To select a menu, simultaneously press the <Alt> key and the accelerator character indicated on a menu button. The arrows keys can then be used to select other menus and menu items. To invoke a menu item, press <Return> or press the accelerator character indicated on the menu item.

Each accelerator character will be assigned automatically unless traverseSpec is supplied to the addmenu(), addmenuitem() or addcascademenu() methods. The automatically selected accelerator character for a menu button (or menu item) is the first character in the label text that has not already been used as an accelerator for a menu button (or in the menu containing the menu item).

If traverseSpec is given, it must be either an integer or a character. If an integer, it specifies the index of the character in the label text to use as the accelerator character. If a character, it specifies the character to use as the accelerator character. The default is 1.

padx
Initialisation option. Specifies a padding distance to leave between each menu button in the x direction and also between the menu buttons and the outer edge of the menu bar. The default is 0.

Components

Components created by this megawidget and its base classes are described below.

hull
This acts as the body for the entire megawidget. Other components are created as children of the hull to further specialise this class. By default, this component is a Tkinter.Frame.

Dynamic components

Menu button components are created dynamically by the addmenu() method. By default, these are of type Tkinter.Menubutton and are created with a component group of Button.

Menu components are created dynamically by the addmenu() and addcascademenu() methods. By default, these are of type Tkinter.Menu and are created with a component group of Menu.

Methods

Only methods specific to this megawidget are described below. For a description of its inherited methods, see the manual for its base class Pmw.MegaWidget.

addcascademenu(parentMenuName, menuName, statusHelp = '', traverseSpec = None, **kw)
Add a cascade menu (sub-menu) to the menu parentMenuName. The menuName argument must not be the same as any menu already created using the addmenu() or addcascademenu() methods.

A menu item in the parent menu is created (with the add_cascade() method of the parent menu) using all keyword arguments except tearoff.

If the label keyword argument is not given, the label option of the menu item defaults to menuName. If the underline keyword argument is not given (and the hotkeys megawidget option is true) the underline option is determined as described under hotkeys and is used to specify the keyboard accelerator.

The statusHelp argument is used as the help string for the menu item. This is displayed using the showstatus() method of the balloon.

The tearoff keyword argument, if present, is passed to the constructor of the menu. The menu is created as a component named menuName-menu.

addmenu(menuName, balloonHelp, statusHelp = None, side = 'left', traverseSpec = None, **kw)
Add a menu button and its associated menu to the menu bar. The menuName argument must not be the same as any menu already created using the addmenu() or addcascademenu() methods.

Any keyword arguments present (except tearoff) will be passed to the constructor of the menu button. If the text keyword argument is not given, the text option of the menu button defaults to menuName. If the underline keyword argument is not given (and the hotkeys megawidget option is true) the underline option is determined as described under hotkeys and is used to specify the keyboard accelerator. Each menu button is packed into the menu bar using the given side, which should be either left or right. The menu button is created as a component named menuName-button.

If the balloon option has been defined, balloonHelp and statusHelp are passed to the balloon as the help strings for the menu button. See the bind() method of Pmw.Balloon for how these strings may be displayed.

The tearoff keyword argument, if present, is passed to the constructor of the menu. The menu is created as a component named menuName-menu.

addmenuitem(menuName, itemType, statusHelp = '', traverseSpec = None, **kw)
Add a menu item to the menu menuName. The kind of menu item is given by itemType and may be one of command, separator, checkbutton, radiobutton or cascade (although cascade menus are better added using the addcascademenu() method). Any keyword arguments present will be passed to the menu when creating the menu item. See Tkinter.Menu for the valid options for each item type. In addition, a keyboard accelerator may be automatically given to the item, as described under hotkeys.

When the mouse is moved over the menu item, the helpString will be displayed by the balloon's statuscommand.

deletemenu(menuName)
Delete the menu menuName and all its items. The menu may either be a toplevel menu (in which case the corresponding menu button is also deleted) or a cascade menu.

deletemenuitems(menuName, start, end = None)
Delete menu items from the menu menuName. If end is not given, the start item is deleted. Otherwise all items from start to end are deleted.

disableall()
Disable all toplevel menus.

enableall()
Enable all toplevel menus.

Example

The image at the top of this manual is a snapshot of the window (or part of the window) produced by the following code.

class Demo:
    def __init__(self, parent):
        # Create the Balloon.
        self.balloon = Pmw.Balloon(parent)

        # Create and pack the MenuBar.
        menuBar = Pmw.MenuBar(parent,
                hull_relief = 'raised',
                hull_borderwidth = 1,
                balloon = self.balloon)
        menuBar.pack(fill = 'x')
        self.menuBar = menuBar

        # Add some buttons to the MenuBar.
        menuBar.addmenu('File', 'Close this window or exit')
        menuBar.addmenuitem('File', 'command', 'Close this window',
                command = PrintOne('Action: close'),
                label = 'Close')
        menuBar.addmenuitem('File', 'separator')
        menuBar.addmenuitem('File', 'command', 'Exit the application',
                command = PrintOne('Action: exit'),
                label = 'Exit')

        menuBar.addmenu('Edit', 'Cut, copy or paste')
        menuBar.addmenuitem('Edit', 'command', 'Delete the current selection',
                command = PrintOne('Action: delete'),
                label = 'Delete')

        menuBar.addmenu('Options', 'Set user preferences')
        menuBar.addmenuitem('Options', 'command', 'Set general preferences',
                command = PrintOne('Action: general options'),
                label = 'General...')

        # Create a checkbutton menu item.
        self.toggleVar = Tkinter.IntVar()
        # Initialise the checkbutton to 1:
        self.toggleVar.set(1)
        menuBar.addmenuitem('Options', 'checkbutton', 'Toggle me on/off',
                label = 'Toggle',
                command = self._toggleMe,
                variable = self.toggleVar)
        self._toggleMe()

        menuBar.addcascademenu('Options', 'Size',
                'Set some other preferences', traverseSpec = 'z', tearoff = 1)
        for size in ('tiny', 'small', 'average', 'big', 'huge'):
            menuBar.addmenuitem('Size', 'command', 'Set size to ' + size,
                    command = PrintOne('Action: size ' + size),
                    label = size)

        menuBar.addmenu('Help', 'User manuals', side = 'right')
        menuBar.addmenuitem('Help', 'command', 'About this application',
                command = PrintOne('Action: about'),
                label = 'About...')

        # Create and pack the main part of the window.
        self.mainPart = Tkinter.Label(parent,
                text = 'This is the\nmain part of\nthe window',
                background = 'black',
                foreground = 'white',
                padx = 30,
                pady = 30)
        self.mainPart.pack(fill = 'both', expand = 1)

        # Create and pack the MessageBar.
        self.messageBar = Pmw.MessageBar(parent,
                entry_width = 40,
                entry_relief='groove',
                labelpos = 'w',
                label_text = 'Status:')
        self.messageBar.pack(fill = 'x', padx = 10, pady = 10)
        self.messageBar.message('state', 'OK')

        buttonBox = Pmw.ButtonBox(parent)
        buttonBox.pack(fill = 'x')
        buttonBox.add('Disable\nall', command = menuBar.disableall)
        buttonBox.add('Enable\nall', command = menuBar.enableall)
        buttonBox.add('Create\nmenu', command = self.add)
        buttonBox.add('Delete\nmenu', command = self.delete)
        buttonBox.add('Create\nitem', command = self.additem)
        buttonBox.add('Delete\nitem', command = self.deleteitem)

        # Configure the balloon to displays its status messages in the
        # message bar.
        self.balloon.configure(statuscommand = self.messageBar.helpmessage)

        self.testMenuList = []

    def _toggleMe(self):
        print 'Toggle value:', self.toggleVar.get()

    def add(self):
        if len(self.testMenuList) == 0:
            num = 0
        else:
            num = self.testMenuList[-1]
        num = num + 1
        name = 'Menu%d' % num
        self.testMenuList.append(num)

        self.menuBar.addmenu(name, 'This is ' + name)

    def delete(self):
        if len(self.testMenuList) == 0:
            self.menuBar.bell()
        else:
            num = self.testMenuList[0]
            name = 'Menu%d' % num
            del self.testMenuList[0]
            self.menuBar.deletemenu(name)

    def additem(self):
        if len(self.testMenuList) == 0:
            self.menuBar.bell()
        else:
            num = self.testMenuList[-1]
            menuName = 'Menu%d' % num
            menu = self.menuBar.component(menuName + '-menu')
            if menu.index('end') is None:
                label = 'item X'
            else:
                label = menu.entrycget('end', 'label') + 'X'
            self.menuBar.addmenuitem(menuName, 'command', 'Help for ' + label,
                    command = PrintOne('Action: ' + menuName + ': ' + label),
                    label = label)
            
    def deleteitem(self):
        if len(self.testMenuList) == 0:
            self.menuBar.bell()
        else:
            num = self.testMenuList[-1]
            menuName = 'Menu%d' % num
            menu = self.menuBar.component(menuName + '-menu')
            if menu.index('end') is None:
                self.menuBar.bell()
            else:
                self.menuBar.deletemenuitems(menuName, 0)
            
class PrintOne:
    def __init__(self, text):
        self.text = text

    def __call__(self):
        print self.text

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 22 April 2000

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9231184 Pmw-2.1/Pmw/Pmw_1_3_3/doc/MessageBar.gif0000664000175000017500000000066700000000000020016 0ustar00gregmgregm00000000000000GIF87a,ق,,ڋ޼H扦ʶ L ĢL*̦ JԪjܮ #N (8HXhx)9IYiy ə* T:Zqª*;jaK k{[̀1LzL=\L=]k\.,>ޮ1?O^m]vMJ8f1p0 A"B8j<d9sMR;M(kBQk-eLDTRIi4] SGZ15F֫\Cl}رd˚=6Z:U\z 7ܹtڽ;޽| 8 >8Ō;~ 9ɔ+w*;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9311185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/MessageBar.html0000664000175000017500000002741300000000000020213 0ustar00gregmgregm00000000000000 Pmw.MessageBar reference manual

Pmw.MessageBar

Name

Pmw.MessageBar() - information line for displaying short messages

Inherits

Pmw.MegaWidget

Description

A message bar contains a single-line message display area. Messages of several different types may displayed. Messages are cleared after a period defined for each message type. Each message type has a priority so that if the application attempts to display more than one message at a time, the message with the highest priority will be displayed. Messages may be accompanied by a number of audible bells.

This megawidget can be used for both interactive help messages (when the mouse enters certain widgets) and also for other general messages.

To perform the help function it can cooperate with the Pmw.Balloon megawidget so that the programmer (or user) can choose either balloon help, message bar help, both or neither.

This megawidget supports a configurable number of message types. The default types include 'state', 'help', 'usererror' and 'systemerror'. The difference between these are the length of time they are displayed, the number of bells that are rung and the priority of the message. For example, the 'help' message type is lower in priority than the 'usererror', so that error messages will always be displayed in preference to help messages regardless of the order the messages are created. The 'state' message type is lowest in priority but has no timeout, so it should contain messages describing the current state of the application, such as Waiting for database connection or 'Waiting for file to be unlocked'. Generally this should be set to the empty string when the application is running normally. By default the help messages (with message type 'help') time out after 5 seconds, so that if the cursor happens to be left over a widget, the application state will be redisplayed after a short time.

Options

Options for this megawidget and its base classes are described below.

labelmargin
Initialisation option. If the labelpos option is not None, this specifies the distance between the label component and the rest of the megawidget. The default is 0.

labelpos
Initialisation option. Specifies where to place the label component. If not None, it should be a concatenation of one or two of the letters 'n', 's', 'e' and 'w'. The first letter specifies on which side of the megawidget to place the label. If a second letter is specified, it indicates where on that side to place the label. For example, if labelpos is 'w', the label is placed in the center of the left hand side; if it is 'wn', the label is placed at the top of the left hand side; if it is 'ws', the label is placed at the bottom of the left hand side.

If None, a label component is not created. The default is None.

messagetypes
Initialisation option. This defines what message types are supported by the message bar and the characteristics of those message types. It is a dictionary where the key is a string specifying a message type and the value is a tuple of four integers, (priority, showtime, bells, logmessage), where priority is the rank of the message type, showtime is the number of seconds to display messages of this message type, bells is the number of audible bells to ring and logmessage is a boolean specifying whether this message should be logged for retrieval later. Messages with a higher priority are displayed in preference to those with lower priority. If a high priority message times out (because it has been displayed for showtime seconds), then a lower priority message may be displayed. A showtime of 0 means that the message will never time out and is useful for displaying messages describing the current state of the application as opposed to messages describing events. Logging is not currently implemented. The default is

 {
     'systemerror'  : (5, 10, 2, 1),
     'usererror'    : (4, 5, 1, 0),
     'busy'         : (3, 0, 0, 0),
     'systemevent'  : (2, 5, 0, 0),
     'userevent'    : (2, 5, 0, 0),
     'help'         : (1, 5, 0, 0),
     'state'        : (0, 0, 0, 0),
 }
silent
If true, no audible bells will sound, regardless of the value for bells defined in the messagetypes option. The default is 0.

sticky
Initialisation option. The default is 'ew'.

Components

Components created by this megawidget and its base classes are described below.

entry
The widget where the messages are displayed. Long messages may be scrolled horizontally by dragging with the middle mouse button. By default, this component is a Tkinter.Entry.

hull
This acts as the body for the entire megawidget. Other components are created as children of the hull to further specialise this class. By default, this component is a Tkinter.Frame.

label
If the labelpos option is not None, this component is created as a text label for the megawidget. See the labelpos option for details. Note that to set, for example, the text option of the label, you need to use the label_text component option. By default, this component is a Tkinter.Label.

Methods

Only methods specific to this megawidget are described below. For a description of its inherited methods, see the manual for its base class Pmw.MegaWidget. In addition, methods from the Tkinter.Entry class are forwarded by this megawidget to the entry component.

helpmessage(text)
A convenience method to display text in the message bar according to the characteristics defined by the help message type. Equivalent to message('help', text).

message(type, text)
Display text in the message bar according to the characteristics defined by the type message type, as discussed under messagetypes.

resetmessages(type)
Clear the type message and all message types with a lower priority, except permanent messages, such as state. This is useful to clear the busy message and any outstanding event and help messages.

Example

The image at the top of this manual is a snapshot of the window (or part of the window) produced by the following code.

class Demo:
    def __init__(self, parent):
        # Create and pack the MessageBar.
        self._messagebar = Pmw.MessageBar(parent,
                entry_width = 40,
                entry_relief='groove',
                labelpos = 'w',
                label_text = 'Status:')
        self._messagebar.pack(side = 'bottom', fill = 'x',
                expand = 1, padx = 10, pady = 10)

        # Create and pack the ScrolledListBox to change the MessageBar.
        self.box = Pmw.ScrolledListBox(parent,
                listbox_selectmode='single',
                items=('state', 'help', 'userevent', 'systemevent',
                        'usererror', 'systemerror', 'busy',),
                label_text='Message type',
                labelpos='n',
                selectioncommand=self.selectionCommand)
        self.box.pack(fill = 'both', expand = 'yes', padx = 10, pady = 10)

        self._index = 0
        self._stateCounter = 0

    def selectionCommand(self):
        sels = self.box.getcurselection()
        if len(sels) > 0:
            self._index = self._index + 1
            messagetype = sels[0]
            if messagetype == 'state':
                self._stateCounter = (self._stateCounter + 1) % 3
                text = stateMessages[self._stateCounter]
                if text != '':
                    text = text + ' (' + messagetype + ')'
                self._messagebar.message('state', text)
            else:
                text = messages[messagetype]
                text = text + ' (' + messagetype + ')'
                self._messagebar.message(messagetype, text)
                if messagetype == 'busy':
                    Pmw.showbusycursor()
                    self.box.after(2000)
                    Pmw.hidebusycursor()
                    self._messagebar.resetmessages('busy')
                    text = 'All files successfully removed'
                    text = text + ' (userevent)'
                    self._messagebar.message('userevent', text)


messages = {
    'help': 'Save current file',
    'userevent': 'Saving file "foo"',
    'busy': 'Busy deleting all files from file system ...',
    'systemevent': 'File "foo" saved',
    'usererror': 'Invalid file name "foo/bar"',
    'systemerror': 'Failed to save file: file system full',
}

stateMessages = {
    0: '',
    1: 'Database is down',
    2: 'Waiting for reply from database',
}

Pmw 1.3.3 - 29 Mar 2014 - Home

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9271185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/MessageDialog.gif0000664000175000017500000000647000000000000020507 0ustar00gregmgregm00000000000000GIF87a5`w`0;,5hN.I8ͻ`@Fel뾰qzix.|pH,Ȥrɴ2EsJZجvJQplL."E]}Ml|Nf|ؽS xx5$oÀǬɅφԇ›|׆㪭߸-7‡j9|nÈlMh 6 @O!` @A:V8S&2l. f?2 s.J"$>(tncΡ>wŞ}% ^RU\j'Փ όZ+L-7RAmSz:]۱0|X1fWeov{F[w_ew,4o~ȁF;ON؋N8mllνJ;ލO_ӭ^yGxQ8aDt\$ 6A@VhfR ($h(,0(4 <@)DiH&PF)Xf\rd`id])h&_馗V)tNfx"If;矀ygg'~^&蟇~裔Vz䠖 gv$i*9*Z):('~ +ZfY@@JFJK%?:[jImb룶 |vB,6{+*f{o++;'Ie:B|"2l$):8s2 2cL4l8OG4S#{"tKcGܱ,v/]4~mr@6g[vzmVrcr+Lvw|xI̅'|89+~xm5OJ>ו{ylgMR^ΰ5ܒnygSϼC;N(z N%s<[ok^}N_Ŋ|w ?c_ۿ~L: 'Z#H jWrӟpNBW0i,lK8ɰS/ op<| 1 p+{D\K^-DnlnSTZuEˇ5&i>-2H;+j4iՊ6'QM$NX¨"u]6¾5f\QRbg)A١er=ۼ&olMO [ֆ%)jo; Ewܹ%Ŷ ]ksjӴo)OY>fpou Nw] #t\&{mqxmn1?煣U-Wn~(Pv|no~wh\9W1{_Nj2MHgV S۸j|#(3|LOxN]8vVȇICE%e^(T=_j[Weg}h]2,qx=_Uf*ļ?>2-~}H?;?]~7uӾ|O;smͯ~$[~a>w wTpWHWwVtB5a b6{ jwsb&X~AzxuQ0^Jy=~VxcVzT7mkrLvEbxÃ[b{3e„u_$SrXy\YbxC҆p)i?kHxrZtXyׂ燒u*"x0}(g(&(%ȈfH bgX"c!"h+|(G8.xhBhb\?(3dH2Jx4؉ȊHSƸZʸ8Y\f,8؍X{&8:RR̨0Lswvv(V&tOVZxN i(0Ձ=؏ yޘ[9w7+U!)S27uh.I%02x"W8?8j-u{qhBْD;)w'YL)6sZZE!25ٸ#.ɸ,pwyI{o} (jKlyN)WA9XT(x1uً}Y9"9 vy{Z釳\YYV K ZeyȩIX!9ԉq`ڹٝ m@Yɝz_R  ;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9271185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/MessageDialog.html0000664000175000017500000002662200000000000020707 0ustar00gregmgregm00000000000000 Pmw.MessageDialog reference manual

Pmw.MessageDialog

Name

Pmw.MessageDialog() - a dialog displaying a text message and an icon

Inherits

Pmw.Dialog

Description

A message dialog is a dialog window which displays a simple message to the user along with one or more buttons to press.

Options

Options for this megawidget and its base classes are described below.

activatecommand
If this is callable, it will be called whenever the megawidget is activated by a call to activate(). The default is None.

borderx
Initialisation option. The padding to the left and right of the text message and icon. The default is 20.

bordery
Initialisation option. The padding above and below the text message and icon. The default is 20.

buttonboxpos
Initialisation option. Specifies on which side of the dialog window to place the button box. Must be one of 'n', 's', 'e' or 'w'. The default is 's'.

buttons
This must be a tuple or a list and specifies the names on the buttons in the button box. The default is ('OK',).

command
Specifies a function to call whenever a button in the button box is invoked or the window is deleted by the window manager. The function is called with a single argument, which is the name of the button which was invoked, or None if the window was deleted by the window manager.

If the value of command is not callable, the default behaviour is to deactivate the window if it is active, or withdraw the window if it is not active. If it is deactivated, deactivate() is called with the button name or None as described above. The default is None.

deactivatecommand
If this is callable, it will be called whenever the megawidget is deactivated by a call to deactivate(). The default is None.

defaultbutton
Specifies the default button in the button box. If the <Return> key is hit when the dialog has focus, the default button will be invoked. If defaultbutton is None, there will be no default button and hitting the <Return> key will have no effect. The default is None.

iconmargin
Initialisation option. The padding between the text message and icon. The default is 20.

iconpos
Initialisation option. Specifies on which side of the text message to place the icon. Must be one of 'n', 's', 'e' or 'w'. The default is None.

master
This is used by the activate() method to control whether the window is made transient during modal dialogs. See the activate() method. The default is 'parent'.

separatorwidth
Initialisation option. If this is greater than 0, a separator line with the specified width will be created between the button box and the child site, as a component named separator. Since the default border of the button box and child site is raised, this option does not usually need to be set for there to be a visual separation between the button box and child site. The default is 0.

title
This is the title that the window manager displays in the title bar of the window. The default is None.

Components

Components created by this megawidget and its base classes are described below.

buttonbox
This is the button box containing the buttons for the dialog. By default it is created with the options (hull_borderwidth = 1, hull_relief = 'raised'). By default, this component is a Pmw.ButtonBox.

dialogchildsite
This is the child site for the dialog, which may be used to specialise the megawidget by creating other widgets within it. By default it is created with the options (borderwidth = 1, relief = 'raised'). By default, this component is a Tkinter.Frame.

hull
This acts as the body for the entire megawidget. Other components are created as children of the hull to further specialise this class. By default, this component is a Tkinter.Toplevel.

icon
If the iconpos option is not None, this component is created to contain the icon label for the dialog. To display a bitmap as an icon, set the icon_bitmap component option to any of the forms acceptable to Tk, such as 'warning' or 'error'. By default, this component is a Tkinter.Label.

message
The label to contain the text message for the dialog. To set the text, use the message_text component option. By default, this component is a Tkinter.Label.

separator
If the separatorwidth initialisation option is non-zero, the separator component is the line dividing the area between the button box and the child site. By default, this component is a Tkinter.Frame.

Methods

This megawidget has no methods of its own. For a description of its inherited methods, see the manual for its base class Pmw.Dialog.

Example

The image at the top of this manual is a snapshot of the window (or part of the window) produced by the following code.

class Demo:
    def __init__(self, parent):
        self.parent = parent

        # Create dialog 1.
        self.dialog1 = Pmw.MessageDialog(parent,
            title = 'Simple message dialog',
            defaultbutton = 0,
            message_text = 'A simple message dialog\nwith no callback.')
        self.dialog1.iconname('Simple message dialog')
        self.dialog1.withdraw()

        # Create dialog 2.
        self.dialog2 = Pmw.MessageDialog(parent,
            title = 'Bell ringing dialog',
            message_text = 'This message dialog\nwill ring the bell ' +
                'when\nyou click on the buttons.',
            iconpos = 'w',
            icon_bitmap = 'error',
            command = self.execute2,
            buttons = ('One', 'Two', 'Three', 'Close'))
        self.dialog2.iconname('Bell ringing dialog')
        self.dialog2.withdraw()

        # Create dialog 3.
        self.dialog3 = Pmw.MessageDialog(parent,
            title = 'Vertical button dialog',
            message_text = 'This message dialog\nhas the buttons on the\n' +
                'right hand side.',
            buttonboxpos = 'e',
            iconpos = 'n',
            icon_bitmap = 'warning',
            buttons = ('Goodbye', 'Au revoir', 'Sayonara', 'Close'),
            defaultbutton = 'Close')
        self.dialog3.iconname('Vertical button dialog')
        self.dialog3.withdraw()

        # Create some buttons to launch the dialogs.
        w = Tkinter.Button(parent, text = 'Simple dialog',
                command = lambda self = self:
                        self.dialog1.activate(geometry = 'first+100+100'))
        w.pack(padx = 8, pady = 8)

        w = Tkinter.Button(parent, text = 'Bell ringing dialog',
                command = self.dialog2.activate)
        w.pack(padx = 8, pady = 8)

        w = Tkinter.Button(parent, text = 'Vertical buttons',
                command = self.dialog3.activate)
        w.pack(padx = 8, pady = 8)

        w = Tkinter.Button(parent, text = 'On the fly dialog',
                command = self._createOnTheFly)
        w.pack(padx = 8, pady = 8)

    def execute2(self, result):
        print 'You clicked on', result
        if result is None:
            self.dialog2.deactivate(result)
        elif result == 'Close':
            self.dialog2.deactivate(result)
        else:
            for count in range({'One': 1, 'Two': 2, 'Three': 3}[result]):
                if count != 0:
                    self.dialog2.after(200)
                self.dialog2.bell()

    def _createOnTheFly(self):
        dialog = Pmw.MessageDialog(self.parent,
            title = 'On the fly dialog',
            defaultbutton = 0,
            buttons = ('OK', 'Apply', 'Cancel', 'Help'),
            message_text = 'This dialog was created when you clicked ' +
                'on the button.')
        dialog.iconname('Simple message dialog')
        result = dialog.activate()

        print 'You selected', result

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 18 May 2002

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9271185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/NoteBook.gif0000664000175000017500000000504100000000000017514 0ustar00gregmgregm00000000000000GIF87aق,ڋ޼H扦ʶ L ĢL*̦ JԪjNl =`7(@(g190T i$ ٙi JJ TT:;{pKi!K,zbL m[q}$NE~c~0U/ >y AD'@u < %WI"Md2C!ckΦJ/=mȘ*;I"a5$̩;*4'U[VĮ,Z0Zz=LN T^#F)޹UMSte_y/VoTn'uUxI+ MآMHA䆞_7FzBf891C7xa&ŒS.avm?#^wﰁZ69x)(?\`'LN@ڝJ+R׏lwVHZ_}{DTiGG&nv睆e\1HXm%aeOC$v2acr٨$z͈! DցH8i`QN ]pyH !B&m[jzugbrq'}֐'{c故蔃jEk"J"^in)f JjZ)9~1ijjΊkF&jj+kWJl Vc >KZm^~KEsK. [n{{K"[o4;ɮh&p.XlP10 exW#l`(GEȹ$i>W. azzLtFtJ/tN? uROMuMcLiX%jЩbMvfBZRGB7y7ӺMwys'YC/l3,߀=lӴq(sx}רvtVNkٽa%@έz/:n1k/u* NēkРk<я<n{OmTOxj 4 p k}Ɛ) P^g&Y|^GrvUH m6)H 9,*PT&C 7ڟ^ȏAhjQIgIB%I K˴o͢ 81MҡЉu:bXϔ-v8142q2D1Lr4H&Rrm<${")3-|#+Je5Dq%CH**rK#3 =:zᐨ?1mq#T/M4 D LQ`Ȧ&U$#p Kj?L,`O$ D'}*L "@ {TU<94a?'ڹWEI9t$-IOҔt#(vt4i$Ҏb:O{utBjjԿ!5'Sԧr,RmUJQbZQU5M(YjѳլjXjշ5l+]j׊]5œ+_=׿k+pgF`%R@MDl6V:ôg TӐJ94)VX\e ̰3CAaی&0dGHh1t-ic/5̃芳R@QaQȚ4f@c͎f# Ҷ̙3NjDKº_+|BG`~dkq 6j[ _zFlpaik|NN B-5gDv'd[DM-xjM(53հ.Ьj; m;GԤ6 ׹^Oқ͊E/(Hgz+uM=N3Ov͗-op@+X1my-,΅T7m>c]kUﺨt7;Nz^vKh[.?k@wl2n3X3^>yW}˲/k޶w?ЋYe;L[&U=jo>8uǞ·q#_>AKԯl=ekΜ/Ϗo;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9311185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/NoteBook.html0000664000175000017500000003156300000000000017723 0ustar00gregmgregm00000000000000 Pmw.NoteBook reference manual

Pmw.NoteBook

Name

Pmw.NoteBook() - a set of tabbed pages

Inherits

Pmw.MegaArchetype

Description

A notebook contains a set of tabbed pages. At any one time only one of these pages (the selected page) is visible, with the other pages being hidden "beneath" it. Another page in the notebook may be displayed by clicking on the tab attached to the page. The tabs are displayed along the top edge.

Optionally, the notebook may be displayed without tabs. In this case, another selection widget, such as Pmw.OptionMenu, may be used to select the pages.

This megawidget is derived from Pmw.MegaArchetype (not Pmw.MegaWidget like most other megawidgets), with the hull class being Tkinter.Canvas.

Options

Options for this megawidget and its base classes are described below.

arrownavigation
Initialisation option. If true and a tab button has the keyboard focus, then the Left and Right arrow keys can be used to select the page before or after the tab button with the focus. The default is 1.

borderwidth
Initialisation option. The width of the border drawn around each tab and around the selected page. The default is 2.

createcommand
Specifies a function to call when a page is selected for the first time. The function is called with a single argument, which is the name of the selected page, and is called before the raisecommand function. This allows the creation of the page contents to be deferred until the page is first displayed. The default is None.

lowercommand
Specifies a function to call when the selected page is replaced with a new selected page. The function is called with a single argument, which is the name of the previously selected page, and is called before the createcommand or raisecommand functions. The default is None.

pagemargin
Initialisation option. The margin (in pixels) around the selected page inside the notebook's page border. The default is 4.

raisecommand
Specifies a function to call when a new page is selected. The function is called with a single argument, which is the name of the selected page. The default is None.

tabpos
Initialisation option. Specifies the location of the tabs. If 'n', tabs are created for each page and positioned at the top of the notebook. If None, no tabs are created, in which case another selection widget can be used to select pages by calling the selectpage() method. The default is 'n'.

Components

Components created by this megawidget and its base classes are described below.

hull
This acts as the body for the megawidget. The contents of the megawidget are created as canvas items and positioned in the hull using the canvas coordinate system. By default, this component is a Tkinter.Canvas.

Dynamic components

Page and tab components are created dynamically by the add() and insert() methods. By default, the pages are of type Tkinter.Frame and are created with a component group of Page and the tabs are of type Tkinter.Button and are created with a component group of Tab.

Methods

Only methods specific to this megawidget are described below. For a description of its inherited methods, see the manual for its base class Pmw.MegaArchetype. In addition, methods from the Tkinter.Canvas class are forwarded by this megawidget to the hull component.

add(pageName, **kw)
Add a page at the end of the notebook. See the insert() method for full details.

delete(*pageNames)
Delete the pages given by pageNames from the notebook. Each of the pageNames may have any of the forms accepted by the index() method.

If the currently selected page is deleted, then the next page, in index order, is selected. If the end page is deleted, then the previous page is selected.

getcurselection()
Return the name of the currently selected page.

index(index, forInsert = 0)
Return the numerical index of the page corresponding to index. This may be specified in any of the following forms:

name
Specifies the page labelled name.

number
Specifies the page numerically, where 0 corresponds to the first page.

Pmw.END
Specifies the last page.

Pmw.SELECT
Specifies the currently selected page.

If forInsert is true, Pmw.END returns the number of pages rather than the index of the last page.

insert(pageName, before = 0, **kw)
Add a page to the notebook as a component named pageName. The page is added just before the page specified by before, which may have any of the forms accepted by the index() method. If tabpos is not None, also create a tab as a component named pageName-tab. Keyword arguments prefixed with page_ or tab_ are passed to the respective constructors when creating the page or tab. If the tab_text keyword argument is not given, the text option of the tab defaults to pageName. If a page is inserted into an empty notebook, the page is selected. To add a page to the end of the notebook, use add(). The method returns the pageName component widget.

nextpage(pageIndex = None)
If pageIndex is None, then select the page after the currently selected page. Otherwise select the page after pageIndex, which may have any of the forms accepted by the index() method.

page(pageIndex)
Return the frame component widget of the page pageIndex, where pageIndex may have any of the forms accepted by the index() method.

pagenames()
Return a list of the names of the pages, in display order.

previouspage(pageIndex = None)
If pageIndex is None, then select the page before the currently selected page. Otherwise select the page before pageIndex, which may have any of the forms accepted by the index() method.

recolorborders()
Change the color of the page and tab borders. This method is required because the borders are created as canvas polygons and hence do not respond to normal color changing techniques, such as Pmw.Color.changecolor().

selectpage(page)
Select page to be the currently selected page. The page will be raised and the previous selected page will be lowered.

setnaturalsize(pageNames = None)
Set the width and height of the notebook to be the maximum requested width and height of the pages specified by pageNames. If pageNames is None, the size of all pages are used to determine the size of the notebook. Otherwise, pageNames must be a list of page names whose sizes are to be used to determine the size of the notebook. This method should be called after all pages and their contents have been created. It calls update_idletasks() so that the width and height of the pages can be determined. This may cause the notebook to flash onto the screen at the default size before resizing to the natural size.

tab(pageIndex)
Return the tab component widget of the page pageIndex, where pageIndex may have any of the forms accepted by the index() method. If tabpos is None, return None.

Example

The image at the top of this manual is a snapshot of the window (or part of the window) produced by the following code.

class Demo:
    def __init__(self, parent):
        # Create and pack the NoteBook.
        notebook = Pmw.NoteBook(parent)
        notebook.pack(fill = 'both', expand = 1, padx = 10, pady = 10)

        # Add the "Appearance" page to the notebook.
        page = notebook.add('Appearance')
        notebook.tab('Appearance').focus_set()

        # Create the "Toolbar" contents of the page.
        group = Pmw.Group(page, tag_text = 'Toolbar')
        group.pack(fill = 'both', expand = 1, padx = 10, pady = 10)
        b1 = Tkinter.Checkbutton(group.interior(), text = 'Show toolbar')
        b1.grid(row = 0, column = 0)
        b2 = Tkinter.Checkbutton(group.interior(), text = 'Toolbar tips')
        b2.grid(row = 0, column = 1)

        # Create the "Startup" contents of the page.
        group = Pmw.Group(page, tag_text = 'Startup')
        group.pack(fill = 'both', expand = 1, padx = 10, pady = 10)
        home = Pmw.EntryField(group.interior(), labelpos = 'w',
            label_text = 'Home page location:')
        home.pack(fill = 'x', padx = 20, pady = 10)

        # Add two more empty pages.
        page = notebook.add('Helpers')
        page = notebook.add('Images')

        notebook.setnaturalsize()

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 30 October 1999

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9271185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/OptionMenu.gif0000664000175000017500000000447300000000000020101 0ustar00gregmgregm00000000000000GIF87a*삂,*(0I8ͻ@(di~hl뾫)#lx)퟼pH,r~Hql:qsJZ%Qu?xLf}zM9=\ 7@~bmc$^!:]7[/V,XS)N kp<^G+B9[;8 !8PY-- JHQ |1G ?v`~12`ˆ/í8ӛƘ8+n˜5?F_\JetTxSj 3+ i(YPm"Jjnjqr[_Fo@>:}:PPM|ƫ"la!Ȧ{v'Gz: eG1[m XC,V2a]Ah(ʦ5E&Ra!)*bN0"+JW !<@)DidlX PF)иT _XDh '*I<*曣 mzIɉ 矒 JLn.g ipNJ)^fi`~ *e.ꪎJ諴֚')-Ht&n(&g8{&`'- iz0E zu}-27;P1e]nKaڪoUv߿x.gۧXQt$noMD<_|2+\ZՄu\u#WE$> l1Wյe]La-t̚ڴXcbLa3\,-7.rfvPW:C}IiCgKbfV|nc ܶvgwm\5`Sw{+^]5gmmy"X]{tpJjqo lm :믏Axpy8\qOB5Ϯ<Þ2Z,K<*4k_kJ>oM2 Ǿ}W1G<(hߜ%hi2< O= Ā,}.>&E*z'd+`Ƈ@>p]?Y AD M4(VEP,`]m;qf(Έ:aYRGh1thި?8oܳ!>{(DhHm9n" H2qOÚ{&YI^R (~ DR8FJW~ł$RRn/w1HS|S1qL&Sw#)FTs ì5hgi˛fyeIJ9YUq'_bnF!>~ @J~,[jU $NPЊZAɦ{j)yB5%@Q4(MJф-js]T^"]0CVJԢVj(P'kj^S,C5jFՁ"+܄ó o 8T*](WQ+Xݦ+~dU7Q.L?O:6+c3؁u_U@6i|Xz,E-mDOB6ue)q,oY N&g*\mPYϹ6}mZ Ys9v[jrӃh~2(TjXײuu\v5m&SNrVr`0hKNW΍pt[^wQ"so+]>ؽ|;\a^Qf҆?x#n}?0}u\_RLF_="Ul,C2%#c,25]2`N> (2ͰAL:xγg Pmw.OptionMenu reference manual

Pmw.OptionMenu

Name

Pmw.OptionMenu() - single item selection megawidget

Inherits

Pmw.MegaWidget

Description

An option menu consists of a menu button and an associated menu which pops up when the button is pressed. The text displayed in the menu button is updated whenever an item is selected in the menu. The currently selected value can be retrieved from the megawidget.

Options

Options for this megawidget and its base classes are described below.

command
Specifies a function to call whenever a menu item is selected or the invoke() method is called. The function is called with the currently selected value as its single argument. The default is None.

initialitem
Initialisation option. Specifies the initial selected value. This option is treated in the same way as the index argument of the setitems() method. The default is None.

items
Initialisation option. A sequence of strings containing the initial items to be displayed in the menu component. The default is ().

labelmargin
Initialisation option. If the labelpos option is not None, this specifies the distance between the label component and the rest of the megawidget. The default is 0.

labelpos
Initialisation option. Specifies where to place the label component. If not None, it should be a concatenation of one or two of the letters 'n', 's', 'e' and 'w'. The first letter specifies on which side of the megawidget to place the label. If a second letter is specified, it indicates where on that side to place the label. For example, if labelpos is 'w', the label is placed in the center of the left hand side; if it is 'wn', the label is placed at the top of the left hand side; if it is 'ws', the label is placed at the bottom of the left hand side.

If None, a label component is not created. The default is None.

sticky
Initialisation option. The default is 'ew'.

Components

Components created by this megawidget and its base classes are described below.

hull
This acts as the body for the entire megawidget. Other components are created as children of the hull to further specialise this class. By default, this component is a Tkinter.Frame.

label
If the labelpos option is not None, this component is created as a text label for the megawidget. See the labelpos option for details. Note that to set, for example, the text option of the label, you need to use the label_text component option. By default, this component is a Tkinter.Label.

menu
The popup menu displayed when the menubutton is pressed. By default, this component is a Tkinter.Menu.

menubutton
The menu button displaying the currently selected value. By default, this component is a Tkinter.Menubutton.

Methods

Only methods specific to this megawidget are described below. For a description of its inherited methods, see the manual for its base class Pmw.MegaWidget.

getcurselection()
Same as getvalue() method.

getvalue()
Return the currently selected value.

index(index)
Return the numerical index of the menu item corresponding to index. This may be specified in any of the following forms:

name
Specifies the menu item labelled name.

number
Specifies the menu item numerically, where 0 corresponds to the first menu item.

Pmw.END
Specifies the last menu item.

Pmw.SELECT
Specifies the currently selected menu item.

invoke(index = Pmw.SELECT)
Calling this method is the same as selecting the menu item specified by index: the text displayed by the menubutton component is updated and the function specified by the command option is called. index may have any of the forms accepted by the index() method. The value returned by command is returned.

setitems(items, index = None)
Replace all the items in the menu component with those specified by items, which must be a sequence of strings.

If index is not None, set the selected value to index, which may have any of the forms accepted by the index() method.

If index is None and the textvariable option of the menubutton component is the empty string, then if the previous selected value is one of the items, then do not change the selection. If the previous selected value is no longer in items, then set the selected value to the first value in items. If items is empty, set the selected value to the empty string.

If index is None and the textvariable option of the menubutton component is not the empty string, then do not set the selected value. This assumes that the variable is already (or will be) set to the desired value.

setvalue(text)
Set the text displayed by the menubutton component to text.

Example

The image at the top of this manual is a snapshot of the window (or part of the window) produced by the following code.

class Demo:
    def __init__(self, parent):
        # Create and pack the OptionMenu megawidgets.
        # The first one has a textvariable.
        self.var = Tkinter.StringVar()
        self.var.set('steamed')
        self.method_menu = Pmw.OptionMenu(parent,
                labelpos = 'w',
                label_text = 'Choose method:',
                menubutton_textvariable = self.var,
                items = ['baked', 'steamed', 'stir fried', 'boiled', 'raw'],
                menubutton_width = 10,
        )
        self.method_menu.pack(anchor = 'w', padx = 10, pady = 10)

        self.vege_menu = Pmw.OptionMenu (parent,
                labelpos = 'w',
                label_text = 'Choose vegetable:',
                items = ('broccoli', 'peas', 'carrots', 'pumpkin'),
                menubutton_width = 10,
                command = self._printOrder,
        )
        self.vege_menu.pack(anchor = 'w', padx = 10, pady = 10)

        self.direction_menu = Pmw.OptionMenu (parent,
                labelpos = 'w',
                label_text = 'Menu direction:',
                items = ('flush', 'above', 'below', 'left', 'right'),
                menubutton_width = 10,
                command = self._changeDirection,
        )
        self.direction_menu.pack(anchor = 'w', padx = 10, pady = 10)

        menus = (self.method_menu, self.vege_menu, self.direction_menu)
        Pmw.alignlabels(menus)

    def _printOrder(self, vege):
        # Can use 'self.var.get()' instead of 'getcurselection()'.
        print 'You have chosen %s %s.' % \
            (self.method_menu.getcurselection(), vege)

    def _changeDirection(self, direction):
        for menu in (self.method_menu, self.vege_menu, self.direction_menu):
            menu.configure(menubutton_direction = direction)

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 23 October 1998

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9271185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/PanedWidget.gif0000664000175000017500000000360700000000000020175 0ustar00gregmgregm00000000000000GIF87aق,ڋ޼H扦 L Ģ8 X% 6P* ɶ KU5 j3R|^q(xgxxA(IR9񘨆yv)ɠ':ZrjPZ:![IG;" @H+\ܬlLJ-6Mmҽjݫp n-M~nV.>\~<7OZ7m+a4JuҰA~#:Lh >[sMDZGp$Ja 3tS3fx ƧB#QSѡԎY*)+LIeCYR1W:+Azc@Zlk/=ۇs)ԅB.X`[);Johix=$"rܡ]4[?7<3Ϧ-ṳE&:jym+~_I9l$y'ռ9d.o,[9;ٍ,y{&$ۿ0frK_{~M|8!8ՇwH_uQȊ`8 x (\gpFX~ȕ'bޙ_:ϟ[έ W8U{?h}};&ZfEe 6P-j^:^!a' ~~ W=#D ax( V-YhCqs|Bվl4Qrmc\XơINXaȾZ%0Z CA5z1qQ# $H6ѐwDd GMR>J| #IBN$d&O~{aF%1(GIa'|F/xKYej`b|TRz5709-WERfY);R_4 HѩiT'4i;d;Ys?#r-A[t&C Q =AMjUEѐ6|9+vÎΤ'e7Tv.McjәF8NS@"?M^P΢b!ꁜTP}JT'TsԅW%OyӮj) Xz`d=) ֪FKn WZҺZ5^cײҕkZ; 'm*ZػRUdJވ$Qfكx`3KڦֱyMVWAjgiն-F] =,lo]KEmrCc-s{`q FIW- x^:hnT|VeeWH x.;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9311185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/PanedWidget.html0000664000175000017500000003136200000000000020373 0ustar00gregmgregm00000000000000 Pmw.PanedWidget reference manual

Pmw.PanedWidget

Name

Pmw.PanedWidget() - frame subdivided into several resizable panes

Inherits

Pmw.MegaWidget

Description

A paned widget is a container megawidget which manages a number of resizable frames, known as panes. Each pane may act as the container for other widgets. The user may interactively resize the panes by dragging a small rectangle (the handle) or the line between the panes (the separator). The panes may be arranged horizontally or vertically. Each pane may have maximum and minimum limits of its size.

Options

Options for this megawidget and its base classes are described below.

command
Specifies a function to be called whenever the size of any of the panes changes. The function is called with a single argument, being a list of the sizes of the panes, in order. For vertical orientation, the size is the height of the panes. For horizontal orientation, the size is the width of the panes. The default is None.

handlesize
Initialisation option. Specifies the size in pixels of the square handle which appears on the lines separating the panes. The default is 8.

orient
Initialisation option. Specifies the orientation of the paned widget. This may be 'horizontal' or 'vertical'. If 'vertical', the panes are stacked above and below each other, otherwise the panes are laid out side by side. The default is 'vertical'.

separatorrelief
Initialisation option. Specifies the relief of the lines separating the panes. The default is 'sunken'.

separatorthickness
Initialisation option. Specifies the thickness of the lines separating the panes. The default is 2.

Pane options

Each pane has the following options. These may be set when creating or configuring a pane. The value of each option may be an integer, which specifies a pane size in pixels, or a real number between 0.0 and 1.0, which specifies a pane size proportional to the size of the entire paned widget.

size
Specifies the initial size of the pane. The default is 0.

min
Specifies the minimum size of the pane. The default is 0.

max
Specifies the maximum size of the pane. The default is a very large number.

Components

Components created by this megawidget and its base classes are described below.

hull
This acts as the body for the entire megawidget. Other components are created as children of the hull to further specialise this class. By default, this component is a Tkinter.Frame.

Dynamic components

Frame, separator and handle components are created dynamically by the add() and insert() methods. The components are of type Tkinter.Frame and are created with component groups of Frame, Separator and Handle respectively.

Methods

Only methods specific to this megawidget are described below. For a description of its inherited methods, see the manual for its base class Pmw.MegaWidget.

add(name, **kw)
Add a pane to the end of the paned widget as a component named name. This is equivalent to calling insert() with before set to the current number of panes. The method returns the name component widget.

configurepane(name, **kw)
Configure the pane specified by name, where name is either an integer, specifying the index of the pane, or a string, specifying the name of the pane. The keyword arguments specify the new values for the options for the pane. These options are described in the Pane options section.

delete(name)
Delete the pane specified by name, where name is either an integer, specifying the index of the pane, or a string, specifying the name of the pane.

If the pane deleted was not the only pane in the paned widget, also delete the separator and handle components named separator-n and handle-n, where n is the number of panes remaining.

insert(name, before = 0, **kw)
Add a pane to the paned widget as a component named name. The pane is added just before the pane specified by before, where before may be either an integer, specifying the index of the pane, or a string, specifying the name of the pane. The keyword arguments specify the initial values for the options for the new pane. These options are described in the Pane options section. To add a pane to the end of the paned widget, use add().

The new pane is created as a Tkinter.Frame component named name. If this is not the only pane, a separator and handle are also created as components named separator-n and handle-n, where n is one less than the number of panes. The method returns the name component widget.

move(name, newPos, newPosOffset = 0)
Move the pane specified by name to the new position specified by newPos. The first two arguments may be either an integer, specifying the index of the pane, or a string, specifying the name of the pane. If newPosOffset is specified, it is added to the newPos index. For example, to move a horizontal pane one pane to the left, specify the name or index of the pane for both name and newPos and specify -1 for newPosOffset.

pane(name)
Return the Tkinter.Frame pane widget for the pane specified by name, where name is either an integer, specifying the index of the pane, or a string, specifying the name of the pane.

panes()
Return a list of the names of the panes, in display order.

setnaturalsize()
If oriented horizontally, set the width of the paned widget to the sum of the requested widths of all panes and set the height to the maximum requested height of all panes.

If oriented vertically, set the height of the paned widget to the sum of the requested heights of all panes and set the width to the maximum requested width of all panes.

updatelayout()
Recalculate size and position of panes. This method must be called after adding or deleting one or more panes. However it does not need to be called when panes are first added to a newly created paned widget, before it has been displayed.

Example

The image at the top of this manual is a snapshot of the window (or part of the window) produced by the following code.

class Demo:
    def __init__(self, parent):

        # Create a main PanedWidget with a few panes.
        self.pw = Pmw.PanedWidget(parent,
                orient='vertical',
                hull_borderwidth = 1,
                hull_relief = 'sunken',
                hull_width=300,
                hull_height=400)
        for self.numPanes in range(4):
            if self.numPanes == 1:
                name = 'Fixed size'
                pane = self.pw.add(name, min = .1, max = .1)
            else:
                name = 'Pane ' + str(self.numPanes)
                pane = self.pw.add(name, min = .1, size = .25)
            label = Tkinter.Label(pane, text = name)
            label.pack(side = 'left', expand = 1)
            button = Tkinter.Button(pane, text = 'Delete',
                    command = lambda s=self, n=name: s.deletePane(n))
            button.pack(side = 'left', expand = 1)
            # TODO: add buttons to invoke self.moveOneUp and self.moveOneUp.

        self.pw.pack(expand = 1, fill='both')

        buttonBox = Pmw.ButtonBox(parent)
        buttonBox.pack(fill = 'x')
        buttonBox.add('Add pane', command = self.addPane)   
        buttonBox.add('Move pane', command = self.move)   
        self.moveSrc = 0
        self.moveNewPos = 1
        self.moveBack = 0

    def move(self):
        numPanes = len(self.pw.panes())
        if numPanes == 0:
            print 'No panes to move!'
            return

        if self.moveSrc >= numPanes:
            self.moveSrc = numPanes - 1
        if self.moveNewPos >= numPanes:
            self.moveNewPos = numPanes - 1
        print 'Moving pane', self.moveSrc, 'to new position', self.moveNewPos
        self.pw.move(self.moveSrc, self.moveNewPos)

        self.moveSrc, self.moveNewPos = self.moveNewPos, self.moveSrc
        if self.moveBack:
            if self.moveNewPos == numPanes - 1:
                self.moveNewPos = 0
                if self.moveSrc == numPanes - 1:
                    self.moveSrc = 0
                else:
                    self.moveSrc = self.moveSrc + 1
            else:
                self.moveNewPos = self.moveNewPos + 1
        self.moveBack = not self.moveBack

    def addPane(self):
        self.numPanes = self.numPanes + 1
        name = 'Pane ' + str(self.numPanes)
        print 'Adding', name
        pane = self.pw.add(name, min = .1, size = .25)
        label = Tkinter.Label(pane, text = name)
        label.pack(side = 'left', expand = 1)
        button = Tkinter.Button(pane, text = 'Delete',
                command = lambda s=self, n=name: s.deletePane(n))
        button.pack(side = 'left', expand = 1)
        self.pw.updatelayout()

    def deletePane(self, name):
        print 'Deleting', name
        self.pw.delete(name)
        self.pw.updatelayout()

    def moveOneUp(self, name):
        self.pw.move(name, name, -1)

    def moveOneDown(self, name):
        self.pw.move(name, name, 1)

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 14 April 2001

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9311185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/PmwFunctions.html0000664000175000017500000010051000000000000020624 0ustar00gregmgregm00000000000000 Pmw functions reference manual

Pmw functions

Pmw.aboutcontact(value)

The value passed to this function is used to construct the text displayed by Pmw.AboutDialog megawidgets created subsequently.

Pmw.aboutcopyright(value)

The value passed to this function is used to construct the text displayed by Pmw.AboutDialog megawidgets created subsequently.

Pmw.aboutversion(value)

The value passed to this function is used to construct the text displayed by Pmw.AboutDialog megawidgets created subsequently.

Pmw.aligngrouptags(groups)

This function takes a sequence of Pmw.Groups and adjusts the vertical position of the tags in each group so that they all have the height of the tallest tag. This can be used when groups are positioned side-by-side but the natural height of the tags are different because, for example, different fonts with different sizes are used.

Pmw.alignlabels(widgets, sticky = None)

Adjust the size of the labels of all the widgets to be equal, so that the body of each widget lines up vertically. This assumes that each widget is a megawidget with a label component in column 0 (ie, the labelpos option was set to 'w', 'wn' or 'ws'). If sticky is set to a combination of 'n', 's', 'e' and 'w', the label will be positioned within its cell accordingly. For example to make labels right justified, set sticky to 'e', 'ne' or 'se'.

Pmw.alphabeticvalidator(text)

Validator function for Pmw.EntryField alphabetic standard validator.

Pmw.alphanumericvalidator(text)

Validator function for Pmw.EntryField alphanumeric standard validator.

Pmw.busycallback(command, updateFunction = None)

Create a wrapper function which displays a busy cursor while executing command and return the wrapper. When the wrapper function is called, it first calls Pmw.showbusycursor(), then the command (passing any arguments to it), then Pmw.hidebusycursor(). The return value of command is returned from the wrapper.

If updateFunction is specified, it is called just before the call to Pmw.hidebusycursor(). This is intended to be the Tkinter update() method, in which case it will clear any events that may have occurred while command was executing. An example of this usage is in the ShowBusy demonstration: run the demonstration, click on the entry widget then click on the button and type some characters while the busy cursor is displayed. No characters should appear in the entry widget.

Note that the Tkinter update() method should only be called when it is known that it can be safely called. One case where a problem has been found is when a filehandler has been created (on a non-blocking Oracle database connection), but the filehandler does not read from the connection. The connection is read (by a call to the Oracle fetch function ofen) in a loop which also contains a call to _tkinter.dooneevent(). If update() is called from dooneevent() and there is data to be read on the connection, then the filehandler will be called continuously, thus hanging the application.

Pmw.clearbusycursor()

Unconditionally remove the event block and busy cursor from all windows. This undoes all outstanding calls to Pmw.showbusycursor().

Pmw.datestringtojdn(text, format = 'ymd', separator = '/')

Return the Julian Day Number corresponding to the date in text. A Julian Day Number is defined as the number of days since 1 Jan 4713 BC. The date must be specified as three integers separated by the separator character. The integers must be in the order specified by format, which must be a combination of 'd', 'm' and 'y' in any order. These give the order of the day, month and year fields. Examples of valid input are:

 'dmy':  31/01/99  31/1/1999  31/1/99
 'mdy':  01/31/99  1/31/1999  1/31/99
 'ymd':  99/01/31  1999/1/31  99/1/31

If the application's pivot year (default 50) is not None and the year specified in text has only one or two digits, then the year is converted to a four digit year. If it is less than or equal to the pivot year, then it is incremented by the application's century value (default 2000). If it is more than the pivot year then it is incremented by the century value less 100.

The function Pmw.setyearpivot() can be used to change the default values for the application's pivot and century.

Pmw.datevalidator(text, format = 'ymd', separator = '/')

Validator function for Pmw.EntryField date standard validator.

Pmw.displayerror(text)

This is a general purpose method for displaying background errors to the user. The errors would normally be programming errors and may be caused by errors in Tk callbacks or functions called by other asynchronous events.

If the global error report file (set by calling Pmw.reporterrorstofile()) is None, the error message `text` is written to standard error and also shown in a text window. If displayerror is called while previous error messages are being displayed, the window is raised and the new error is queued. The queued errors may be viewed by the user or ignored by dismissing the window.

If the global error report file is not None, `text` is written to the file. file may be any object with a write() method, such as sys.stderr.

Pmw.drawarrow(canvas, color, direction, tag, baseOffset = 0.25, edgeOffset = 0.15)

Draw a triangle in the Tkinter.Canvas canvas in the given color. The value of direction may be 'up', 'down', 'left' or 'right' and specifies which direction the arrow should point. The values of baseOffset and edgeOffset specify how far from the edges of the canvas the points of the triangles are as a fraction of the size of the canvas.

Pmw.forwardmethods(fromClass, toClass, toPart, exclude = ())

Forward methods from one class to another.

This function adds methods to the class fromClass. The names of the methods added are the names of the methods of the class toClass (and its base classes) except those which are already defined by fromClass or are found in the exclude list. Special methods with one or more leading or trailing underscores are also excluded.

When one of the added methods is called, the method of the same name is called on an instance defined by toPart and the return value passed back. If toPart is a string, then it specifies the name of an attribute (not a component) of the fromClass object. The class of this attribute should be toClass. If toPart is not a string, it must be a function taking a fromClass object and returning a toClass object.

This function must be called outside of and after the definition of fromClass.

For example:

class MyClass:
    def __init__(self):
        ...
        self.__target = TargetClass()
        ...

    def foo(self):
        pass

    def findtarget(self):
        return self.__target

Pmw.forwardmethods(MyClass, TargetClass, '__target',
    ['dangerous1', 'dangerous2'])

# ...or...

Pmw.forwardmethods(MyClass, TargetClass,
    MyClass.findtarget, ['dangerous1', 'dangerous2'])

In both cases, all TargetClass methods will be forwarded from MyClass except for dangerous1, dangerous2, special methods like __str__, and pre-existing methods like foo.

Pmw.grabstacktopwindow()

Return the window at the top of the grab stack (the window currently with the grab) or None if the grab stack is empty (no window has the grab). See also pushgrab().

Pmw.hexadecimalvalidator(text)

Validator function for Pmw.EntryField hexadecimal standard validator.

Pmw.hidebusycursor(forceFocusRestore = 0)

Undo one call to Pmw.showbusycursor(). If there are no outstanding calls to Pmw.showbusycursor(), remove the event block and busy cursor.

If the focus window has not been changed since the corresponding call to Pmw.showbusycursor(), or if forceFocusRestore is true, then the focus is restored to that saved by Pmw.showbusycursor().

Pmw.initialise(root = None, size = None, fontScheme = None, useTkOptionDb = 0, noBltBusy = 0, disableKeyboardWhileBusy = None)

Initialise Pmw. This performs several functions:

  • Set up a trap in the Tkinter Toplevel constructor so that a list of Toplevels can be maintained. A list of all Toplevel windows needs to be kept so that Pmw.showbusycursor() can create busy cursors for them.

  • Set up a trap in the Tkinter Toplevel and Frame destructors so that Pmw is notified when these widgets are destroyed. This allows Pmw to destroy megawidgets when their hull widget is destroyed and to prune the list of Toplevels.

  • Modify Tkinter's CallWrapper class to improve the display of errors which occur in callbacks. If an error occurs, the new CallWrapper class calls Pmw.clearbusycursor() to remove any outstanding busy cursors and calls Pmw.displayerror() to display the error.

  • Using the window given by root, set the WM_DELETE_WINDOW root window protocol to destroy the root window. This means that the root window is destroyed if the window manager deletes it. This is only done if the protocol has not been set before the call to Pmw.initialise(). This protocol is required if there is a modal dialog displayed and the window manager deletes the root window. Otherwise the application will not exit, even though there are no windows.

  • Set the base font size for the application to size. This is used by Pmw.logicalfont() as the default point size for fonts. If this is not given, the default is 14, except under NT where it is 16. These are reasonable default sizes for most screens, but for unusually high or low screen resolutions, an appropriate size should be supplied. Note that Tk's definition of point size, is somewhat idiosyncratic.

  • Set the Tk option database for root according to fontScheme. This changes the default fonts set by Tk. fontScheme may be one of

    None
    Do not change the Tk defaults.

    'pmw1'
    If running under posix (Unix), set the default font to be Helvetica with bold italic menus, italic scales and a special balloon font 6 points smaller than the base font size and with the 'pixel' field set to '12'. For other operating systems (such as NT or Macintosh), simply set the default font to be Helvetica. All fonts are as returned by calls to Pmw.logicalfont().

    'pmw2'
    This is the same as 'pmw1' except that under posix the balloon font is 2 points smaller than the base font size and the 'pixel' field is not set.

    'default'
    This sets the default fonts using the Tk font naming convention, rather than that returned by Pmw.logicalfont(). The default font is bold Helvetica. The font for entry widgets is Helvetica. The font for text widgets is Courier The size of all fonts is the application base font size as described above.

  • If root is None, use the Tkinter default root window as the root, if it has been created, or create a new Tk root window. The initialise() method returns this root.

  • If useTkOptionDb is true, then, when a megawidget is created, the Tk option database will be queried to get the initial values of the options which have not been set in the call to the constructor. The resource name used in the query is the same as the option name and the resource class is the option name with the first letter capitalised. If useTkOptionDb is false, then options for newly created megawidgets will be initialised to default values.

  • If noBltBusy is true, then Pmw.showbusycursor() will not display a busy cursor, even if the BLT busy command is present.

  • If disableKeyboardWhileBusy is false, then do not disable keyboard input while displaying the busy cursor. Normally, Pmw ignores keyboard input while displaying the busy cursor by setting the focus for each toplevel window to the Blt busy window. However, under NT, this may cause the toplevel windows to be raised. If this is not acceptable, programs running on NT can request show/hidebusycursor to not ignore keyboard input by setting disableKeyboardWhileBusy to true in Pmw.initialise().

It is not absolutely necessary to call this function to be able to use Pmw. However, some functionality will be lost. Most importantly, Pmw megawidgets will not be notified when their hull widget is destroyed. This may prevent the megawidget from cleaning up timers which will try to access the widget, hence causing a background error to occur.

Pmw.installedversions(alpha = 0)

If alpha is false, return the list of base versions of Pmw that are currently installed and available for use. If alpha is true, return the list of alpha versions.

Pmw.integervalidator(text)

Validator function for Pmw.EntryField integer standard validator.

Pmw.jdntoymd(jdn, julian = -1, papal = 1)

Return the year, month and day of the Julian Day Number jdn. If julian is 1, then the date returned will be in the Julian calendar. If julian is 0, then the date returned will be in the modern calendar. If julian is -1, then which calendar to use will be automatically determined by the value of jdn and papal. If papal is true, then the date set by Pope Gregory XIII's decree (4 October 1582) will be used as the last day to use the Julian calendar. If papal is false, then the last day to use the Julian calendar will be according to British-American usage (2 September 1752).

Pmw.logicalfont(name = 'Helvetica', sizeIncr = 0, **kw)

Return the full name of a Tk font, being a hyphen-separated list of font properties. The logical name of the font is given by name and may be one of 'Helvetica', 'Times', 'Fixed', 'Courier' or 'Typewriter'. Pmw uses this name to define the default values of many of the font properties. The size of the font is the base font size for the application specified in the call to Pmw.initialise() increased or decreased by the value of sizeIncr. The other properties of the font may be specified by other named arguments. These may be 'registry', 'foundry', 'family', 'weight', 'slant', 'width', 'style', 'pixel', 'size', 'xres', 'yres', 'spacing', 'avgwidth', 'charset' and 'encoding'.

Pmw.logicalfontnames()

Return the list of known logical font names that can be given to Pmw.logicalfont().

Pmw.numericvalidator(text)

Validator function for Pmw.EntryField numeric standard validator.

Pmw.popgrab(window)

Remove window from the grab stack. If there are not more windows in the grab stack, release the grab. Otherwise set the grab and the focus to the next window in the grab stack. See also pushgrab().

Pmw.pushgrab(grabWindow, globalMode, deactivateFunction)

The grab functions (pushgrab(), popgrab(), releasegrabs() and grabstacktopwindow()) are an interface to the Tk grab command which implements simple pointer and keyboard grabs. When a grab is set for a particular window, Tk restricts all pointer events to the grab window and its descendants in Tk's window hierarchy. The functions are used by the activate() and deactivate() methods to implement modal dialogs.

Pmw maintains a stack of grabbed windows, where the window on the top of the stack is the window currently with the grab. The grab stack allows nested modal dialogs, where one modal dialog can be activated while another modal dialog is activated. When the second dialog is deactivated, the first dialog becomes active again.

Use pushgrab() to add grabWindow to the grab stack. This releases the grab by the window currently on top of the stack (if there is one) and gives the grab and focus to the grabWindow. If globalMode is true, perform a global grab, otherwise perform a local grab. The value of deactivateFunction specifies a function to call (usually grabWindow.deactivate) if popgrab() is called (usually from a deactivate() method) on a window which is not at the top of the stack (that is, does not have the grab or focus). For example, if a modal dialog is deleted by the window manager or deactivated by a timer. In this case, all dialogs above and including this one are deactivated, starting at the top of the stack.

For more information, see the Tk grab manual page.

Pmw.realvalidator(text, separator = '.')

Validator function for Pmw.EntryField real standard validator.

Pmw.releasegrabs()

Release grab and clear the grab stack. This should normally not be used, use popgrab() instead. See also pushgrab().

Pmw.reporterrorstofile(file = None)

Sets the global error report file, which is initially None. See Pmw.displayerror()

Pmw.setalphaversions(*alpha_versions)

Set the list of alpha versions of Pmw to use for this session to the arguments. When searching for Pmw classes and functions, these alpha versions will be searched, in the order given, before the base version. This must be called before any other Pmw class or function, except functions setting or querying versions.

Pmw.setbusycursorattributes(window, **kw)

Use the keyword arguments to set attributes controlling the effect on window (which must be a Tkinter.Toplevel) of future calls to Pmw.showbusycursor(). The attributes are:

exclude
a boolean value which specifies whether the window will be affected by calls to Pmw.showbusycursor(). If a window is excluded, then the cursor will not be changed to a busy cursor and events will still be delivered to the window. By default, windows are affected by calls to Pmw.showbusycursor().

cursorName
the name of the cursor to use when displaying the busy cursor. If None, then the default cursor is used.

Pmw.setgeometryanddeiconify(window, geom)

Deiconify and raise the toplevel window and set its position and size according to geom. This overcomes some problems with the window flashing under X and correctly positions the window under NT (caused by Tk bugs).

Pmw.setversion(version)

Set the version of Pmw to use for this session to version. If Pmw.setversion() is not called, the latest installed version of Pmw will be used. This must be called before any other Pmw class or function, except functions setting or querying versions.

Pmw.setyearpivot(pivot, century = None)

Set the pivot year and century for the application's date processing. These values are used in the datestringtojdn() method, which is used by Pmw.Counter and Pmw.EntryField and derived classes. The initial values of pivot and century are 50 and 2000 repectively. Return a tuple containing the old values of pivot and century.

Pmw.showbusycursor()

Block events to and display a busy cursor over all windows in this application that are in the state 'normal' or 'iconic', except those windows whose exclude busycursor attribute has been set to true by a call to Pmw.setbusycursorattributes().

If a window and its contents have just been created, update_idletasks() may have to be called before Pmw.showbusycursor() so that the window is mapped to the screen. Windows created or deiconified after calling Pmw.showbusycursor() will not be blocked.

To unblock events and remove the busy cursor, use Pmw.hidebusycursor(). Nested calls to Pmw.showbusycursor() may be made. In this case, a matching number of calls to Pmw.hidebusycursor() must be made before the event block and busy cursor are removed.

If the BLT extension to Tk is not present, this function has no effect other than to save the value of the current focus window, to be later restored by Pmw.hidebusycursor().

Pmw.stringtoreal(text, separator = '.')

Return the real number represented by text. This is similar to string.atof() except that the character representing the decimal point in text is given by separator.

Pmw.timestringtoseconds(text, separator = ':')

Return the number of seconds corresponding to the time in text. The time must be specified as three integers separated by the separator character and must be in the order hours, minutes and seconds. The first number may be negative, indicating a negative time.

Pmw.timevalidator(text, separator = ':')

Validator function for Pmw.EntryField time standard validator.

Pmw.tracetk(root = None, on = 1, withStackTrace = 0, file = None)

Print debugging trace of calls to, and callbacks from, the Tk interpreter associated with the root window . If root is None, use the Tkinter default root. If on is true, start tracing, otherwise stop tracing. If withStackTrace is true, print a python function call stacktrace after the trace for each call to Tk. If file is None, print to standard error, otherwise print to the file given by file.

For each call to Tk, the Tk command and its options are printed as a python tuple, followed by the return value of the command (if not the empty string). For example:

python executed:
  button = Tkinter.Button()
  button.configure(text = 'Hi')

tracetk output:
  CALL  TK> 1:  ('button', '.3662448') -> '.3662448'
  CALL  TK> 1:  ('.3662448', 'configure', '-text', 'Hi')

Some calls from python to Tk (such as update, tkwait, invoke, etc) result in the execution of callbacks from Tk to python. These python callbacks can then recursively call into Tk. When displayed by tracetk(), these recursive calls are indented proportionally to the depth of recursion. The depth is also printed as a leading number. The return value of a call to Tk which generated recursive calls is printed on a separate line at the end of the recursion. For example:

python executed:
  def callback():
      button.configure(text = 'Bye')
      return 'Got me!'
  button = Tkinter.Button()
  button.configure(command = callback)
  button.invoke()
tracetk output:
  CALL  TK> 1:  ('button', '.3587144') -> '.3587144'
  CALL  TK> 1:  ('.3587144', 'configure', '-command', '3638368callback')
  CALL  TK> 1:  ('.3587144', 'invoke')
  CALLBACK> 2:    callback()
  CALL  TK> 2:    ('.3587144', 'configure', '-text', 'Bye')
  CALL RTN> 1:  -> 'Got me!'

Pmw.initialise() must be called before tracetk() so that hooks are put into the Tkinter CallWrapper class to trace callbacks from Tk to python and also to handle recursive calls correctly.

Pmw.version(alpha = 0)

If alpha is false, return the base version of Pmw being used for this session. If Pmw.setversion() has not been called, this will be the latest installed version of Pmw. If alpha is true, return the list of alpha versions of Pmw being used for this session, in search order. If Pmw.setalphaversions() has not been called, this will be the empty list.

Pmw.ymdtojdn(year, month, day, julian = -1, papal = 1)

Return the Julian Day Number corresponding to year, month and day. See jdntoymd() for description of other arguments)

Pmw 1.3.3 - 29 Mar 2014 - Home

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9271185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/PromptDialog.gif0000664000175000017500000000366200000000000020404 0ustar00gregmgregm00000000000000GIF87a`w`0;,hN.I89A|aih.#p,lx| )Ȥrl:4cmCZY,ʕ2_xLW-p7N~xs{zkGmwvoy/ |nvuSoĴtqr}ĸ~ Ϟt̜ntߤpᠡ{Wn 2( g @i;9"r6'R衇Vib3霨6(n髑*#zi)"j)鱾Jc(2)kuⳡZ갞,6Jm,g/kfIp]< 7G,Wl1)\w ,$l(J0,4׬2-G2(ʖ3t;.yC=!=D՜6txPxnvTwJo]m[?_c?]]gJ-g=ڭv5򩸸svm_8yZ7~]^j7xw>0nztGsNrO;\.~Bo<:+*;;@K/- s/'oY߯/?q 1ۡ^'lET:sDHt#أRP`!MA Gn&,SxP|!c(r!@ h2HL(0A7|b(E:"-GRD ~F")meF&&xjs@ןOH<摎!R:y3<=&2GT"9!A>RF$$)!q{$&:2ǑS]9mw'.xɍ̛45OovYOu\ ~APu.SIF3PF^k(P0TUUڍeeD)=a*lԗ[7IJTi5eI3Q~!9dYHũ%9TƵs< ޼)qE6mN8ub6XXKRJNx=*3tSSVҤ3`QT؅rBkgX2=l)XrZ֕uchh%QcEYqQeh:Z֢_jI8WU~-\[I{ Z)1:w}s [Hw@uH]OrH?*"dty/|#ju3kL8 ; .pL ?8 MF=H;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9271185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/PromptDialog.html0000664000175000017500000002351000000000000020575 0ustar00gregmgregm00000000000000 Pmw.PromptDialog reference manual

Pmw.PromptDialog

Name

Pmw.PromptDialog() - selection dialog displaying an entry field

Inherits

Pmw.Dialog

Description

The prompt dialog is a dialog window which displays an entry field which can be used to prompt the user for a value.

Options

Options for this megawidget and its base classes are described below.

activatecommand
If this is callable, it will be called whenever the megawidget is activated by a call to activate(). The default is None.

borderx
Initialisation option. The padding to the left and right of the entry field. The default is 20.

bordery
Initialisation option. The padding above and below the entry field. The default is 20.

buttonboxpos
Initialisation option. Specifies on which side of the dialog window to place the button box. Must be one of 'n', 's', 'e' or 'w'. The default is 's'.

buttons
This must be a tuple or a list and specifies the names on the buttons in the button box. The default is ('OK',).

command
Specifies a function to call whenever a button in the button box is invoked or the window is deleted by the window manager. The function is called with a single argument, which is the name of the button which was invoked, or None if the window was deleted by the window manager.

If the value of command is not callable, the default behaviour is to deactivate the window if it is active, or withdraw the window if it is not active. If it is deactivated, deactivate() is called with the button name or None as described above. The default is None.

deactivatecommand
If this is callable, it will be called whenever the megawidget is deactivated by a call to deactivate(). The default is None.

defaultbutton
Specifies the default button in the button box. If the <Return> key is hit when the dialog has focus, the default button will be invoked. If defaultbutton is None, there will be no default button and hitting the <Return> key will have no effect. The default is None.

master
This is used by the activate() method to control whether the window is made transient during modal dialogs. See the activate() method. The default is 'parent'.

separatorwidth
Initialisation option. If this is greater than 0, a separator line with the specified width will be created between the button box and the child site, as a component named separator. Since the default border of the button box and child site is raised, this option does not usually need to be set for there to be a visual separation between the button box and child site. The default is 0.

title
This is the title that the window manager displays in the title bar of the window. The default is None.

Components

Components created by this megawidget and its base classes are described below.

buttonbox
This is the button box containing the buttons for the dialog. By default it is created with the options (hull_borderwidth = 1, hull_relief = 'raised'). By default, this component is a Pmw.ButtonBox.

dialogchildsite
This is the child site for the dialog, which may be used to specialise the megawidget by creating other widgets within it. By default it is created with the options (borderwidth = 1, relief = 'raised'). By default, this component is a Tkinter.Frame.

entryfield
The entry field for the user to enter a value. By default, this component is a Pmw.EntryField.

hull
This acts as the body for the entire megawidget. Other components are created as children of the hull to further specialise this class. By default, this component is a Tkinter.Toplevel.

separator
If the separatorwidth initialisation option is non-zero, the separator component is the line dividing the area between the button box and the child site. By default, this component is a Tkinter.Frame.

Component aliases

Sub-components of components of this megawidget may be accessed via the following aliases.

entry
Alias for entryfield_entry.
label
Alias for entryfield_label.

Methods

Only methods specific to this megawidget are described below. For a description of its inherited methods, see the manual for its base class Pmw.Dialog. In addition, methods from the Pmw.EntryField class are forwarded by this megawidget to the entryfield component.

deleteentry(first, last = None)
Delete text from the entry field's entry widget. An alias for component('entry').delete().

indexentry(index)
An alias for component('entry').index().

insertentry(index, text)
Insert text into the entry field's entry widget. An alias for component('entry').insert().

Example

The image at the top of this manual is a snapshot of the window (or part of the window) produced by the following code.

class Demo:
    def __init__(self, parent):
        # Create the dialog to prompt for the password.
        self.dialog = Pmw.PromptDialog(parent,
            title = 'Password',
            label_text = 'Password:',
            entryfield_labelpos = 'n',
            entry_show = '*',
            defaultbutton = 0,
            buttons = ('OK', 'Cancel'),
            command = self.execute)
        self.dialog.withdraw()

        # Create the confirmation dialog.
        self.confirm = Pmw.MessageDialog(
            title = 'Are you sure?',
            message_text = 'Are you really sure?',
            defaultbutton = 0,
            buttons = ('OK', 'Cancel'))
        self.confirm.withdraw()

        # Create button to launch the dialog.
        w = Tkinter.Button(parent, text = 'Show prompt dialog',
                command = self.dialog.activate)
        w.pack(padx = 8, pady = 8)

    def execute(self, result):
        if result is None or result == 'Cancel':
            print 'Password prompt cancelled'
            self.dialog.deactivate(result)
        else:
            result = self.confirm.activate()
            if result == 'OK':
                print 'Password entered ' + self.dialog.get()
                self.dialog.deactivate()

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 18 May 2002

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9311185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/RadioSelect.gif0000664000175000017500000001062100000000000020172 0ustar00gregmgregm00000000000000GIF87aق0`,(0I8ͻ`(dihlp,tmx|pH,Ȥrl:ШtJZجvzxL.h.`n|N~biVMaB_7],[!Ykuם~X~r W=ڥPiGo{<BFLFxa=TPF2Lѣ,3XH-ü0HL'Teʞif,rScΊ,jAcfQ/B<੓XRt똨RZmCg-]V m;58>/_`oFbL%8`z7D^`bc8Bi0g&=bug/MJNoH]ywg];.mۦU.^j 3^<9?>=vwf[߮!g}7|y]~!W܂ ^9(|yn' B8z&6b,` p%FHt6v%rib<~*F)aiVuEVT Anr彧}.dS~i%mx>~@MNa䕚Q"r~&Xꈨ=r((Z'ivxuFx~difHW|7zކ狪"hf3uV^ZᏤɬjJ,W)Fen: y9~J몹&F* a|8-`ؤ!h '+k \fu 00-)G&k$DN֭, jٙbBP+F;dw.4UMɊB4|#@YB&:,B]] D[ϗK40GZFiru n5W @28WU9h{#-KyC?=E{KnŔٞ;UྔVP'/wVd)Ql]$889U~$yT6/O nti^™KfmD˨3%S hқ 4,rJ&LTF &rSZL)oM5+Qӯ`uꚕԦ†cTt+6E,Uf-dm%?% PJIVy6LɖSfx@C Ѧ5( шd(,Umg I)9΅uOMU}݊ٸ(SAG X0p? ժG%IΕOQ}pԘ*TJV0 ~҈nPXҜ.A6؇t/)KOKzUu2Cw]A*$ZoX-1/JJ3PWi>; n)n5D .N6F@XapT[-,bsmk[p hi If\eeyUT\Iun1YogO0R[_GZ4nU[Je/jakV~;Y5čݰފjUWZ~ ɵ5r$ljjpV[>(Ǣ _I SgANGv4U;/u\>,3ozW.Vn2u/pqIK,AoҔl&*M i|oܧ@귦D0_tzJ+,]RT`r.3IF Xt]ejF :7GXXoVvN_6P܅87٠ua^?a wONdYp=pӳ/8+AƉ48i}{ y7~y(O930gN8Ϲw@Ї> yDʗ$w:/nBKT/կ鬓p\Gz",]}+h{w¼뽮|w k=\x)ڡ7h`Q0EY9S~".qh2Ћћ>o髒o2^2DнOq}tU'>{ _&vR깯'tuq}pumo:DXfkaā#HSGE>$xLÂH'&(؂<>/:h 5kB>H8FxLׄE؀UKH>AxZ: 'HG`bX%Jd]gw_x ]95b b" a}U16Sn"]W'x@x7rH&y"yZ'#LJ}Yj6\ a%*uN͕g75R~6)dh_4K 3`@Yl0e=8v{(`|(2#w*hmIXĘ(byOY GI`dD ǀPi3tHB`WWHU4NAVi 4AYy)'b7A3Ǡ^_gYtЉ?yhI`Н≐sY{ddI6:5]Ʌ﹟9l6 z9/Iek١0_vȩc)Ҟ"jc2>J#t<EjG{ .ZM(ʤȡC:)5 nyh(9:JUIb }E$!Rws*iUejiو*a73ʕ?*5,@2䷩r-`3+.(pfC)P)0JX(CY)) g(<:3 }zXcsYP jc*V^JZ\*Q*p3xYbe*J 8󠭆r1Rijj%J2ڕgY8+'&^HٌK98ZY]48[O]Ig&Кdb0^d @jĩ_[ÉS >{_Zcb O6I{ګņ]f62pha/+誰.Z`jV,:{۪x>WXݗEh֙쑣_kpdqq`?"Iphytm;]d*v;T[ЏZĻ;x;CʥNۜ{KE ͛Ck+ϋD׋ D{CA[H[CA(KC~ +}+^ڿo+ z̸޹l˼7 l+i]D yg :&\ԋ T&K'{8`;6`90|b!+|Im #QA j.;*@KLXܨ#Ƭc< b&sܴm|~x4i/:w|o,ZZ;L|9Zx\Ƒ \xlʝɤ{ w, w lv,w0 <\|ȜʼΌ ;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9311185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/RadioSelect.html0000664000175000017500000003605400000000000020401 0ustar00gregmgregm00000000000000 Pmw.RadioSelect reference manual

Pmw.RadioSelect

Name

Pmw.RadioSelect() - a set of buttons, some of which may be selected

Inherits

Pmw.MegaWidget

Description

A radio select is a container megawidget which manages a number of buttons. The buttons may be laid out either horizontally or vertically. In single selection mode, only one button may be selected at any one time. In multiple selection mode, several buttons may be selected at the same time and clicking on a selected button will deselect it.

The buttons displayed can be either standard buttons, radio buttons or check buttons. When selected, standard buttons are displayed sunken and radio and check buttons are displayed with the appropriate indicator color and relief.

Options

Options for this megawidget and its base classes are described below.

buttontype
Initialisation option. Specifies the default type of buttons created by the add() method. If 'button', the default type is Tkinter.Button. If 'radiobutton', the default type is Tkinter.Radiobutton. If 'checkbutton', the default type is Tkinter.Checkbutton.

If 'radiobutton', single selection mode is automatically set. If 'checkbutton', multiple selection mode is automatically set. The default is 'button'.

command
Specifies a function to call when one of the buttons is clicked on or when invoke() is called.

In single selection mode, the function is called with a single argument, which is the name of the selected button.

In multiple selection mode, the function is called with the first argument being the name of the button and the second argument being true if the button is now selected or false if it is now deselected. The default is None.

labelmargin
Initialisation option. If the labelpos option is not None, this specifies the distance between the label component and the rest of the megawidget. The default is 0.

labelpos
Initialisation option. Specifies where to place the label component. If not None, it should be a concatenation of one or two of the letters 'n', 's', 'e' and 'w'. The first letter specifies on which side of the megawidget to place the label. If a second letter is specified, it indicates where on that side to place the label. For example, if labelpos is 'w', the label is placed in the center of the left hand side; if it is 'wn', the label is placed at the top of the left hand side; if it is 'ws', the label is placed at the bottom of the left hand side.

If None, a label component is not created. The default is None.

orient
Initialisation option. Specifies the direction in which the buttons are laid out. This may be 'horizontal' or 'vertical'. The default is 'horizontal'.

padx
Initialisation option. Specifies a padding distance to leave between each button in the x direction and also between the buttons and the outer edge of the radio select. The default is 5.

pady
Initialisation option. Specifies a padding distance to leave between each button in the y direction and also between the buttons and the outer edge of the radio select. The default is 5.

selectmode
Initialisation option. Specifies the selection mode: whether a single button or multiple buttons can be selected at one time. If 'single', clicking on an unselected button selects it and deselects all other buttons. If 'multiple', clicking on an unselected button selects it and clicking on a selected button deselects it. This option is ignored if buttontype is 'radiobutton' or 'checkbutton'. The default is 'single'.

Components

Components created by this megawidget and its base classes are described below.

frame
If the label component has been created (that is, the labelpos option is not None), the frame component is created to act as the container of the buttons created by the add() method. If there is no label component, then no frame component is created and the hull component acts as the container. By default, this component is a Tkinter.Frame.

hull
This acts as the body for the entire megawidget. Other components are created as children of the hull to further specialise this class. By default, this component is a Tkinter.Frame.

label
If the labelpos option is not None, this component is created as a text label for the megawidget. See the labelpos option for details. Note that to set, for example, the text option of the label, you need to use the label_text component option. By default, this component is a Tkinter.Label.

Dynamic components

Button components are created dynamically by the add() method. The default type of the buttons depends on the value of the buttontype option.

Button components are created with a component group of Button.

Methods

Only methods specific to this megawidget are described below. For a description of its inherited methods, see the manual for its base class Pmw.MegaWidget.

add(componentName, **kw)
Add a button to the end of the radio select as a component named componentName. with a default type as specified by buttontype. Any keyword arguments present (except command) will be passed to the constructor when creating the button. If the text keyword argument is not given, the text option of the button defaults to componentName. The method returns the component widget.

button(buttonIndex)
Return the button specified by buttonIndex, which may have any of the forms accepted by the index() method.

deleteall()
Delete all buttons and clear the current selection.

getcurselection()
Same as getvalue() method.

getvalue()
In single selection mode, return the name of the currently selected button, or None if no buttons have been selected yet.

In multiple selection mode, return a list of the names of the currently selected buttons.

index(index)
Return the numerical index of the button corresponding to index. This may be specified in any of the following forms:

name
Specifies the button named name.

number
Specifies the button numerically, where 0 corresponds to the left (or top) button.

Pmw.END
Specifies the right (or bottom) button.

invoke(index)
Calling this method is the same as clicking on the button specified by index: the buttons are displayed selected or deselected according to the selection mode and command is called. index may have any of the forms accepted by the index() method. The value returned by command is returned.

numbuttons()
Return the number of buttons in the radio select.

setvalue(textOrList)
Set the current selection for the radio select to textOrList, but do not invoke command.

In single selection mode, select only the button specified by the string textOrList.

In multiple selection mode, select only the buttons specified by the list textOrList.

Example

The image at the top of this manual is a snapshot of the window (or part of the window) produced by the following code.

class Demo:
    def __init__(self, parent):
        # Create and pack a horizontal RadioSelect widget.
        horiz = Pmw.RadioSelect(parent,
                labelpos = 'w',
                command = self.callback,
                label_text = 'Horizontal',
                frame_borderwidth = 2,
                frame_relief = 'ridge'
        )
        horiz.pack(fill = 'x', padx = 10, pady = 10)

        # Add some buttons to the horizontal RadioSelect.
        for text in ('Fruit', 'Vegetables', 'Cereals', 'Legumes'):
            horiz.add(text)
        horiz.invoke('Cereals')

        # Create and pack a multiple selection RadioSelect widget.
        self.multiple = Pmw.RadioSelect(parent,
                labelpos = 'w',
                command = self.multcallback,
                label_text = 'Multiple\nselection',
                frame_borderwidth = 2,
                frame_relief = 'ridge',
                selectmode = 'multiple',
        )
        self.multiple.pack(fill = 'x', padx = 10)

        # Add some buttons to the multiple selection RadioSelect.
        for text in ('Apricots', 'Eggplant', 'Rice', 'Lentils'):
            self.multiple.add(text)
        self.multiple.invoke('Rice')

        # Create and pack a vertical RadioSelect widget, with checkbuttons.
        self.checkbuttons = Pmw.RadioSelect(parent,
                buttontype = 'checkbutton',
                orient = 'vertical',
                labelpos = 'w',
                command = self.checkbuttoncallback,
                label_text = 'Vertical,\nusing\ncheckbuttons',
                hull_borderwidth = 2,
                hull_relief = 'ridge',
        )
        self.checkbuttons.pack(side = 'left', expand = 1, padx = 10, pady = 10)

        # Add some buttons to the checkbutton RadioSelect.
        for text in ('Male', 'Female'):
            self.checkbuttons.add(text)
        self.checkbuttons.invoke('Male')
        self.checkbuttons.invoke('Female')

        # Create and pack a RadioSelect widget, with radiobuttons.
        radiobuttons = Pmw.RadioSelect(parent,
                buttontype = 'radiobutton',
                orient = 'vertical',
                labelpos = 'w',
                command = self.callback,
                label_text = 'Vertical,\nusing\nradiobuttons',
                hull_borderwidth = 2,
                hull_relief = 'ridge',
        )
        radiobuttons.pack(side = 'left', expand = 1, padx = 10, pady = 10)

        # Add some buttons to the radiobutton RadioSelect.
        for text in ('Male', 'Female', 'Both', 'Neither'):
            radiobuttons.add(text)
        radiobuttons.invoke('Both')

    def callback(self, tag):
        # This is called whenever the user clicks on a button
        # in a single select RadioSelect widget.
        print 'Button', tag, 'was pressed.'

    def multcallback(self, tag, state):
        # This is called whenever the user clicks on a button
        # in the multiple select RadioSelect widget.
        if state:
           action = 'pressed.'
        else:
           action = 'released.'

        print 'Button', tag, 'was', action, \
                'Selection:', self.multiple.getcurselection()
           
    def checkbuttoncallback(self, tag, state):
        # This is called whenever the user clicks on a button
        # in the checkbutton RadioSelect widget.
        if state:
           action = 'pressed.'
        else:
           action = 'released.'

        print 'Button', tag, 'was', action, \
                'Selection:', self.checkbuttons.getcurselection()
           

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 6 June 2002

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9271185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/ScrolledCanvas.gif0000664000175000017500000000557300000000000020711 0ustar00gregmgregm00000000000000GIF87a~`0;,~H0I8ͻ`(dihlp,tmx|pH,Ȥr98ШtJZجvzxL.Szn| X|'H?~ |u ^yz} {vϧعرN˙Ռ視ӑ޻;7p\Ȱ掕( j:+&ɓ = Ct$KISJ"tBƚ@޸.=}"S@̹r*ϘzW(U,xA _t֭|Ճ7>BZb4*叚`ՅDzXaӸ1VOscz&y0.',E]NXڅjΘ߾Wpqjb]WcoV.a;V~x?{~@o6߁g€V}$dZamp"$`r%X(PA@t1ҨcJ,n89(&6AdEZdKF9D#= X@V^C褑 #hv%L]pfp^&BˑtqœWY'RuÛ:YXhv:Lcb&bViK\J鑪ꧯ^Zk h* 롰P"k2Kf[a'q  tCe.E/M^e/GF2Ba먰iIܰ7?RqB`1߹ |222̴<3x|3 n:3}rˇB3)H'&?W PNӰ.TWXk/ф%d\{HldA 6xݞܠB-*ڝ7- 7!΀1G.9xYk.7By郋55y43pg(،:7l3<ʣ|C?iNP__; >⓯X 3G%=?k_LF." 7]˕7A Lj(g?=`VBv8ahB8 aXaVEtK1NජH=*0RW" u1/0Q@(.3~PiT)Q}JlxTqqjw|c¸j]Fd &BR,yaE/{ȫsd!9rw%#DRR15WВi4[[D!C@$09Ifs_je2w=sL4xDbj* 9f :}iN3K-{VQf$Mg|\J@M94<Z@~&(ENa*ƜF#ВBL FGjQb4+hK-R艔`k*&%GӞr̩'QZT4`H顚TVSRM UoTT2VQUR4Z+jրTغR* L\?G׺.FZ8N<:ΰ~&P:Vxtkb+^'zshHZTֲud#6~ĝmZ>E bXu[4ks& p֓ĕeG)m!2et9֍mxWHhLz]RW_4KK8*32-Dߩ r)Ix/FŻ}y;gЂ:%1jS$ݞ~ixixim`73Vy\)m #7C׍UL 1RclD+#Yfrep952K%#gd88,*졛cg's̴L8w;,\{k;@GTbV"8c*f氊: ]6:1lWc ;v^.KfND\TFl.?vCaQ}}-4HYw̓tSlخܝmxS߷3 M+pP;3F~!J["#P\cu')m Dc.?NoHNFNNFp:`y& &.\ d:JdӼDx\?qldT_r\oQvl(9u@h;w\&]iG6w$, 3p/EK.)vp9;4|e߁!S\zb?>N'ug;=MO;[Ͼ9O1O[@}\g^jdw! ؀bHli*QzG~JX#e( ȁ!hzhb#R^G-Xv(`&Bv3HE`9`W 1xuFB X!  sLH Nh^RhtbW Yf0sx>co+Hn@n8/ƆTхoz$$hP8UQ \Xh#XOKx~HY*Ȉ=\񉨘(XZ}p/8X8}x؋8XxȘʸh! ;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9271185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/ScrolledCanvas.html0000664000175000017500000003126600000000000021106 0ustar00gregmgregm00000000000000 Pmw.ScrolledCanvas reference manual

Pmw.ScrolledCanvas

Name

Pmw.ScrolledCanvas() - canvas with optional scrollbars

Inherits

Pmw.MegaWidget

Description

A scrolled canvas consists of a standard canvas widget with optional scrollbars which can be used to scroll the canvas. The scrollbars can be dynamic, which means that a scrollbar will only be displayed if it is necessary, that is, if the scrollregion of the canvas is larger than the canvas.

Options

Options for this megawidget and its base classes are described below.

borderframe
Initialisation option. If true, the borderframe component will be created. The default is 0.

canvasmargin
Initialisation option. The margin around the items in the canvas. Used by the resizescrollregion() method. The default is 0.

hscrollmode
The horizontal scroll mode. If 'none', the horizontal scrollbar will never be displayed. If 'static', the scrollbar will always be displayed. If 'dynamic', the scrollbar will be displayed only if necessary. The default is 'dynamic'.

labelmargin
Initialisation option. If the labelpos option is not None, this specifies the distance between the label component and the rest of the megawidget. The default is 0.

labelpos
Initialisation option. Specifies where to place the label component. If not None, it should be a concatenation of one or two of the letters 'n', 's', 'e' and 'w'. The first letter specifies on which side of the megawidget to place the label. If a second letter is specified, it indicates where on that side to place the label. For example, if labelpos is 'w', the label is placed in the center of the left hand side; if it is 'wn', the label is placed at the top of the left hand side; if it is 'ws', the label is placed at the bottom of the left hand side.

If None, a label component is not created. The default is None.

scrollmargin
Initialisation option. The distance between the scrollbars and the enclosing canvas widget. The default is 2.

usehullsize
Initialisation option. If true, the size of the megawidget is determined solely by the width and height options of the hull component.

Otherwise, the size of the megawidget is determined by the width and height of the canvas component, along with the size and/or existence of the other components, such as the label, the scrollbars and the scrollmargin option. All these affect the overall size of the megawidget. The default is 0.

vscrollmode
The vertical scroll mode. If 'none', the vertical scrollbar will never be displayed. If 'static', the scrollbar will always be displayed. If 'dynamic', the scrollbar will be displayed only if necessary. The default is 'dynamic'.

Components

Components created by this megawidget and its base classes are described below.

borderframe
A frame widget which snuggly fits around the canvas, to give the appearance of a canvas border. It is created with a border so that the canvas, which is created without a border, looks like it has a border. By default, this component is a Tkinter.Frame.

canvas
The canvas widget which is scrolled by the scrollbars. If the borderframe option is true, this is created with a borderwidth of 0 to overcome a known problem with canvas widgets: if a widget inside a canvas extends across one of the edges of the canvas, then the widget obscures the border of the canvas. Therefore, if the canvas has no border, then this overlapping does not occur. By default, this component is a Tkinter.Canvas.

horizscrollbar
The horizontal scrollbar. By default, this component is a Tkinter.Scrollbar. Its component group is Scrollbar.

hull
This acts as the body for the entire megawidget. Other components are created as children of the hull to further specialise this class. By default, this component is a Tkinter.Frame.

label
If the labelpos option is not None, this component is created as a text label for the megawidget. See the labelpos option for details. Note that to set, for example, the text option of the label, you need to use the label_text component option. By default, this component is a Tkinter.Label.

vertscrollbar
The vertical scrollbar. By default, this component is a Tkinter.Scrollbar. Its component group is Scrollbar.

Methods

Only methods specific to this megawidget are described below. For a description of its inherited methods, see the manual for its base class Pmw.MegaWidget. In addition, methods from the Tkinter.Canvas class are forwarded by this megawidget to the canvas component.

bbox(*args)
This method is explicitly forwarded to the canvas component's bbox() method. Without this explicit forwarding, the bbox() method (aliased to grid_bbox()) of the hull would be invoked, which is probably not what the programmer intended.

interior()
Return the canvas widget within which the programmer should create graphical items and child widgets. This is the same as component('canvas').

resizescrollregion()
Resize the scrollregion of the canvas component to be the bounding box covering all the items in the canvas plus a margin on all sides, as specified by the canvasmargin option.

Example

The image at the top of this manual is a snapshot of the window (or part of the window) produced by the following code.

class Demo:
    def __init__(self, parent):
        # Create the ScrolledCanvas.
        self.sc = Pmw.ScrolledCanvas(parent,
                borderframe = 1,
                labelpos = 'n',
                label_text = 'ScrolledCanvas',
                usehullsize = 1,
                hull_width = 400,
                hull_height = 300,
        )

        # Create a group widget to contain the scrollmode options.
        w = Pmw.Group(parent, tag_text='Scroll mode')
        w.pack(side = 'bottom', padx = 5, pady = 5)

        hmode = Pmw.OptionMenu(w.interior(),
                labelpos = 'w',
                label_text = 'Horizontal:',
                items = ['none', 'static', 'dynamic'],
                command = self.sethscrollmode,
                menubutton_width = 8,
        )
        hmode.pack(side = 'left', padx = 5, pady = 5)
        hmode.invoke('dynamic')

        vmode = Pmw.OptionMenu(w.interior(),
                labelpos = 'w',
                label_text = 'Vertical:',
                items = ['none', 'static', 'dynamic'],
                command = self.setvscrollmode,
                menubutton_width = 8,
        )
        vmode.pack(side = 'left', padx = 5, pady = 5)
        vmode.invoke('dynamic')

        buttonBox = Pmw.ButtonBox(parent)
        buttonBox.pack(side = 'bottom')
        buttonBox.add('yview', text = 'Show\nyview', command = self.showYView)
        buttonBox.add('scroll', text = 'Page\ndown', command = self.pageDown)
        buttonBox.add('center', text = 'Center', command = self.centerPage)

        # Pack this last so that the buttons do not get shrunk when
        # the window is resized.
        self.sc.pack(padx = 5, pady = 5, fill = 'both', expand = 1)

        self.sc.component('canvas').bind('<1>', self.addcircle)

        testEntry = Tkinter.Entry(parent)
        self.sc.create_line(20, 20, 100, 100)
        self.sc.create_oval(100, 100, 200, 200, fill = 'green')
        self.sc.create_text(100, 20, anchor = 'nw',
                text = 'Click in the canvas\nto draw ovals',
                font = testEntry.cget('font'))
        button = Tkinter.Button(self.sc.interior(),
                text = 'Hello,\nWorld!\nThis\nis\na\nbutton.')
        self.sc.create_window(200, 200,
                anchor='nw',
                window = button)

        # Set the scroll region of the canvas to include all the items
        # just created.
        self.sc.resizescrollregion()

        self.colours = ('red', 'green', 'blue', 'yellow', 'cyan', 'magenta',
                'black', 'white')
        self.oval_count = 0
        self.rand = 12345

    def sethscrollmode(self, tag):
        self.sc.configure(hscrollmode = tag)

    def setvscrollmode(self, tag):
        self.sc.configure(vscrollmode = tag)

    def addcircle(self, event):
        x = self.sc.canvasx(event.x)
        y = self.sc.canvasy(event.y)
        width = 10 + self.random() % 100
        height = 10 + self.random() % 100
        self.sc.create_oval(
            x - width, y - height, x + width, y + height,
            fill = self.colours[self.oval_count])
        self.oval_count = (self.oval_count + 1) % len(self.colours)
        self.sc.resizescrollregion()

    # Simple random number generator.
    def random(self):
        self.rand = (self.rand * 125) % 2796203
        return self.rand

    def showYView(self):
        print self.sc.yview()

    def pageDown(self):
        self.sc.yview('scroll', 1, 'page')

    def centerPage(self):
        top, bottom = self.sc.yview()
        size = bottom - top
        middle = 0.5 - size / 2
        self.sc.yview('moveto', middle)

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 20 September 1998

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9311185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/ScrolledField.gif0000664000175000017500000000115100000000000020505 0ustar00gregmgregm00000000000000GIF87a %ق, %ڋ޼H扦ʶ L ĢL*̦ JԪܮ Nt6^gLwAh0hx )@Yb)aXLjayP:j:!* Iyp؁ A;qP|j܈\l|X;\Y\ >;^n -~>Yݞ^./,!kϑpM A6q9Lp]).8b.z'&/_}DWl k Ν'o6';LTɥ7XSfJ]2yjOwb}kJDLժڈ dCL{+rb6{zK0M,-ʷ[!ӢiɁb ̮:ЧVspƌod|;S xͩ%SK_^a׌|!X]9ؓO7țAZR+_O/0^A| ^߯s!BG0\A`` .aNHa^Hna~b"Hb&b*b.8G;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9311185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/ScrolledField.html0000664000175000017500000001477500000000000020724 0ustar00gregmgregm00000000000000 Pmw.ScrolledField reference manual

Pmw.ScrolledField

Name

Pmw.ScrolledField() - single line scrollable output field

Inherits

Pmw.MegaWidget

Description

A scrolled field displays a single line of text. If the text is too wide to display in the megawidget it can be scrolled to the left and right by the user by dragging with the middle mouse button. The text is also selectable by clicking or dragging with the left mouse button.

It can be used instead of a Tkinter.Label widget when displaying text of unknown width such as application status messages.

Options

Options for this megawidget and its base classes are described below.

labelmargin
Initialisation option. If the labelpos option is not None, this specifies the distance between the label component and the rest of the megawidget. The default is 0.

labelpos
Initialisation option. Specifies where to place the label component. If not None, it should be a concatenation of one or two of the letters 'n', 's', 'e' and 'w'. The first letter specifies on which side of the megawidget to place the label. If a second letter is specified, it indicates where on that side to place the label. For example, if labelpos is 'w', the label is placed in the center of the left hand side; if it is 'wn', the label is placed at the top of the left hand side; if it is 'ws', the label is placed at the bottom of the left hand side.

If None, a label component is not created. The default is None.

sticky
Initialisation option. The default is 'ew'.

text
Specifies the text to display in the scrolled field. The default is ''.

Components

Components created by this megawidget and its base classes are described below.

entry
This is used to display the text and allows the user to scroll and select the text. The state of this component is set to 'readonly' (or 'disabled' in earlier versions of Tcl/Tk which do not support 'readonly'), so that the user is unable to modify the text. By default, this component is a Tkinter.Entry.

hull
This acts as the body for the entire megawidget. Other components are created as children of the hull to further specialise this class. By default, this component is a Tkinter.Frame.

label
If the labelpos option is not None, this component is created as a text label for the megawidget. See the labelpos option for details. Note that to set, for example, the text option of the label, you need to use the label_text component option. By default, this component is a Tkinter.Label.

Methods

This megawidget has no methods of its own. For a description of its inherited methods, see the manual for its base class Pmw.MegaWidget. In addition, methods from the Tkinter.Entry class are forwarded by this megawidget to the entry component.

Example

The image at the top of this manual is a snapshot of the window (or part of the window) produced by the following code.

class Demo:
    def __init__(self, parent):
        # Create and pack the ScrolledField.
        self._field = Pmw.ScrolledField(parent, entry_width = 30,
                entry_relief='groove', labelpos = 'n',
                label_text = 'Scroll the field using the\nmiddle mouse button')
        self._field.pack(fill = 'x', expand = 1, padx = 10, pady = 10)

        # Create and pack a button to change the ScrolledField.
        self._button = Tkinter.Button(parent, text = 'Change field',
                command = self.execute)
        self._button.pack(padx = 10, pady = 10)

        self._index = 0
        self.execute()

    def execute(self):
        self._field.configure(text = lines[self._index % len(lines)])
        self._index = self._index + 1

lines = (
  'Alice was beginning to get very tired of sitting by her sister',
  'on the bank, and of having nothing to do:  once or twice she had',
  'peeped into the book her sister was reading, but it had no',
  'pictures or conversations in it, "and what is the use of a book,"',
  'thought Alice "without pictures or conversation?"',
  'Alice\'s Adventures in Wonderland',
  'Lewis Carroll',
)

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 23 August 1998

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9311185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/ScrolledFrame.gif0000664000175000017500000000756300000000000020531 0ustar00gregmgregm00000000000000GIF87a`0P`Â,(0I8ͻ`(dihlp,tmx|pH,ȤrlZШtJZجvzxL.hq*n|N*0 { x |}NM w HP| ͧ̚Fɰܩy@䌙eHYWCȰC 9TP}wW9Q5Di^Ń('2x.{eyc@oZ,(P38KFI'6yC1ex$ͧ6lKɕh%sV d+ؘbj۳Aʕ!nҸL6_ ,X*lz5lS -h[/+#ޜBn*:4Q @/$6}" :p w =mB77^~U @nz ̳Kp>pŅN u2 30z.@e?.T|~! ( XNҥJURT ~ȉ(,Q0(/h2ֈ<& $Nhb; E3,*'Z# A Ő% [@ߔmPVExjvV5Zj5Ak]{2[64Vd2`6"k쬦^2=Rդ+S2neA@e.Yp :.Ck{԰>0d/e_S  ʞ0`ɊX+3\]-Bξ %4<+=ӎ M/J2E!i\csSܵmv|re3|7>+/)m-6e 4*5߄ks rf{Yݪݹ̓uJ;FzjܕF.s<9^~ϼ~=߱;; {ix`^XӚ}Ḩ.<7w|n=B%.}U'%JUP~ T_A^~_A $ZOb.B +"1darxP3@ eta!&B;`)>V\x-rGb(y7ry5⨍nQ(!K! 0N#IXU!p HAU$!HgxtdL2-PqK`x Q1te"(`)URKs# I|R,-9SÎbM~)-ΚWf9[{dNj:bs謦FΜ|g)O|Cms]((s4zC;}^B3?c͕n@:p4XDQy ܞTn cF|R$7V8 Y1 4% JOՔzUZm^]ժ39ЛqBN mU^jM&hP:siMZ6*_WWƕ[ř:ֽbFF*^W7)/95ͳriuʱ1cMk3)څ駱5캤UZ3su\;"&d.՞gQa5|&wnz(p:[:Ϡ-y}^󍷾5ti שڭ7G &mo%K\%+ U&)×-/Ixk {0]F)^j)WD Bp 0|3 TPY MT^Y_<+gyksw]xp{!8113[=~N"YEΩt# E3:E~S!iEҩ@QfU:pbQ:dž1d=}ژtQ}jP5f]=k[ֽE9> lY[I>6im^ߚӹVmf?;<6]NdNluݬu~^Je0}|6x}c✑/o ݂wowŌJYjxzrWg1-QsskKUo W\#H`2nc%YT=c;ug5NݗXfNwusKyvPu}OQvr;wh׫(ovL<ڮf荞܇uDw]tUsjuhVrֵOmiu)܏&=~:[?Lzs]m+[ #?}>=m_}}֏>d݂9Onv}QL纞qX'\7wȶ;#'`|gpyAWX5 2Bfyp3vೂRwZhw* H=H_?AhHXwikOlQxn 6o"598oVxL?NPRTjօ0SpBԷl҆v*xXnwHcgi(kH{ #]feaeRFOf?<$'сCaV(XfTf{q֊?@⊲(gD;uFhHhhggh#hÈViMkti&DRMXmn(lB &ڸx▎؍먎w)uȇzhH|Q8Y y8(v#yI i (s)IRL&\(lȏHhw~&MXೃF;g1yCx2YA$h2d<3)xq&sӔ;xF%4xPwCI}V':ea%}rA.5MqIsѧq.!EMzatV_)l Zyq7FX,/VIŘU@^יHuz7Ňzv1c{x/Kg[x,8uDP 4 }q-sWq鈔i6~%~tœ7s Љs ynsx Ty|}Y>)OSxxߕswo9x!Ui~I䗝9,ژ |P'!N~~ ~,5}I(SUzi7>A78:D.i2:+ǣ ?J7ڜUq„/Iء:聳yR QJX`A$ҎSrdjAw8jBiڦYʦ[zs$3Dx̘z|ڧ~E#{Zzgڨ8Zz`(کC*iV2ezڧ Aȉ툃:Zϸ(Jf㫭"(A3 5R6ɺr"Kr ׺(jͪ@i@ z2Z @H&ٮ񮿊*?e| 1ʮ  +:RԊ°{;)R6!XvL8::$AƊ)Qв:a *;112+<[F{3V1*kNPHB'R[V{VZ\۵^`N;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9311185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/ScrolledFrame.html0000664000175000017500000004561000000000000020723 0ustar00gregmgregm00000000000000 Pmw.ScrolledFrame reference manual

Pmw.ScrolledFrame

Name

Pmw.ScrolledFrame() - frame with optional scrollbars

Inherits

Pmw.MegaWidget

Description

A scrolled frame consists of a scrollable interior frame within a clipping frame. The programmer can create other widgets within the interior frame. If the frame becomes larger than the surrounding clipping frame, the user can position the frame using the horizontal and vertical scrollbars.

The scrollbars can be dynamic, which means that a scrollbar will only be displayed if it is necessary. That is, if the frame is smaller than the surrounding clipping frame, the scrollbar will be hidden.

Options

Options for this megawidget and its base classes are described below.

borderframe
Initialisation option. If true, the borderframe component will be created. The default is 1.

horizflex
Specifies how the width of the scrollable interior frame should be resized relative to the clipping frame.

If 'fixed', the interior frame is set to the natural width, as requested by the child widgets of the frame. If 'expand' and the requested width of the interior frame is less than the width of the clipping frame, the interior frame expands to fill the clipping frame. If 'shrink' and the requested width of the interior frame is more than the width of the clipping frame, the interior frame shrinks to the width of the clipping frame. If 'elastic', the width of the interior frame is always set to the width of the clipping frame. The default is 'fixed'.

horizfraction
Initialisation option. The fraction of the width of the clipper frame to scroll the interior frame when the user clicks on the horizontal scrollbar arrows. The default is 0.05.

hscrollmode
The horizontal scroll mode. If 'none', the horizontal scrollbar will never be displayed. If 'static', the scrollbar will always be displayed. If 'dynamic', the scrollbar will be displayed only if necessary. The default is 'dynamic'.

labelmargin
Initialisation option. If the labelpos option is not None, this specifies the distance between the label component and the rest of the megawidget. The default is 0.

labelpos
Initialisation option. Specifies where to place the label component. If not None, it should be a concatenation of one or two of the letters 'n', 's', 'e' and 'w'. The first letter specifies on which side of the megawidget to place the label. If a second letter is specified, it indicates where on that side to place the label. For example, if labelpos is 'w', the label is placed in the center of the left hand side; if it is 'wn', the label is placed at the top of the left hand side; if it is 'ws', the label is placed at the bottom of the left hand side.

If None, a label component is not created. The default is None.

scrollmargin
Initialisation option. The distance between the scrollbars and the clipping frame. The default is 2.

usehullsize
Initialisation option. If true, the size of the megawidget is determined solely by the width and height options of the hull component.

Otherwise, the size of the megawidget is determined by the width and height of the clipper component, along with the size and/or existence of the other components, such as the label, the scrollbars and the scrollmargin option. All these affect the overall size of the megawidget. The default is 0.

vertflex
Specifies how the height of the scrollable interior frame should be resized relative to the clipping frame.

If 'fixed', the interior frame is set to the natural height, as requested by the child widgets of the frame. If 'expand' and the requested height of the interior frame is less than the height of the clipping frame, the interior frame expands to fill the clipping frame. If 'shrink' and the requested height of the interior frame is more than the height of the clipping frame, the interior frame shrinks to the height of the clipping frame. If 'elastic', the height of the interior frame is always set to the height of the clipping frame. The default is 'fixed'.

vertfraction
Initialisation option. The fraction of the height of the clipper frame to scroll the interior frame when the user clicks on the vertical scrollbar arrows. The default is 0.05.

vscrollmode
The vertical scroll mode. If 'none', the vertical scrollbar will never be displayed. If 'static', the scrollbar will always be displayed. If 'dynamic', the scrollbar will be displayed only if necessary. The default is 'dynamic'.

Components

Components created by this megawidget and its base classes are described below.

borderframe
A frame widget which snuggly fits around the clipper, to give the appearance of a border. It is created with a border so that the clipper, which is created without a border, looks like it has a border. By default, this component is a Tkinter.Frame.

clipper
The frame which is used to provide a clipped view of the frame component. If the borderframe option is true, this is created with a borderwidth of 0 to overcome a known problem with using place to position widgets: if a widget (in this case the frame component) is placed inside a frame (in this case the clipper component) and it extends across one of the edges of the frame, then the widget obscures the border of the frame. Therefore, if the clipper has no border, then this overlapping does not occur. By default, this component is a Tkinter.Frame.

frame
The frame within the clipper to contain the widgets to be scrolled. By default, this component is a Tkinter.Frame.

horizscrollbar
The horizontal scrollbar. By default, this component is a Tkinter.Scrollbar. Its component group is Scrollbar.

hull
This acts as the body for the entire megawidget. Other components are created as children of the hull to further specialise this class. By default, this component is a Tkinter.Frame.

label
If the labelpos option is not None, this component is created as a text label for the megawidget. See the labelpos option for details. Note that to set, for example, the text option of the label, you need to use the label_text component option. By default, this component is a Tkinter.Label.

vertscrollbar
The vertical scrollbar. By default, this component is a Tkinter.Scrollbar. Its component group is Scrollbar.

Methods

Only methods specific to this megawidget are described below. For a description of its inherited methods, see the manual for its base class Pmw.MegaWidget.

interior()
Return the frame within which the programmer may create widgets to be scrolled. This is the same as component('frame').

reposition()
Update the position of the frame component in the clipper and update the scrollbars.

Usually, this method does not need to be called explicitly, since the position of the frame component and the scrollbars are automatically updated whenever the size of the frame or clipper components change or the user clicks in the scrollbars. However, if horizflex or vertflex is 'expand', the megawidget cannot detect when the requested size of the frame increases to greater than the size of the clipper. Therefore, this method should be called when a new widget is added to the frame (or a widget is increased in size) after the initial megawidget construction.

xview(mode = None, value = None, units = None)
Query or change the horizontal position of the scrollable interior frame. If mode is None, return a tuple of two numbers, each between 0.0 and 1.0. The first is the position of the left edge of the visible region of the contents of the scrolled frame, expressed as a fraction of the total width of the contents. The second is the position of the right edge of the visible region.

If mode == 'moveto', adjust the view of the interior so that the fraction value of the total width of the contents is off-screen to the left. The value must be between 0.0 and 1.0.

If mode == 'scroll', adjust the view of the interior left or right by a fixed amount. If what is 'units', move the view in units of horizfraction. If what is pages, move the view in units of the width of the scrolled frame. If value is positive, move to the right, otherwise move to the left.

yview(mode = None, value = None, units = None)
Query or change the vertical position of the scrollable interior frame. If mode is None, return a tuple of two numbers, each between 0.0 and 1.0. The first is the position of the top edge of the visible region of the contents of the scrolled frame, expressed as a fraction of the total height of the contents. The second is the position of the bottom edge of the visible region.

If mode == 'moveto', adjust the view of the interior so that the fraction value of the total height of the contents is off-screen to the top. The value must be between 0.0 and 1.0.

If mode == 'scroll', adjust the view of the interior up or down by a fixed amount. If what is 'units', move the view in units of vertfraction. If what is pages, move the view in units of the height of the scrolled frame. If value is positive, move to down, otherwise move up.

Example

The image at the top of this manual is a snapshot of the window (or part of the window) produced by the following code.

class Demo:
    def __init__(self, parent):
        # Create the ScrolledFrame.
        self.sf = Pmw.ScrolledFrame(parent,
                labelpos = 'n', label_text = 'ScrolledFrame',
                usehullsize = 1,
                hull_width = 400,
                hull_height = 220,
        )

        # Create a group widget to contain the flex options.
        w = Pmw.Group(parent, tag_text='Flex')
        w.pack(side = 'bottom', padx = 5, pady = 3)

        hflex = Pmw.OptionMenu(w.interior(),
                labelpos = 'w',
                label_text = 'Horizontal:',
                items = ['fixed', 'expand', 'shrink', 'elastic'],
                command = self.sethflex,
                menubutton_width = 8,
        )
        hflex.pack(side = 'left', padx = 5, pady = 3)
        hflex.invoke('fixed')

        vflex = Pmw.OptionMenu(w.interior(),
                labelpos = 'w',
                label_text = 'Vertical:',
                items = ['fixed', 'expand', 'shrink', 'elastic'],
                command = self.setvflex,
                menubutton_width = 8,
        )
        vflex.pack(side = 'left', padx = 5, pady = 3)
        vflex.invoke('fixed')

        # Create a group widget to contain the scrollmode options.
        w = Pmw.Group(parent, tag_text='Scroll mode')
        w.pack(side = 'bottom', padx = 5, pady = 0)

        hmode = Pmw.OptionMenu(w.interior(),
                labelpos = 'w',
                label_text = 'Horizontal:',
                items = ['none', 'static', 'dynamic'],
                command = self.sethscrollmode,
                menubutton_width = 8,
        )
        hmode.pack(side = 'left', padx = 5, pady = 3)
        hmode.invoke('dynamic')

        vmode = Pmw.OptionMenu(w.interior(),
                labelpos = 'w',
                label_text = 'Vertical:',
                items = ['none', 'static', 'dynamic'],
                command = self.setvscrollmode,
                menubutton_width = 8,
        )
        vmode.pack(side = 'left', padx = 5, pady = 3)
        vmode.invoke('dynamic')

        self.radio = Pmw.RadioSelect(parent, selectmode = 'multiple',
            command = self.radioSelected)
        self.radio.add('center', text = 'Keep centered vertically')
        self.radio.pack(side = 'bottom')

        buttonBox = Pmw.ButtonBox(parent)
        buttonBox.pack(side = 'bottom')
        buttonBox.add('add', text = 'Add a button', command = self.addButton)
        buttonBox.add('yview', text = 'Show yview', command = self.showYView)
        buttonBox.add('scroll', text = 'Page down', command = self.pageDown)

        # Pack this last so that the buttons do not get shrunk when
        # the window is resized.
        self.sf.pack(padx = 5, pady = 3, fill = 'both', expand = 1)

        self.frame = self.sf.interior()

        self.row = 0
        self.col = 0

        for count in range(15):
            self.addButton()

    def sethscrollmode(self, tag):
        self.sf.configure(hscrollmode = tag)

    def setvscrollmode(self, tag):
        self.sf.configure(vscrollmode = tag)

    def sethflex(self, tag):
        self.sf.configure(horizflex = tag)

    def setvflex(self, tag):
        self.sf.configure(vertflex = tag)

    def addButton(self):
        button = Tkinter.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.sf.cget('horizflex') == 'expand' or \
                self.sf.cget('vertflex') == 'expand':
            self.sf.reposition()

        if 'center' in self.radio.getcurselection():
            self.sf.update_idletasks()
            self.centerPage()

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

    def showYView(self):
        print self.sf.yview()

    def pageDown(self):
        self.sf.yview('scroll', 1, 'page')

    def radioSelected(self, name, state):
        if state:
            self.centerPage()

    def centerPage(self):
        # Example of how to use the yview() method of Pmw.ScrolledFrame.
        top, bottom = self.sf.yview()
        size = bottom - top
        middle = 0.5 - size / 2
        self.sf.yview('moveto', middle)

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 18 February 2001

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9351187 Pmw-2.1/Pmw/Pmw_1_3_3/doc/ScrolledListBox.gif0000664000175000017500000000350600000000000021054 0ustar00gregmgregm00000000000000GIF87a0P`Âuuu,(0I8ͻ`(dihlp,tmx|+@dGry)*ɤ@ʬZ n!GbQ*hB|^x{~gdOedb}&nzm`Zw`NSo{Mmcv% | s iS/r r$#'q"B 8\a- ⃌q(PAs$bW0by¥rei&QA=4dtgLդH^|Bce?:RdTnݮKut,}+ Sp?ΰ57߳9NH29HS}F\iP]ٳ]1; uWv$qQ8dz1Özi9f=iOgPko~Z12FΟ&yb& *HNQ zwV?>&T*#eʙuT:"٢tQ"Lh`ݪF.ir]GDu"LvC/2cvXz\B+,X) Xn2P^+.&;ZBrʮP/9_RfX!o:_{jȺv*J 7dv C)%(,1!Ǽ0lY),ވ H#E+p&6`҉,b*y}fBmWdZKͬV/3+6#a,QݣiWh,t] /ykڲJg)Ngճ+Wté/wɟ09po޹:~&;{vT9һ+>YCyrb;[R<ɐ:"^2[|zG='&o;|x~8zkpݲrYpj@x4Cns?|̠7z &7 tJ W0D 8̡U8bǂ>H"P +4N:"R1F$B .z1O X"TFۄ~c !4Hcψ:jZb:ꑐmLd;8F'Jd-INNQ# _I3J|D%?yVQ ,E<Ҕ%L%*0KP2"Z$4%0b2$IUK]|8YJVZsL LNRrt'])wN_LgLi{$08\d>sVMhmZ3D'Zh@7trpt %JWpF2LgJӚ8ͩNwӞ@ jP˜sN PAf)iAKj^D-kĜƪV9>6AٛN,UoPLZ3Ԟl .u ],1"Z+UdBlU*cP-rê<&+KfٷmBy5VWtdzlgKGm4BHMr:Ѝt;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9311185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/ScrolledListBox.html0000664000175000017500000003320100000000000021246 0ustar00gregmgregm00000000000000 Pmw.ScrolledListBox reference manual

Pmw.ScrolledListBox

Name

Pmw.ScrolledListBox() - listbox with optional scrollbars

Inherits

Pmw.MegaWidget

Description

A scrolled listbox consists of a standard listbox widget with optional scrollbars which can be used to scroll the listbox. The scrollbars can be dynamic, which means that a scrollbar will only be displayed if it is necessary. That is, if the listbox does not contain enough entries, the vertical scrollbar will be automatically hidden and if the entries are not wide enough, the horizontal scrollbar will be automatically hidden.

Options

Options for this megawidget and its base classes are described below.

dblclickcommand
This specifies a function to call when mouse button 1 is double clicked over an entry in the listbox component. The default is None.

hscrollmode
The horizontal scroll mode. If 'none', the horizontal scrollbar will never be displayed. If 'static', the scrollbar will always be displayed. If 'dynamic', the scrollbar will be displayed only if necessary. The default is 'dynamic'.

items
Initialisation option. A tuple containing the initial items to be displayed by the listbox component. The default is ().

labelmargin
Initialisation option. If the labelpos option is not None, this specifies the distance between the label component and the rest of the megawidget. The default is 0.

labelpos
Initialisation option. Specifies where to place the label component. If not None, it should be a concatenation of one or two of the letters 'n', 's', 'e' and 'w'. The first letter specifies on which side of the megawidget to place the label. If a second letter is specified, it indicates where on that side to place the label. For example, if labelpos is 'w', the label is placed in the center of the left hand side; if it is 'wn', the label is placed at the top of the left hand side; if it is 'ws', the label is placed at the bottom of the left hand side.

If None, a label component is not created. The default is None.

scrollmargin
Initialisation option. The distance between the scrollbars and the listbox widget. The default is 2.

selectioncommand
This specifies a function to call when mouse button 1 is single clicked over an entry in the listbox component or if the <Space> or <Return> key is hit while the listbox has focus. The default is None.

usehullsize
Initialisation option. If true, the size of the megawidget is determined solely by the width and height options of the hull component.

Otherwise, the size of the megawidget is determined by the width and height of the listbox component, along with the size and/or existence of the other components, such as the label, the scrollbars and the scrollmargin option. All these affect the overall size of the megawidget. The default is 0.

vscrollmode
The vertical scroll mode. If 'none', the vertical scrollbar will never be displayed. If 'static', the scrollbar will always be displayed. If 'dynamic', the scrollbar will be displayed only if necessary. The default is 'dynamic'.

Components

Components created by this megawidget and its base classes are described below.

horizscrollbar
The horizontal scrollbar. By default, this component is a Tkinter.Scrollbar. Its component group is Scrollbar.

hull
This acts as the body for the entire megawidget. Other components are created as children of the hull to further specialise this class. By default, this component is a Tkinter.Frame.

label
If the labelpos option is not None, this component is created as a text label for the megawidget. See the labelpos option for details. Note that to set, for example, the text option of the label, you need to use the label_text component option. By default, this component is a Tkinter.Label.

listbox
The listbox widget which is scrolled by the scrollbars. By default, this component is a Tkinter.Listbox.

vertscrollbar
The vertical scrollbar. By default, this component is a Tkinter.Scrollbar. Its component group is Scrollbar.

Methods

Only methods specific to this megawidget are described below. For a description of its inherited methods, see the manual for its base class Pmw.MegaWidget. In addition, methods from the Tkinter.Listbox class are forwarded by this megawidget to the listbox component.

bbox(index)
This method is explicitly forwarded to the listbox component's bbox() method. Without this explicit forwarding, the bbox() method (aliased to grid_bbox()) of the hull would be invoked, which is probably not what the programmer intended.

clear()
Delete all items from the scrolled listbox. Equivalent to setlist(()).

get(first = None, last = None)
This is the same as the get() method of the listbox component, except that if first is None all list elements are returned.

getcurselection()
Same as getvalue() method.

getvalue()
Return a list of the currently selected items of the listbox.

setlist(items)
Replace all the items of the listbox component with those specified by the items sequence.

setvalue(textOrList)
Set the current selection for the scrolled list to textOrList.

If textOrList is a string, select only the list item specified.

Otherwise, select only the list items specified by textOrList, which must be a sequence of strings.

size()
This method is explicitly forwarded to the listbox component's size() method. Without this explicit forwarding, the size() method (aliased to grid_size()) of the hull would be invoked, which is probably not what the programmer intended.

Example

The image at the top of this manual is a snapshot of the window (or part of the window) produced by the following code.

class Demo:
    def __init__(self, parent):
        # Create the ScrolledListBox.
        self.box = Pmw.ScrolledListBox(parent,
                items=('Sydney', 'Melbourne', 'Brisbane'),
                labelpos='nw',
                label_text='Cities',
                listbox_height = 6,
                selectioncommand=self.selectionCommand,
                dblclickcommand=self.defCmd,
                usehullsize = 1,
                hull_width = 200,
                hull_height = 200,
        )

        # Create a group widget to contain the scrollmode options.
        w = Pmw.Group(parent, tag_text='Scroll mode')
        w.pack(side = 'bottom', padx = 5, pady = 5)

        hmode = Pmw.OptionMenu(w.interior(),
                labelpos = 'w',
                label_text = 'Horizontal:',
                items = ['none', 'static', 'dynamic'],
                command = self.sethscrollmode,
                menubutton_width = 8,
        )
        hmode.pack(side = 'top', padx = 5, pady = 5)
        hmode.invoke('dynamic')

        vmode = Pmw.OptionMenu(w.interior(),
                labelpos = 'w',
                label_text = 'Vertical:',
                items = ['none', 'static', 'dynamic'],
                command = self.setvscrollmode,
                menubutton_width = 8,
        )
        vmode.pack(side = 'top', padx = 5, pady = 5)
        vmode.invoke('dynamic')

        buttonBox = Pmw.ButtonBox(parent)
        buttonBox.pack(side = 'bottom')
        buttonBox.add('yview', text = 'Show\nyview', command = self.showYView)
        buttonBox.add('scroll', text = 'Page\ndown', command = self.pageDown)
        buttonBox.add('center', text = 'Center', command = self.centerPage)

        # Pack this last so that the buttons do not get shrunk when
        # the window is resized.
        self.box.pack(fill = 'both', expand = 1, padx = 5, pady = 5)

        # Do this after packing the scrolled list box, so that the
        # window does not resize as soon as it appears (because
        # alignlabels has to do an update_idletasks).
        Pmw.alignlabels((hmode, vmode))

        # Add some more entries to the listbox.
        items = ('Andamooka', 'Coober Pedy', 'Innamincka', 'Oodnadatta')
        self.box.setlist(items)
        self.box.insert(2, 'Wagga Wagga', 'Perth', 'London')
        self.box.insert('end', 'Darwin', 'Auckland', 'New York')
        index = list(self.box.get(0, 'end')).index('London')
        self.box.delete(index)
        self.box.delete(7, 8)
        self.box.insert('end', 'Bulli', 'Alice Springs', 'Woy Woy')
        self.box.insert('end', 'Wallumburrawang', 'Willandra Billabong')

    def sethscrollmode(self, tag):
        self.box.configure(hscrollmode = tag)

    def setvscrollmode(self, tag):
        self.box.configure(vscrollmode = tag)

    def selectionCommand(self):
        sels = self.box.getcurselection()
        if len(sels) == 0:
            print 'No selection'
        else:
            print 'Selection:', sels[0]

    def defCmd(self):
        sels = self.box.getcurselection()
        if len(sels) == 0:
            print 'No selection for double click'
        else:
            print 'Double click:', sels[0]

    def showYView(self):
        print self.box.yview()

    def pageDown(self):
        self.box.yview('scroll', 1, 'page')

    def centerPage(self):
        top, bottom = self.box.yview()
        size = bottom - top
        middle = 0.5 - size / 2
        self.box.yview('moveto', middle)

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 30 August 1998

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9311185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/ScrolledText.gif0000664000175000017500000002741700000000000020423 0ustar00gregmgregm00000000000000GIF87a6@@xxN @@tt$t 4@@&{ N0O @E-9$@@@ a}`^+9at`t$<^E-xL{t @@7+@Ixt@ @t@XtaX0"X_@Kx٘-8 N $_ ,|-&x/x @tx+ @@aa PzN\\R``l6݌8@$`<l@yPz@\\,kx + 6TXQk@@8$@t$|E-@@`y{Plz ,6 H*\ȰÇ#JHŋ3jȱ@CIɓ(S$ r˗0cʜI–6sɳO8 JQA*]ʴӈIJJΨVju#֮`ÊuٳhMK[e(]s87AE:xe^6ފ}#lϵ9~|Ί=%dёM>-Zu뺟Yy5齑SÖ9$GVmWxֳQLϓ# :纯_o^5pg4Κ|sӎ^c><;wӼs u%[zm^|]A(_~]_zz5`݇mmH!]bڇ)" wc8Xڂ3b$c u}-N %Q*yUCKiZlpt6fxҝz~*JI `衈&袉裐F*餔Vj饘f馜v駠^ A& RꪬRʧA :g:jAޚ+ĊWѱlTJQ->ӱMvK澔Rf;U.kaۭoQL*4A"|j0A*,0)A'2LgoqH%+lN#6Lq9\[M@\q96LSgٛE [AIHݳNaw-b6,R%}XӜUvMk}c6hSL]SKnY=1d}v҄^RrSβߝ; [_-Tdx[A!{l:2;;2 .ҥ5;-S9E }OO}zoSKT+_mo Hy2:'H ˠZVVFH(L)i,UR gHP8Nyʡ@"`F$"xh!b`$&q EBI񊆚"I0핯h| hD\;̢ 4x̣>z7*1dh?򑐌dB8V늈dn1ycD %8iJF!ʣ9GB$O)G0SJ6ϊTl!ǨE/ml|I3 e Ǜ 84]MҦ7i?;Gzўx4%YIBf{*u@FؙN&/h\JJ7(FMX6DhO||4IHѥUcڜ36Tth7U 4!k|J(QuFeJHzӗ &VOQfod&@=ESLZzoBUD.bk:JseztuBqi`Y_nժZgbQU$4B[:f;Y>5?zu4Z!'U,$U:=Ld]H]̀B׶ݩDk\"DM[jt#ElkKUS!k(Vʋkl\v6ZeFDO˂)Gܩ]fUM0UH6Ff.:rKuUziX?e]yuíDEzϷıV㮂WUTy/쐅W*IwdHO$nH.#r#.?yU$oy/nّ^N#f^Y:mrƧ;˲xO{W:d"epI!i8sarp~晟3igwN.۾6V}C =RsԻ}D4ۑ{nwx~;g)?ئ;9c-Ov,WӗKd):.k!M}+󘘡G~ 1r⑼$\q'~?Q'j9& /<}FY$t5{Kp!luc_O"MqKd}ieFbA#dt{nv'tuoklۧ]pSbwT\FnUKTlgi hawcVx<[+8~!EK#wu۷nZq4t:XmE 7vydhpe뇂d} WywTUzWX'iww]t#nyb(` oEnqIW|nIE0(ʕy3Gs6x|VRXUk!h'u-v@2]f8gzw~rHM,tjVwXUXhN/f_f(w6ShmrwJoL؄lkWNEX{hsht8!ru\Y?xd=58~Vp7yyH` ҉Hm'xO7_ͅmfVa;x(6ǁG|$e|XO:|=8\0G"6{ǁiX'ubď !}Q6vgOQ=uF~7הYIX[Yg]UYa~Xl>QjvG3pba4Y wXHXQJؗ9(\jF&&nZtvs{v/xq3zw7XƃHwi]⋐_ yyTbP/caljVGhu68e2jTg]=UkLau(WɆ`ɛ{9Hki]|h}ce肸xv(y8y6TT`iVv3q#՚v(%(b&7IIg iHhȋxߘja+Iy[ iىUzJvvɖa'&kyu6!uQ6)Xt7n㈆twPxd 2w9q U.jnSS9JC8IؑhIB8z)gRƝb)8z(wqے'%Ʌc?5[ڈ~ tRxNtʤ,H0ꒅ~v2瓤-J_K5:w{mUh Jr5ۡŹq-piyJacz0#a**ڊ1H;vvl : ؓ@餳h愼WI9}ZG'a諸D?ʭdǬB’$B^#C*,e,.J[fڿi y(랛mۗJhfĆ cb;KÖ [ڻ˚;OYMJ_ &Fc5 I7q-sm:x׀=1tv-:A؅mW:˦z#k@B H1)χ d%_؉2I<ǵPzƛ&qƏצi; hSo}0Mtg˚[n|s}]L6[3`F;ݺS{ 'ݮ6H>l<:ƹܧd`׽ۋ̾|hL\{urM̏ н #;)ߣ}RNkѸ-Ba@=(,.0޻܅E߾h]ۖ8T/&ͰMD>lR^;=F#4$L%+H=jUMUM2'b*ц#\Ih=k]ozҍ] }$ٓu~gv~NóGn~_g\׏!nGmXc˘|IsKiXMEv4 .rø]ߟ ܅L S>ܫJ m}}L@B\]ѻ(}ma܁+ɂx4N&ޜNx ݢ f^.-9pj>MۥXKJb jI= | ،|/9})>uG}R ȥ4o\VoXݸ6Р87Xrbl_npvOE('qҽK{,C* DʾesVǾS ڞ6r {Bͻ, UM]s[pIlM}4q>ז댝ۿDE_~\#8oK $PB xaB%RhPʼnrqcE/|QHE|II-;0P*wTN4(QJ^- 0+֫Z n+XUC$ڨNT k~| eǻ2S 8D  xx!bL=R[މaǎW9?\i[~U/t1þ<˵&أ `9D唏;8v_(q{@-rFǍZ7푳N/[=gƃ#WhйVb 6B J|CQEEDg,-.+9+PR%$-BT#kIGPJ5+E26Z#/\vhĔbJS^ShעR>+ܮ4l-brB 3D-}v&hԺa\j˦uť]b48lmO|qXI{ =SԾ/MfYbE6j5Ed>5_g?RyѧV]Yw:?Kb9a[ʄPuml䓖ַwUxqmwDE Ms] %kF55NaJJ  M=b>aIEt=™zR{Dz3tІ!\堮EixR WVA Ҍ|" Ʌ*^e,.U{:Bix[ v~? d|W?t'%-E9wZ0X>0s0ٜ?7jn%[Ĭ2Y#X1*iش i1!uMqf[X05*D'W̹Nvzx 3װr3ϢA9o g:М%v2QRTTJiE6+vòRd!f^5ymmTмf\ˋ_jџTԧhX= ˠ[4YS/ZSWx'O< ϛL5s@T@kZպ֠l2TQ+Ef1=SňͬqD=k$H8rĎ^o&[kdE{9Kꦌ _h׺|u߈>MkX&Rr=duKY>JfF^Lv,dUX- ;Z2#8ͦ~.pZ7$֪dVJ*8*Tz5TCgE4ɆU$xX_R%~]T|G_0ZȾ-/[9N82I!!YI/9*V*XE]'8#z \2jUsR}xIL ۑֆq]<ϸm&KhU8`/sEw2{p]rܖa活bi'eW#kMVMnxbFA sNB#FYF:=miR/Z#n\GҧFue0XW)jbͥ?ʯzPs.lA ӲɌm/p[e6s k*zNѬlI`NSq;-i. r{v FGRCga (uݣ9v ;nӣCtcp`W7A9^zg/R5¡B:]MF]~Q\#XY~wVcyo֜c^r^Y@4Ek?l{:d 2쫻̋w"JKK+YB<; SZsY@=۾V@TԾk tA$a "[!f: 6x6{kA&!Zd۳t9B.[*+0k?(%LѣS!ۻ~cj*+0ڎ,GJ;ܷ׃Hc8C$Ե <; 8Ւ雷z*k7,/b7%7m ȱÖ[:DD#Bhj9 WåcJ*DbS6dk,2D$_r6㠽M9lyLŗ-uKES1~<=K <,[B\K7ȄO(5(! B)4h;NjA0[?6RUZplSJIlO}+I͍F`8eݹόЀW5u!J}] `_e6[`-\.4<7!\ Fo ʕe2FCa\ -Pͮb_tT ?q6biU[-4OfQbk#f$T[C [U$.]e}E,VuN{kC-_Υ>OWԇ\)Ne5-@MNQպgT|;HQdUڤ<[FaQd!)M\D<{ 0>5 tvgb-n7>锭IkQ|baw@vW%n(~b(.M¦Խa'Nl,e{_al>ŎlzY{e9 `ۏ\f(<ˬ 5NDZ#ũlT {j$j4ܟlIߗv[AƢ+UNNdc#&o׼d5d;ek^FUם8KT/9#FP^x^Jz.&oRg;n^\[mf叴k2c%Pݫ:D_;;ݳGQ-fozggRGq); [uDko^ҷ剞qjΚo\m2Z=EhP^fpo s>r/܏p^]D>Ga&Twa r}9As =3DTfnIf\]si3pX}I*U,mk.F?_YE ܬ}3n޾9ZfLJ~H;Np&&mke8l^YhfM9A|&Wlvlv:vrwwoa͆|wxahqkk7wu_b|?xrgp'7GWg t6yo 羈'/xO2W!FwzL'7GWzy7'GyW0F혾Mgɧʷ|T||~|οG;zcG}oo}?]7 x *} : J8Zx!j`z!!P#x")^W-"/;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9311185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/ScrolledText.html0000664000175000017500000003574200000000000020622 0ustar00gregmgregm00000000000000 Pmw.ScrolledText reference manual

Pmw.ScrolledText

Name

Pmw.ScrolledText() - text widget with optional scrollbars

Inherits

Pmw.MegaWidget

Description

A scrolled text consists of a standard text widget with optional scrollbars which can be used to scroll the text. The scrollbars can be dynamic, which means that a scrollbar will only be displayed if it is necessary. That is, if the text widget does not contain enough text (either horizontally or vertically), the scrollbar will be automatically hidden. If it is displayed, the horizontal scrollbar is under the text widget. Similarly, if it is displayed, the vertical scrollbar is to the right of the text widget.

Row and column headers may also be displayed, which scroll in sync with the text widget and may be useful when displaying tabular data. To assist in ensuring that columns line up when using a column header, a fixed width font should be used.

Options

Options for this megawidget and its base classes are described below.

borderframe
Initialisation option. If true, the borderframe component will be created. The default is 0.

columnheader
Initialisation option. If true, the columnheader component will be created. The default is 0.

hscrollmode
The horizontal scroll mode. If 'none', the horizontal scrollbar will never be displayed. If 'static', the scrollbar will always be displayed. If 'dynamic', the scrollbar will be displayed only if necessary. The default is 'dynamic'.

labelmargin
Initialisation option. If the labelpos option is not None, this specifies the distance between the label component and the rest of the megawidget. The default is 0.

labelpos
Initialisation option. Specifies where to place the label component. If not None, it should be a concatenation of one or two of the letters 'n', 's', 'e' and 'w'. The first letter specifies on which side of the megawidget to place the label. If a second letter is specified, it indicates where on that side to place the label. For example, if labelpos is 'w', the label is placed in the center of the left hand side; if it is 'wn', the label is placed at the top of the left hand side; if it is 'ws', the label is placed at the bottom of the left hand side.

If None, a label component is not created. The default is None.

rowcolumnheader
Initialisation option. If true, the rowcolumnheader component will be created. The default is 0.

rowheader
Initialisation option. If true, the rowheader component will be created. The default is 0.

scrollmargin
Initialisation option. The distance between the scrollbars and the text widget. The default is 2.

usehullsize
Initialisation option. If true, the size of the megawidget is determined solely by the width and height options of the hull component.

Otherwise, the size of the megawidget is determined by the width and height of the text component, along with the size and/or existence of the other components, such as the label, the scrollbars and the scrollmargin option. All these affect the overall size of the megawidget. The default is 0.

vscrollmode
The vertical scroll mode. If 'none', the vertical scrollbar will never be displayed. If 'static', the scrollbar will always be displayed. If 'dynamic', the scrollbar will be displayed only if necessary. The default is 'dynamic'.

Components

Components created by this megawidget and its base classes are described below.

borderframe
A frame widget which snuggly fits around the text widget, to give the appearance of a text border. It is created with a border so that the text widget, which is created without a border, looks like it has a border. By default, this component is a Tkinter.Frame.

columnheader
A text widget with a default height of 1 displayed above the main text widget and which scrolls horizontally in sync with the horizontal scrolling of the main text widget. By default, this component is a Tkinter.Text. Its component group is Header.

horizscrollbar
The horizontal scrollbar. By default, this component is a Tkinter.Scrollbar. Its component group is Scrollbar.

hull
This acts as the body for the entire megawidget. Other components are created as children of the hull to further specialise this class. By default, this component is a Tkinter.Frame.

label
If the labelpos option is not None, this component is created as a text label for the megawidget. See the labelpos option for details. Note that to set, for example, the text option of the label, you need to use the label_text component option. By default, this component is a Tkinter.Label.

rowcolumnheader
A text widget displayed to the top left of the main text widget, above the row header and to the left of the column header if they exist. The widget is not scrolled automatically. By default, this component is a Tkinter.Text. Its component group is Header.

rowheader
A text widget displayed to the left of the main text widget and which scrolls vertically in sync with the vertical scrolling of the main text widget. By default, this component is a Tkinter.Text. Its component group is Header.

text
The text widget which is scrolled by the scrollbars. If the borderframe option is true, this is created with a borderwidth of 0 to overcome a known problem with text widgets: if a widget inside a text widget extends across one of the edges of the text widget, then the widget obscures the border of the text widget. Therefore, if the text widget has no border, then this overlapping does not occur. By default, this component is a Tkinter.Text.

vertscrollbar
The vertical scrollbar. By default, this component is a Tkinter.Scrollbar. Its component group is Scrollbar.

Methods

Only methods specific to this megawidget are described below. For a description of its inherited methods, see the manual for its base class Pmw.MegaWidget. In addition, methods from the Tkinter.Text class are forwarded by this megawidget to the text component.

appendtext(text)
Add text to the end of the text component. Scroll to the bottom of the text, but only if it was already visible before the new text was added.

bbox(index)
This method is explicitly forwarded to the text component's bbox() method. Without this explicit forwarding, the bbox() method (aliased to grid_bbox()) of the hull would be invoked, which is probably not what the programmer intended.

clear()
Delete all text from the text component.

exportfile(fileName)
Write the contents of the text component to the file fileName.

get(first = None, last = None)
This is the same as the get() method of the text component, except that if first is None the entire contents of the text widget are returned.

getvalue()
Return the entire contents of the text widget.

importfile(fileName, where = 'end')
Read the contents of the file fileName and insert into the text component at the position given by where.

settext(text)
Same as setvalue() method.

setvalue(text)
Replace the entire contents of the text component with text.

Example

The image at the top of this manual is a snapshot of the window (or part of the window) produced by the following code.

class Demo:
    def __init__(self, parent):

        # Create the ScrolledText with headers.
        fixedFont = Pmw.logicalfont('Fixed')
        self.st = Pmw.ScrolledText(parent,
                # borderframe = 1,
                labelpos = 'n',
                label_text='ScrolledText with headers',
                columnheader = 1,
                rowheader = 1,
                rowcolumnheader = 1,
                usehullsize = 1,
                hull_width = 400,
                hull_height = 300,
                text_wrap='none',
                text_font = fixedFont,
                Header_font = fixedFont,
                Header_foreground = 'blue',
                rowheader_width = 3,
                rowcolumnheader_width = 3,
                text_padx = 4,
                text_pady = 4,
                Header_padx = 4,
                rowheader_pady = 4,
        )

        self.st.pack(padx = 5, pady = 5, fill = 'both', expand = 1)

        funcs = 'atan cos cosh exp log log10 sin sinh sqrt tan tanh'
        funcs = string.split(funcs)

        # Create the header for the row headers
        self.st.component('rowcolumnheader').insert('end', 'x')

        # Create the column headers
        headerLine = ''
        for column in range(len(funcs)):
            headerLine = headerLine + ('%-7s   ' % (funcs[column],))
        headerLine = headerLine[:-3]
        self.st.component('columnheader').insert('0.0', headerLine)

        self.st.tag_configure('yellow', background = 'yellow')

        # Create the data rows and the row headers
        numRows = 50
        tagList = []
        for row in range(1, numRows):
            dataLine = ''
            x = row / 5.0
            for column in range(len(funcs)):
                value = eval('math.' + funcs[column] + '(' + str(x) + ')')
                data = str(value)[:7]
                if value < 0:
                    tag1 = '%d.%d' % (row, len(dataLine))
                    tag2 = '%d.%d' % (row, len(dataLine) + len(data))
                    tagList.append(tag1)
                    tagList.append(tag2)
                data = '%-7s' % (data,)
                dataLine = dataLine + data + '   '
            dataLine = dataLine[:-3]
            header = '%.1f' % (x,)
            if row < numRows - 1:
                dataLine = dataLine + '\n'
                header = header + '\n'
            self.st.insert('end', dataLine)
            self.st.component('rowheader').insert('end', header)
        apply(self.st.tag_add, ('yellow',) + tuple(tagList))

        # Prevent users' modifying text and headers
        self.st.configure(
            text_state = 'disabled',
            Header_state = 'disabled',
        )

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 30 August 1998

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9351187 Pmw-2.1/Pmw/Pmw_1_3_3/doc/ScrolledText_test.py0000664000175000017500000000644300000000000021341 0ustar00gregmgregm00000000000000# Based on iwidgets2.2.0/tests/scrolledtext.test code. import Test import Pmw Test.initialise() c = Pmw.ScrolledText def _testYView(doBottom): w = Test.currentWidget() top, bottom = w.yview() if type(top) != type(0.0) or type(bottom) != type(0.0): return 'bad type ' + str(top) + ' ' + str(bottom) if doBottom: if bottom != 1.0: return 'bottom is ' + str(bottom) else: if top != 0.0: return 'top is ' + str(top) kw_1 = {'labelpos': 'n', 'label_text': 'ScrolledText'} tests_1 = ( (c.pack, (), {'padx' : 10, 'pady' : 10, 'fill' : 'both', 'expand' : 1}), (Test.num_options, (), 10), (c.importfile, 'ScrolledText_test.py'), ('hull_background', 'aliceblue'), ('text_borderwidth', 3), ('Scrollbar_borderwidth', 3), ('hull_cursor', 'gumby'), ('text_exportselection', 0), ('text_exportselection', 1), ('text_foreground', 'Black'), ('text_height', 10), ('text_width', 20), ('text_insertbackground', 'Black'), ('text_insertborderwidth', 1), ('text_insertofftime', 200), ('text_insertontime', 500), ('text_insertwidth', 3), ('label_text', 'Label'), ('text_relief', 'raised'), ('text_relief', 'sunken'), ('Scrollbar_repeatdelay', 200), ('Scrollbar_repeatinterval', 105), ('vscrollmode', 'none'), ('vscrollmode', 'static'), ('vscrollmode', 'dynamic'), ('hscrollmode', 'none'), ('hscrollmode', 'static'), ('hscrollmode', 'dynamic'), ('Scrollbar_width', 20), ('text_selectborderwidth', 2), ('text_state', 'disabled'), ('text_state', 'normal'), ('text_background', 'GhostWhite'), ('text_wrap', 'char'), ('text_wrap', 'none'), ('vscrollmode', 'bogus', 'ValueError: bad vscrollmode ' + 'option "bogus": should be static, dynamic, or none'), ('hscrollmode', 'bogus', 'ValueError: bad hscrollmode ' + 'option "bogus": should be static, dynamic, or none'), (c.cget, 'vscrollmode', 'bogus'), (c.cget, 'hscrollmode', 'bogus'), ('vscrollmode', 'dynamic'), ('hscrollmode', 'dynamic'), (c.insert, ('end', 'Hello there\n')), (_testYView, 0), (c.yview, ('moveto', 0.02)), (c.yview, ('moveto', 0.04)), (c.yview, ('moveto', 0.06)), (c.yview, ('moveto', 0.08)), (c.yview, ('moveto', 0.10)), (c.yview, ('moveto', 0.12)), (c.yview, ('moveto', 0.14)), (c.yview, ('moveto', 0.16)), (c.yview, ('moveto', 0.18)), (c.yview, ('moveto', 0.20)), (c.yview, ('moveto', 0.22)), (c.yview, ('moveto', 0.24)), (c.yview, ('moveto', 0.26)), (c.yview, ('moveto', 0.28)), (c.yview, ('moveto', 0.98)), (_testYView, 1), (c.yview, ('scroll', -1, 'page')), (c.yview, ('scroll', -50, 'page')), (_testYView, 0), (c.yview, ('scroll', 1, 'page')), (c.yview, ('scroll', 50, 'page')), (_testYView, 1), (c.clear, ()), (c.get, (), '\n'), ) kw_2 = { 'hscrollmode' : 'dynamic', 'label_text' : 'Label', 'labelpos' : 'n', 'scrollmargin': 20, } tests_2 = ( (c.pack, (), {'padx' : 10, 'pady' : 10, 'fill' : 'both', 'expand' : 1}), (c.importfile, 'ScrolledText_test.py'), ('text_relief', 'raised'), ('text_relief', 'sunken'), ) alltests = ( (tests_1, kw_1), (tests_2, kw_2), ) testData = ((Pmw.ScrolledText, alltests),) if __name__ == '__main__': Test.runTests(testData) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9311185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/SelectionDialog.gif0000664000175000017500000000620700000000000021046 0ustar00gregmgregm00000000000000GIF87aÂ`w`0;uuu,I56ͻ`(Ulpjx~|pH,.l:ШtL1GvfAOu w̵UaN~xpd~v|}rc;s}uyt|{ɹΕtzy߳ѴNSr;gj.4~ŃF2X]NI|r 'ζ8f*-f^cˮy1䬼=[r.tmնs''$:ޖyܛ2!nM8xpe;k>o$"(&nCPl¶mcwgAS<87*1Y[#Fq+!'EJ1yd$y\ERtFLIA"FIROCI ,gIZ̥.w^eDbL2:p$+aI c`̦6)fr|#yM_L:s2<8)ulGiD,:O|3OW,8)QZTiI>gE1JҒR$xm@_:ҙԢ5-M ӝ5FOOaFhT:Ѫ2 jUiF9ղ"SjWVՐjJ׳:K^eVu=h_ՊMb:d'Kld. vRpAIgnE\FZpsZFimKd̲0[+owަv0tk"TgLb՘\ӦeK9}Sns}W-#wKz6Lr^wMdշֵ)W/-0|I70B{%'L0 OnRg!xĐUy baTJ La'LqFQq+H$OH, Lo>1⑩\!(l\A21u5Өn 9ٵ5|7y}^]]+շ:&<Ybf%8AHY/&y^~r jL6"$P0p-]j] WXeZ(&SݣC mJǭv lDklMpw7tsqήmΛzc 0.8+û7x򫸽1^eoz6EqOGU^pe>o9umk:niCF:hw:gkz5oyn7HaF;>nv}pwwrK}B?k0Oʾ[񐏼'ǫVϼ7roC!ב~\7>=Lw$b=쯋ٓ-Ӷs/p'"O}vO=OL֏0O7mnvF_oB/4v?⣿?M~yr?FqW{jx"4V􇀆u€6~H'mz7w8tԁ bh(X*ޗ "6&5Tb"rqn %@i":D"(l5+hc&44#kb#OgQ"@B9x9eh#4eEԅGddȅ&df8`\z2()7"IiSxc^X&Uh(##4lˆh3uvÇ؉T8exXlIT@-艟,l4HA?聻؊'r{˜dRG-ll}2h1h_)8ȋz G)Ph'x!'H 4x&(z~XDh&X8(v8׏o2[88wyi"}oi_%i8D+~'y4x:ICo:5iB~}I@9PFEHi|cPR !VyX>"$j`b@d)hhXBZrIp;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9311185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/SelectionDialog.html0000664000175000017500000002334700000000000021251 0ustar00gregmgregm00000000000000 Pmw.SelectionDialog reference manual

Pmw.SelectionDialog

Name

Pmw.SelectionDialog() - selection dialog displaying a scrolled list

Inherits

Pmw.Dialog

Description

The selection dialog is a dialog window which displays a scrolled list which can be used to prompt the user for a value.

Options

Options for this megawidget and its base classes are described below.

activatecommand
If this is callable, it will be called whenever the megawidget is activated by a call to activate(). The default is None.

borderx
Initialisation option. The padding to the left and right of the scrolled list. The default is 10.

bordery
Initialisation option. The padding above and below the scrolled list. The default is 10.

buttonboxpos
Initialisation option. Specifies on which side of the dialog window to place the button box. Must be one of 'n', 's', 'e' or 'w'. The default is 's'.

buttons
This must be a tuple or a list and specifies the names on the buttons in the button box. The default is ('OK',).

command
Specifies a function to call whenever a button in the button box is invoked or the window is deleted by the window manager. The function is called with a single argument, which is the name of the button which was invoked, or None if the window was deleted by the window manager.

If the value of command is not callable, the default behaviour is to deactivate the window if it is active, or withdraw the window if it is not active. If it is deactivated, deactivate() is called with the button name or None as described above. The default is None.

deactivatecommand
If this is callable, it will be called whenever the megawidget is deactivated by a call to deactivate(). The default is None.

defaultbutton
Specifies the default button in the button box. If the <Return> key is hit when the dialog has focus, the default button will be invoked. If defaultbutton is None, there will be no default button and hitting the <Return> key will have no effect. The default is None.

master
This is used by the activate() method to control whether the window is made transient during modal dialogs. See the activate() method. The default is 'parent'.

separatorwidth
Initialisation option. If this is greater than 0, a separator line with the specified width will be created between the button box and the child site, as a component named separator. Since the default border of the button box and child site is raised, this option does not usually need to be set for there to be a visual separation between the button box and child site. The default is 0.

title
This is the title that the window manager displays in the title bar of the window. The default is None.

Components

Components created by this megawidget and its base classes are described below.

buttonbox
This is the button box containing the buttons for the dialog. By default it is created with the options (hull_borderwidth = 1, hull_relief = 'raised'). By default, this component is a Pmw.ButtonBox.

dialogchildsite
This is the child site for the dialog, which may be used to specialise the megawidget by creating other widgets within it. By default it is created with the options (borderwidth = 1, relief = 'raised'). By default, this component is a Tkinter.Frame.

hull
This acts as the body for the entire megawidget. Other components are created as children of the hull to further specialise this class. By default, this component is a Tkinter.Toplevel.

scrolledlist
The scrolled list for the user to enter a value. By default, this component is a Pmw.ScrolledListBox.

separator
If the separatorwidth initialisation option is non-zero, the separator component is the line dividing the area between the button box and the child site. By default, this component is a Tkinter.Frame.

Component aliases

Sub-components of components of this megawidget may be accessed via the following aliases.

label
Alias for scrolledlist_label.
listbox
Alias for scrolledlist_listbox.

Methods

Only methods specific to this megawidget are described below. For a description of its inherited methods, see the manual for its base class Pmw.Dialog. In addition, methods from the Pmw.ScrolledListBox class are forwarded by this megawidget to the scrolledlist component.

bbox(index)
This method is explicitly forwarded to the listbox component's bbox() method. Without this explicit forwarding, the bbox() method (aliased to grid_bbox()) of the hull would be invoked, which is probably not what the programmer intended.

size()
This method is explicitly forwarded to the listbox component's size() method. Without this explicit forwarding, the size() method (aliased to grid_size()) of the hull would be invoked, which is probably not what the programmer intended.

Example

The image at the top of this manual is a snapshot of the window (or part of the window) produced by the following code.

class Demo:
    def __init__(self, parent):
        # Create the dialog.
        self.dialog = Pmw.SelectionDialog(parent,
            title = 'My SelectionDialog',
            buttons = ('OK', 'Cancel'),
            defaultbutton = 'OK',
            scrolledlist_labelpos = 'n',
            label_text = 'What do you think of Pmw?',
            scrolledlist_items = ('Cool man', 'Cool', 'Good', 'Bad', 'Gross'),
            command = self.execute)
        self.dialog.withdraw()

        # Create button to launch the dialog.
        w = Tkinter.Button(parent, text = 'Show selection dialog',
                command = self.dialog.activate)
        w.pack(padx = 8, pady = 8)

    def execute(self, result):
        sels = self.dialog.getcurselection()
        if len(sels) == 0:
            print 'You clicked on', result, '(no selection)'
        else:
            print 'You clicked on', result, sels[0]
        self.dialog.deactivate(result)

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 18 May 2002

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9311185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/TextDialog.gif0000664000175000017500000001156000000000000020043 0ustar00gregmgregm00000000000000GIF87aj`w`0;,jx^.I8ͻ`(Dbylp,ϩgxpH,Ȥrl:_SDجvzժBz>/oˍ~?v7&vtÎS ͼӍۍˣsȦ穴ц>#&."FGj{71ڼet#$T $X1J(УKx ]t"8gQ˟iXDD%Ўٔi57ӯ,dJѢI X(ZO/RWⳬurWȾ-9d€eף5t+TZ{ރإѳh-jx蠧;'|d>kosļU+z)8JRZ7)&Ow9_ccEߞZ|3<:#޼+.p EϿAŀh& F(Vhfv ($h0(4h8<@)D)IhL6PF)S" Tf\vKZy؊`ihbp)t &o֩|S砄jI袌6"d:*餔 )fT^*(**jꩨXj骮*+j|֊++*6,liˬe:Kb& ݎ"6im@Fkܺhn+.~.LKp\o +۫{_c>.#z)(oK2";35ܲ32Oo [1#>hC/voWKCMc^j]1bmr$vavL ,>7:h 8+[a *:Nflw砇.褗n騧ꬷۨ,.9c|nGOC|/}?J|~.fDvo^=}_ `Ǿz{'戀[_⧪ρ׽RyL^G oxVf;0aЅ0)H9$Y*aAч["Qx¯=?DA>tU@/Q$Lqj\# =?-Hq5d7QnJB? S[\WߔeFȼFP!hH7l%g#eo6[[ܶ6E.Ғ?Z)įTiV$>ʥQ g3%&K6e1m)--sb8ZrhTK܆2)L+q&̖$eҘrmӜbd+ʠ3_XOpvF4xHi 9/m Bʀ] TFe9ю>o-&QdhImP@2PLgJQӘ&$2)KHT)Es:ԛ"'OsZJ.,f!GU0?#ŅfA>UG5ظշyl f9JL󟚔*'ZИnZ 4*XbuhҺ&Կ>'5<ӶXʴ+Uqb*pM-lQڴBl,Z1:ۭի;]XRX{Ɖ fZtԲ9nׇd ;yQj2yeOysU$׎ ֦Iαe~5J\4ϑG(ǰ.1LX=օo .^Ft^+V=p|v祙=.Vm-\URtd7V񌜮# jZؒ-em^ZTlca=Aj~>6-Jwna"6J0n9w׾$p o8[.c;~ƜMmr?ww%\ g`'ig\xq;;R2^O2fu}í?2yDŽ6U+>s0qdsnW|Ⴓ=E˸Xf.mo>԰QMyMQy8oﳯ:_eoʺW; ROO'پ`^x<=gVG^#o㗺b:m'8=B=MW>"MKkJU4f; f NK u2ӼμOzO_)#ox? ~ЋO0x'&+d~ۇԢ6GĀGbYH|– ,F'(,)Xs++-(/"q$a35xr7q9h+1Md{uFe]r91qWn;8z'Q#vX*GIM5rNmKڗrg(Zs$OX$yBB7ldeWEfNwjwMrvyZOgJx"wqFgsN7fxLBVG{[Uu#e4vk˕\u` X] `[x?QtW[GVx\zGV&oJkH`w\>Gljh]DWSkuWru{j0vXll7ToxhwwUF[%y(iGjkiEψulH(zTa%4v4yP=e6n Y][yzhǘ\`^Gvrl]_,'xF;i2GtX1VVIo_}m_IJ6_gCu1ɏӓ~n7Gi6W!x _:oY)YgyHPaVZV[tƝ=qwQ9Xk(ٍ\Ԝ/IyY کv9kmKɔy)^VHj%RğǠYo vUHM`tU+{âvɞx ,an"GbȤP@ڒxSUW Y:*Rbj*dZrh *jҦn)p2tz}[:O٢wZ)vڧ򧀪(jڎňHMs|ècgw^d>dS*I6'dƌQcmrH'aʡTDYOf(O{ؘƈ_rX'Z{X^DzN65wm845Ϊ0@$& X5z&j ]'ؐJF*H"4H؉`!u)i8f0舛u`(LB;YyhH^ExZyzyXŬ1Se){ywVtjLfىl:铼(3N EGKdKܖ_{oenWOfU{F]k$e\qslʲKJK{0[_[a({!;v#a($ M!vfB 8ʷ7VĒ\zPYe6D%zڥ|ʚ'0LGڇwˋ[{C ûVՔK- \SJeWGR+$CD{j\˱IwߨؾڃeAږlkkr{K'n+l9jԩ\{u4B~iyA{w=T†'VZዓ@һ8f@do7W Ň /׼tl:>仓OA E6vd\ _ 3z #"|~ǀȂ<&"aǶCȊȌȎȁL;v 5Srɘ|-ɞ\,ʻ2ʤ|+|ʍcAɬʟʰ,I<|˸˺˼˛$<\Dz<˥ʌ̫~м<\͔=L:#ʃ3`C΀#_B̓B,eΐ͘C`"B<7%|жA7%8 %A M7%@7%@63!-@#5%)@+m#1m?34-#9]?;3= cr1t.-b8]0ӟΕ%]Υ}Χ)-ԫ ͩRF۵ϱp[QM|R؛͸}(܅=(]}rؽ'=ޜ r9 2&|=](6-~~IPE;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9351187 Pmw-2.1/Pmw/Pmw_1_3_3/doc/TextDialog.html0000664000175000017500000002363100000000000020244 0ustar00gregmgregm00000000000000 Pmw.TextDialog reference manual

Pmw.TextDialog

Name

Pmw.TextDialog() - a dialog displaying a scrolled text

Inherits

Pmw.Dialog

Description

A text dialog is a dialog window which displays a text message to the user along with one or more buttons to press.

Options

Options for this megawidget and its base classes are described below.

activatecommand
If this is callable, it will be called whenever the megawidget is activated by a call to activate(). The default is None.

borderx
Initialisation option. The padding to the left and right of the scrolled text. The default is 10.

bordery
Initialisation option. The padding above and below the scrolled text. The default is 10.

buttonboxpos
Initialisation option. Specifies on which side of the dialog window to place the button box. Must be one of 'n', 's', 'e' or 'w'. The default is 's'.

buttons
This must be a tuple or a list and specifies the names on the buttons in the button box. The default is ('OK',).

command
Specifies a function to call whenever a button in the button box is invoked or the window is deleted by the window manager. The function is called with a single argument, which is the name of the button which was invoked, or None if the window was deleted by the window manager.

If the value of command is not callable, the default behaviour is to deactivate the window if it is active, or withdraw the window if it is not active. If it is deactivated, deactivate() is called with the button name or None as described above. The default is None.

deactivatecommand
If this is callable, it will be called whenever the megawidget is deactivated by a call to deactivate(). The default is None.

defaultbutton
Specifies the default button in the button box. If the <Return> key is hit when the dialog has focus, the default button will be invoked. If defaultbutton is None, there will be no default button and hitting the <Return> key will have no effect. The default is None.

master
This is used by the activate() method to control whether the window is made transient during modal dialogs. See the activate() method. The default is 'parent'.

separatorwidth
Initialisation option. If this is greater than 0, a separator line with the specified width will be created between the button box and the child site, as a component named separator. Since the default border of the button box and child site is raised, this option does not usually need to be set for there to be a visual separation between the button box and child site. The default is 0.

title
This is the title that the window manager displays in the title bar of the window. The default is None.

Components

Components created by this megawidget and its base classes are described below.

buttonbox
This is the button box containing the buttons for the dialog. By default it is created with the options (hull_borderwidth = 1, hull_relief = 'raised'). By default, this component is a Pmw.ButtonBox.

dialogchildsite
This is the child site for the dialog, which may be used to specialise the megawidget by creating other widgets within it. By default it is created with the options (borderwidth = 1, relief = 'raised'). By default, this component is a Tkinter.Frame.

hull
This acts as the body for the entire megawidget. Other components are created as children of the hull to further specialise this class. By default, this component is a Tkinter.Toplevel.

scrolledtext
The scrolled text to contain the text for the dialog. By default, this component is a Pmw.ScrolledText.

separator
If the separatorwidth initialisation option is non-zero, the separator component is the line dividing the area between the button box and the child site. By default, this component is a Tkinter.Frame.

Component aliases

Sub-components of components of this megawidget may be accessed via the following aliases.

label
Alias for scrolledtext_label.
text
Alias for scrolledtext_text.

Methods

Only methods specific to this megawidget are described below. For a description of its inherited methods, see the manual for its base class Pmw.Dialog. In addition, methods from the Pmw.ScrolledText class are forwarded by this megawidget to the scrolledtext component.

bbox(index)
This method is explicitly forwarded to the text component's bbox() method. Without this explicit forwarding, the bbox() method (aliased to grid_bbox()) of the hull would be invoked, which is probably not what the programmer intended.

Example

The image at the top of this manual is a snapshot of the window (or part of the window) produced by the following code.

class Demo:
    def __init__(self, parent):
        # Create the dialog.
        dialog = Pmw.TextDialog(parent, scrolledtext_labelpos = 'n',
                title = 'My TextDialog',
                defaultbutton = 0,
                label_text = 'Lawyer jokes')
        dialog.withdraw()
        dialog.insert('end', jokes)
        dialog.configure(text_state = 'disabled')

        # Create button to launch the dialog.
        w = Tkinter.Button(parent, text = 'Show text dialog',
                command = dialog.activate)
        w.pack(padx = 8, pady = 8)

jokes = """
Q: What do you call 5000 dead lawyers at the bottom of the ocean?
A: A good start!

Q: How can you tell when a lawyer is lying?
A: His lips are moving.

Q: Why won't sharks attack lawyers?
A: Professional courtesy.

Q: What do have when a lawyer is buried up to his neck in sand?
A: Not enough sand.

Q: How do you get a lawyer out of a tree?
A: Cut the rope.

Q: What is the definition of a shame (as in "that's a shame")?
A: When a bus load of lawyers goes off a cliff.

Q: What is the definition of a "crying shame"?
A: There was an empty seat.

Q: What do you get when you cross the Godfather with a lawyer?
A: An offer you can't understand.

Q. What do lawyers use as contraceptives?
A. Their personalities.

Q. What's brown and black and looks good on a lawyer?
A. A doberman.

Q. Why are lawyers buried 12 feet underground?
A. Deep down their good.

Q. What's the difference between a catfish and a lawyer?
A. One's a slimy scum-sucking scavenger, the other is just a fish.

"""

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 18 May 2002

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9351187 Pmw-2.1/Pmw/Pmw_1_3_3/doc/TimeCounter.gif0000664000175000017500000000207000000000000020231 0ustar00gregmgregm00000000000000GIF87aUق,Uڋ޼H扦ʶn L p3 qʥM0,NZjmbcèG ʸ)~a39vC`A n/SyҶ&'"8wW88hШpɐp8xI Jbj*i٪@[r{{,Fbz;lll-9}R ^, %-nؾN~N;/} kn?!PD.p = #"ノy9&K;.Hly3T 4hD-NG:U4)ԨEu.ՠiūʕH5,PaU; ܟreV컮u 6/8#o;ػXq⿑Rp 9/kȓIO88cY ϖ6bڵkw,h}R;h6+` aoztDz~K.?sùa.!>ހ|g7wf{|QԷ]p~N|{|tnv)xoܧA~QH(b"n'^m e &`y>1v"' N؝e!w>8%z42xxH@9|?_0)Kf^eVg)':deF‰hD-[K:*i.zZE*:I)nf)6Ji |*hꤦZ"r wUJv,HRJy(zd:>K&8մ⚭.+4K.n3.߾9:ڮ;/L:ELDDTѽ0$@LAG1{+9rU$B %r<@+mY#\VPDoVFG'FqЏ% # i(Y-ݾb0UEAh_lK u$f'6{\u\.vW(^8aٽON9Z}_yoyl;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9311185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/TimeCounter.html0000664000175000017500000003045500000000000020440 0ustar00gregmgregm00000000000000 Pmw.TimeCounter reference manual

Pmw.TimeCounter

Name

Pmw.TimeCounter() - counter for display and input of time

Inherits

Pmw.MegaWidget

Description

A time counter is similar to a regular Pmw.Counter except that the user may increment and decrement the hours, minutes and seconds individually.

Options

Options for this megawidget and its base classes are described below.

autorepeat
If true, the counter will continue to count up or down while an arrow button is held pressed down. The default is 1.

buttonaspect
Initialisation option. Specifies the width of the arrow buttons as a proportion of their height. Values less than 1.0 will produce thin arrow buttons. Values greater than 1.0 will produce fat arrow buttons. The default is 1.0.

command
This specifies a function to call whenever the <Return> key is pressed in one of the entry fields or invoke() is called. The default is None.

initwait
Specifies the initial delay (in milliseconds) before a depressed arrow button automatically starts to repeat counting. The default is 300.

labelmargin
Initialisation option. If the labelpos option is not None, this specifies the distance between the label component and the rest of the megawidget. The default is 0.

labelpos
Initialisation option. Specifies where to place the label component. If not None, it should be a concatenation of one or two of the letters 'n', 's', 'e' and 'w'. The first letter specifies on which side of the megawidget to place the label. If a second letter is specified, it indicates where on that side to place the label. For example, if labelpos is 'w', the label is placed in the center of the left hand side; if it is 'wn', the label is placed at the top of the left hand side; if it is 'ws', the label is placed at the bottom of the left hand side.

If None, a label component is not created. The default is None.

max
Specifies the maximum acceptable time in the form "HH:MM:SS", or None if no maximum checking should be performed. The default is None.

min
Specifies the minimum acceptable time in the form "HH:MM:SS", or None if no minimum checking should be performed. The default is None.

padx
Initialisation option. Specifies how much wider to make each column than the default width (where a column consists of two arrows and an entry field). The entry fields expand to fill the extra space, but the arrow buttons are centered in the available space. The default is 0.

pady
Initialisation option. Specifies how much higher to make each row of arrow buttons than the default hight. The arrow buttons are centered in the available space. The default is 0.

repeatrate
Specifies the delay (in milliseconds) between automatic counts while an arrow button is held pressed down. The default is 50.

value
Initialisation option. Specifies the initial contents of the time counter, in the form "HH:MM:SS". If this is None, the current time is used as the initial contents. The default is None.

Components

Components created by this megawidget and its base classes are described below.

downhourarrow
The arrow button used for decrementing the hour field. By default, this component is a Tkinter.Canvas. Its component group is Arrow.

downminutearrow
The arrow button used for decrementing the minute field. By default, this component is a Tkinter.Canvas. Its component group is Arrow.

downsecondarrow
The arrow button used for decrementing the second field. By default, this component is a Tkinter.Canvas. Its component group is Arrow.

frame
If the label component has been created (that is, the labelpos option is not None), the frame component is created to act as the container of the entry fields and arrow buttons. If there is no label component, then no frame component is created and the hull component acts as the container. In either case the border around the container of the entry fields and arrow buttons will be raised (but not around the label). By default, this component is a Tkinter.Frame.

hourentryfield
The entry field where the hours are entered and displayed. By default, this component is a Pmw.EntryField.

hull
This acts as the body for the entire megawidget. Other components are created as children of the hull to further specialise this class. By default, this component is a Tkinter.Frame.

label
If the labelpos option is not None, this component is created as a text label for the megawidget. See the labelpos option for details. Note that to set, for example, the text option of the label, you need to use the label_text component option. By default, this component is a Tkinter.Label.

minuteentryfield
The entry field where the minutes are entered and displayed. By default, this component is a Pmw.EntryField.

secondentryfield
The entry field where the seconds are entered and displayed. By default, this component is a Pmw.EntryField.

uphourarrow
The arrow button used for incrementing the hour field. By default, this component is a Tkinter.Canvas. Its component group is Arrow.

upminutearrow
The arrow button used for incrementing the minute field. By default, this component is a Tkinter.Canvas. Its component group is Arrow.

upsecondarrow
The arrow button used for incrementing the second field. By default, this component is a Tkinter.Canvas. Its component group is Arrow.

Component aliases

Sub-components of components of this megawidget may be accessed via the following aliases.

hourentry
Alias for hourentryfield_entry.
minuteentry
Alias for minuteentryfield_entry.
secondentry
Alias for secondentryfield_entry.

Methods

Only methods specific to this megawidget are described below. For a description of its inherited methods, see the manual for its base class Pmw.MegaWidget.

decrement(seconds = 1)
Decrement the time by seconds seconds.

getint()
Return the currently displayed time as a number of seconds.

getstring()
Same as getvalue() method.

getvalue()
Return the currently displayed time as a string in the form "HH:MM:SS".

increment(seconds = 1)
Increment the time by seconds seconds.

invoke()
Invoke the command specified by the command option as if the <Return> key had been pressed.

setvalue(text)
Set the contents of the time counter, where text must be in the form "HH:MM:SS".

Example

The image at the top of this manual is a snapshot of the window (or part of the window) produced by the following code.

class Demo:
    def __init__(self, parent):
        self._time = Pmw.TimeCounter(parent,
                labelpos = 'w',
                label_text = 'HH:MM:SS',
                min = '00:00:00',
                max = '23:59:59')
        self._time.pack(padx=10, pady=5)

        button = Tkinter.Button(parent, text = 'Show', command = self.show)
        button.pack()

    def show(self):
        stringVal = self._time.getstring()
        intVal =  self._time.getint()
        print stringVal + '  (' + str(intVal) + ')'

Pmw 1.3.3 - 29 Mar 2014 - Home
Manual page last reviewed: 25 May 2002

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9311185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/blue_line.gif0000664000175000017500000000173300000000000017736 0ustar00gregmgregm00000000000000GIF87a@zsi~aw ±ꥮXkPdEZ=R;RҢꜥ北3G*?)?5,, “僌}s~kvitakXbP[EQ=I3=*5ꫫꥥ,@@ +eH8m5v+Xq8Kxu:D/HxL8H` f^*qp-NѣH[=%Z2qea^VPX@R6`i 5xtӃ7fYX- @o$aI%⹳aC/ <ԒK9qdʜI1[jFR0EsN:}TY-%'NQo)! f ±daM4h,GTQ j|C.Kw} >}wX@NA<]yD:MM3Z$ List of known bugs

List of known bugs

This is a list of some of the known bugs in Pmw. If you fix any of these, please let the maintainer (gregm@iname.com) know.

  • Under the Enlightenment window manager, if show() is called when a window is already displayed (and is not obscured by other windows), then the application will hang for two seconds. This is either a bug in Tcl/Tk or in Enlightenment. See the comment in the Tk function WaitForConfigureNotify() in the Tk source file tk8.3.2/unix/tkUnixWm.c:

     /*
      * One more tricky detail about this procedure.  In some cases the
      * window manager will decide to ignore a configure request (e.g.
      * because it thinks the window is already in the right place).
      * To avoid hanging in this situation, only wait for a few seconds,
      * then give up.
      */
  • On NT, Pmw.MenuBar does not display message bar help for menu items. It seems that Tk menu widgets do not support <Motion> events on MS. This probably is an issue that should be taken up with the Tcl/Tk people. (Reported by Stefan Schone. Pmw.0.7)

  • Run the CounterDialog.py demo, select the show dialog button and press ok. Now exit the dialog (either with the exit button or the close box). The following error appears:

     Menu ID 256 is already in use!Fatal Python Error: Tcl/Tk panic

    This may be a problem with Mac version of Tk. (Reported by Anthony Wilson.)

  • Pmw.Balloons bind to widgets and canvas items. This means that bindings made by other users are deleted when the balloon makes its bindings. (For example, the "Delete" canvas item in the Balloon demo overrides that <ButtonPress> binding and so that balloon is not withdrawn when the mouse button is pressed over the item.)

    The obvious solution is for Pmw.Balloon to add its bindings with a +. But this would make the unbind and tagunbind methods inconsistent - they would remove all bindings, not just the ones added by the balloon. A better way would be for the balloon to add a bindtag to each widget`s bindtag list - then it would not upset any other bindings and it could be deleted cleanly. (Reported by Joe Saltiel)

 import Tkinter
 import Pmw
 
 def foo(event):
     print '<Enter> event on text'
 
 root = Pmw.initialise()
 balloon = Pmw.Balloon()
 
 canvas = Tkinter.Canvas()
 canvas.pack()
 
 text1 = canvas.create_text(50, 50, text = 'hello
there')
 
 # As is, the balloon does not appear over the text, but foo
 # is called.  Swap the following two lines and the balloon
 # appears but foo will not be called.
 canvas.tag_bind(text1, "<Enter>", foo)
 balloon.tagbind(canvas, text1, 'text 1 help')
 
 root.mainloop()
  • In Pmw.Balloon, the balloon should not be withdrawn when the pointer leaves a widget or item and it immediatly enters another widget or item with balloon help. Instead, the balloon should be moved and its contents changed immediately.

  • When a Pmw.Balloon is bound to a canvas item, moving the item becomes very slow. (Reported by Joe Saltiel)

     > Second, after I fixed my ordering problem I noticed, there
     > is a pretty big delay in updating widgets that have balloon
     > messages bound to them.  (For example dragging a box across
     > a screen, the box has a delayed reaction.) I believe this is
     > due to some of the timing functions used in PmwBalloon, I am
     > not sure if there is a way around it.  I set all timers to
     > zero, and still had the problem.
  • When running Pmw demos under ptui the busy cursor does not appear.

  • If a combobox has a horizontal scrollbar and it displays its listbox above the entry, then it is misplaced.

  • Bug in Pmw.PanedWidget: repeat by creating new panes in Demo - existing panes jump to the right 1 or 2 pixels.

  • Bug in Pmw.PanedWidget: repeat by setting hull_borderwidth to 20 in demo - initial drag jumps to right by about 20 pixels. Also right hand side border is missing. (Fix may be similar to method used in Pmw.ScrolledFrame to give canvas border.)

  • Fix ButtonRelease events so they do not trigger without a corresponding ButtonPress event.

    From Joe Saltiel: I was playing around with a scrolledlistbox and tkFileDialog. When I have the dialog open above the list box and I doubleclick on it, I invoke the selectioncmd of the listbox as well as the tkFileDialog box, should this be happening?

    Attached is small sample program you can try. To get the bug to show you must do two things. First, when you open the file dialog box, make sure the item you are going to select if over(above) the scrolledlistbox. Second, you have to double click on that item. If you single click and hit "Open" you do not get the bug. Nor do you get it unless the file you click on is directly over the clickable region of the scrolledlist box.

     import Tkinter
     import Pmw
     import tkFileDialog
     import string 
     
     def askOpen():
         file = tkFileDialog.askopenfile(filetypes=[("all files", "*")])  
         print file
     
     def printMe():
         print "Me"
     
     root = Tkinter.Tk()
     Pmw.initialise(root)
     
     frame1 = Tkinter.Frame(root)
     lst = string.split("abc def ghi jkl mno pqr stu vwx yz")
     lstbox = Pmw.ScrolledListBox(frame1, items=lst, selectioncommand=printMe)
     lstbox.grid(row=0, column=0, columnspan=2)
     Tkinter.Button(frame1, text='open', command=askOpen).grid(row=1, column=0)
     Tkinter.Button(frame1, text='exit', command=root.destroy).grid(row=1, column=1)
     frame1.pack()
     
     root.mainloop()

    Response: I have found where the problem is but I am not sure how to fix it. It appears that the tkFileDialog box closes on a ButtonPress event. The corresponding ButtonRelease event is then sent to whichever widget is under the cursor at the time of the Release. I have reproduced the problem with a Tcl-only script:

     listbox .l
     .l insert 0 1 2 3 4
     bind .l <ButtonRelease-1> {puts AAAGGHHH!}
    
     button .b -text open -command tk_getOpenFile
     pack .l .b

    If you do a quick Press-Release-Press over the file dialog, it is withdrawn. If you then keep the mouse button down and move the mouse around, you will see that the button and the listbox still respond to it. If you do the final button Release over the listbox, its <ButtonRelease-1> binding is invoked.

    I think the correct solution is to modify Pmw to be very careful when to accept ButtonRelease events. It will need to also bind to ButtonPress events and make sure that it gets a Press before it accepts the Release. I'll try to do the change as soon as possible, but the code involved is fairly complex so I it may take a little time.

  • Investigate bug in Tk8.0: When a dialog pops up over the pointer then the keyboard focus is not set and so <Return> does not invoke default button.

  • Under both X and NT, the arrows in the timecounter, counter and combobox do not match the scrollbar arrows.

  • Pmw.Group does not work correctly when the tag is a compound widget. The tag is placed such that the top of the tag is cut off. (Reported by Peter Stoehr.)

     import Tkinter
     import Pmw
     
     root = Tkinter.Tk()
     Pmw.initialise(root, fontScheme = 'pmw1')
     exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy)
     exitButton.pack(side = 'bottom')
     
     def makeGroup(tagClassName):
         tagClass = eval(tagClassName)
         group = Pmw.Group(
             tag_pyclass = tagClass,
             hull_background = 'red',
             groupchildsite_background = 'blue',
         )
         group.pack(fill = 'both', expand = 1, padx = 6, pady = 6)
         child = Tkinter.Label(group.interior(),
             text = 'Group with tag ' + tagClassName,
             background = 'aliceblue',
         )
         child.pack(padx = 10, pady = 5, expand = 1, fill = 'both')
    
         return group
     
     grp1 = makeGroup('Pmw.EntryField')
     grp2 = makeGroup('Pmw.ComboBox')
     grp3 = makeGroup('Tkinter.Entry')
     
     root.mainloop()

    Also, Pmw.Group does not resize correctly if the simple widget changes size. For example:

     grp3.configure(tag_font = ('Helveltica', '-160'))
  • Bug(s) in PmwScrolledCanvas. There is a bug in 0.8.1 PmwScrolledCanvas._setRegion. If there are no objects in the canvas, then error occurs on len(region) because region is None. Below is an attempt to fix it. Click on Show, then on Delete. The window then continuously resizes. If the ScrolledCanvas is created with canvasmargin = 0, the problem goes away. (Reported by Anders Henja.)

     import Tkinter
     import Pmw
     
     def _setRegion(self):
         # Attempt to fix PmwScrolledCanvas._setRegion.
         self.setregionTimer = None
     
         region = self._canvas.bbox('all')
         canvasmargin = self['canvasmargin']
         if region is None:
             region = (0, 0, 0, 0)
         region = (region[0] - canvasmargin, region[1] - canvasmargin,
             region[2] + canvasmargin, region[3] + canvasmargin)
         self._canvas.configure(scrollregion = region)
     
     def show():
         canvas.component('canvas').delete('all')
         canvas.create_oval(0, 0, 800, 600, fill = 'red')
         canvas.configure(canvas_width = 600, canvas_height = 450)
         canvas.resizescrollregion()
     
     def delete():
         canvas.component('canvas').delete('all')
         canvas.configure(canvas_width = 0, canvas_height = 0)
         canvas.resizescrollregion()
     
     root=Tkinter.Tk()
     Pmw.initialise(root)
     
     buttonbox=Pmw.ButtonBox()
     buttonbox.pack(fill='x',side='bottom',padx=5,pady=5)
     buttonbox.add('Show',command=show)
     buttonbox.add('Delete',command=delete)
     buttonbox.alignbuttons()
     
     canvas=Pmw.ScrolledCanvas(canvasmargin=2)
     canvas.__class__._setRegion = _setRegion
     canvas.pack(fill='both',side='right',expand=1)
     
     root.mainloop()
  • Bug in Pmw.Dialog: if defaultbutton is configured before buttons during self.initialiseoptions() (that is if self._constructorKeywords.keys() returns a different order), then setdefault() fails.

  • Bugs in Tk which affect Pmw.MainMenuBar:

    • Extra bindings assigned to a Tkinter.Menu widget using bindtags have no effect. Hence the method used in Pmw.MenuBar for status help (bind_class followed by bindtags) does not work and therefore binding to the menu widget is used instead.

    • The 'active' tag for the index() method of Tkinter.Menu always returns None. Hence, in the menu widget motion binding, event.y and the '@' format is used instead, for all menus except the toplevel main menu.

    • For the toplevel main menu, event.x must be used for the index() method, but it returns the wrong index. It appears that the Tk widget is assuming vertical layout to calculate distances, rather than horizontal.

    • For toplevel main menus, several Tk commands, such as winfo_height(), do not work. This prevents the use of balloon help for Pmw.MainMenuBar.

  • Bug in Pmw.ComboBox: Tab to combobox arrow, use up/down arrow keys to change selection, hit return, nothing happens, <Shift Tab> to entry window, hit return, combobox changes

    • actually, it would be better if you could not tab to the arrow, only the entry field, like the Pmw.Counter.

    • the problem is if the entry field is not editable, what to do then?

  • Bug in TimeCounter: Arrow keys don't work when focus is on entry.

  • Bug in Pmw.NoteBook: The size of the tab does not change when the text value changes

  • Bug in Pmw.NoteBook: The name of the tab components has a "-" sign in it, which means that component options can not be used in the configure command. Eg:

     n = Pmw.NoteBook()
     p = n.add('page1')
     n.configure(page1_background = 'red')   # works
     n.configure(page1-tab_background = 'red')   # fail, must do this:
     n.component('page1-tab').configure(background = 'red')   # works

Pmw 1.3.3 - 29 Mar 2014 - Home

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9311185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/changes.html0000664000175000017500000016245500000000000017620 0ustar00gregmgregm00000000000000 Changes to Pmw

Changes to Pmw

6 January 1997

  • Release of version 0.1

14 February 1997

  • Fixed bug in Counter demo for the Macintosh - the maximum size of an integer is smaller than the value returned by time.time().

  • Fixed bug in Grid demo for Tk 4.2 - grid_bbox returns garbage if it is called without update_idletasks. Also, grid_bbox can only have two arguments in Tk 4.1.

  • Modified ScrolledText demo so that the text widget contains enough text to require a vertical scrollbar.

  • Changes to PmwBase:

    • Prefixed the name of several private variables with a double underscore.

    • Added symbolic constants for the indexes into an optionInfo list.

    • Changed names of several methods and variables to be more descriptive.

    • Removed options() method.

    • Simplified configuration option data structures. Modified option handling code so that default options are set correctly. If an option is created before initialise() is called then initialise() checks if the option is set by the keyword arguments to initialise(). If not, then it is given the value found in the Tk option database, if a value exists, or the default value. If an option is created after initialise() is called, then it is given the value found in the Tk option database, if a value exists, or the default value.

  • Replaced usage of self._hull in megawidgets by interior() method.

  • Added autoclear option to ComboBox.

  • Fixed bug in ComboBox - fast clicking on the arrow button could result in an attempt to grab a window that was not yet visible.

  • Added "sys.exc_traceback = None" to the except clauses of all try statements so that references to objects in the stack trace would not be left.

  • Added takefocus option to PushButton.

  • Modified the getcurselection() method of ScrolledListBox so that it returns a string if the selection mode is 'single' or 'browse', rather than a tuple with one element. This also affects methods forwarded and derived from ScrolledListBox.

  • Modified ScrolledListBox so that it avoids unnecessary updates by using idle timer.

  • Modified ScrolledText to use grid instead of pack.

  • Added shutdown() function to Tk module to clean up all references to the Tcl interpreter and then delete it.

  • Fixed bug in Tk module for the Macintosh - update() was being called in initialise() before the Tcl interpreter was created.

14 February 1997

  • Version 0.1.1 completed and released internally.

6 March 1997

  • Pmw now uses the standard Tkinter module. The Tk module has been dropped. This means that the Tk module functions such as after, bell, bind, update, etc, are no longer available and the equivalent Tkinter methods should be used.

  • To restore some of the features of the Tk module, Pmw.initialise() now adds run-time hooks into Tkinter to get notification of when Tk widgets are created and destroyed. It also modifies the CallWrapper class so that errors during callbacks and bindings can be displayed in a window. If Pmw.initialise() is not called, Tkinter is not modified and these features are not available.

  • If a Tk widget which is acting as the hull of a megawidget is destroyed, then the megawidget is destroyed as well. This can only happen if Pmw.initialise() is called.

  • Pmw.initialise() now takes the Tkinter root as its argument.

  • The parent of megawidgets now defaults to the Tk root. Previously, the parent of non-toplevel megawidgets had to be given.

  • Added PmwBase.tracetk() function to get trace of calls to the Tcl interpreter for debugging.

  • Added functions to PmwBase to display a busy cursor over the application such as when a modal dialog is displayed or it is blocked doing a long calculation. Uses busy command of the blt extension, if present.

  • Created a nifty new demo which demonstrates most of the megawidgets in a convenient way.

  • Added a TextDialog.

  • Added functionality to handle the grabbing of nested modal dialogs correctly.

  • Added an activatecommand option to Dialog which allows, for example, the PromptDialog widget to set the keyboard focus when it is activated.

  • Added tests for Counter and logicalfont.

  • The ScrolledListBox selectioncommand is no longer given the widget as its first argument.

  • Several method, function and component names were changed, to be consistent with the coding conventions.

  • Some of the effects of moving from the Tk module to Tkinter are:

    • The Tk module used to exit if there were no non-root toplevel windows shown. This is no longer the case and so the application must handle this explicitly, particularly if the root window is withdrawn and the last non-root toplevel is deleted by the window manager.

    • The Tk module bind functions and methods used to take a noEvent argument to indicate that the Tk event should not be passed to the callback. Tkinter does not support this.

    • The Tk module initialise() function should be replaced by "root = Tkinter.Tk()" and root should be used instead of "Tk.Root()"

    • The Tk module quit() function should be replace by "root.destroy()".

    • Toplevels are not hidden when created. To be consistent, MegaToplevels are not hidden either.

    • The hide and show methods are not available for Tkinter Toplevels, only MegaToplevels

    • There is no grid_configure method.

    • Tkinter.Canvas.coords() returns a python list, not a tuple.

    • The Tkinter cget and configure widget methods always return strings for the option values. The Tk module used to convert the string to the appropriate python type (such as string, integer, float, Variable, Image, callback function).

    • Tkinter Menu and Toplevel classes incorrectly have a pack method.

    • Menu class has no geometry method.

    • Canvas focus returns '' rather than None.

    • Text mark_gravity returns '' rather than None.

13 March 1997

  • Release of version 0.2

17 March 1997

  • Set default WM_DELETE_WINDOW protocol of Tkinter.Toplevel to destroy() and removed duplicated protocol request from all demos.

  • Modified text of ShowBusy demo to indicate that busy cursor will only be seen if the BLT extension is present.

  • Replaced call to update() in PmwLabeledWidget.py with update_idletasks().

  • Changed name of PromptDialog component from 'entry' to 'entryfield'.

28 April 1997

  • Version 0.3 released internally

19 August 1997

  • Many changes made (see the version 0.4 porting guide for more details).

  • The option propagation mechanism that iwidgets uses is too cumbersome, too hard to understand and, in python, too slow. Developed a new mechanism which is more explicit in naming options. This resulted in most options which were simply propagated to components being removed. Removed keep(), rename() and ignore() methods and "usual" options.

  • For speed, Pmw no longer queries the Tk option database for default values for megawidget options. Hence, resource names and classes do not need to be supplied when creating options and None is returned for the resource name and class when using configure() to query the options. Option "types" no longer used.

  • Changed method and component names to be more consistent.

  • Replaced most uses of pack() with grid().

  • Megawidgets no longer inherit from LabeledWidget. Instead they call createlabel() to optionally create the label component.

  • Removed child site from EntryField and rewrote ComboBox accordingly.

  • Wrote lots more documentation, including automatically generated reference manuals.

  • Removed PushButton and rewrote ButtonBox to directly create Tkinter.Buttons rather than PushButtons.

  • Added initialisation options - options which can be set at creation time but not later using configure().

  • Added aliases for components.

  • Modified the base classes so that during option configuration, components are configured before configuration called functions are called.

  • Added several more megawidgets.

  • Added interface to BLT graph and vector commands.

  • Created PmwLazy module for lazy importing of Pmw - avoids loading megawidgets which are not used.

  • Added several more functions for handling color and fonts.

  • Replaced Counter and EntryField time with timeN and time24

  • Pmw.initialise() will now create Tkinter.Tk if not given root.

1 September 1997

  • Release of version 0.4

5 September 1997

  • Modified the base classes so that the Tk option database resource class of megawidgets can be overridden in the call to the constructor using the hull_class option.

  • The separators in Pmw.PanedWidget are now active - they can be grabbed, like the handles, and moved around. The cursor now changes to the correct left/right or up/down cursor when over a separator or handle. (Clemens Hintze)

  • Fixed bug in MessageInfo demo Dismiss button. If it is invoked, an error occurs saying "not enough arguments". (Mark Colclough)

9 September 1997

  • Added the useTkOptionDb argument to Pmw.initialise which specifies that the initial values of megawidget options are to be set by querying the Tk option database.

  • When used to query options, the configure() method now returns the resource class and name of the options.

19 September 1997

  • Changed functions datestringtoint() and timestringtoint() to datestringtojdn() and timestringtoseconds(). Changed return value of datestringtojdn() to be Julian Day Numbers rather than seconds since the epoch.

  • Fixed a bug in the date Counter due to use of time.timezone, by replacing, when calculating date increments, calls to the time module with calls to datestringtojdn().

  • Added century pivot year (setyearpivot function) to Counter date datatypes to handle two-digit years.

  • Added date_dmy4, date_mdy4 and date_y4md datatypes to Counter.

  • Modified demos All.py and ScrolledText.py so that demos can be called from directories other than the demos directory. (Case Roole and Guido van Rossum)

  • Changed the default for the Pmw.Balloon label_justify option to left to improve appearance of multi-line balloons. Pmw.Balloon now replaces newlines with spaces in the statusHelp string so that the strings look better when displayed in a Pmw.MessageBar. (Andreas Kostyrka)

  • Pmw.Blt now calls package require BLT when checking for the existence of Blt, so that it can be loaded if it is not statically linked. (Clemens Hintze, Matthias Klose)

  • Copied earthris.gif and flagup.bmp files from Tcl distribution to test directory, just in case they have not been installed. (Jonathan Kelly)

  • Lots of improvements to the documentation and documenting recent changes.

16 October 1997

  • Modified Pmw.Balloon and Pmw.ComboBox to work around a bug in the Windows95 version of Tk which caused the popup windows to appear in the wrong place. (Fredrik Lundh and Jerome Gay)

  • Added Pmw.maxfontwidth() function. (Rob Pearson)

24 October 1997

  • Changed PmwBase._reporterror to handle the class exceptions of python 1.5. (Case Roole)

29 October 1997

  • Fixed a bug in forwardmethods() function which occurred if the toClass class had a method called type.

7 November 1997

  • Changed tests/Test._getErrorValue to handle the class exceptions of python 1.5. (Michael McLay)

  • Changed bug fix in forwardmethods() function to use the exec execString in d construct. (Guido van Rossum)

  • Can now use Pmw.MegaArchetype as a base class just to get option handling; it will not create the hull component unless requested. Moved __str__() and interior() methods from Pmw.MegaToplevel and Pmw.MegaWidget to Pmw.MegaArchetype class.

10 November 1997

  • Added textclass option to Pmw.ScrolledText and listboxclass option for Pmw.ScrolledListBox to allow embedding of custom widgets.

  • Added Mitch Chapman's FontText module to the demos directory and used it to display the demo source code in color.

  • Added two notebook megawwidgets, Pmw.NoteBookR and Pmw.NoteBookS. (Case Roole and Joe Saltiel)

  • Added Pmw.ScrolledCanvas megawidget. (Joe Saltiel)

  • Added Pmw.TreeBrowse megawidget. (Michael McLay)

  • Added Pmw.Group megawidget and modified to use grid() instead of pack(). (Case Roole)

  • Release of version 0.5

12 November 1997

  • Added pyclass option to components and removed textclass option from Pmw.ScrolledText and listboxclass option from Pmw.ScrolledListBox. (Suggested by Shen Wang)

  • Added label component to Pmw.ButtonBox megawidget.

  • Fixed mis-spelling of PmwTreeBrowse in Pmw.py.

  • Release of version 0.5.1

5 December 1997

  • The pyclass option can now be None. If so, createcomponent returns None.

  • Removed tagtype option from Pmw.Group. Can now use the more general tag_pyclass instead.

  • Added tcl call to load {} Blt when testing for presence of Blt.

  • Added julian and papal options to Pmw.ymdtojulian and Pmw.juliantoymd functions and made sure divisions give the same result as C even when operands are negative.

  • Exported ymdtojulian and juliantoymd functions.

  • Fixed bug in activate method. Did not prepend TclError with Tkinter.

  • When the Blt busy hold command is called from showbusycursor, the bindtags on the busy window are set so that no events cause callbacks to occur for the toplevel or all bindings. Also, while a busy window is up, the focus is changed to the busy window so that no keyboard events are accepted. This fixes a bug where the Tkinter._nametowidget function could crash with a KeyError: _Busy if there was a binding on a toplevel window and the mouse was pressed while the busy cursor was up.

9 December 1997

  • Fixed bug in Pmw.datestringtojdn() when dealing with century year, such as 2000.

10 December 1997

  • Added where option to Pmw.ScrolledText.importfile(). (Graham Matthews)

16 December 1997

  • Modified Pmw.RadioSelect and Pmw.ButtonBox so that you can no longer index their buttons using regular expressions. This feature seemed to have little use and caused problems with buttons labeled for example a* and b*. (Problem reported by Rob Hooft)

  • Added updateFunction option to Pmw.busycallback(). If set, the function will be called just after the command given to Pmw.busycallback(). If the function is set the Tkinter update() method, then this will clear any events that may have occurred while the command was executing.

30 December 1997

  • Changed ymdtojulian and juliantoymd functions to jdntoymd and ymdtojdn, because the meaning of "julian" is ambiguous, whereas the meaning of "Julian Day Number" is not (maybe).

  • Converted Pmw to use python 1.5 package mechanism. (Michael McLay and Case Roole)

  • Removed Pmw.py and PmwLazy files. Added __init__.py, PmwLoader.py and Pmw.def files. (Case Roole)

  • Applications can now specify at runtime which version of Pmw to use and also which alpha versions, if any. (Case Roole)

  • Modified Pmw code for the version of Tkinter released with python 1.5.

  • Release of version 0.6

5 January 1998

  • Fixed alpha version handling so that alpha versions do not have to supply PmwBase.py and PmwUtils.py. (Case Roole)

  • Added example alpha directory and documentation. (Case Roole)

7 January 1998

  • Added selectmode option to Pmw.RadioSelect megawidget. (Roman Sulzhyk)

  • Added some changes to Pmw.ScrolledCanvas to get around some bugs. (Joe Saltiel)

  • Release of version 0.6.1

8 January 1998

  • Added some more changes to Pmw.ScrolledCanvas. (from Joe Saltiel)

12 January 1998

  • Added Pmw.OptionMenu megawidget. (Roman Sulzhyk)

20 February 1998

  • Added new Pmw.MenuBar features to delete menus and menuitems, enable and disable menu bar and to add cascade menus. (Rob Pearson)

  • Added extra arguments to Pmw.Color.spectrum for more control over color choice.

23 February 1998

  • Added canvasbind() method to Pmw.Balloon.

  • Fixed demos/All.py so that it will correctly determine which Pmw version to use even if it is in a directory symlinked to the demos directory.

  • Removed "import DemoVersion" from all demos, except All.py, so that they will work unchanged when copied outside of the Pmw distribution.

  • Release of version 0.6.2

26 February 1998

  • Fixed PmwLoader so that it works on Macintoshes. (Jack Jansen)

2 March 1998

  • Fixed PmwBase and PmwBlt so that an attempt is made to dynamically load Blt before it is used. Previously only attempted to load Blt when calling showbusycursor.

16 March 1998

  • Added hulldestroyed() method.

  • Modified displayerror() function to use value given to reporterrorstofile() if it is set.

  • Fixed bug in Pmw.EntryField which occurred when the command option destroyed the megawidget.

  • Pmw.EntryField invoke method now passes on the value returned by the command function.

3 April 1998

  • Added Pmw.ScrolledFrame megawidget. (Joe Saltiel)

  • Color.rgb2hsi() now uses the built-in min() and max() functions.

20 April 1998

  • Moved time and date functions from PmwCounter.py to new file, PmwTimeFuncs.py.

  • Added optional separator argument to timestringtoseconds and datestringtojdn functions. These functions are now stricter when checking if a string is a valid date or time. For example, it now checks for correct day in month, month in year, etc. These changes also affect the Pmw.Counter date and time validators.

  • The datestringtojdn function now accepts all combinations of 'd', 'm', 'y' as format string.

  • Moved functions to bottom of file and class to top of file in PmwEntryField.py and PmwCounter.py.

  • The validation for Pmw.EntryField integer, hexadecimal and real types now use string.atol or string.atof rather than regular expressions.

  • The validation for the Pmw.EntryField real type accepts a separator argument, for those who prefer a comma instead of a full stop/period/point as the decimal dividing symbol.

  • The Pmw.EntryField time* and date_* validators have been removed. The functionality can be replaced by using the new time and date validators with min and max fields.

  • The Pmw.EntryField maxwidth option has been removed. The functionality can be replaced by using the max field of the validator.

  • Added an extravalidators option to Pmw.EntryField. This allows new types of validation to be added, particularly in classes derived from Pmw.EntryField. It also allows the use of different names for the same validation, by using aliases. Added SpecialEntry demo to show extravalidators option, based on work by Joachim Schmitz.

  • Fixed a bug in Pmw.EntryField when combining use of value and entry_textvariable options.

  • The Pmw.EntryField validate option now also accepts a dictionary to handle minimum and maximum validation and to allow the passing of other arguments to the validating functions, such as date, time and number formats and separators.

  • Fixed bug in Pmw.EntryField where the entry would scroll to the start of the text if an invalid character was typed.

  • Added checkentry() method to Pmw.EntryField, so that it can be updated if the entry widget is tied to a textvariable.

10 May 1998

  • The activate() method now takes a geometry option to allow more flexible positioning of the modal dialog.

  • Fixed rarely occurring bug in deactivate() method if it is called (perhaps from a timer) during the call to wait_visibility() in the activate() method. This bug used to generate an error and the application would not exit properly.

  • Fixed another rarely occurring bug in deactivate() method if it is called while another application has the grab.

  • Removed "sys.exc_traceback = None" for except clauses which used to be required by python 1.4 so that references to objects in the stack trace would not be left.

  • Now uses sys.exc_info() function when displaying exception traceback.

  • The state option of Pmw.Balloon and the orient option of several others now generate an exception if they have a bad value.

  • Added a deactivatecommand option to Pmw.MegaToplevel which can be used, for example, to cancel timers.

  • Made changes to Pmw.Counter so that the entry display continuously changes when arrow key presses are repeated quickly.

  • Made changes to Pmw.Counter so that the insertion cursor is maintained while counting and the entry scrolls to the end if the value is long.

  • Pmw.Counter now behaves correctly when counting past the maximum and minimum values of the EntryField.

28 May 1998

  • Made all Pmw.EntryField standard validators publicly available as Pmw.numericvalidator, etc.

  • Now uses faster string.replace() instead of regsub.gsub() when applicable.

  • If the balloonHelp argument of the Pmw.Balloon bind methods is None, no balloon is displayed.

  • Merged the code from the PmwUtils module (forwardmethods()) into PmwBase, since it was always used, was used nowhere else, and made freezing a little more complicated.

  • Added a short delay between calling Tkinter bell() method (sounds nicer).

  • The functions datestringtojdn() and timestringtoseconds() now return ValueError on invalid input.

  • Created bundlepmw.py, to help when freezing in Pmw. Placed in bin directory.

29 May 1998

  • Fixed rare bug in Pmw.Counter which occured if the counter was unmapped while the mouse button was held down over an arrow button.

  • Created contrib directory and placed PmwVerticalGuage.py in it. (Chris Wright)

  • Patched PmwNoteBookR.py. (Siggy Brentrup)

  • Added addoptions() method to Pmw.MegaArchetype class. (Dieter Maurer)

  • By default, MenuBar creates hotkeys for menus and menu items for keyboard traversal. Added traversSpec argument to MenuBar add methods. (Michael McLay)

31 May 1998

  • Cleaned up bbox() methods in Pmw.ScrolledCanvas and Pmw.ScrolledListBox.

  • The createcomponent() method now disallows the creation of component names containing an underscore, since the query functions would not be able to find them.

2 June 1998

  • Release of version 0.7

3 June 1998

  • Moved Pmw.TreeBrowse megawidget to contrib directory.

17 June 1998

  • Added PmwFullTimeCounter.py to contrib directory (Daniel Michelson)

1 July 1998

  • Changed mispelt file PmwVerticalGuage.py to PmwVerticalGauge.py in contrib directory.

7 July 1998

  • Fixed bug in Pmw.Counter real datatype. Sometimes incorrectly counted negative decimal fractions. (Reported by David Ascher)

12 July 1998

  • The format argument of Pmw.datestringtojdn() now defaults to 'ymd'.

  • Removed Tkinter_test.py from tests since it does not test any Pmw functionality (only Tkinter) and it fails under MS-Windows 95.

23 August 1998

  • Changed several exception types to be more consistent.

  • Made the interface to Pmw.Blt.Vector more like the builtin python list type.

  • It is no longer an error to call Pmw.setversion() or Pmw.setalphaversions() after initialisation, as long as the requested version matches the actual version.

  • Fixed Pmw.NoteBookR so that it behaves better when the highlightthickness is changed.

  • The setyearpivot() function now returns a tuple containing the old values of pivot and century.

  • Added PmwFileDialog.py to contrib directory (Rob Hooft)

  • Modified demos so that full tracebacks are displayed if an error occurs when importing a module.

  • Removed justify() method from Pmw.ScrolledListBox, since it is just a wrapper around the xview and yview methods of the listbox. Also, it was not a permanent justification, as the name implied.

20 September 1998

  • Changed implementation of Pmw.ScrolledCanvas.

  • Added borderframe option to Pmw.ScrolledText and Pmw.ScrolledCanvas.

18 October 1998

  • Major overhaul of all scrolled widgets. Modified all to use similar structure, given the peculiarities of each. Fixed several subtle bugs.

  • Pmw.ScrolledFrame: now uses a frame positioned within a clipping frame using the place geometry manager. Added borderframe, horizflex, horizfraction, usehullsize, vertflex, vertfraction options. Added reposition() method. Removed getFrame() method; use interior() method instead.

  • Pmw.ScrolledListBox: added usehullsize option.

  • Pmw.ScrolledText: added borderframe and usehullsize options.

  • Pmw.ScrolledCanvas: simplified widget structure. Added borderframe, canvasmargin, scrollmargin and usehullsize options. Added label.

  • Modified Pmw.OptionMenu to use standard widgets rather than call tcl procedure. Added initialitem option. Now handles menubutton_textvariable component option correctly.

1 November 1998

  • Documented more Pmw functions and Pmw.ComboBox.

15 November 1998

  • Fixed some bugs, cleaned up code and wrote documentation for Pmw.Group. Removed ringpadx and ringpady options, since this functionality is more generally available by padding the megawidget itself and by padding the children of the megawidget. Modified Pmw.aligngrouptags so that it takes into account the borderwidth and highlightthickness of the ring and so that it works when there is no tag widget. Added tagindent option.

18 November 1998

  • Renamed canvasbind() and canvasunbind() methods of Pmw.Balloon to tagbind() and tagunbind() and modified so that they work with both Tkinter.Canvas items and Tkinter.Text tagged items.

19 November 1998

  • Added havebltbusy() method to Pmw.Blt. (Robin Becker)

21 November 1998

  • Modified contrib/PmwFileDialog.py so that when a file is selected with the mouse, the highlight (in the file list) persists and the file list does not scroll to the top. (Rob Hooft)

  • Modified Pmw.Balloon so that it can be bound to a tag associated with several Canvas or Text items. (Magnus Kessler)

21 November 1998

  • Cleaned up appearance and colors of Pmw.NoteBookR tabs. (Georg Mischler)

  • Added buttontype option to Pmw.RadioSelect to support radiobuttons and checkbuttons. (Georg Mischler)

23 November 1998

  • Updated usage of bind_class(tag) due to change in return value in Tkinter module in python 1.5.2. (Magnus Kessler, Fredrik Lundh)

  • The default time displayed in Pmw.TimeCounter is now the current local time, not GMT as before.

  • The times displayed in the Counter demonstration are now the current local time, not GMT as before.

7 December 1998

  • Modified Pmw.ComboBox to take advantage of the fix to the Tkinter bind() method callback handling of Event.widget in python 1.5.2. It works even if the selectioncommand destroys the combobox. For simple comboboxes, the invoke() method now returns the return value of the selectioncommand.

  • Modified Pmw.EntryField to take advantage of the fix to the Tkinter bind() method callback handling of Event.widget in python 1.5.2. It works even if a user-supplied callback (command, invalidcommand, validator or stringtovalue) destroys the entryfield. Cleans up correctly when destroyed. The invoke() method now returns the return value of the command.

  • The invoke() method of Pmw.TimeCounter now returns the return value of the command.

  • Modified Pmw.ButtonBox to use the new (in Tk8.0) default option of the Tkinter Button widget instead of a separate frame. Changed default padding to be more compact. Removed "ring" frame component and "ringborderwidth", "ringpadx" and "ringpady" options. (Georg Mischler)

  • Changed 'pmw1' fontScheme to set default fonts only when running under posix, since the default fonts on other systems look better.

10 December 1998

  • Release of version 0.8

20 January 1999

  • Added master option to Pmw.MegaToplevel and removed master argument from the activate method.

  • Replaced rand module in demos with a simple random number generator (since rand is not built-in on all versions of python).

22 February 1999

  • Modified __init__.py so that it only accepts directories whose names begin with Pmw_M_N and which have a /lib/PmwLoader.py/ file.

13 May 1999

  • Changed Pmw.ScrolledCanvas, Pmw.ScrolledText and Pmw.ScrolledListBox to speed up scrolling if the scrollmodes are not both dynamic.

  • Changed busy cursor and activate/deactivate code so that it works correctly under fast mouse clicking or fast keyboarding (using accelerators). Also fixed so that grab is correctly restored after a Pmw.ComboBox popup list is unmapped inside a modal dialog. (Clemens Hintze)

  • Several dialogs now give focus to one of their components (listbox or entry widget) when activated. (Clemens Hintze)

  • Fixed Pmw.ComboBox so that it unposts popup if the combobox is unmapped and returns grab and focus correctly if destroyed.

  • Improved tracetk() output to be more readable. Also displays nested calls to the Tk mainloop better and shows callbacks from tcl to python.

  • Upgraded Blt support to blt2.4i. Graph widget is not backwards compatible with blt2.1.

19 May 1999

  • Fixed bug in Pmw.Balloon in placement of balloons over canvas items when the canvas was scrolled. (Tessa Lau)

20 May 1999

  • Added new Tk event types (new in Tk 8.0 and 8.0.5) to PmwBase error display method. Also added check for unknown event types to safeguard against future changes. (Magnus Kessler)

  • Added exclude argument to showbusycursor(). (Rob Hooft)

1 June 1999

  • Added wrappers for Blt Stripchart and Tabset widgets. (Nick Belshaw)

  • Changed createcomponent() so that arguments to the constructor of the component can now be specified as either multiple trailing arguments to createcomponent() or as a single tuple argument.

7 June 1999

  • Added call to update_idletasks() in Pmw.ScrolledCanvas, Pmw.ScrolledFrame, Pmw.ScrolledText and Pmw.ScrolledListBox to avoid endless mapping/unmapping of two dynamic scrollbars when the window is first mapped and only one scrollbar is needed. (Reported by Mark C Favas, solution suggested by Dieter Maurer.)

10 June 1999

  • Fixed bug in bundlepmw.py when called with -noblt option. (Reported by Kevin O'Connor)

  • Pmw.ComboBox now unposts the dropdown listbox before the selection callback is invoked, to avoid problems when the callback takes a long time to run. (Reported by Randall Hopper)

11 June 1999

  • Release of version 0.8.1

29 June 1999

  • PmwMessageBar.message() now replaces newlines with spaces before displaying message. Also applies to helpmessage().

2 July 1999

  • Improved toplevel window positioning under NT, and stopped most of the ugly flashing.

5 July 1999

  • The pmw1 fontScheme is now supported under NT, as is the size option to Pmw.initialise().

6 July 1999

  • Changed the names of positional arguments in the following methods, so that they have less chance of conflicting with keyword arguments: MegaArchetype.createcomponent(), ButtonBox.insert(), ButtonBox.add(), MenuBar.addcascademenu(), MenuBar.addmenuitem() and RadioSelect.add().

9 July 1999

  • Added images and example code to the megawidget reference manuals. (Suggested by Joerg Henrichs)

  • Fixed showbusycursor() under NT. It now calls update() instead of update_idletasks() to force display of cursor. (Solution suggested by George Howlett)

  • Improved display of arrows in ComboBox, Counter and TimeCounter.

16 July 1999

  • Removed Pmw.maxfontwidth() function, since better functionality is now supplied by the Tk "font measure" command.

  • Removed Pmw.fontexists() function, since in Tk8.0 all fonts exist.

28 July 1999

  • Fixed bug in date counter with separator other than '/' and time counter with separator other than ':'. (David M. Cooke, Alan Robinson)

  • Under NT, the font named 'fixed' is not fixed width, so added alias from 'Fixed' to 'Courier'.

  • Changed the bind() and tagbind() methods of Pmw.Balloon to remove a potential memory leak. The methods now store the funcids of the callback functions, so that if the same widget or tag is bound twice, the balloon can remove the old bindings. (Peter Stoehr)

  • Changed NoteBookR so that lowercmd, creatcmd and raisecmd are called in that order when a page is selected. Also fixed bug which always raised page 0 when notebook is resized. (Scott Evans, Charles Choi)

1 August 1999

  • Added dynamicGroups argument to defineoptions() method and modified ButtonBox, MenuBar, PanedWidget, RadioSelect to register their dynamic groups.

  • Pmw.initialise() can now be called multiple times, with different root arguments, but only sequentially. Pmw does not (yet) support multiple simultaneous interpreters. Modified Pmw.EntryField so that it recreates class bindings when Tkinter.root changes.

4 August 1999

  • Added relmouse option to Pmw.Balloon. Fixed Pmw.Balloon so that the balloon is not displayed off-screen. (Tessa Lau)

16 August 1999

  • Added disableKeyboardWhileBusy option to initialise(). To ignore keyboard input while displaying the busy cursor, Pmw sets the focus for each toplevel window to the Blt busy window. However, under NT, this causes each window to be raised. If this is not acceptable, programs running on NT can request show/hidebusycursor not to ignore keyboard input.

25 August 1999

  • Added Pmw.Blt.busy_forget() and used it in Pmw.hidebusycursor() when running under NT. There is a bug in the Blt busy release command under NT where it sometimes fails to display the busy cursor. Using busy forget avoids the problem.

27 September 1999

  • Added busyCursorName option to Pmw.initialise() and added cursor argument to Pmw.Blt.busy_hold(). (Mark Favas)

20 October 1999

  • Replaced Pmw.NoteBookR and Pmw.NoteBookS with completely rewritten Pmw.NoteBook.

  • Renamed Pmw.OptionMenu.get() to Pmw.OptionMenu.getcurselection() and Pmw.PanedWidget.remove() to Pmw.PanedWidget.delete(), to be more consistent with other megawidgets.

  • The index() method of several megawidgets now use Pmw.END, Pmw.SELECT and Pmw.DEFAULT instead of strings, since these may conflict with component names.

  • Pmw.OptionMenu.index() now uses Pmw.SELECT to return index of the currently selected menu item, rather than None.

  • Added destroy() method to Pmw.MegaArchetype to handle cleaning up of _hullToMegaWidget mapping.

  • Removed exclude argument from Pmw.showbusycursor() and added Pmw.excludefrombusycursor() function instead. (Rob Hooft)

  • Fixed several bugs for Windows NT.

  • Added Pmw.ButtonBox.button() and Pmw.RadioSelect.button().

  • Added Pmw.Color.bordercolors().

21 October 1999

  • Release of version 0.8.3. (Version 0.8.2 was not released.)

30 October 1999

  • Added arrownavigation option and previouspage() and nextpage() methods to Pmw.NoteBook. (Peter Funk)

  • Renamed the setnaturalpagesize() method of Pmw.NoteBook to setnaturalsize() to be consistent with Pmw.PanedWidget.

  • Changed Pmw.excludefrombusycursor() to Pmw.setbusycursorattributes(). Removed busyCursorName option from Pmw.initialise() and added cursorName attribute to Pmw.setbusycursorattributes().

  • Added documentation source and build scripts to ftp site.

6 November 1999

  • Fixed memory leaks when destroying megawidgets. Added automatic check for memory leak to test script used by all tests. Pmw.initialise() now uses a hook into Tkinter.Widget.destroy rather than Tkinter.Frame.destroy to handle the case of Pmw.NoteBook being destroyed (since the notebook hull is a canvas and not a frame). Window manager delete protocol callbacks are now cleaned up. Pmw.ScrolledListBox event bindings now do not leak. (Reported by Jeff Weeks)

  • Removed key bindings for Pmw.ScrolledListBox except space and return keys.

20 November 1999

  • Fixed bug in Pmw.Balloon when the canvas or text item that triggered the balloon is deleted before the balloon is displayed by the initwait timer. (Magnus Kessler)

  • Added 'nograb' to globalMode option of activate() method. (Rob Hooft)

  • Added __setitem__ method to Pmw.MegaArchetype, so that megawidget options can be now set using megawidget['option'] = value style. (Oliver Gathmann)

27 December 1999

  • Converted from regex module to re module, since regex is not implemented for Jpython. (Finn Bock)

30 December 1999

  • Added clear() method to Pmw.ScrolledListBox (suggested by Carson Fenimore).

15 March 2000

  • Fixed problem in PmwBase when deleting windows that were created before Pmw was initialised (such as splash windows displayed while the application is coming up). (Mark Favas)

  • Added splash window to Pmw demo. (Mark Favas)

30 April 2000

  • Added Pmw.MainMenuBar megawidget, which uses the menubar feature of Tk to provide platform specific menu bars.

  • Fixed Pmw.Counter and several other megawidgets so that certain hull constructor keywords, such as hull_relief and hull_borderwidth, are not overriden in the constructor.

  • Thanks to Peter Cashin for his help on how to unpack gzipped tar files on Microsoft Windows operating systems.

  • Added Pmw.HistoryText megawidget. This can be used as the basis of an interactive text-based database query gui. It maintains a history of each query and allows editing of prior queries.

  • Added references to the Pmw.Blt.Graph documentation by Bjorn Ove Thue and Hans Petter Langtangen.

  • Searched for and fixed memory leaks. There are no more known memory leaks.

    • For commands created by bind: these are cleaned up by Tkinter when the widget is destroyed. Pmw.Balloon, which repeatedly binds to the same widget (or item, using tag_bind), has been fixed by passing the old command into the call to unbind or tag_unbind which is cleaned up by Tkinter.

    • For commands created by class_bind: most class bindings are only created once (per Tk interpreter) and so do not need to be cleaned up. The exception is adding and deleting menus in Pmw.MenuBar. This has now been fixed to clean up class_bind commands when deleting menus.

    • Callbacks given to command, xscrollcommand, yscrollcommand, etc options are cleaned up by Tkinter when the widget is destroyed. Cases where Pmw repeatedly sets such options have now been fixed to clean up the old command before configuring the new one. These are in setitems in Pmw.OptionMenu and when modifying the scrollcommand options in several of the scrolled widgets.

    • Pmw now cleans up calbacks it registers with the WM_DELETE_WINDOW protocol for toplevel windows.

  • Added ManualTests.py to tests directory for tests which need to be run by hand.

12 May 2000

  • Release of version 0.8.4.

17 May 2000

  • Modified Pmw.Counter to deal with the presence (python up to 1.5.2) or absence (python 1.6 and after) of an L at the end of the ascii representation of a long. (Mark Favas)

  • Fixed bug in Pmw.ScrolledFrame when given invalid flex options. (Stephen D Evans)

23 January 2001

  • Moved Pmw home from www.dscpl.com.au to pmw.sourceforge.net.

  • Added pmw2 font scheme, since the font used for balloon text with pmw1 is too small on Linux.

  • Removed syntax coloring from code window in demos. It did not look good and the pattern matching was not always correct.

  • Changed font size used for demos to 12 for Unix, since 14 looked too big under Linux.

  • Minor fixes to tests for Tk 8.3.

8 February 2001

  • Release of version 0.8.5

18 February 2001

  • Added xview() and yview() methods to Pmw.ScrolledFrame (suggested by Christer Fernstrom).

  • Made tktrace output more readable.

  • Added noBltBusy option to Pmw.initialise.

  • Fixed bug where combobox dropdown list could stay mapped after entryfield was unmapped.

  • Improved scrolling in scrolled frame.

21 February 2001

  • Fixed tests for recent version of Blt graph (reported by Venkatesh Prasad Ranganath).

  • Fixed problem in Pmw.ScrolledFrame in python 1.5 - string.atof does not accept a number as argument, but it does in python 2.0.

24 February 2001

  • Modified Pmw.OptionMenu documentation to specify that list elements must be strings (problem reported by Guy Middleton).

  • Fixed bug in Pmw.OptionMenu where the wrong item was displayed when an integer item in the menu was selected with the mouse (even though items should be strings).

  • Added work around to Pmw.ScrolledFrame for bug in Tk when retrieving value from scrollbars soon after creation.

27 February 2001

  • Added HistoryText and MainMenuBar to bin/bundlepmw.py - accidently left out.

13 April 2001

  • Changed default foreground (text) of Pmw.Balloown to black. (Eric Pettersen)

  • Added default fontScheme to Pmw.initialise().

  • Added -fontscheme and -fontsize options to demo.

  • Added updatelayout() to Pmw.PanedWidget for use when dynamically adding and deleting panes. (G Cash)

  • Added move() to Pmw.PanedWidget to move panes. (G Cash)

20 April 2001

  • Fixed bug in Pmw.Balloon where the balloon would reappear if the mouse button was pressed down inside a widget and then, while the mouse button was being held down, the mouse was moved outside of the widget and then moved back over the widget.

  • Fixed bug in Pmw.Balloon when destroying widgets while the balloon was up. In this case, the balloon remained displayed even though the widget had been destroyed. (Reported by Stefan Schone.)

  • Fixed bug in Pmw.Balloon when destroying widgets during the initwait period. In this case, an error occurred when the initwait timer went off when it tried to access the destroyed widget. (Reported by Stefan Schone.)

  • Fixed Pmw.Balloon so that unbinding withdraws the balloon if the widget being unbound is the widget which triggered the balloon.

  • Modified Pmw.Balloon so that when deleting a canvas or text item, tagunbind() can be called which will withdraw the balloon if it was triggered by the item. Unfortunately this can not be automated as for widgets since Tk does not support <Destroy> bindings on canvas or text items, so there is no way that Pmw.Balloon can be notified of the deletion of an item.

  • Updated tests for python 2.1.

21 May 2001

  • Pmw.OptionMenu now defaults to taking focus (on <Tab> key).

15 May 2002

  • Fixed bug in Pmw.Graph.element_closest() where element names should follow option arguments. (Val Shkolnikov)

5 June 2002

  • Added command option to Pmw.TimeCounter.

  • Finished all documentation.

  • Fixed bug in documentation creation script which, since python 2.0, printed default values of real options (such as the horizfraction option of Pmw.ScrolledFrame) with too many digits (such as 0.050000000000000003).

  • Fixed bug in setgeometryanddeiconify for cygwin python (John Williams).

4 July 2002

  • Added master option to MegaToplevel.show()

  • Improved MegaToplevel.show() so that tkraise is not called unecessarily, thus avoiding 2 second delay under certain window managers (such as sawfish) in most circumstances. There are still problems with the Enlightenment window manager.

18 August 2002

  • Added columnheader, rowheader and rowcolumnheader components to Pmw.ScrolledText. (Rob Pearson)

  • Added getvalue() and setvalue() methods to several megawidgets as a consistent way to set and get the user-modifiable state. (Cimarron Taylor)

  • Made sub-classing simpler when no new options or components are being created. A sub-class of a Pmw megawidget does not need to have an __init__() method. If it does, it does not need to call defineoptions(). Also, initialiseoptions() no longer requires an argument (for backwards compatibility it may take an argument, but it is ignored).

24 August 2002

  • Release of version 1.0

26 August 2002

  • Minor fixes.

  • Release of version 1.1

4 September 2002

  • Added collapse, expand and toggle methods and collapsedsize option to Pmw.Group. (Rob Pearson)

5 September 2002

  • Added sticky option to several megawidgets.

18 September 2002

  • Added appendtext method to Pmw.ScrolledText. (Graham Dumpleton)

26 September 2002

  • Modified Pmw.ScrolledListBox to call dblclickcommand on <Double-ButtonRelease-1> rather than <Double-ButtonPress-1> which caused problems if the double button press unmapped the ScrolledListBox. In this case, the second button release of the double click is given to another widget. (Eric Pettersen)

14 June 2003

  • Changes for python 2.3 and Tcl/Tk 8.4.2:

    • Wrapped calls to cget() for Tkinter widgets in a call to str(). Before python 2.3 cget() always returned a string. Under python 2.3, Tkinter sometimes returns non-string values (such as int, or Tcl_Obj). Made similar change when using configure() to retrieve values. Fixed tests to handle integer and Tcl_Obj return value from cget(). (Charles Doutriaux)

    • Fixed uses of col field of grid command. Must use full column under Tcl/Tk 8.4.2.

    • Fixed PmwEntryField.py, PmwMessageBar.py, PmwScrolledField.py so that the text is not greyed out under Tcl/Tk 8.4.2. This was caused by a change in behaviour of the 'disabled' state and the Tk entry widget. Now use new 'readonly' state for Tcl/Tk 8.4.2.

    • Test script now ignores Blt test for Tcl/Tk 8.4.2, since it causes Blt 2.4z to core dump. Blt needs to be fixed.

    • Changed Dialog test to work around problem caused by Tk 8.4.2 enforcing transient behaviour of windows. When activate() is called on a dialog whose parent is withdrawn, then the dialog window is made transient. Under old versions of Tk, the transient dialog was displayed, but under 8.4.2 the dialog is not displayed. Work around is to deiconify parent of dialog.

5 August 2003

  • Release of version 1.2

  • Changes for python 2.4 and 2.5:

    5 August 2007

    • In module PmwBase.py: An explicit cast is now required from exception to string (str) .

    • Release of version 1.3

    21 Februar 2010

    • change bin/bundlepmw.py to use module re instead of regsub.

    24 Februar 2010

    • change /bin/env to /usr/bin/env in Tests/ManualTests.py

Pmw 1.3.3 - 29 Mar 2014 - Home

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9311185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/copyright.html0000664000175000017500000000372100000000000020206 0ustar00gregmgregm00000000000000 Pmw copyright

Pmw copyright

Copyright 1997-1999 Telstra Corporation Limited, Australia Copyright 2000-2002 Really Good Software Pty Ltd, Australia

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Pmw 1.3.3 - 29 Mar 2014 - Home

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9351187 Pmw-2.1/Pmw/Pmw_1_3_3/doc/counter1.gif0000664000175000017500000000103700000000000017535 0ustar00gregmgregm00000000000000GIF87a.ق,.80I8ͻ`(dihlp,tmx|pH,dl:ШtJZجvR9P`L.znD~v^ cc ua\[LJL@Ġ>ͳ hʪޜ;۞Pf[ȑ/?i!#sa]t01XZ#Bx` ULӠ$ah*8ѥG4B<ŁC#_N:4SӨI Th)TR;*e`Nv+XHVm2^V/Y7Ox^anJknرORyBY D=BӨ 2Q+S˞M^]৷;УKwسkνËOӫǑ;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9351187 Pmw-2.1/Pmw/Pmw_1_3_3/doc/counter2.gif0000664000175000017500000000247500000000000017545 0ustar00gregmgregm00000000000000GIF87a ~ق, ~0I8ͻC(dihlp,t| ',ȤRF\:Ш՜Zlz7L.z͆-~oH~#. Eb"\be4]@جdL%3 sǚ-1r#kDS?ȒhJ9Q-`9UTf_S@THc'ؕiإbE-+OFyиDpuOd8;6`UfK1]yr.YrzyX[4[_kB~_m53ͩ;ϕM;4ǷqSDkF+3[VNu` 6 6׋7W{ 쩯- y>=|Vfz {old `OaKvЇ%xGu*vߌ$ʏ@r=8$L6EIif RcXfmC[)dgCTp)^hgܩ{ D~z&:&" Njginʩ{~\Fj|jTSFk0筸뮼+Ъrl,,%> IV"i^mnj޾ nKnE*W˺ Nȋ >ěAb/OpKqp 0 2q wTo,KxvWȂ Cz-u~z,d;:CC~f ߗ}{":ݰ̾W{P}lWB,] <9ӯ=9kx /,FK!?͏}W(4 ^z5̑PN3 Qh6N)L8!=<"5$Nd"`ZXb;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9351187 Pmw-2.1/Pmw/Pmw_1_3_3/doc/demosandtests.html0000664000175000017500000002416700000000000021062 0ustar00gregmgregm00000000000000 Pmw demonstrations and tests

Pmw demonstrations and tests

Pmw comes with an extensive range of demonstrations and tests. The demonstrations can be used to get a feel for what is provided by Pmw and the demonstration code can be viewed to see examples of how to use Pmw. The tests can be executed to check that there are no problems with running Pmw in your environment.

Demonstrations

The Pmw demos directory contains demonstration scripts showing many of the features of Pmw megawidgets. To view a comprehensive package of all the demonstrations, including a view of the source code, run the All.py script. Run All.py -help for a short description of the script's options.

All of the demonstrations may also be run separately. Most of the demonstrations show some of the features of one of the Pmw megawidgets. For example, to see a demonstration of the ButtonBox megawidget, change into the demos directory and run

python ButtonBox.py

Other demonstrations, which show other features of Pmw include

BltGraph.py         demonstrates the Pmw interface to
                    the BLT graph and vector commands
BltTabset.py        demonstrates the Pmw interface to
                    the BLT tabset command
Colors.py           how to set color schemes
ConfigClass.py      how to configure the python class
                    of a megawidger component
ErrorHandling.py    how Pmw displays run time errors
                    in a window
ExampleDemo.py      template for new demonstrations
Grid.py             the Tkinter Grid geometry manager
LogicalFont.py      how to use standard values for fonts
MessageInfo.py      how to extend the Pmw MegaToplevel
                    class
NestedDialogs.py    how nested modal dialogs behave
Resources.py        how to use the option database to
                    modify Tk widget option defaults
Resources_Pmw.py    how to use the option database to
                    modify megawidget option defaults
ShowBusy.py         demonstrates the Pmw interface to
                    the BLT busy command
SpecialEntry.py     deriving from Pmw.EntryField
Spectrum.py         some of the Pmw color handling
                    functions
SpeedTest.py        tests the speed of creating Pmw
                    megawidgets
TextDisplay.py      how to extend the Pmw MegaWidget
                    class
WidgetDestroy.py    megawidget destruction
Creating demonstrations of new megawidgets

If you create a new megawidget you can create a demonstration for it by using the file ExampleDemo.py as a template. This template allows the demonstration to be run individually or to be automatically included as part of the demonstration package All.py. You should take a copy of the template and name the new file after your megawidget. You should then replace each instance of the word EXAMPLE with the name of your megawidget and replace the code in the __init__ method with code to create and initialise one or more instances of your megawidget, which should be a child of parent. You can add other methods as necessary.

Tests

The Pmw tests directory contains a test framework and a set of test scripts for Pmw. The tests cover the standard Tkinter module and most of the Pmw megawidgets. The tests make a great demonstration of the flexibility of the megawidgets. Simply change into the tests directory and run python All.py.

If all tests pass there should be no output printed to standard output. If any of the tests fail, please send the test output to the maintainer at gregm@iname.com.

All of the tests may be run separately. Most of the tests test the features of one of the Pmw megawidgets. For example, to execute the test for the ButtonBox megawidget, run

python ButtonBox_test.py

The Test.py file contains general testing functions and is imported by all test files. Other files, which test other features of Pmw include

Blt_test.py           BLT vector and graph interface
Colors_test.py        setting color schemes
MegaWidget_test.py    creation of megawidget classes
Options_test.py       option and component handling
PmwBase_test.py       more option and component handling
Tkinter_test.py       Tk widgets in the Tkinter module
Creating tests for new megawidgets

If you create a new megawidget you should create a test for it. There is no template file for creating tests, but by looking at the other Pmw tests (for example, ScrolledText_test.py) you will get some idea of how to create a test for your megawidget.

The test files are designed to be run both individually or automatically by the test package All.py. Each test file must define the testData tuple. This consists of a sequence of 2-element tuples, each tuple being a test specification for one megawidget. Usually a file tests only one megawidget and so there is only one test specification. The first element in the specification is the megawidget class and the second is a sequence of (yet more) 2-element tuples. In each of these tuples, the first element is a sequence of individual tests to perform on an instance of the megawidget and the second element is a dictionary to use for the keyword arguments when creating the instance. Each individual test is a tuple, the meaning of which depends on the type of the first element, which may be either a string, a function or a method of the megawidget class, as explained below.

  • If the first element is a string, then it is treated as an option of the megawidget and configure() is called to set the option to the value specified by the second element. After setting the option, cget() is called to query the option. If the test tuple has three elements, then the value returned by cget() must equal the value specified by the third element. Otherwise, the value returned must equal the value specified by the second element. For example,

    ('vscrollmode', 'static'),
    ('text_relief', 'sunken'),
    ('vscrollmode', 'bogus', 'ValueError: bad vscrollmode ' +
      'option "bogus": should be static, dynamic, or none'),
    
  • If the first element is a function or method, then the function or method is called. The arguments to the call are given by the second element. (As a special case, if the second element is not a tuple, it is used as the only argument to the call.) The test tuple may have 2, 3 or 4 elements.

    • If it has two elements, then the value returned by the call must be None. For example,

      (c.exportfile, '/tmp/ScrolledText_test.py'),
      (os.unlink, '/tmp/ScrolledText_test.py'),
      
    • If it has four elements, then the third element is a dictionary to use for the keyword arguments in the call and the value returned by the call must equal the value specified by the fourth element. For example,

      (c.search, ('abc', '0.0'), {'nocase': 1}, '2.24'),
      
    • If is has three elements and the third element is a dictionary, then it is used for the keyword arguments in the call and the value returned by the call must be None. For example

      (c.configurepane, 'first', {'size' : 200}),
      
    • If is has three elements and the third element is not a dictionary, then the value returned by the call must equal the value specified by the third element. For example,

      (c.components, (), ['hull', 'label']),
      (c.add, ('Legumes',),
        'ValueError: name "Legumes" already exists'),
      

Some special functions and values supplied by the Test module that may be used in the tests include:

Test.callback       callback taking no arguments
Test.callback1      callback taking one argument
Test.callbackN      callback taking any number of arguments

Test.currentWidget  returns the widget instance being tested
Test.num_options    returns number of options for the widget

Test.earthris       a sample Tkinter.PhotoImage
Test.flagup         a sample Tkinter.BitmapImage
Test.floatvar       a Tkinter.DoubleVar
Test.stringvar      a Tkinter.StringVar

To slow down a test (to see what is being displayed), add the following line which sets the delay between tests to (say) 1000 milliseconds:

Test.setdelay(1000)

To print information about what is being tested, add the line:

Test.setverbose(1)

Pmw 1.3.3 - 29 Mar 2014 - Home

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9311185 Pmw-2.1/Pmw/Pmw_1_3_3/doc/dynamicloader.html0000664000175000017500000001630000000000000021006 0ustar00gregmgregm00000000000000 Dynamic loader

Dynamic loader

There are two aspects of Pmw, unrelated to megawidgets, that require special attention. Firstly, Pmw is made up of many sub-modules, potentially making access to its various classes and functions cumbersome for the user. Secondly, Pmw is regularly being modified and added to, thus requiring the release of new versions. Therefore, techniques for making access to the sub-modules easy and efficient and for dealing with the different versions have been developed. These techniques are incorporated into the dynamic loader which Pmw creates when it is first imported.

The first purpose of the loader is to give access to all Pmw classes and functions through a single entry point, the Pmw. prefix. For example, to access the ComboBox class (which resides in one of the sub-modules of Pmw), you just have to use Pmw.ComboBox. Without the loader, this would be a more complicated reference, such as, hypothetically, Pmw.PmwComboBox.ComboBox.

The second purpose of the loader is to delay the importing of the sub-modules until they are needed. This improves the startup time of applications which only use a few Pmw megawidgets. It also allows more megawidgets to be added to the library without slowing down applications which do not use them.

The third purpose of the loader is to allow a script using Pmw to specify which version of Pmw it requires. This allows an application to continue working correctly even after newer releases of Pmw have been made which are not compatible with the version expected by the application. Several versions of Pmw can be installed at once, with the actual version used being specified by each application. In addition, the loader can be configured to search in one or more alpha versions of Pmw. These versions may contain new megawidgets, or new versions of existing megawidgets, that are currently not in the base releases.

Several functions are available to set and query the version of Pmw being used. These are Pmw.setversion() and Pmw.setalphaversions() which specify the version and alpha versions (if any) to use for this session; Pmw.version() which returns the version(s) being used by this session; and Pmw.installedversions() which returns the version(s) of Pmw currently installed. These are described in the Pmw functions reference manual.

When Pmw is first imported, an instance of PmwLoader is created and placed into sys.modules['Pmw']. From that point on, any reference to attributes of the Pmw 'module' is handled by the loader. The real Pmw package is stored in sys.modules['_Pmw'].

The loader searches the Pmw package base directory for sub-directories with the prefixes Pmw_ and Alpha_, which contain Pmw base releases and alpha releases. The version numbers are given by the part of the directory name following the prefix. These versions are available for use and are those returned by the Pmw.installedversions function. The initial version is set to the base release with the greatest version number. When the first reference to a Pmw class or function is made, the loader reads the files named Pmw.def in the current base version directory and also in the alpha directories (if any). These files list all the classes and functions supported by the version. Pmw attributes are first searched for in the alpha directories and then in the base version directory. The first directory which supports the reference is used. In this way, alpha versions override base versions.

The directory Alpha_99_9_example contains a simple example of how to structure an alpha version. The following code can be used to request that the alpha version be used and then creates an instance of a new megawidget defined in the alpha version.

 import Pmw
 Pmw.setalphaversions('99.9.example')

 # Create a standard message dialog using the base Pmw version.
 ordinary = Pmw.MessageDialog(
     message_text = 'Ordinary\nPmw Dialog')

 # Create an example dialog using the alpha Pmw version.
 alpha = Pmw.AlphaExample()

Freezing Pmw

Since the dynamic loader requires that Pmw be installed at run time, it can not be used when freezing Pmw. In this case, a single module containing all Pmw code is required, which can then be frozen with the rest of the application's modules. The bundlepmw.py script in the Pmw bin directory can be used to create such a file. This script concatenates (almost) all Pmw megawidget files into a single file, Pmw.py, which it writes to the current directory. The script is called like this:

 bundlepmw.py [-noblt] [-nocolor] /path/to/Pmw/Pmw_X_X_X/lib

The last argument should be the path to the lib directory of the required version of Pmw. By default, the Pmw.py file imports the PmwBlt and PmwColor modules and so, to freeze an application using Pmw, you will need to copy the files PmwBlt.py and PmwColor.py to the application directory before freezing.

If you are sure that your application does not use any of the Pmw.Blt or Pmw.Color functions, you can use the -noblt or -nocolor options. In this case Pmw.py will be modified so that it does not import these module(s) and so will not need to be included when freezing the application.

If your application only uses a few Pmw megawidgets, you can remove the references to the usused ones in the files list in the bundlepmw.py code. To make the change, take a copy of the script and modify it. This will make the Pmw.py file smaller. However, be sure that you do not delete megawidgets that are components or base classes of megawidgets that you use.

Pmw 1.3.3 - 29 Mar 2014 - Home

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9351187 Pmw-2.1/Pmw/Pmw_1_3_3/doc/example.py0000664000175000017500000000412600000000000017315 0ustar00gregmgregm00000000000000import Tkinter import Pmw class ThresholdScale(Pmw.MegaWidget): """ Megawidget containing a scale and an indicator. """ def __init__(self, parent = None, **kw): # Define the megawidget options. optiondefs = ( ('colors', ('green', 'red'), None), ('threshold', 50, None), ('value', None, Pmw.INITOPT), ) self.defineoptions(kw, optiondefs) # Initialise base class (after defining options). Pmw.MegaWidget.__init__(self, parent) # Create the components. interior = self.interior() # Create the indicator component. self.indicator = self.createcomponent('indicator', (), None, Tkinter.Frame, interior, width = 16, height = 16, borderwidth = 2, relief = 'raised') self.indicator.grid() # Create the scale component. self.scale = self.createcomponent('scale', (), None, Tkinter.Scale, interior, command = self._doCommand, tickinterval = 20, length = 200, from_ = 100, to = 0, showvalue = 0) self.scale.grid() value = self['value'] if value is not None: self.scale.set(value) # Check keywords and initialise options. self.initialiseoptions() def _doCommand(self, valueStr): if self.scale.get() > self['threshold']: color = self['colors'][1] else: color = self['colors'][0] self.indicator.configure(background = color) Pmw.forwardmethods(ThresholdScale, Tkinter.Scale, 'scale') # Initialise Tkinter and Pmw. root = Pmw.initialise() root.title('Pmw ThresholdScale demonstration') # Create and pack two ThresholdScale megawidgets. mega1 = ThresholdScale() mega1.pack(side = 'left', padx = 10, pady = 10) mega2 = ThresholdScale( colors = ('green', 'yellow'), threshold = 75, value = 80, indicator_width = 32, scale_width = 25) mega2.pack(side = 'left', padx = 10, pady = 10) # Let's go. root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9351187 Pmw-2.1/Pmw/Pmw_1_3_3/doc/example1.gif0000664000175000017500000000301700000000000017511 0ustar00gregmgregm00000000000000GIF87aAق,A80I8ͻ`(dihlp,tmx|pH,Ȥrl:ШtJZ `zxL.zn|$+^gGny  ~ n} O[ NHʾ}KFҨ .ݝ ᯪЀu(sA x(A"E{& /B9uP_#QN.bG+1,PfȚ$g`{^pCt/\e ys'N5Ϩ>v5&գ3φh( -Ze[kTjm]3jw>&8O_ I԰g[!;G۷9iv*ؤ꫰ fjE~ZgzRšæPǖPhЬdySZv̵\y-r&Bfkh gUnOvzIGYw V_;fV]tF qRZ#MkG/r]W1(.Ro2ؽv!VZx9ǯjh<WU}ta/3KP@"d1L?s}tP3@Y>lzҍHrL:v(I(6E!2<.EH@#.T6sLN+; i O3wtaMSD`%IU8뎥05Mͫ.kb- h?u$" G+A2(,["prMv ɧ!(xy+~J) @Ҥi=h)`>7Ї&{6½WxV݀s؟_o߸~ᄒihW (Zx9߁'n _-5\؟raz΅tg]ؑ !z}Wk^yZbwT0V:X}蠍ޑ/hYa%~T: }SlqMh%pmbf"F&[=`HGBiUո&p%AZgyxPKds-J類b() sRhY꥾E)}"d&:)fJ*Rf鐫b-Wjhfcb j⪭mJabi$ꩵZ#N {eyVӞ9dV,2로F˰pa"my\OBs^ " lcv|crXk7[[/;1cb9(y^@T Pn XmLCsY t($ݗ=Ԯ`oҰ5ig@4'=B@T&=w< |wE&Sn",:>ِP``[H^ H@.tl? 4/?.',7?/=Togw/o觯/o HL:'H Z̠7z GH(L W0 gH8̡w@ E3b6=s]LESHQFT")*-b01Q?h=dl<#8ZQљ %xTxGUH9bUXHMYl)YkL$FLq "=ɎM\c #)CA2R+Y1r֨enhlD,/M s1Leol&"d7=nHӘ5nz 8IrL:v;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9351187 Pmw-2.1/Pmw/Pmw_1_3_3/doc/exercises.py0000664000175000017500000000705400000000000017657 0ustar00gregmgregm00000000000000import Tkinter import Pmw class ThresholdScale(Pmw.MegaWidget): """ Megawidget containing a scale and an indicator. """ def __init__(self, parent = None, **kw): # Define the megawidget options. optiondefs = ( ('colors', ('green', 'red'), None), ('orient', 'vertical', Pmw.INITOPT), ('labelmargin', 0, Pmw.INITOPT), ('labelpos', None, Pmw.INITOPT), ('threshold', (50,), None), ('value', None, Pmw.INITOPT), ) self.defineoptions(kw, optiondefs) # Initialise base class (after defining options). Pmw.MegaWidget.__init__(self, parent) # Create the components. interior = self.interior() # Create the indicator component. self.indicator = self.createcomponent('indicator', (), None, Tkinter.Frame, interior, width = 16, height = 16, borderwidth = 2, relief = 'raised') # Create the value component. self.value = self.createcomponent('value', (), None, Tkinter.Label, interior, width = 3) # Create the scale component. if self['orient'] == 'vertical': # The default scale range seems to be # the wrong way around - reverse it. from_ = 100 to = 0 else: from_ = 0 to = 100 self.scale = self.createcomponent('scale', (), None, Tkinter.Scale, interior, orient = self['orient'], command = self._doCommand, tickinterval = 20, length = 200, from_ = from_, to = to, showvalue = 0) value = self['value'] if value is not None: self.scale.set(value) # Use grid to position all components if self['orient'] == 'vertical': self.indicator.grid(row = 1, column = 1) self.value.grid(row = 2, column = 1) self.scale.grid(row = 3, column = 1) # Create the label. self.createlabel(interior, childRows=3) else: self.indicator.grid(row = 1, column = 1) self.value.grid(row = 1, column = 2) self.scale.grid(row = 1, column = 3) # Create the label. self.createlabel(interior, childCols=3) # Check keywords and initialise options. self.initialiseoptions() def _doCommand(self, valueStr): valueInt = self.scale.get() colors = self['colors'] thresholds = self['threshold'] color = colors[-1] for index in range(len(colors) - 1): if valueInt <= thresholds[index]: color = colors[index] break self.indicator.configure(background = color) self.value.configure(text = valueStr) Pmw.forwardmethods(ThresholdScale, Tkinter.Scale, 'scale') # Initialise Tkinter and Pmw. root = Pmw.initialise() root.title('Pmw ThresholdScale demonstration') # Create and pack two ThresholdScale megawidgets. mega1 = ThresholdScale(scale_showvalue = 1) mega1.pack(side = 'left', padx = 10, pady = 10) mega2 = ThresholdScale( colors = ('green', 'yellow', 'red'), threshold = (50, 75), value = 80, indicator_width = 32, scale_width = 25) mega2.pack(side = 'left', padx = 10, pady = 10) # Create and pack two horizontal ThresholdScale megawidgets. mega3 = ThresholdScale( orient = 'horizontal', labelpos = 'n', label_text = 'Horizontal') mega3.pack(side = 'top', padx = 10, pady = 10) mega4 = ThresholdScale(orient = 'horizontal') mega4.pack(side = 'top', padx = 10, pady = 10) # Let's go. root.mainloop() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9351187 Pmw-2.1/Pmw/Pmw_1_3_3/doc/features.html0000664000175000017500000000544700000000000020023 0ustar00gregmgregm00000000000000 Pmw features

Pmw features

Pmw is a toolkit for building high-level compound widgets, or megawidgets, constructed using other widgets as component parts. It promotes consistent look and feel within and between graphical applications, is highly configurable to your needs and is easy to use.

Pmw consists of:

  • A few base classes, providing a foundation for building megawidgets.

  • A library of flexible and extensible megawidgets built on the base classes, such as buttonboxes, notebooks, comboboxes, selection widgets, paned widgets, scrolled widgets and dialog windows.

  • A lazy importer/dynamic loader which is automatically invoked when Pmw is first imported. This gives unified access to all Pmw classes and functions through the Pmw. prefix. It also speeds up module loading time by only importing Pmw sub-modules when needed.

  • Complete reference documentation, covering all classes and functions including all megawidgets and their options, methods and components. Helpful tutorial material is also available.

  • A test framework and tests for Pmw megawidgets.

  • A slick demonstration of the megawidgets.

  • An interface to the BLT busy, graph and vector commands.

The interface to Pmw megawidgets is similar to basic Tk widgets, so it is easy for developers to include both megawidgets and basic Tk widgets in their graphical applications. In addition, Pmw megawidgets may themselves be extended, using either inheritance or composition.

The use of the Pmw megawidgets replaces common widget combinations with higher level abstractions. This simplifies code, making it more readable and maintainable. The ability to extend Pmw megawidgets enables developers to create new megawidgets based on previous work.

Pmw 1.3.3 - 29 Mar 2014 - Home

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9351187 Pmw-2.1/Pmw/Pmw_1_3_3/doc/halfblueball.gif0000664000175000017500000000045300000000000020413 0ustar00gregmgregm00000000000000GIF87a{Bxcv{j{j1{!v^h_YNIL=s0c!Jc;k-Z*J1`HsJw,P@pH,Ā`0p@$p< Gc (ʢX,LFsTl2G !"#}$!!$%mBA;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9351187 Pmw-2.1/Pmw/Pmw_1_3_3/doc/howtobuild.html0000664000175000017500000003365700000000000020371 0ustar00gregmgregm00000000000000 How to build Pmw megawidgets

How to build Pmw megawidgets

Introduction

This document briefly describes how to design and code Pmw megawidgets by inheriting from the Pmw base classes. It shows step by step how to build a simple example megawidget. This megawidget allows the user to select one of a range of numbers and it also indicates if the selected number is greater than a given threshold.

Choosing the components

The megawidget will be built using a Tkinter.Scale widget to allow the user to select a number in a range, and a Tkinter.Frame widget to act as an indicator, displaying red (say) if the selected number exceeds the threshold. It will look something like this:

Scale 2

The programmer using this megawidget will need access to the scale widget, since they will need to set the scale's range. Therefore the scale will be made a component of the megawidget. The programmer will probably not need access to the indicator frame, but, just in case the need arises to change the borderwidth or relief of the indicator, we will make it a component too. This illustrates a convention about components - for maximum configurability, make all sub-widgets components.

Choosing the options

Apart from the component options now available through the scale and indicator components, the megawidget will need a few options of its own. It will need a threshold option to set the threshold. It may also need options to set the colors of the indicator when the selected value is both above and below the threshold. Other options could be orient or indicatorpos to specify the relative position of components and margin, padx or pady to specify spacing between and around the components. For this example, we will define three options - threshold, colors and value. The colors option will be a 2-element sequence specifying two colors (below threshold, above threshold). The value option will be the initial value of the scale.

Coding the megawidget

The first things to do are to decide on a name for the new megawidget, decide which base class to inherit from and to begin to write the constructor. Most Pmw megawidgets are derived from either Pmw.MegaWidget, Pmw.MegaToplevel or Pmw.Dialog. In this case, since the widget is not to be contained within its own toplevel window, we will inherit from Pmw.MegaWidget. The constructors of megawidgets take one argument (the widget to use as the parent of the megawidget's hull, defaulting to the root window) and any number of keyword arguments.

class ThresholdScale(Pmw.MegaWidget):
    """ Megawidget containing a scale and an indicator.
    """
 
    def __init__(self, parent = None, **kw):

Next, we need to define the options supplied by this megawidget. Each option is specified by a 3-element sequence. The first element is the option's name. The second element is the default value. The third element is either a callback function, Pmw.INITOPT or None. In the first case, the function is called at the end of construction (during the call to self.inialiseoptions) and also whenever the option is set by a call to configure. Pmw.INITOPT indicates that the option is an initialisation option - it cannot be set by calling configure. None indicates that the option can be set by calling configure, but that there is no callback function.

The call to self.defineoptions also includes the keyword arguments passed in to the constructor. The value given to any option specified in the keywords will override the default value.

        # Define the megawidget options.
        optiondefs = (
            ('colors',    ('green', 'red'), None),
            ('threshold', 50,               None),
            ('value',     None,             Pmw.INITOPT),
        )
        self.defineoptions(kw, optiondefs)

After defining the options, the constructor of the base class should be called. The options need to be defined first so that a derived class can redefine the default value of an option defined in a base class. This is because the value specified by the derived class must be made available before the base class constructor is called. The keyword arguments should not be passed into the base class constructor since they have already been dealt with in the previous step.

        # Initialise base class (after defining options).
        Pmw.MegaWidget.__init__(self, parent)

Now we should create the components. The components are created as children (or grandchildren ...) of the megawidget's interior.

        # Create the components.
        interior = self.interior()

The first component to create is the indicator. The createcomponent method creates the sub-widget and registers the widget as a component of this megawidget. It takes five arguments plus any number of keyword arguments. The arguments are name, aliases, group, class and constructor arguments. See the Pmw.MegaArchetype reference manual) for full details.

        # Create the indicator component.
        self.indicator = self.createcomponent('indicator',
                (), None,
                Tkinter.Frame, (interior,),
                        width = 16,
                        height = 16,
                        borderwidth = 2,
                        relief = 'raised')
        self.indicator.grid()

The scale component is created in a similar way. In this case, the initial value of the scale is also set to the value of the value initialisation option.

        # Create the scale component.
        self.scale = self.createcomponent('scale',
                (), None,
                Tkinter.Scale, (interior,),
                        command = self._doCommand,
                        tickinterval = 20,
                        length = 200,
                        from_ = 100,
                        to = 0,
                        showvalue = 0)
        self.scale.grid()
 
        value = self['value']
        if value is not None:
            self.scale.set(value)

At the end of the constructor, the initialiseoptions method is called to check that all keyword arguments have been used (that is, the caller did not specify any unknown or misspelled options) and to call the option callback functions.

        # Check keywords and initialise options.
        self.initialiseoptions()

All other methods must now be defined. In this case, only one method is required - a method called whenever the scale changes and which sets the indicator color according to the threshold.

    def _doCommand(self, valueStr):
        if self.scale.get() > self['threshold']:
            color = self['colors'][1]
        else:
            color = self['colors'][0]
        self.indicator.configure(background = color)

To complete the megawidget, methods from other classes can be copied into this class. In this case, all Tkinter.Scale methods not already defined by the megawidget are made available as methods of this class and are forwarded to the scale component. Note that the third argument to Pmw.forwardmethods is the name of the instance variable referring to the Tkinter.Scale widget and not the name of the component. This function is called outside of and after the class definition.

Pmw.forwardmethods(ThresholdScale, Tkinter.Scale, 'scale')

Important note: If a megawidget defines options using defineoptions(), then this method must be called in the megawidget constructor before the call to the base class constructor and a matching call to initialiseoptions() must made at the end of the constructor. For example:

    def __init__(self, parent = None, **kw):
	optionDefs = ...
	self.defineoptions(kw, optionDefs)
	BaseClass.__init__(self, parent)
	...
	self.initialiseoptions()

Creating instances of the megawidget

The code below creates two of our example megawidgets. The first is created with default values for all options. The second is created with new values for the options. It also redefines some of the options of the components.

# Create and pack two ThresholdScale megawidgets.
mega1 = ThresholdScale()
mega1.pack(side = 'left', padx = 10, pady = 10)

mega2 = ThresholdScale(
        colors = ('green', 'yellow'),
        threshold = 75,
        value = 80,
        indicator_width = 32,
        scale_width = 25)
mega2.pack(side = 'left', padx = 10, pady = 10)

Scale 1

The complete code

The complete code for this example can be seen here.

Exercises

These exercises build on the example presented so far.

  1. Change the call to create mega1 so that the scale widget displays the current value next to the slider. (You may need to look at the Tk scale manual page to find which option to the scale component to set.) You will be able to do this without modifying the ThresholdScale class code.
  2. Add a Tkinter.Label component between the indicator and scale components. Modify the _doCommand method so that it displays the current value of the scale in this label.
  3. Modify the colors and threshold options so that they both accept a tuple. Now implement multiple thresholds, so that the indicator displays one of several colors, depending on the value of the scale.
  4. Add an orient initialisation option and lay out the components horizontally or vertically depending on its value.
  5. Read the description of the createlabel() method in the Pmw.MegaArchetype reference manual and add labelpos and labelmargin initialisation options which allow the creation of a label for the megawidget.

An example of how these changes can be made can be seen here.

Contributing your megawidgets to Pmw

If you have completed a megawidget that may be useful to others, you may like to consider contributing it to Pmw. See Contributions welcome for how to contribute.

Pmw coding conventions

As a final note, the Pmw code makes an attempt to follow these coding conventions.

  • Class names: initial of each word is upper case (including first word).
  • Public method and function names: all in lower case.
  • Megawidget options: all in lower case.
  • Megawidget component names: all in lower case.
  • Function arguments: initial of each word is upper case (except first word).
  • Private names: initial of each word is upper case (except first word if not a class)
  • Underscores as word separators are only used when overriding Tkinter methods of same name.
  • Indent is four spaces.
  • Continuation lines are indented by eight spaces, so that they won't be confused with a following nested code block. Continuation lines should be used when a statement, which would normally be written on one line, is longer than 80 characters. Examples are "if" statements which contain many conditions and function calls with many arguments.
  • Surround = with spaces when used with keyword parameters in function calls.
  • Multi-line function calls should have one keyword parameter per line.

Pmw 1.3.3 - 29 Mar 2014 - Home

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9351187 Pmw-2.1/Pmw/Pmw_1_3_3/doc/howtouse.html0000664000175000017500000004514300000000000020057 0ustar00gregmgregm00000000000000 How to use Pmw megawidgets

How to use Pmw megawidgets

Introduction

This document briefly describes the features of the Pmw megawidget toolkit and how to use the megawidgets. Using examples, it describes those features common to all Pmw megawidgets. For a description of individual Pmw megawidgets see the reference manuals. For complete information on general Pmw megawidget functionality see the Pmw.MegaArchetype reference manual. For a lot more example code, run any of the files in the Pmw demos directory.

A simple example of a megawidget is a counter. This widget contains an entry field and two small arrow buttons. Users may enter a value directly into the entry field or they may use the buttons to increment and decrement the value displayed without having to use the keyboard. Having this and other megawidgets in your toolbox allows you to choose the best graphical interface for your application.

Getting started

Initialisation of Pmw

To run the examples in the tutorial, make sure that the Pmw lib directory is in sys.path. You should be able to cut and paste the examples into an interactive python session, or you can copy them to a file and run the file with python.

The following two lines should be entered before any of the examples. These import and initialise Pmw. For more information on Pmw.initialise() see the Pmw functions reference manual.

import Pmw
root = Pmw.initialise()

If necessary, you can have more control over how Tkinter and Pmw are initialised by using this form of initialisation:

import Tkinter
root = Tkinter.Tk()
import Pmw
Pmw.initialise(root)

Megawidget construction

Creating a counter

Now that you have the formalities out of the way, you can create and pack a counter megawidget (see Pmw.Counter reference manual) using its default configuration like this:

counter1 = Pmw.Counter()
counter1.pack(padx = 10, pady = 10)

Now enter a number and click on the arrow buttons to see the number increment or decrement. The result looks something like this:

Counter 1

The above example creates the counter as a child of the root window. If you want to create it as a child of another window (for example, a Tkinter.Frame widget called 'frame'), add the parent as an argument to the constructor:

counter1a = Pmw.Counter(frame)

Methods

Once a megawidget has been created, you can call any of its other methods in a similar way to Tk widgets. The following sets the value of the counter and then increments it:

counter1.setentry(41)
counter1.increment()

Options

Like any widget, a megawidget may have options to allow it to be configured for a particular use. Options allow the megawidget user to modify the appearance and behaviour of the megawidget. The counter megawidget has several such options. One of them, datatype, specifies how the counter should count up and down, such as, for example, by integers, reals, times or dates. The default value is 'numeric', which means the counter expects integers to be entered and will support incrementing and decrementing by whole numbers.

Another option is increment, which specifies how many units should be added or subtracted when the counter is incremented or decremented. Using these options, you can create a time counter, supporting the format HH:MM:SS, and counting in minutes, like this (note also the call to the setentry method to set the contents of the entry field):

counter2 = Pmw.Counter(
    datatype = 'time',
    increment = 60)
counter2.setentry('00:00:00')
counter2.pack(padx = 10, pady = 10)

Many megawidget options can be modified using the configure() method. For example, you can change the value of the increment option to 10 minutes like this:

counter2.configure(increment = 60 * 10)
Initialisation options

Some megawidget options can only be set when creating the megawidget. These options can not be set by calling the configure() method, but they can be queried in all the usual ways. For example, the counter has an orient initialisation option which specifies whether the arrow buttons should appear to the left and right of the entry field ('horizontal') or above and below ('vertical'). You can create a numeric counter with arrow buttons above and below the entry field like this:

counter3 = Pmw.Counter(orient = 'vertical')
counter3.pack(padx = 10, pady = 10)
Querying options

You can query the value of megawidget options (initialisation or not) in similar ways as for normal Tkinter widgets. For example, the following code prints the values of some of the counter options.

print counter3.cget('increment')
    --> 1
print counter3.configure('orient')
    --> ('orient', 'orient', 'Orient', 'horizontal', 'vertical')

When a Tk widget option is queried, its value is always returned as a string, regardless of the type used when setting the option. However, when a Pmw megawidget option is queried, a reference to the object used when setting the option is returned. In other words it is not always a string. For example, the type returned by cget('increment') above was integer.

Components

Megawidgets are made up of other widgets, which we call components. Each component is known by a logical name and may be either a simple Tk widget, or may itself be a megawidget. Pmw gives the megawidget user access to not only the functionality supported directly by the megawidget through its options and methods, but also to the components of the megawidget and their options and methods. To access a component directly, use the component() method. For example, to call method doit of component comp of megawidget mega:

mega.component('comp').doit()
Component options

There is a short-hand way to access the options of components, by using the notation component_option. This allows, for example, a counter megawidget to be configured with different colored backgrounds for each of its arrow button components (these components are called downarrow and uparrow):

counter2.configure(
    downarrow_background = 'green',
    uparrow_background = 'red')
The hull

All megawidgets are enclosed in a containing widget which is created automatically by the Pmw base classes. For normal megawidgets the container is a Tkinter Frame widget. For megawidgets which are toplevel windows, the container is a Tkinter Toplevel widget. The containing widget is accessible as the hull component.

To access options of the containing widget use the form hull_option. For example to create a counter megawidget with a wide sunken border around it:

counter4 = Pmw.Counter(
    hull_relief = 'sunken',
    hull_borderwidth = 5 
)
The interior

Some megawidgets, such as Dialog and LabeledWidget, also have a frame into which users can pack other widgets. This frame may be a component but can also be accessed with the interior() method. For the Pmw.MegaToplevel and Pmw.MegaWidget classes, the interior widget is the same as the hull widget. For other megawidgets, the hull is the outer, containing widget and the interior is the empty frame which can be used to extend the megawidget by including extra internal widgets.

Sub components and aliases

Components may themselves be megawidgets and so their (sub-)components can be referred to using the notation component_sub-component. For example, the entryfield component of the counter is a Pmw.EntryField megawidget (which handles the input validation). In turn, this has a Tkinter.Entry component named entry. Therefore, you can change the background of the counter's Tkinter.Entry widget with:

counter2.configure(entryfield_entry_background = 'yellow')

Most component path names (like entryfield_entry) have a shorter alias defined for them. In this case, you can use the equivalent:

counter2.configure(entry_background = 'yellow')
Changing the python class of a component

Each megawidget component is an instance of some python class. The default class of each component is given in the reference manual. By using the special pyclass component option, you can specify a different python class to use when creating the component. For example, to create a Pmw.Counter megawidget which has a Tkinter.Button as its label, rather than the default Tkinter.Label:

counter5 = Pmw.Counter(
        labelpos = 'w',
        label_text = 'Hello',
        label_pyclass = Tkinter.Button
)

Forwarding methods

Since a Pmw megawidget is a normal python class, it both inherits methods from its base classes and also may have other methods defined for it in the usual way. Pmw also supports a third way that a megawidget may gain methods - by 'forwarding' methods to one or more of its subwidgets. This is also known as 'delegating'. For example, a Pmw.Counter megawidget delegates the methods related to its Pmw.EntryField component, entryfield, to the component. It does not have to explicitely define methods which call the component methods. This is why we can call counter2.setentry() - since setentry() is a method of the Pmw.EntryField component, it is available to the Pmw.Counter.

Methods already defined by a class or its base classes take precedence over delegated methods. For example, Pmw.Counter inherits a cget method from Pmw.MegaArchetype. Therefore, this method is not delegated to the cget method of Pmw.EntryField.

Extending Pmw megawidgets

There are several ways of extending Pmw megawidgets. Firstly, the flexibility of the options and components allows the widget's appearance and behaviour to be greatly modified. Secondly, widgets of the user's choice can be added inside some megawidgets by using the interior() method. The Pmw classes MegaToplevel, MegaWidget, Dialog and LabeledWidget are particularly designed to be extended in this way. For example, to create a dialog window containing a counter:

dialog = Pmw.Dialog(
        title = 'Counter dialog',
        buttons = ('OK', 'Cancel'))
interior = dialog.interior()
counter = Pmw.Counter(interior)
counter.pack(padx = 20, pady = 20)

Counter 2

A third way to extend megawidgets is to inherit from (or subclass) them. See How to build Pmw megawidgets for information on how to use inheritance to extend a megawidget by adding new options. For simpler cases, where new methods are to be added to an existing megawidget and/or the default values for some options are to be changed, normal subclassing can be used. For example, to create new classes based on a Pmw.Counter, one with a new method getminutes() and one with a default datatype of 'time' and a white entry background:

class MinuteCounter1(Pmw.Counter):

    def getminutes(self):
	return Pmw.timestringtoseconds(self.getvalue()) / 60

class MinuteCounter2(Pmw.Counter):

    def __init__(self, parent = None, **kw):
        kw['datatype'] = 'time'
        kw['entry_background'] = 'white'
        kw['entryfield_value'] = '00:00:00'
        kw['increment'] = 60
	apply(Pmw.Counter.__init__, (self, parent), kw)

A quick example

The following code is a small example of how to use Pmw megawidgets. It is a complete program which displays three ways for the user to enter a value - using an up-down counter, an entry field with validation and a dropdown combobox.

import Pmw
root = Pmw.initialise(fontScheme = 'pmw1')

counter = Pmw.Counter(
        label_text = 'Counter:',
        labelpos = 'w',
        entryfield_value = '00:00:00',
        entryfield_validate = 'time',
        datatype='time',
        increment=5*60,
)
counter.pack(fill = 'x', padx = 10, pady = 10)

entry = Pmw.EntryField(
        label_text = 'Real entry:',
        labelpos = 'w',
        value = '+2.9979e+8',
        validate = 'real',
)
entry.pack(fill = 'x', padx = 10, pady = 10)

combo = Pmw.ComboBox(
        label_text = 'ComboBox:',
        labelpos = 'w',
        scrolledlist_items = map(str, range(20))
)
combo.pack(fill = 'x', padx = 10, pady = 10)

# Make the labels line up neatly
Pmw.alignlabels((counter, entry, combo))

root.title('Pmw megawidgets example')
root.mainloop()

Example 1

Another example

The following also shows how to use Pmw megawidgets. It displays a RadioSelect megawidget and an exit button packed into the root window.

import Tkinter
import Pmw

def callback(tag):
    # This is called whenever the user clicks on a
    # button in the RadioSelect widget.
    print tag, 'was pressed.'

# Initialise Tkinter and Pmw.
root = Pmw.initialise(fontScheme = 'pmw1')
root.title('Pmw RadioSelect demonstration')

# Create and pack a RadioSelect widget.
radio = Pmw.RadioSelect(
        command = callback,
        labelpos = 'w',
        label_text = 'Food group:')
radio.pack(padx = 20, pady = 20)

# Add some buttons to the RadioSelect.
for text in ('Fruit', 'Vegetables', 'Cereals', 'Legumes'):
    radio.add(text)
radio.invoke('Vegetables')

# Create an exit button.
exit = Tkinter.Button(text = 'Exit', command = root.destroy)
exit.pack(pady = 20)

# Let's go.
root.mainloop()

Example 2

Using the Tk option database

There are several ways to use the Tk option database to customise a Pmw application. Firstly you can customise all the basic Tk widgets in the usual way. For example, to set the background of all Tkinter.Label widgets (whether a megawidget component or not):

root.option_add('*Label.background', 'pink')

To set the background of all Pmw.EntryField label components:

root.option_add('*EntryField.Label.background', 'green')

To set the background of all Pmw.EntryField components, including the hull component:

root.option_add('*EntryField*background', 'blue')

The above option settings affect basic Tk widgets and, since it is built into the Tk widgets, this functionality is always available. However, to be able to use the Tk option database to set the default values for Pmw megawidget options, Pmw.initialise() must be called with useTkOptionDb = 1. If this is not done, Pmw does not query the Tk option database for megawidget option defaults. This is the default behaviour because there is a slight performance penalty for using the Tk option database.

Assuming useTkOptionDb has been set, the default buttonbox position of all Pmw.Dialog megawidgets can be changed with:

root.option_add('*Dialog.buttonboxpos', 'e')

To set the label position of all Pmw.EntryField megawidgets, thus giving them a label component by default:

root.option_add('*EntryField.labelpos', 'w')

Pmw 1.3.3 - 29 Mar 2014 - Home

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9391186 Pmw-2.1/Pmw/Pmw_1_3_3/doc/index.html0000664000175000017500000001001100000000000017273 0ustar00gregmgregm00000000000000 Pmw megawidgets 1.3.3

Pmw 1.3.3

Python megawidgets

Pmw is a toolkit for building high-level compound widgets in Python using the Tkinter module.

It consists of a set of base classes and a library of flexible and extensible megawidgets built on this foundation. These megawidgets include notebooks, comboboxes, selection widgets, paned widgets, scrolled widgets, dialog windows, etc.

Local documentation

Main features
Getting started - including downloading and installation
How to use Pmw megawidgets - creating and configuring megawidgets
How to build Pmw megawidgets - inheriting (sub-classing) from Pmw megawidgets
Demonstrations and tests - how to run
Dynamic loader - also discusses how to "freeze" Pmw
Reference manuals - complete documentation of all Pmw classes and functions
Porting between different versions of Pmw
Change log
Todo list and list of known bugs
Copyright

External links

Pmw project home page on SourceForge - contains CVS source repository, bug tracking, release distributions, mailing list, etc
Pmw-general mailing list - subscribe to this list to get announcements of Pmw releases and general discussion on Pmw
A User's Guide to Pmw.Blt - an excellent tutorial and reference covering the Pmw interface to the powerful Blt graph widget, written by Bjrn Ove Thue and Hans Petter Langtangen. You can also download the full HTML document for local viewing.

See the Pmw megawidgets home page for the latest information about Pmw.

Comments, bugs, fixes to the Pmw discussion and announcement mailing list.

Pmw 1.3.3 - 29 Mar 2014

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9351187 Pmw-2.1/Pmw/Pmw_1_3_3/doc/porting.html0000664000175000017500000002764000000000000017666 0ustar00gregmgregm00000000000000 Porting between different versions of Pmw

Porting between different versions of Pmw

This document contains a brief guide to porting existing code between different versions of Pmw. It includes significant functionality changes but does not include bug fixes or compatible enhancements. For details of all changes, see Changes to Pmw versions.

*Porting from 1.2 to 1.3:

  • Bug fix, documention and new features only. No backwards-incompatible changes.

Porting from 0.8.5 to 1.0, 1.1 and 1.2

  • Bug fix, documention and new features only. No backwards-incompatible changes.

Porting from 0.8.4 to 0.8.5

  • Bug fix release only. No interface changes.

Porting from 0.8.3 to 0.8.4

  • Change the setnaturalpagesize() method of Pmw.NoteBook to setnaturalsize() (to be consistent with Pmw.PanedWidget).

  • Change Pmw.excludefrombusycursor() to Pmw.setbusycursorattributes(). Replace busyCursorName option of Pmw.initialise() with cursorName attribute of Pmw.setbusycursorattributes().

  • Several rarely used key bindings for Pmw.ScrolledListBox were removed, changing the behaviour of the megawidget.

Porting from 0.8.1 to 0.8.3

  • The megawidgets Pmw.NoteBookR and Pmw.NoteBookS have been replaced by a new Pmw.NoteBook. The interfaces are not compatible, so see the Pmw.NoteBook reference manual for details.

  • Change the get() method of Pmw.OptionMenu to getcurselection() and the remove() method of Pmw.PanedWidget to delete().

  • If you use 'end', 'default' or None in calls to the index() method of several megawidgets, change these to Pmw.END, Pmw.DEFAULT and Pmw.SELECT, respectively.

  • The exclude argument has been removed from Pmw.showbusycursor(). Use Pmw.excludefrombusycursor() instead.

  • The names of some of the positional arguments in the following methods have changed: MegaArchetype.createcomponent(), ButtonBox.insert(), ButtonBox.add(), MenuBar.addcascademenu(), MenuBar.addmenuitem() and RadioSelect.add().

  • The Pmw.maxfontwidth() function has been removed. Use the font_measure() Tkinter method, or if that has not yet been implemented:

     someWidget.tk.call('font', 'measure', someFont, 'W')
  • The Pmw.fontexists() function has been removed. This is because, since Tk8.0, all fonts exist, so it no longer has any meaning.

Porting from 0.8 to 0.8.1

  • The Blt.Graph now supports blt2.4i which is not backwards compatible with blt2.1.

Porting from 0.7 to 0.8

  • The format argument of Pmw.datestringtojdn() now defaults to 'ymd'. If you want to display dates with year, month and day in a different order, add a format option to Pmw.datestringtojdn() or to the datatype option of Pmw.Counter or the validate option of Pmw.EntryField.

  • The justify() method from Pmw.ScrolledListBox has been removed. Use the xview() or yview() methods instead.

  • Replace the getFrame() method of Pmw.ScrolledFrame with the interior() method.

  • Replace the ringpadx and ringpady options of Pmw.Group by padding the megawidget itself or by padding the children of the megawidget.

  • Replace the canvasbind() and canvasunbind() methods of Pmw.Balloon with tagbind() and tagunbind().

  • The return value of Pmw.EntryField command callback is now ignored. Previously, if the callback destroyed the megawidget, it was required to return the string 'break', to work around a problem in the event handling mechanism in Tkinter. With python 1.5.2, Tkinter has been fixed. Therefore, user-supplied callback functions should use Pmw.hulldestroyed to check if the megawidget has been destroyed before performing any operations on it.

  • If you require the 'pmw1' fontScheme when running under Microsoft Windows and Macintosh, you will need to set the Tk font options manually.

Porting from 0.6 to 0.7

  • Replace the maxwidth option of Pmw.EntryField with the 'max' field of the validate option.

  • To specify that there should be no validation performed for a Pmw.EntryField, the validate option must be None, not '' as before.

  • The date and time values of the Pmw.EntryField validate option (such as 'date_dmy' and 'time24', etc) are no longer supported. Instead use a dictionary as the value of the validate option with 'date' or 'time' in the 'validator' field. Include other fields in the dictionary to further specify the validation.

  • Pmw.Counter no longer supports the old date and time values for the datatype option. Use a dictionary with a 'counter' field of 'date' or 'time' and other fields to further specify the counting.

  • Pmw.Counter no longer supports the min and max options. Use the Pmw.EntryField validate option instead.

  • The bbox method of Pmw.ScrolledListBox now refers to the bbox method of the listbox component, not the hull component.

  • By default, Pmw.MenuBar now automatically adds hotkeys to menus and menu items for keyboard traversal. To turn this off, use the hotkeys = 0 option.

  • The createcomponent() method now disallows the creation of component names containing an underscore. If any component names contain an underscore, rename them.

Porting from 0.5 to 0.6

To port applications using Pmw version 0.5 to version 0.6, make sure you are using python1.5. Then, simply change any lines in your application like this:

 from PmwLazy import Pmw

to this:

 import Pmw

Also, if you have added the lib directory of a specific version of Pmw to sys.path or PYTHONPATH, this can be removed, as long as Pmw can now be found from the default path, such as in the python site-packages directory.

Porting from 0.2 to 0.4

  • To get Pmw.0.2 default fonts (helvetica with bold italic menus and italic scales) initialise with:

     Pmw.initialise(fontScheme = 'pmw1')

    If no fontScheme is given, the standard Tk default fonts are used.

  • Remove all calls to setdefaultresources(), usual(), keep(), renameoptions(), ignore() and defineoptiontypes().

  • Move call to defineoptions() to before call to base class constructor, create optiondefs tuple from self.defineoptions arguments, then call defineoptions().

  • Remove resource class and name from optiondefs.

  • The last element in the optiondefs tuple (callback function) must be given (may be None).

  • Add to classes currently without any options:

     optiondefs = ()
     self.defineoptions(kw, optiondefs)
  • Use createcomponent() to create components - this replaces the calls to the component widget constructor and to registercomponent().

  • Do not inherit from Pmw.LabeledWidget. Instead, replace with Pmw.MegaWidget with labelpos and labelmargin options and a call to self.createlabel(). If calling createlabel(), must replace pack() with grid().

  • When calling a megawidget constructor, include subcomponent name when setting subcomponent options (eg labeltext -> label_text)

  • The items option of ScrolledListBox is an initialisation option only - use setlist() method after initialisation.

  • The autorelief option for Counter, EntryField, ScrolledText, TextDialog has been removed.

  • ScrolledListBox.getcurselection() always returns a tuple of strings, possibly of zero length.

  • Counter increment is always initialised to 1.

  • The 'time' Counter datatype option has been replaced by 'timeN' and 'time24'.

  • The 'time' EntryField validate option has been replaced by 'timeN' and 'time24'.

  • Replace call to initialise() with initialiseoptions(), removing "kw" arg. This should always be the last line in a megawidget constructor.

  • Replace hide() with withdraw().

  • Now need iconpos option for MessageDialogs with icon_bitmap option set.

  • Example megawidget class definition:

class MyBigWidget(Pmw.MegaWidget):
    def __init__(self, parent = None, **kw):

        # Define the megawidget options.
        optiondefs = (
            ('errorbackground',   'pink',      None),
            ('maxwidth',          0,           self._myfunc),
            ('myinit',            'good',      Pmw.INITOPT),
        )
        self.defineoptions(kw, optiondefs)

        # Initialise the base class (after defining the options).
        Pmw.MegaWidget.__init__(self, parent)

        # Create the components.
        interior = self.interior()
        self._widget = self.createcomponent('component',
                (('alias', 'component_alias'),), None,
                Tkinter.Button, (interior,))
        self._widget.grid(column=0, row=0, sticky='nsew')

        self.createlabel(interior)

        # Initialise instance variables.
        self.deriveddummy = None

        # Check keywords and initialise options.
        self.initialiseoptions(MyBigWidget)

Pmw 1.3.3 - 29 Mar 2014 - Home

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9351187 Pmw-2.1/Pmw/Pmw_1_3_3/doc/refindex.html0000664000175000017500000001075000000000000020002 0ustar00gregmgregm00000000000000 Pmw reference manual index

Pmw reference manual
index

Base classes
Pmw.MegaArchetype Pmw.MegaWidget Pmw.MegaToplevel
Widgets
Pmw.ButtonBox Pmw.ComboBox Pmw.Counter Pmw.EntryField Pmw.Group Pmw.HistoryText Pmw.LabeledWidget Pmw.MainMenuBar Pmw.MenuBar Pmw.MessageBar Pmw.NoteBook Pmw.OptionMenu Pmw.PanedWidget Pmw.RadioSelect Pmw.ScrolledCanvas Pmw.ScrolledField Pmw.ScrolledFrame Pmw.ScrolledListBox Pmw.ScrolledText Pmw.TimeCounter
Dialogs
Pmw.AboutDialog Pmw.ComboBoxDialog Pmw.CounterDialog Pmw.Dialog Pmw.MessageDialog Pmw.PromptDialog Pmw.SelectionDialog Pmw.TextDialog
Miscellaneous
Pmw.Balloon Pmw.Blt Pmw.Color Module functions

Pmw 1.3.3 - 29 Mar 2014 - Home

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9351187 Pmw-2.1/Pmw/Pmw_1_3_3/doc/scale1.gif0000664000175000017500000000177200000000000017153 0ustar00gregmgregm00000000000000GIF87aFÂ,FI8ͻ`(dihlp,t"x @ 0$v(DDMzEN[kכ_, O׺mie}JzvBL&{vŨqkf`ֻZڷ,޲')sNj !$@0 w`? adHqEnl8c<{@ҘI4OZ6 srK"=ut'Ўp4J黡6B!U8Vk\9z}:`Y`s2lڥSiT}{5WxޭA3aMz0Ɣ, …7Dxbɗi9d3r9FhIw6}xūYdva-nh)<Gj,`ũ gݮW?xsc`m;sm/س޽NÄ_|mZ@Lhq$`DjfυeHfyFZF%"98"J 8teV;vWuVIC#YGd]K$O%HHdVHB _Z@- "&b).b|jRneDhb%:Rz#d2٩BRYW%ֱzMʖTUZ\n)frګبvp<*眶yĶ@۝>4۟~XA$_Ҋu[j+/i&/V۪\+!1LÔBBy˭ĎwJ[}k1[/3{o/)sBtљ$L7PG-TWmu ;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9391186 Pmw-2.1/Pmw/Pmw_1_3_3/doc/scale2.gif0000664000175000017500000000363700000000000017156 0ustar00gregmgregm00000000000000GIF87aÂ,I8ͻ`(dihlp,tmx|pH,urL ШtJJlzQ61(eW%| @ݝpuczh|l tvAxfAmnwdik@@??~>>r=z=Áq?|1\SKf-ڵ!<͙htN.0Λxʃ;N:򼰧Sf>v컩s>|~xzg3|~A^nFj4r6i`֗܂2D~m1$M6š}Ɨ~хX_0!/hH8#O'ff#iCc ?$;$ b9ѕXfEbҖ`i%>NBi9f}Ied"i% gO' zMnr5Zw2ꧣ*@z57ak%੧Pj `3Q Gg^I(*kqlmZuwۜ-z{ޫ*K!ɂ\ݖnZy餏{ӽ;0i頳^ Q'<<Oo$&X [. J cw<ϸ9? pa4Wl.(<-Qߨ4,tLl5/#Ү j֢ٙ) >K[A~hp:-xm7J쳫 ~x{k..zB{+~s3Zle.욮UC b.^>u݅66w{_lO%/~77c4{=.=@˛> =>?;ܷ_p?Ow4eq_8M#NlO8AO*fN|raHog9ahizzLhH(qCDJĸlRY7R j8T bT?&wH>6*Џx\`H4; #c?Bчr1Yd GH8td=YHI(IJ H$iD%#Fg&vJw-qL⻶Dk\BW1Ѵ淘bn vҙ eֹM*$iݨ 4OM+ Njl`?NPt0H\ƒL_0*рBԗ)^D3ѐu'MJK$n1v@,0/ra(*M 1(U"Ej|6uTU(SwաWMWʃuէĊ֮jTx]ɪJ[֩uV-zWB3A+*2O{T38_ ˹xBuj_7gH gmleȾggES{֠o[-lYWhs*AݲPJv-S+wm.tK,Vԭs&R`Zw]+^) z+|Kͯ~L7;././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9391186 Pmw-2.1/Pmw/Pmw_1_3_3/doc/starting.html0000664000175000017500000003067600000000000020042 0ustar00gregmgregm00000000000000 Getting started with Pmw

Getting started with Pmw

Introduction

This document describes how to fetch and install Pmw, and how to run the demonstrations and tests.

Requirements

Pmw.1.3.3 requires the _tkinter and Tkinter modules. It works with python versions 1.5.2 and greater (tested up to 2.2.1) and Tk versions 8.0 and greater (tested up to 8.3.2).

If the BLT extension to Tk is present, Pmw will use the BLT busy command during modal dialogs to display a clock cursor. Also, the Pmw.Blt interface to the BLT busy, graph, stripchart, tabset and vector commands will be available. BLT versions 2.4i and greater are supported (tested up to 2.4u). You can find BLT at http://www.tcltk.com/blt/.

Distribution and installation

Releases of the Pmw distribution are available via http from http://download.sourceforge.net/pmw/. This release is available as Pmw.1.3.3.tar.gz, released on 29 March 2014. This is a compressed tar file.
Under Linux, Unix, etc, you will need to unpack it using tar and you may also need to use gzip or gunzip to uncompress it.
Under Microsoft Windows, you will need a program such as WinZip (http://www.winzip.com) that can unpack the gzipped tar files. You may need to change the suffix of the file to .tgz for WinZip to recognise it.

This will unpack into a directory named src containing the directory Pmw and the installation utility setup.py. You now need to put this directory Pmw somewhere python can find it, preferably in one of the standard places, such as in the site-packages directory (eg: /usr/lib/python2.2/site-packages/Pmw) or the sys.prefix directory (eg: C:\Program Files\Python\Pmw or /usr/lib/python2.2).

One easy way to install the Pmw directory in the site-packages directory of your installation is to use the setup.py utility.

This is done as follows:

python setup.py install (as root)

or

sudo python setup.py install (under Ubuntu or Mac OS X)

Alternatively, to install manually, for example under Unix, assuming you have placed the tar file in the /tmp directory, you can simply run the following commands:

cd /usr/lib/python2.2/site-packages
gunzip /tmp/Pmw.1.3.3.tar.gz (or gzip -d /tmp/Pmw.1.3.3.tar.gz)
tar xvf /tmp/Pmw.1.3.3.tar

If you do not have write permission for these standard directories, place the Pmw directory somewhere on your PYTHONPATH or sys.path. If this is not possible, place the Pmw directory somewhere else and add the parent directory to your PYTHONPATH or sys.path.

If you have previously installed Pmw version 0.6 or later, then the new version can share the same Pmw directory as the previous versions. You will need to perform the tar extraction in the directory containing (that is, the parent directory of) the existing Pmw directory. By default, your applications will use the most recent version of Pmw. If required, the function Pmw.setversion() can be used to specify a version to be used. See the reference manual for details. If you are no longer using the older versions, you can safely remove the corresponding subdirectories from the Pmw directory.

If you need assistance in installing BLT under Unix, please contact me (gregm@iname.com) and I will try to help. For other operating systems, such as Microsoft or Macintosh, you should try asking the python newsgroup. If anyone can give me a description of how to install BLT under other operating systems please contribute it and I will place it here.

Documentation

The doc directory for each Pmw version contains all the documentation for that version of Pmw. See the local home page for a complete list of documents. The files in this directory are also available from the official Pmw home page.

An excellent tutorial and reference covering the Pmw interface to the powerful Blt graph widget, "A User's Guide to Pmw.Blt" written by Bjrn Ove Thue and Hans Petter Langtangen, is available. You can also download the full HTML document for local viewing.

Demonstrations and tests

A good way to get an overview of the functionality provided by Pmw is to run the demonstrations and tests and look at the demonstration code. To view a comprehensive demonstration of many of the features of Pmw run the All.py script, which can be found in the demos subdirectory of each version of Pmw.

You do not have to install Pmw to run the demonstrations and tests, simply change into the appropriate directory and run the file All.py. See Demonstrations and tests for more information about running the demonstrations and tests and how to create your own.

Note that there are some bugs in later versions of BLT (at least 2.4t and 2.4u) which cause some tests of Pmw.Blt.Graph to crash with python2.0 under Linux. These tests have been commented out (until BLT is fixed).

Contributions welcome

If you create some whiz-bang megawidgets and would like to contribute them to Pmw, they will be most welcome. You should be able to get some idea of the coding style used in Pmw code by reading How to build Pmw megawidgets and by looking at the Pmw library code itself in the lib directory of each Pmw version.

If you would like to contribute a megawidget, it would be preferable if it also came with a simple demonstration and a test script. See Demonstrations and tests for information about how to create new demonstrations and tests.

Each megawidget should also have a reference manual describing its options, components and methods.

Generating the documentation

The released reference manuals are automatically generated by merging specially marked-up text with the output from megawidget query methods, such as components(), options() and componentaliases(), and various other introspective devices. If you are interested to see how the documentation is generated, you can fetch the marked-up text and the python script to convert the text to html from http://download.sourceforge.net/pmw/Pmw.1.3.3.docsrc.tar.gz . Download this file into the Pmw/Pmw_1_3_3 directory of the Pmw source tree. Unzip and untar the file. This will create a docsrc sub-directory of Pmw/Pmw_1_3_3. If you want to keep the documentation which came with the Pmw distribution, rename the old doc directory. Then change directory to docsrc and run createmanuals.py. After printing lots of warnings about documentation that has not been written yet, this will create a new doc directory containing all the html documentation.

Here is an example set of commands to unpack the documentation source and regenerate the documentation, assuming you have downloaded the source in the Pmw/Pmw_1_3_3 directory:

cd Pmw/Pmw_1_3_3
gunzip Pmw.1.3.3.docsrc.tar.gz
tar xvf Pmw.1.3.3.docsrc.tar
mv doc doc.old
cd docsrc
./createmanuals.py

If running under Unix, you will need to run the createmanuals.py script with a valid DISPLAY environment variable, since it creates each megawidget and then queries it for its options, components, etc. This is because Tk (and hence Tkinter) requires a connection to an X server to run.

Future plans and bugs

The todo list contains a long list of of suggestions, bugs and enhancements for Pmw. If you are interested in doing any of these, please let the maintainer (gregm@iname.com) know. Some of the items in the todo list may be considered bugs. There are also some other problems due to idiosyncrasies in the implementation of Tk.

Licence

The official Pmw licence (see copyright) basically lets you do anything with Pmw as long as you don't hurt anyone. There is also another licence, the "Postcard Licence":

"I'd like to get a postcard from you! I'm interested in who is using Pmw, where you live and where in the world Pmw is doing it's job"

Please send me an e-mail to gregm@iname.com to get my postal address.

Acknowledgements

The initial ideas for Pmw were blatantly stolen from the itcl extensions [incr Tk] by Michael McLennan and [incr Widgets] by Mark Ulferts. Several of the megawidgets are direct translations from the itcl to python.

The base classes and most megawidgets were written by Greg McFarlane and Peter Munnings. Contributed megawidgets include: Pmw.TimeCounter by Joe VanAndel, Pmw.Group and an early version of Pmw.NoteBook by Case Roole, Pmw.ScrolledCanvas, Pmw.ScrolledFrame and another early version of Pmw.NoteBook by Joe Saltiel and Pmw.OptionMenu by Roman Sulzhyk. A big thank you to the following people for their bug reports, fixes, enhancements and suggestions: David Ascher, Robin Becker, Siggy Brentrup, Mark Colclough, Jerome Gay, Clemens Hintze, Rob Hooft Jack Jansen, Jonathan Kelly, Magnus Kessler, Matthias Klose, Andreas Kostyrka, Fredrik Lundh, Magnus Lycka, Graham Matthews, Dieter Maurer, Michael McLay, Daniel Michelson, Georg Mischler, Rob Pearson, Case Roole, Joe Saltiel, Roman Sulzhyk, Shen Wang, Chris Wright, and Guido van Rossum. Special thanks to Case Roole and Michael McLay for help with getting Pmw to work with python packages and many other nifty features. My deepest apologies if I have forgotten anyone. Please let me know.

The Pmw home page and project site is made available courtesy of SourceForge.

The current maintainer is Greg McFarlane. I monitor the Pmw discussion and announcement mailing list so please send any problems, comments, suggestions or enhancements to the list. You may also contact me directly at gregm@iname.com.

Pmw 1.3.3 - 29 Mar 2014 - Home

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9391186 Pmw-2.1/Pmw/Pmw_1_3_3/doc/todo.html0000664000175000017500000012070000000000000017140 0ustar00gregmgregm00000000000000 Pmw todo list

Pmw todo list

This is a long list of suggestions and enhancements for Pmw. If you are interested in doing any of these, please let the Pmw maintainer (gregm@iname.com) know.

New Pmw megawidgets

  • Multicolumn listbox.

    Useful features - smooth scrolling, embedded images, different fonts and colours, text correctly masked when it is longer than its column width, interactive resizing of columns.

    Probably should be implemented as canvas widget rather than by using multiple frames or multiple listboxes. There would be a lot of work needed to position all the elements - you can't just pack or grid them.

  • File dialog.

  • Main window class (App class), with menu bar, information line with status boxes and an about box. (See iwidgets' mainwindow class for example.) This should handle creation of multiple main windows, recycling of unused main windows and should exit if last open main window is closed.

  • Searchable text megawidget.

  • Tree browser.

  • Check out Doug Hellmann's contributed megawidgets at <http://www.mindspring.com/~doughellmann/Projects/PmwContribD> or <http://members.home.net/doughellmann/PmwContribD/> and integrate into Pmw.

Changes to current megawidgets

MegaToplevel

  • Modify activate() geometry argument to allow window positioning relative to the pointer, another window or the screen and allow the centering of the window relative to the positioning point or by a specified offset. Also add the ability to position the window so that the mouse is over a particular widget in the toplevel.

    Should handle all combinations of

     when (always/first)
     where (center/geometry/mouse)
     parent (screen/window)
    
     and None (don't position)

    Check Tix4.1.0/library/DialogS.tcl center method for how to center over another window

    Check iwidget's shell.itk for code to center widget over screen or another widget.

    See Pmw.Balloon code for how to position over pointer.

    Tcl code to center over another (parent) window:

     # center client relative to master (default xoff, yoff = -1)
     set geomaster [split [wm geometry $master] "x+"]
     set geoclient [split [wm geometry $client] "x+"]
    
     if {$xoff == -1} {
       set xoff [expr (
         ([lindex $geomaster 0] - [lindex $geoclient 0]) / 2)]
     }
     set newxpos [expr [lindex $geomaster 2] + $xoff]
    
     if {$yoff == -1} {
       set yoff [expr (
         ([lindex $geomaster 1] - [lindex $geoclient 1]) / 2)]
     }
     set newypos [expr [lindex $geomaster 3] + $yoff]
    
     wm geometry $client +$newxpos+$newypos

    More tcl code to center dialog over another (parent) window:

     (args: parent dlg)
     # First, display the dialog offscreen to get dimensions.
     set screenW [winfo screenwidth $parent]
     set screenH [winfo screenheight $parent]
     set w [expr $screenW + 1]
     wm geometry $dlg +$w+0
     update
    
     # Get relative center of parent. 
     set w [winfo width $parent]
     set h [winfo height $parent]
     set w [expr $w/2]
     set h [expr $h/2]
    
     # Get and add screen offset of parent.
     set w [expr $w + [winfo rootx $parent]]
     set h [expr $h + [winfo rooty $parent]]
    
     # Get dimensions of dialog.
     set dlgW [winfo width $dlg]
     set dlgH [winfo height $dlg]
    
     # Make adjustments for actual dimensions of dialog.
     set w [expr $w - $dlgW / 2]
     set h [expr $h - $dlgH / 2]
    
     # Let's keep the entire dialog onscreen at all times.
     # Center in screen if things are awry.
     set recenter 0
     if { $w < 0 } { set recenter 1 }
     if { $h < 0 } { set recenter 1 }
     if { [expr $w + $dlgW] > $screenW } { set recenter 1 }
     if { [expr $h + $dlgH] > $screenH } { set recenter 1 }
     if { $recenter } {
       set w [expr ($screenW -$dlgW) / 2]
       set h [expr ($screenH - $dlgH) / 2]
     }
    
     wm geometry $dlg +$w+$h
  • Add geometry argument to show() (same as activate() above).

Dialog

  • Add label (header?) to Dialog class. May not be necessary, or too complicated.

ButtonBox

  • When a horizontal ButtonBox is stretched, the left button stays anchored to the left edge and there is too much space between the last button and the right edge.

  • Add an option to either evenly space the buttons across the button box, or to keep them together and justify them to the left, right or center. Check that deleting buttons works correctly.

ComboBox

  • Remove arrowrelief option from ComboBox and do what counter does: gets value of arrow's relief just before sinking it, then restores it later.

  • Change bindings: remove all bindings from arrow key and remove arrow key from <tab> focus sequence; only implement these bindings on the entry widget:

     Up    popup dropdown list, scroll up if already displayed
     Down  popup dropdown list, scroll down if already displayed
     Esc   popdown dropdown list, return entry to previous value
     Enter popdown dropdown list, execute current selection

    Remove bindings from listbox and scrollbar(s), so that all bindings are via the entry widget?

  • When entering keys when list is displayed, scroll list to first entry beginning with entered keys. If no match, scroll list to top.

  • Remove many of the arrow bindings from Pmw.ComboBox - there are just too many key bindings on the arrow button. There is no need for it to respond to keys such as the up/down keys when the adjacent Entry widget already does so. I propose to remove all Pmw.ComboBox arrow button key bindings except for <space>, which can be used to bring up the dropdown list. The Entry widget behaviour would remain unchanged: when it has focus, you can use the up/down keys to go to the next/previous entries and then use <Return> to invoke the selection command.

    Alternatively, make the bindings the same as the MS-Windows combobox. (Use the url entry field in Navigator or IE as an example of MS-Windows behaviour). These have been reported to be:

    • All mouse actions are exclusively triggered by the left button.

    • Right button displays "Direkthilfe" on my german system ("Direct Help"). This is a floating button, that triggers display of a tool tip like the |?| button that appears next to the |x| at the right end of the title bar of some native windows dialogs.

    • The arrow is very slim (acutally flat: width/height is about 2/1)

    • Entry and popup have the same color ("window color")

    • The popup has a 1 pixel dark border, no spacing between popup and scrollbar.

    • If the box has the focus, the full entry is displayed in "selected" style.

    • If the box has the focus, up and left keys rotate items up, down and right keys rotate items down, all with immediate effect.

    • If the box has the focus, keys a-z (not case sensitive) rotate through the items with same first character, with immediate effect.

    • No separate focus for the arrowbutton

    • Discussing how the combobox behaves with arrow keys when it has the focus: "The concept is almost identical to what you already have, just gives more visual feedback. In your current implementation you allow to rotate through the values with the up and down arrow keys, showing the strings in the entryfield, and accepting the values when the user presses the spacebar (hmmm, how can I exit this without moving back to the original value manually?). On Windows, the choice is not shown in the entryfield, but the popup opens when you press the up or down arrow keys, as if you clicked on the arrowbutton, and you then navigate the values in the listbox. This avoids the display of not finally selected values in the entryfield and is a lot more obvious and less confusing. The current behaviour certainly confused me, which is why I first proposed the changes to the moveup/down methods." (Georg Mischler)

    Also, check bindings on other megawidgets for consistency.

  • Modify Pmw.ComboBox so that the width of the entry widget is forced to be the same as the width of the dropdown listbox. If the "width" option to the standard listbox is 0, Tk sets the requested width of the listbox to be just large enough to hold the widest element in the listbox. Using this option, I can see that listbox.winfo_reqwidth() is changing as I insert items into an unmapped listbox. The question is, how do I get notified of these events so that I can set the width of the entry?

    The problem is that the listbox is in another toplevel which has not yet been displayed, so I can't bind to <Configure> to determine its width.

    One suggestion is to override the insert and delete methods of the Listbox class. The problem with this is what if the font changed, or the borderwidth, etc? You would need to override and check many more methods.

  • Add ability to tearoff dropdown list (suggested by Dean N. Williams).

  • Should be able to disable/enable arrow button.

Counter

  • Add option for different increment/decrement behaviour. For example, assuming increment is 1:

    1. Current behaviour - move to the next multiple of the increment, eg: 1.0 -> 2.0, 1.234 -> 2.0

    2. Add or subtract the increment to whatever is displayed, eg: 1.0 -> 2.0, 1.234 -> 2.234

    3. Move to the next multiple of the increment, offset by some value. eg: (if offset is 0.5) 0.5 -> 1.5, 1.234 -> 1.5, 1.678 -> 2.5

  • Add wrap option (to wrap around at limits) (then don't need time24 arg to 'time' datatype).

  • Add a state option to disable Counter.

  • Add option to Counter to allow the buttons to be on the same side, one on top of the other, like Tix, Itcl, Motif, Windows 95, etc. There should probably also be an option to lay the current large buttons on the same side of the entry field, next to each other.

  • Redo TimeCounter using vertical Counter, add limitcommand option to Counter to allow overflow from seconds to minutes to hours

Arrowed megawidgets (Counter, ComboBox, TimeCounter)

  • Potential construction speed up if Canvas arrows are replaced by Label with Bitmap or BitmapImage. The hard part would be to make the bitmap change size depending on size of Label.

  • Pmw.drawarrow should draw arrows which look like Tk cascade menu arrows.

EntryField

  • Can it be modified to change all entered characters to upper or lower case automatically? Or first-upper or first-of-each-word-upper?

  • If the validity of the currently displayed text is ERROR, allow any changes, even those which result in invalid text. This is useful when invalid data has been given to the value option and the user is trying to correct it.

LabeledWidget

  • Add tix-style border.

MenuBar

  • Maybe Pmw.MenuBar should also have (optional) balloon help for menu items as well as menu buttons. I am not sure whether users would find this useful.

  • The status help hints do not appear when using F10/arrow keys.

  • Look at the Tk8.0 menu demo and check the help bindings for ideas, in particular, how can you get help when using keyboard bindings.

  • Check the new menu features in Tk8.0 for creating "native" menu bars and the special ".help" menu.

  • Add index() method.

  • Add a 'position' option to addmenu and deletemenu methods. This option should accept an index number, a menuName or Pmw.END.

  • Look at itcl menubar for ideas.

Balloon

  • Positioning of the balloon with respect to the target widget or canvas item: There are a number of ways that Pmw.Balloon could be improved. For example, currently the the top left corner of the balloon is positioned relative to the bottom left corner of the target, offset by the [xy]offset options. These options apply to all targets - they can not be set differently for different targets.

    To make it more configurable, the user should be able to specify, for each target:

    • the base position in the target relative to which the balloon should be placed (n, s, e, w, nw, sw, ne, se, c) (Currently sw)

    • the x and y offsets (Default (20, 1))

    • the position in the balloon that should be placed at the offset position (n, s, e, w, nw, sw, ne, se, c) (Currently nw)

      Note, if this is anything other than nw, update_idletasks() will need to be called to get the size of the balloon before it is positioned - there is a possibility that this may cause weird ugly flashing.

    • whether either the base x or y position should be taken relative to the current mouse position rather than as one of the corners of the target. This would be useful for large targets, such as text widgets, or strange shaped canvas items. This could be specified using special base positions, such as (nm, sm, em, wm). For example, for 'sm', the x base position is the mouse x position and y base position is the bottom (south) edge of the target.

    The user should be able to specify global defaults for all of these, as well as be able to override them for each target. The Pmw.Balloon options and their defaults could be:

     basepoint   sw        # Position on target.
     anchor      nw        # Position on the balloon
     xoffset     20        # x distance between basepoint and anchor
     yoffset     1         # y distance between basepoint and anchor

    To be able to override these, the bind() and tagbind() methods would have to accept these as additional arguments. Each would default to None, in which case the default values at the time the balloon is deiconified would be used.

    I'm not sure about how to handle the case when the balloon is configured to come up under the mouse. When this happens the balloon flashes on and off continuously. This can happen now if you set the yoffset to a negative number. Should the balloon widget detect this and do something about it?

  • Add showballoon(x, y, text) method to Balloon and use in balloon help for a listbox:

    On 3 Dec, Michael Lackhoff wrote:

     And another question:
     Is it possible to create a balloon-help for the entries
     in the listbox?  Not all the information is in the
     listbox and it would be nice if a balloon help could
     give addtional information.

    Rather than popup a balloon help window as the mouse moves over items in the listbox, I think it would be better if it pops up after you clicked on an item (or a short time afterwards). Pmw.Balloon displays the balloon help a short time after the mouse enters a widget, so is not directly usable in this case. However, a method could be added to Pmw.Balloon to request it to popup the balloon at a particular x,y position. This method could be called from the listbox_focus method above. Something like:

     def listbox_focus(self, event):
         self.indexlist.component('listbox').focus_set()
         text = self.indexlist.getcurselection()
         # expand text to whatever you want:
         text = 'This is ' + text
         self.balloon.showballoon(x, y, text)

    The Pmw.Balloon showballoon() method would have to set a timer which sometime later calls another method which displays the text. You would also need to bind <ButtonRelease-1> to a hideballoon() method which withdraws the popup.

  • The balloon can be displayed off-screen if the window is near the edge of the screen. Add a fix so that the balloon always stays on the screen (but does not popup under the mouse, otherwise it will immediately pop down).

  • Add a fix so that the balloon does not disappear if the mouse enters it. Could do this by setting a short timer on the Leave event before withdrawing the balloon and if there is an Enter event on the balloon itself, do not withdraw it.

  • For tagged items in text widgets, the balloon is placed relative to the character in the tagged item closest to the mouse. This is not consistent: in the other cases (including canvas), the balloon is placed relative to the bottom left corner of the widget or canvas item. This should also be the case for text items.

  • Is the new (in Tk8) "<<MenuSelect>>" event useful for balloon and/or status help.

MessageBar

  • Finish logmessage functionality.

  • Add colours and fonts to MessageBar message types. For example, systemerror message types could have bold font on a red background.

  • Add message logging history view (like the ddd debugger).

NoteBook

  • Notebook should recalculate layout if the requested size of a tab changes (eg font size, text, etc).

  • The tabpos option should accept s, e and w as well as n.

  • Possible new options (borrowed from iwidgets):

    • equaltabs

      If set to true, causes horizontal tabs to be equal in in width and vertical tabs to equal in height.

      Specifies whether to force tabs to be equal sized or not. A value of true means constrain tabs to be equal sized. A value of false allows each tab to size based on the text label size. The value may have any of the forms accepted by the Tcl_GetBoolean, such as true, false, 0, 1, yes, or no.

      For horizontally positioned tabs (tabpos is either s or n), true forces all tabs to be equal width (the width being equal to the longest label plus any padX speci- fied). Horizontal tabs are always equal in height.

      For vertically positioned tabs (tabpos is either w or e), true forces all tabs to be equal height (the height being equal to the height of the label with the largest font). Vertically oriented tabs are always equal in width.

      Could have a special value which sets equal sized and also forces tabs to completely fill notebook width (apparently like Windows).

    • tabgap

      Specifies the amount of pixel space to place between each tab. Value may be any pixel offset value. In addi- tion, a special keyword overlap can be used as the value to achieve a standard overlap of tabs. This value may have any of the forms acceptable to Tk_GetPixels.

    • raiseselect

      Sets whether to raise selected tabs slightly (2 pixels).

      Specifes whether to slightly raise the selected tab from the rest of the tabs. The selected tab is drawn 2 pixels closer to the outside of the tabnotebook than the unselected tabs. A value of true says to raise selected tabs, a value of false turns this feature off. The default is false. The value may have any of the forms accepted by the Tcl_GetBoolean, such as true, false, 0, 1, yes, or no.

    • bevelamount

      Specifies pixel size of tab corners. 0 means no corners.

  • There should be a way to temporarily hide a page, without deleting it (like pack_forget). (Suggested by Michel Sanner)

OptionMenu

  • Should accept focus and obey up and down arrow keys.

PanedWidget

  • Add index() method

  • Modify all methods so that they accept Pmw.END as a pane identifier as well as an index or a name.

  • Check iwidgets pane and panedwindow classes.

RadioSelect

  • Add insert() and delete() methods.

  • The index method should have forInsert argument.

  • Add Pmw.SELECT to index() method. For single selectmode this returns an integer, for multiple selectmode this returns a list of integers.

  • Add option to set background color on selected buttons. Maybe should also be able set selected foreground as well. Any others?

LogicalFont

  • Add boldFixed fonts,

  • Search for closest size font if no exact match.

  • Maybe replace with Tk8.0 font mechanism.

  • Can the Tk8.0 font measuring functionality be used in Pmw somehow?

Scrolled widgets

  • Can some common scrolling methods be factored out, either as a base class, "ScrolledMixin" mixin class or as helper functions? Candidate methods: constructor, destroy, interior, _hscrollMode, _vscrollMode, _configureScrollCommands, _scrollXNow, _scrollYNow, _scrollBothLater, _scrollBothNow, _toggleHorizScrollbar, _toggleVertScrollbar.

  • ScrolledField should have optional arrow buttons, so that it can still be scrolled even if the mouse does not have a middle button.

Miscellaneous

  • Add a button to the Pmw "Stack trace window" which optionally removes all grabs:

    I normally interact with the "Stack trace window" immediately, and dismiss it afterwards. In many cases where a bug appears like this, the rest of the application is still functional (many of the problems appearing at this stage of development of my application are unforeseen exceptions communicating with a robot on the other end of a socket, not affecting the GUI per se). For that reason I'd prefer if the "stack trace window" would push another grab on the grab stack (if any grabs are active at the moment the exception occurs). Could the window have an extra "Terminate application" option for this case?

  • need to handle component option queries in configure():

     foo = Pmw.AboutDialog(applicationname = 'abc XYZ')
     foo.component('message').configure('text')    - works
     foo.cget('message_text')                      - works
     foo.configure('message_text')                 - doesn't
  • Implement bindings (ComboBox, etc) via a dictionary lookup, to allow people to invent new bindings, such as for handicapped users. (Suggested by Michael McLay)

  • Modify bundlepmw.py so that it checks Pmw.def to see that no files have been missed.

  • Potential cheap speedup by adding this to each module, or inside functions if it has a loop containing calls to builtins:

     from __builtin__ import *
  • Look at how update_idletasks and after_* are used in Pmw - are they consistent? could it be improved? What are the problems of using these on other bits of an application (such as when the size of the toplevel is being determined for the window manager).

  • If lots of errors occur (such as in a fast time callback) the error window may not appear, since Tk will wait until it is idle - which may never occur. The solution is to call update_idletask when updating the error window, but only after a short time has passed. This will provide better user response. However, it may not be possible to do this if some python interpretes (omppython, for example) do not handle calls to update_idletasks at certain times.

  • In the Pmw FAQ, in the "Why don't Pmw megawidgets have a 'state' option?" section, it mentions several Pmw megawidgets that can not be disabled. Fix them.

  • Add RCSID version string to all files.

  • When raising exceptions use the third argument to raise:

     raise SimulationException, msg, sys.exc_info()[2]
  • When update_idletasks is called all pending changes are flushed to the window system server. However, it may take some time for the server to display the changes. If it is required that the display be up-to-date, update_idletasks should be followed by a call that blocks until processed by the server and a reply received. This may be useful in Pmw.busycallback to ensure the busy cursor remains visible until the display is actually modified.

  • There is a small bug which appears only with Tk8.0 (the bug is not apparent with Tk4.2). If a dialog is activated and pops up directly over the cursor and the dialog has a default button, then pressing the <strong>Return</strong> key will not invoke the default button. If you move the mouse out of and then back into the dialog, pressing the <strong>Return</strong> key will work. This behaviour has been noticed in Tcl-only programs, so it is probably a bug in Tk. (Tested on Solaris.)

  • Modify PmwBlt.py to use blt2.4 instead of blt8.0.unoff. Nick Belshaw <nickb@earth.ox.ac.uk> is looking at wrapping the new BLT StripChart and TabSet into Pmw.

  • Perhaps Pmw should have its own exception defined, like TkInters's TclError, perhaps called PmwError.

  • This one is caused by a bug in the implementation of Tcl/Tk for Microsoft Windows NT (and maybe other Microsoft products). Mouse release events can get lost if the grab_set and grab_release commands are used and the mouse goes outside of the window while the mouse button is down. This can occur while Pmw modal dialogs are active. Below is some Tkinter-only code which demonstrates the problem. Maybe there is a work around.

     # Test script to demonstrate bug in Tk
     #implementation of grab under NT.
                                     
     # Click on "Dialog" to bring up the modal
     # dialog window.  Then button down on the scale,
     # move the mouse outside the window,
     # then button up.  The scale slider will still
     # be sunken and clicks on the "OK" button
     # will be ineffective.
     
     import Tkinter
     
     def activate():
         waitVar.set(0)
         toplevel.deiconify()
         toplevel.wait_visibility()
         toplevel.grab_set()        # Problem here
         toplevel.focus_set()
         toplevel.wait_variable(waitVar)
     
     def deactivate():
         toplevel.withdraw()
         toplevel.grab_release()    # and here
         waitVar.set(1)
     
     root = Tkinter.Tk()
     toplevel = Tkinter.Toplevel()
     waitVar = Tkinter.IntVar()
     toplevel.withdraw()
     scale = Tkinter.Scale(toplevel, orient='horizontal', length=200)
     scale.pack()
     button = Tkinter.Button(toplevel, text='OK', command=deactivate)
     button.pack()
     
     button = Tkinter.Button(text='Dialog', command=activate)
     button.pack()
     button = Tkinter.Button(text='Exit', command=root.destroy)
     button.pack()
     
     root.mainloop()

Documentation

  • Document how to get Pmw working on a Mac, for example:

    • Unzip and untar

      This depends on what you use to unpack the tar file. If you use (macgzip and) SunTar you have to tell it that files with ".py" extensions are text files (in the preferences/file type section). If you use stuffit expander: this can be made to do the conversion correctly, but it could be that this only works if you set the .py extension correctly in Internet Config.

      • Where do you untar Pmw?

      • How do you get line terminators correct (carriage return/line feed)?

      • Is there any problem with file name case? (mixed upper/lower case)

      • Is there any problem with file name length?

      (Joseph Saltiel says: It was the same type of operation as in Windows/Unix. Run a program that unzips it and untars it. It seems to get case and length right on its own.)

    • Let python know where Pmw is

      • If Pmw is in its own folder you will have to add the parent of that folder to the sys paths in Edit PythonPaths. If it is in the Python home folder, you do not need to do this.

      • Make sure that the Pmw folder is called "Pmw" and not something else. Since Pmw is a package, python expects to find a "Pmw" folder somewhere in sys.path.

      (Joseph Saltiel says: With the Python distribution on the Mac there is an application called editPythonPrefs, when you run it it gives you a list of a paths. These paths are similiar to the PYTHONPATH variable. I just added the path to Pmw at the bottom of this list.)

  • Document general ideas about building guis, eg:

    When I write gui applications, I usually defer creation of windows as much as possible - this means that the application starts up quickly because it usually only has to create the main window. Whenever another window is required for the first time, it is created then. When the user has finished with the window, the window is withdrawn, not deleted, so that next time it is required it much faster to come up.

    In summary - don't create a window until you need and don't destroy a window if you may want it again.

    The amount of memory required to keep the windows should not be very much - except for very long running programs where the user may create thousands of different windows.

  • Add class hierarchy diagram to documentation:

     MegaArchetype
         MegaToplevel
            etc
         MegaWidget
            etc
  • Add to doco something like: "Another way to extend a Pmw megawidget is to specify a non-default type for one of the components. For example text_pytype = FontText."

  • Document pyclass and pyclass = None (options for null components are ignored; the only time this can be used is with the Group's tag component - all other's use the component widget in some way)

  • Create index of all Pmw methods, functions, options, components.

  • Add description of how to run the Pmw demos without installing.

  • Add description of how to install Pmw.

  • Describe grid structure of megawidgets, so that it is possible to extend megawidgets by adding new widgets into the interior (hence avoiding a childsite in most megawidgets)

  • Document error display and difference between callback and binding error reports.

  • Document difference between 'Helvetica 12' and 'Helvetica size: 12' in logicalfont.

  • Add to howtouse, to describe using the option database to set options for a specific megawidget:

     import Pmw
     root = Pmw.initialise(useTkOptionDb = 1)
     root.option_add('*entryfield24*Label.text', 'German')
     e = Pmw.EntryField(hull_name = 'entryfield24', labelpos = 'w')
     e.pack()
     root.update()
  • Also document hull_name and hull_class.

  • Finish FAQ, ReleaseProcedure and StructuredText test.

  • Put html through gifwizard and html lint.

     http://www.cen.uiuc.edu/cgi-bin/weblint
     (eg: http://www.cre.canon.co.uk/~neilb/weblint/manpage.html)
  • Delete comments from source if they have been added to docs (should not have two copies of anything).

  • Need to document non-standard initial values for component options, such as border in ButtonBox and Dialog's childsite.

  • Docs should have DEFAULT BINDINGS section (like iwidget combobox).

  • Promote home page:

     http://www.geocities.com/homestead/promote.html
     http://www.submit-it.com/subopt.htm, etc
  • Create man pages as well as html (modify createmanuals to produce both).

  • Maybe something with html frames like: itcl2.2/html/index.html

  • Add to starting.html a note that Pmw is a python "package" and add a pointer to python documentation on packages.

  • Document scrolled widget implementations, explaining why they are all slightly different (because the underlying widgets which are being scrolled have different behaviors).

  • Make copyright clearer. Maybe borrow python's?

Demos

  • Check for missing demos.

  • In all demos can move the three lines beginning with "Import Pmw from the sibling directory", to inside "if __name__" clause. Also, "sibling directory" is now incorrect. Also, add note that this is only necessary when running demos without installing Pmw.

  • Change demo/All.py so that it displays the traceback if it cannot load or run a demo (easier for users to report errors).

  • Add option to demo/All.py: "Display demos in separate window" to allow resizing of sub-demos

  • TimeCounter and Spectrum demos beep when they come up, using:

     root.option_add('*EntryField*value', 'VALUE')
  • In demos, add title = 'blah' to top of file and replace root.title(..) with root.title(title) at bottom.

  • Add comprehensive speed test demo which creates one or more of each (common) megawidget. Remove old SpeedTest demo.

  • Check demos work when called from ptui. (Changes have to do with calling compile/exec where __name__ is not the name of the All.py script, but is '__builtin__')

  • PromptDialog demo should not remember password.

  • Finish Counter, Radioselect demos.

  • Modify the All demo so that you can reload a demo module.

  • The syntax-coloured code viewer looks strange on Microsoft NT, because the size of the fonts differ. Check out Guido's idle-0.1 text colouring for Pmw code viewer.

  • Document restrictions on adding bindings to a megawidget: you probably need to bind to components of the megawidget and also check that you are not destroying bindings set up by the megawidget itself.

  • Add a demo that demonstrates setting the color scheme at run time.

Tests

  • Check for missing tests, such as TimeCounter, RadioSelect, SelectionDialog, MessageBar, MenuBar, ComboBoxDialog, Balloon.

  • Create test for useTkOptionDb option to Pmw.initialise().

  • Check that destroyed widgets' python classes are garbage collected (add test and/or demo).

  • Add tests for changecolor, setscheme, etc.

  • Need Resources test.

  • Create tests for deriving from Pmw classes (eg ComboBox).

Ideas

  • Add more Tix (www.xpi.com/tix/screenshot.html) and iwidgets widgets.

  • Look at spinner.itk for how to do vertical orientation on same side for Counter.

  • Investigate these new features in Tk8.0 and see if they could be used in Pmw:

     embedded images in text widgets
     destroy command ignores windows that don't exist
    

Pmw 1.3.3 - 29 Mar 2014 - Home

././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9351187 Pmw-2.1/Pmw/Pmw_1_3_3/doc/transdove.gif0000664000175000017500000000067100000000000020005 0ustar00gregmgregm00000000000000GIF89aFK! !) Imported from GIF image: tempa29659.gif,FK3ڋQj3t ejRpˉ5w7'Y&z4OGل (8Z#G\wǘ뉽]Yl% ~S駇hADuxؠ')YBI8hI57X镒j jxt 9z ۫'kX v::, -=Mm[ ͥ-ylMDjJ*,aR_@oUlLQ&e0K$|eKh\ ,5 O|Y12djEW6Ѩcs`8aE,W%*Jt_(W%Χz<ݛ%R\zuP;././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1609332343.947119 Pmw-2.1/Pmw/Pmw_1_3_3/lib/0000775000175000017500000000000000000000000015306 5ustar00gregmgregm00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9391186 Pmw-2.1/Pmw/Pmw_1_3_3/lib/Pmw.def0000664000175000017500000000435400000000000016537 0ustar00gregmgregm00000000000000# [Emacs: -*- python -*-] # --- This is the Pmw definition file --- # # It is invoked by the Pmw dynamic loader in Pmw.__init__. # # widgets : tuple with the names of those widget classes that are # stacked in a module of the same name. # widgetclasses : dictionary from names of widget classes to module names. # functions : dictionary from function names to modules names. # modules : tuple of module names that don't contain widget classes # of the same name. # # Widgets whose name is the same as its module. _widgets = ( 'AboutDialog', 'Balloon', 'ButtonBox', 'ComboBox', 'ComboBoxDialog', 'Counter', 'CounterDialog', 'Dialog', 'EntryField', 'Group', 'HistoryText', 'LabeledWidget', 'MainMenuBar', 'MenuBar', 'MessageBar', 'MessageDialog', 'NoteBook', 'OptionMenu', 'PanedWidget', 'PromptDialog', 'RadioSelect', 'ScrolledCanvas', 'ScrolledField', 'ScrolledFrame', 'ScrolledListBox', 'ScrolledText', 'SelectionDialog', 'TextDialog', 'TimeCounter', ) # Widgets whose name is not the same as its module. _extraWidgets = { } _functions = { 'logicalfont' : 'LogicalFont', 'logicalfontnames' : 'LogicalFont', 'aboutversion' : 'AboutDialog', 'aboutcopyright' : 'AboutDialog', 'aboutcontact' : 'AboutDialog', 'datestringtojdn' : 'TimeFuncs', 'timestringtoseconds' : 'TimeFuncs', 'setyearpivot' : 'TimeFuncs', 'ymdtojdn' : 'TimeFuncs', 'jdntoymd' : 'TimeFuncs', 'stringtoreal' : 'TimeFuncs', 'aligngrouptags' : 'Group', 'OK' : 'EntryField', 'ERROR' : 'EntryField', 'PARTIAL' : 'EntryField', 'numericvalidator' : 'EntryField', 'integervalidator' : 'EntryField', 'hexadecimalvalidator' : 'EntryField', 'realvalidator' : 'EntryField', 'alphabeticvalidator' : 'EntryField', 'alphanumericvalidator' : 'EntryField', 'timevalidator' : 'EntryField', 'datevalidator' : 'EntryField', } _modules = ( 'Color', 'Blt', ) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9391186 Pmw-2.1/Pmw/Pmw_1_3_3/lib/PmwAboutDialog.py0000664000175000017500000000311400000000000020535 0ustar00gregmgregm00000000000000import Pmw class AboutDialog(Pmw.MessageDialog): # Window to display version and contact information. # Class members containing resettable 'default' values: _version = '' _copyright = '' _contact = '' def __init__(self, parent = None, **kw): # Define the megawidget options. INITOPT = Pmw.INITOPT optiondefs = ( ('applicationname', '', INITOPT), ('iconpos', 'w', None), ('icon_bitmap', 'info', None), ('buttons', ('Close',), None), ('defaultbutton', 0, None), ) self.defineoptions(kw, optiondefs) # Initialise the base class (after defining the options). Pmw.MessageDialog.__init__(self, parent) applicationname = self['applicationname'] if not kw.has_key('title'): self.configure(title = 'About ' + applicationname) if not kw.has_key('message_text'): text = applicationname + '\n\n' if AboutDialog._version != '': text = text + 'Version ' + AboutDialog._version + '\n' if AboutDialog._copyright != '': text = text + AboutDialog._copyright + '\n\n' if AboutDialog._contact != '': text = text + AboutDialog._contact self.configure(message_text=text) # Check keywords and initialise options. self.initialiseoptions() def aboutversion(value): AboutDialog._version = value def aboutcopyright(value): AboutDialog._copyright = value def aboutcontact(value): AboutDialog._contact = value ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9391186 Pmw-2.1/Pmw/Pmw_1_3_3/lib/PmwBalloon.py0000664000175000017500000003472700000000000017747 0ustar00gregmgregm00000000000000import os import string import Tkinter import Pmw class Balloon(Pmw.MegaToplevel): def __init__(self, parent = None, **kw): # Define the megawidget options. optiondefs = ( ('initwait', 500, None), # milliseconds ('label_background', 'lightyellow', None), ('label_foreground', 'black', None), ('label_justify', 'left', None), ('master', 'parent', None), ('relmouse', 'none', self._relmouse), ('state', 'both', self._state), ('statuscommand', None, None), ('xoffset', 20, None), # pixels ('yoffset', 1, None), # pixels ('hull_highlightthickness', 1, None), ('hull_highlightbackground', 'black', None), ) self.defineoptions(kw, optiondefs) # Initialise the base class (after defining the options). Pmw.MegaToplevel.__init__(self, parent) self.withdraw() self.overrideredirect(1) # Create the components. interior = self.interior() self._label = self.createcomponent('label', (), None, Tkinter.Label, (interior,)) self._label.pack() # The default hull configuration options give a black border # around the balloon, but avoids a black 'flash' when the # balloon is deiconified, before the text appears. if not kw.has_key('hull_background'): self.configure(hull_background = \ str(self._label.cget('background'))) # Initialise instance variables. self._timer = None # The widget or item that is currently triggering the balloon. # It is None if the balloon is not being displayed. It is a # one-tuple if the balloon is being displayed in response to a # widget binding (value is the widget). It is a two-tuple if # the balloon is being displayed in response to a canvas or # text item binding (value is the widget and the item). self._currentTrigger = None # Check keywords and initialise options. self.initialiseoptions() def destroy(self): if self._timer is not None: self.after_cancel(self._timer) self._timer = None Pmw.MegaToplevel.destroy(self) def bind(self, widget, balloonHelp, statusHelp = None): # If a previous bind for this widget exists, remove it. self.unbind(widget) if balloonHelp is None and statusHelp is None: return if statusHelp is None: statusHelp = balloonHelp enterId = widget.bind('', lambda event, self = self, w = widget, sHelp = statusHelp, bHelp = balloonHelp: self._enter(event, w, sHelp, bHelp, 0)) # Set Motion binding so that if the pointer remains at rest # within the widget until the status line removes the help and # then the pointer moves again, then redisplay the help in the # status line. # Note: The Motion binding only works for basic widgets, and # the hull of megawidgets but not for other megawidget components. motionId = widget.bind('', lambda event = None, self = self, statusHelp = statusHelp: self.showstatus(statusHelp)) leaveId = widget.bind('', self._leave) buttonId = widget.bind('', self._buttonpress) # Set Destroy binding so that the balloon can be withdrawn and # the timer can be cancelled if the widget is destroyed. destroyId = widget.bind('', self._destroy) # Use the None item in the widget's private Pmw dictionary to # store the widget's bind callbacks, for later clean up. if not hasattr(widget, '_Pmw_BalloonBindIds'): widget._Pmw_BalloonBindIds = {} widget._Pmw_BalloonBindIds[None] = \ (enterId, motionId, leaveId, buttonId, destroyId) def unbind(self, widget): if hasattr(widget, '_Pmw_BalloonBindIds'): if widget._Pmw_BalloonBindIds.has_key(None): (enterId, motionId, leaveId, buttonId, destroyId) = \ widget._Pmw_BalloonBindIds[None] # Need to pass in old bindings, so that Tkinter can # delete the commands. Otherwise, memory is leaked. widget.unbind('', enterId) widget.unbind('', motionId) widget.unbind('', leaveId) widget.unbind('', buttonId) widget.unbind('', destroyId) del widget._Pmw_BalloonBindIds[None] if self._currentTrigger is not None and len(self._currentTrigger) == 1: # The balloon is currently being displayed and the current # trigger is a widget. triggerWidget = self._currentTrigger[0] if triggerWidget == widget: if self._timer is not None: self.after_cancel(self._timer) self._timer = None self.withdraw() self.clearstatus() self._currentTrigger = None def tagbind(self, widget, tagOrItem, balloonHelp, statusHelp = None): # If a previous bind for this widget's tagOrItem exists, remove it. self.tagunbind(widget, tagOrItem) if balloonHelp is None and statusHelp is None: return if statusHelp is None: statusHelp = balloonHelp enterId = widget.tag_bind(tagOrItem, '', lambda event, self = self, w = widget, sHelp = statusHelp, bHelp = balloonHelp: self._enter(event, w, sHelp, bHelp, 1)) motionId = widget.tag_bind(tagOrItem, '', lambda event = None, self = self, statusHelp = statusHelp: self.showstatus(statusHelp)) leaveId = widget.tag_bind(tagOrItem, '', self._leave) buttonId = widget.tag_bind(tagOrItem, '', self._buttonpress) # Use the tagOrItem item in the widget's private Pmw dictionary to # store the tagOrItem's bind callbacks, for later clean up. if not hasattr(widget, '_Pmw_BalloonBindIds'): widget._Pmw_BalloonBindIds = {} widget._Pmw_BalloonBindIds[tagOrItem] = \ (enterId, motionId, leaveId, buttonId) def tagunbind(self, widget, tagOrItem): if hasattr(widget, '_Pmw_BalloonBindIds'): if widget._Pmw_BalloonBindIds.has_key(tagOrItem): (enterId, motionId, leaveId, buttonId) = \ widget._Pmw_BalloonBindIds[tagOrItem] widget.tag_unbind(tagOrItem, '', enterId) widget.tag_unbind(tagOrItem, '', motionId) widget.tag_unbind(tagOrItem, '', leaveId) widget.tag_unbind(tagOrItem, '', buttonId) del widget._Pmw_BalloonBindIds[tagOrItem] if self._currentTrigger is None: # The balloon is not currently being displayed. return if len(self._currentTrigger) == 1: # The current trigger is a widget. return if len(self._currentTrigger) == 2: # The current trigger is a canvas item. (triggerWidget, triggerItem) = self._currentTrigger if triggerWidget == widget and triggerItem == tagOrItem: if self._timer is not None: self.after_cancel(self._timer) self._timer = None self.withdraw() self.clearstatus() self._currentTrigger = None else: # The current trigger is a text item. (triggerWidget, x, y) = self._currentTrigger if triggerWidget == widget: currentPos = widget.index('@%d,%d' % (x, y)) currentTags = widget.tag_names(currentPos) if tagOrItem in currentTags: if self._timer is not None: self.after_cancel(self._timer) self._timer = None self.withdraw() self.clearstatus() self._currentTrigger = None def showstatus(self, statusHelp): if self['state'] in ('status', 'both'): cmd = self['statuscommand'] if callable(cmd): cmd(statusHelp) def clearstatus(self): self.showstatus(None) def _state(self): if self['state'] not in ('both', 'balloon', 'status', 'none'): raise ValueError, 'bad state option ' + repr(self['state']) + \ ': should be one of \'both\', \'balloon\', ' + \ '\'status\' or \'none\'' def _relmouse(self): if self['relmouse'] not in ('both', 'x', 'y', 'none'): raise ValueError, 'bad relmouse option ' + repr(self['relmouse'])+ \ ': should be one of \'both\', \'x\', ' + '\'y\' or \'none\'' def _enter(self, event, widget, statusHelp, balloonHelp, isItem): # Do not display balloon if mouse button is pressed. This # will only occur if the button was pressed inside a widget, # then the mouse moved out of and then back into the widget, # with the button still held down. The number 0x1f00 is the # button mask for the 5 possible buttons in X. buttonPressed = (event.state & 0x1f00) != 0 if not buttonPressed and balloonHelp is not None and \ self['state'] in ('balloon', 'both'): if self._timer is not None: self.after_cancel(self._timer) self._timer = None self._timer = self.after(self['initwait'], lambda self = self, widget = widget, help = balloonHelp, isItem = isItem: self._showBalloon(widget, help, isItem)) if isItem: if hasattr(widget, 'canvasx'): # The widget is a canvas. item = widget.find_withtag('current') if len(item) > 0: item = item[0] else: item = None self._currentTrigger = (widget, item) else: # The widget is a text widget. self._currentTrigger = (widget, event.x, event.y) else: self._currentTrigger = (widget,) self.showstatus(statusHelp) def _leave(self, event): if self._timer is not None: self.after_cancel(self._timer) self._timer = None self.withdraw() self.clearstatus() self._currentTrigger = None def _destroy(self, event): # Only withdraw the balloon and cancel the timer if the widget # being destroyed is the widget that triggered the balloon. # Note that in a Tkinter Destroy event, the widget field is a # string and not a widget as usual. if self._currentTrigger is None: # The balloon is not currently being displayed return if len(self._currentTrigger) == 1: # The current trigger is a widget (not an item) triggerWidget = self._currentTrigger[0] if str(triggerWidget) == event.widget: if self._timer is not None: self.after_cancel(self._timer) self._timer = None self.withdraw() self.clearstatus() self._currentTrigger = None def _buttonpress(self, event): if self._timer is not None: self.after_cancel(self._timer) self._timer = None self.withdraw() self._currentTrigger = None def _showBalloon(self, widget, balloonHelp, isItem): self._label.configure(text = balloonHelp) # First, display the balloon offscreen to get dimensions. screenWidth = self.winfo_screenwidth() screenHeight = self.winfo_screenheight() self.geometry('+%d+0' % (screenWidth + 1)) self.update_idletasks() if isItem: # Get the bounding box of the current item. bbox = widget.bbox('current') if bbox is None: # The item that triggered the balloon has disappeared, # perhaps by a user's timer event that occured between # the event and the 'initwait' timer calling # this method. return # The widget is either a text or canvas. The meaning of # the values returned by the bbox method is different for # each, so use the existence of the 'canvasx' method to # distinguish between them. if hasattr(widget, 'canvasx'): # The widget is a canvas. Place balloon under canvas # item. The positions returned by bbox are relative # to the entire canvas, not just the visible part, so # need to convert to window coordinates. leftrel = bbox[0] - widget.canvasx(0) toprel = bbox[1] - widget.canvasy(0) bottomrel = bbox[3] - widget.canvasy(0) else: # The widget is a text widget. Place balloon under # the character closest to the mouse. The positions # returned by bbox are relative to the text widget # window (ie the visible part of the text only). leftrel = bbox[0] toprel = bbox[1] bottomrel = bbox[1] + bbox[3] else: leftrel = 0 toprel = 0 bottomrel = widget.winfo_height() xpointer, ypointer = widget.winfo_pointerxy() # -1 if off screen if xpointer >= 0 and self['relmouse'] in ('both', 'x'): x = xpointer else: x = leftrel + widget.winfo_rootx() x = x + self['xoffset'] if ypointer >= 0 and self['relmouse'] in ('both', 'y'): y = ypointer else: y = bottomrel + widget.winfo_rooty() y = y + self['yoffset'] edges = (string.atoi(str(self.cget('hull_highlightthickness'))) + string.atoi(str(self.cget('hull_borderwidth')))) * 2 if x + self._label.winfo_reqwidth() + edges > screenWidth: x = screenWidth - self._label.winfo_reqwidth() - edges if y + self._label.winfo_reqheight() + edges > screenHeight: if ypointer >= 0 and self['relmouse'] in ('both', 'y'): y = ypointer else: y = toprel + widget.winfo_rooty() y = y - self._label.winfo_reqheight() - self['yoffset'] - edges Pmw.setgeometryanddeiconify(self, '+%d+%d' % (x, y)) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609332343.9351187 Pmw-2.1/Pmw/Pmw_1_3_3/lib/PmwBase.py0000664000175000017500000020652600000000000017231 0ustar00gregmgregm00000000000000# Pmw megawidget base classes. # This module provides a foundation for building megawidgets. It # contains the MegaArchetype class which manages component widgets and # configuration options. Also provided are the MegaToplevel and # MegaWidget classes, derived from the MegaArchetype class. The # MegaToplevel class contains a Tkinter Toplevel widget to act as the # container of the megawidget. This is used as the base class of all # megawidgets that are contained in their own top level window, such # as a Dialog window. The MegaWidget class contains a Tkinter Frame # to act as the container of the megawidget. This is used as the base # class of all other megawidgets, such as a ComboBox or ButtonBox. # # Megawidgets are built by creating a class that inherits from either # the MegaToplevel or MegaWidget class. import os import string import sys import traceback import types import Tkinter # Special values used in index() methods of several megawidgets. END = ['end'] SELECT = ['select'] DEFAULT = ['default'] # Constant used to indicate that an option can only be set by a call # to the constructor. INITOPT = ['initopt'] _DEFAULT_OPTION_VALUE = ['default_option_value'] _useTkOptionDb = 0 # Symbolic constants for the indexes into an optionInfo list. _OPT_DEFAULT = 0 _OPT_VALUE = 1 _OPT_FUNCTION = 2 # Stacks _busyStack = [] # Stack which tracks nested calls to show/hidebusycursor (called # either directly or from activate()/deactivate()). Each element # is a dictionary containing: # 'newBusyWindows' : List of windows which had busy_hold called # on them during a call to showbusycursor(). # The corresponding call to hidebusycursor() # will call busy_release on these windows. # 'busyFocus' : The blt _Busy window which showbusycursor() # set the focus to. # 'previousFocus' : The focus as it was when showbusycursor() # was called. The corresponding call to # hidebusycursor() will restore this focus if # the focus has not been changed from busyFocus. _grabStack = [] # Stack of grabbed windows. It tracks calls to push/popgrab() # (called either directly or from activate()/deactivate()). The # window on the top of the stack is the window currently with the # grab. Each element is a dictionary containing: # 'grabWindow' : The window grabbed by pushgrab(). The # corresponding call to popgrab() will release # the grab on this window and restore the grab # on the next window in the stack (if there is one). # 'globalMode' : True if the grabWindow was grabbed with a # global grab, false if the grab was local # and 'nograb' if no grab was performed. # 'previousFocus' : The focus as it was when pushgrab() # was called. The corresponding call to # popgrab() will restore this focus. # 'deactivateFunction' : # The function to call (usually grabWindow.deactivate) if # popgrab() is called (usually from a deactivate() method) # on a window which is not at the top of the stack (that is, # does not have the grab or focus). For example, if a modal # dialog is deleted by the window manager or deactivated by # a timer. In this case, all dialogs above and including # this one are deactivated, starting at the top of the # stack. # Note that when dealing with focus windows, the name of the Tk # widget is used, since it may be the '_Busy' window, which has no # python instance associated with it. #============================================================================= # Functions used to forward methods from a class to a component. # Fill in a flattened method resolution dictionary for a class (attributes are # filtered out). Flattening honours the MI method resolution rules # (depth-first search of bases in order). The dictionary has method names # for keys and functions for values. def __methodDict(cls, dict): # the strategy is to traverse the class in the _reverse_ of the normal # order, and overwrite any duplicates. baseList = list(cls.__bases__) baseList.reverse() # do bases in reverse order, so first base overrides last base for super in baseList: __methodDict(super, dict) # do my methods last to override base classes for key, value in cls.__dict__.items(): # ignore class attributes if type(value) == types.FunctionType: dict[key] = value def __methods(cls): # Return all method names for a class. # Return all method names for a class (attributes are filtered # out). Base classes are searched recursively. dict = {} __methodDict(cls, dict) return dict.keys() # Function body to resolve a forwarding given the target method name and the # attribute name. The resulting lambda requires only self, but will forward # any other parameters. __stringBody = ( 'def %(method)s(this, *args, **kw): return ' + #'apply(this.%(attribute)s.%(method)s, args, kw)') 'this.%(attribute)s.%(method)s(*args, **kw)') # Get a unique id __counter = 0 def __unique(): global __counter __counter = __counter + 1 return str(__counter) # Function body to resolve a forwarding given the target method name and the # index of the resolution function. The resulting lambda requires only self, # but will forward any other parameters. The target instance is identified # by invoking the resolution function. __funcBody = ( 'def %(method)s(this, *args, **kw): return ' + #'apply(this.%(forwardFunc)s().%(method)s, args, kw)') 'this.%(forwardFunc)s().%(method)s(*args, **kw)'); def forwardmethods(fromClass, toClass, toPart, exclude = ()): # Forward all methods from one class to another. # Forwarders will be created in fromClass to forward method # invocations to toClass. The methods to be forwarded are # identified by flattening the interface of toClass, and excluding # methods identified in the exclude list. Methods already defined # in fromClass, or special methods with one or more leading or # trailing underscores will not be forwarded. # For a given object of class fromClass, the corresponding toClass # object is identified using toPart. This can either be a String # denoting an attribute of fromClass objects, or a function taking # a fromClass object and returning a toClass object. # Example: # class MyClass: # ... # def __init__(self): # ... # self.__target = TargetClass() # ... # def findtarget(self): # return self.__target # forwardmethods(MyClass, TargetClass, '__target', ['dangerous1', 'dangerous2']) # # ...or... # forwardmethods(MyClass, TargetClass, MyClass.findtarget, # ['dangerous1', 'dangerous2']) # In both cases, all TargetClass methods will be forwarded from # MyClass except for dangerous1, dangerous2, special methods like # __str__, and pre-existing methods like findtarget. # Allow an attribute name (String) or a function to determine the instance if type(toPart) != types.StringType: # check that it is something like a function if callable(toPart): # If a method is passed, use the function within it if hasattr(toPart, 'im_func'): toPart = toPart.im_func # After this is set up, forwarders in this class will use # the forwarding function. The forwarding function name is # guaranteed to be unique, so that it can't be hidden by subclasses forwardName = '__fwdfunc__' + __unique() fromClass.__dict__[forwardName] = toPart # It's not a valid type else: raise TypeError, 'toPart must be attribute name, function or method' # get the full set of candidate methods dict = {} __methodDict(toClass, dict) # discard special methods for ex in dict.keys(): if ex[:1] == '_' or ex[-1:] == '_': del dict[ex] # discard dangerous methods supplied by the caller for ex in exclude: if dict.has_key(ex): del dict[ex] # discard methods already defined in fromClass for ex in __methods(fromClass): if dict.has_key(ex): del dict[ex] for method, func in dict.items(): d = {'method': method, 'func': func} if type(toPart) == types.StringType: execString = \ __stringBody % {'method' : method, 'attribute' : toPart} else: execString = \ __funcBody % {'forwardFunc' : forwardName, 'method' : method} exec execString in d # this creates a method fromClass.__dict__[method] = d[method] #============================================================================= def setgeometryanddeiconify(window, geom): # To avoid flashes on X and to position the window correctly on NT # (caused by Tk bugs). if os.name == 'nt' or \ (os.name == 'posix' and sys.platform[:6] == 'cygwin'): # Require overrideredirect trick to stop window frame # appearing momentarily. redirect = window.overrideredirect() if not redirect: window.overrideredirect(1) window.deiconify() if geom is not None: window.geometry(geom) # Call update_idletasks to ensure NT moves the window to the # correct position it is raised. window.update_idletasks() window.tkraise() if not redirect: window.overrideredirect(0) else: if geom is not None: window.geometry(geom) # Problem!? Which way around should the following two calls # go? If deiconify() is called first then I get complaints # from people using the enlightenment or sawfish window # managers that when a dialog is activated it takes about 2 # seconds for the contents of the window to appear. But if # tkraise() is called first then I get complaints from people # using the twm window manager that when a dialog is activated # it appears in the top right corner of the screen and also # takes about 2 seconds to appear. #window.tkraise() # Call update_idletasks to ensure certain window managers (eg: # enlightenment and sawfish) do not cause Tk to delay for # about two seconds before displaying window. #window.update_idletasks() #window.deiconify() window.deiconify() if window.overrideredirect(): # The window is not under the control of the window manager # and so we need to raise it ourselves. window.tkraise() #============================================================================= class MegaArchetype: # Megawidget abstract root class. # This class provides methods which are inherited by classes # implementing useful bases (this class doesn't provide a # container widget inside which the megawidget can be built). def __init__(self, parent = None, hullClass = None): # Mapping from each megawidget option to a list of information # about the option # - default value # - current value # - function to call when the option is initialised in the # call to initialiseoptions() in the constructor or # modified via configure(). If this is INITOPT, the # option is an initialisation option (an option that can # be set by the call to the constructor but can not be # used with configure). # This mapping is not initialised here, but in the call to # defineoptions() which precedes construction of this base class. # # self._optionInfo = {} # Mapping from each component name to a tuple of information # about the component. # - component widget instance # - configure function of widget instance # - the class of the widget (Frame, EntryField, etc) # - cget function of widget instance # - the name of the component group of this component, if any self.__componentInfo = {} # Mapping from alias names to the names of components or # sub-components. self.__componentAliases = {} # Contains information about the keywords provided to the # constructor. It is a mapping from the keyword to a tuple # containing: # - value of keyword # - a boolean indicating if the keyword has been used. # A keyword is used if, during the construction of a megawidget, # - it is defined in a call to defineoptions() or addoptions(), or # - it references, by name, a component of the megawidget, or # - it references, by group, at least one component # At the end of megawidget construction, a call is made to # initialiseoptions() which reports an error if there are # unused options given to the constructor. # # After megawidget construction, the dictionary contains # keywords which refer to a dynamic component group, so that # these components can be created after megawidget # construction and still use the group options given to the # constructor. # # self._constructorKeywords = {} # List of dynamic component groups. If a group is included in # this list, then it not an error if a keyword argument for # the group is given to the constructor or to configure(), but # no components with this group have been created. # self._dynamicGroups = () if hullClass is None: self._hull = None else: if parent is None: parent = Tkinter._default_root # Create the hull. self._hull = self.createcomponent('hull', (), None, hullClass, (parent,)) _hullToMegaWidget[self._hull] = self if _useTkOptionDb: # Now that a widget has been created, query the Tk # option database to get the default values for the # options which have not been set in the call to the # constructor. This assumes that defineoptions() is # called before the __init__(). option_get = self.option_get _VALUE = _OPT_VALUE _DEFAULT = _OPT_DEFAULT for name, info in self._optionInfo.items(): value = info[_VALUE] if value is _DEFAULT_OPTION_VALUE: resourceClass = string.upper(name[0]) + name[1:] value = option_get(name, resourceClass) if value != '': try: # Convert the string to int/float/tuple, etc value = eval(value, {'__builtins__': {}}) except: pass info[_VALUE] = value else: info[_VALUE] = info[_DEFAULT] def destroy(self): # Clean up optionInfo in case it contains circular references # in the function field, such as self._settitle in class # MegaToplevel. self._optionInfo = {} if self._hull is not None: del _hullToMegaWidget[self._hull] self._hull.destroy() #====================================================================== # Methods used (mainly) during the construction of the megawidget. def defineoptions(self, keywords, optionDefs, dynamicGroups = ()): # Create options, providing the default value and the method # to call when the value is changed. If any option created by # base classes has the same name as one in , the # base class's value and function will be overriden. # This should be called before the constructor of the base # class, so that default values defined in the derived class # override those in the base class. if not hasattr(self, '_constructorKeywords'): # First time defineoptions has been called. tmp = {} for option, value in keywords.items(): tmp[option] = [value, 0] self._constructorKeywords = tmp self._optionInfo = {} self._initialiseoptions_counter = 0 self._initialiseoptions_counter = self._initialiseoptions_counter + 1 if not hasattr(self, '_dynamicGroups'): self._dynamicGroups = () self._dynamicGroups = self._dynamicGroups + tuple(dynamicGroups) self.addoptions(optionDefs) def addoptions(self, optionDefs): # Add additional options, providing the default value and the # method to call when the value is changed. See # "defineoptions" for more details # optimisations: optionInfo = self._optionInfo optionInfo_has_key = optionInfo.has_key keywords = self._constructorKeywords keywords_has_key = keywords.has_key FUNCTION = _OPT_FUNCTION for name, default, function in optionDefs: if '_' not in name: # The option will already exist if it has been defined # in a derived class. In this case, do not override the # default value of the option or the callback function # if it is not None. if not optionInfo_has_key(name): if keywords_has_key(name): value = keywords[name][0] optionInfo[name] = [default, value, function] del keywords[name] else: if _useTkOptionDb: optionInfo[name] = \ [default, _DEFAULT_OPTION_VALUE, function] else: optionInfo[name] = [default, default, function] elif optionInfo[name][FUNCTION] is None: optionInfo[name][FUNCTION] = function else: # This option is of the form "component_option". If this is # not already defined in self._constructorKeywords add it. # This allows a derived class to override the default value # of an option of a component of a base class. if not keywords_has_key(name): keywords[name] = [default, 0] def createcomponent(self, componentName, componentAliases, componentGroup, widgetClass, *widgetArgs, **kw): # Create a component (during construction or later). if self.__componentInfo.has_key(componentName): raise ValueError, 'Component "%s" already exists' % componentName if '_' in componentName: raise ValueError, \ 'Component name "%s" must not contain "_"' % componentName if hasattr(self, '_constructorKeywords'): keywords = self._constructorKeywords else: keywords = {} for alias, component in componentAliases: # Create aliases to the component and its sub-components. index = string.find(component, '_') if index < 0: self.__componentAliases[alias] = (component, None) else: mainComponent = component[:index] subComponent = component[(index + 1):] self.__componentAliases[alias] = (mainComponent, subComponent) # Remove aliases from the constructor keyword arguments by # replacing any keyword arguments that begin with *alias* # with corresponding keys beginning with *component*. alias = alias + '_' aliasLen = len(alias) for option in keywords.keys(): if len(option) > aliasLen and option[:aliasLen] == alias: newkey = component + '_' + option[aliasLen:] keywords[newkey] = keywords[option] del keywords[option] componentPrefix = componentName + '_' nameLen = len(componentPrefix) for option in keywords.keys(): if len(option) > nameLen and option[:nameLen] == componentPrefix: # The keyword argument refers to this component, so add # this to the options to use when constructing the widget. kw[option[nameLen:]] = keywords[option][0] del keywords[option] else: # Check if this keyword argument refers to the group # of this component. If so, add this to the options # to use when constructing the widget. Mark the # keyword argument as being used, but do not remove it # since it may be required when creating another # component. index = string.find(option, '_') if index >= 0 and componentGroup == option[:index]: rest = option[(index + 1):] kw[rest] = keywords[option][0] keywords[option][1] = 1 if kw.has_key('pyclass'): widgetClass = kw['pyclass'] del kw['pyclass'] if widgetClass is None: return None if len(widgetArgs) == 1 and type(widgetArgs[0]) == types.TupleType: # Arguments to the constructor can be specified as either # multiple trailing arguments to createcomponent() or as a # single tuple argument. widgetArgs = widgetArgs[0] widget = apply(widgetClass, widgetArgs, kw) componentClass = widget.__class__.__name__ self.__componentInfo[componentName] = (widget, widget.configure, componentClass, widget.cget, componentGroup) return widget def destroycomponent(self, name): # Remove a megawidget component. # This command is for use by megawidget designers to destroy a # megawidget component. self.__componentInfo[name][0].destroy() del self.__componentInfo[name] def createlabel(self, parent, childCols = 1, childRows = 1): labelpos = self['labelpos'] labelmargin = self['labelmargin'] if labelpos is None: return label = self.createcomponent('label', (), None, Tkinter.Label, (parent,)) if labelpos[0] in 'ns': # vertical layout if labelpos[0] == 'n': row = 0 margin = 1 else: row = childRows + 3 margin = row - 1 label.grid(column=2, row=row, columnspan=childCols, sticky=labelpos) parent.grid_rowconfigure(margin, minsize=labelmargin) else: # horizontal layout if labelpos[0] == 'w': col = 0 margin = 1 else: col = childCols + 3 margin = col - 1 label.grid(column=col, row=2, rowspan=childRows, sticky=labelpos) parent.grid_columnconfigure(margin, minsize=labelmargin) def initialiseoptions(self, dummy = None): self._initialiseoptions_counter = self._initialiseoptions_counter - 1 if self._initialiseoptions_counter == 0: unusedOptions = [] keywords = self._constructorKeywords for name in keywords.keys(): used = keywords[name][1] if not used: # This keyword argument has not been used. If it # does not refer to a dynamic group, mark it as # unused. index = string.find(name, '_') if index < 0 or name[:index] not in self._dynamicGroups: unusedOptions.append(name) if len(unusedOptions) > 0: if len(unusedOptions) == 1: text = 'Unknown option "' else: text = 'Unknown options "' raise KeyError, text + string.join(unusedOptions, ', ') + \ '" for ' + self.__class__.__name__ # Call the configuration callback function for every option. FUNCTION = _OPT_FUNCTION for info in self._optionInfo.values(): func = info[FUNCTION] if func is not None and func is not INITOPT: func() #====================================================================== # Method used to configure the megawidget. def configure(self, option=None, **kw): # Query or configure the megawidget options. # # If not empty, *kw* is a dictionary giving new # values for some of the options of this megawidget or its # components. For options defined for this megawidget, set # the value of the option to the new value and call the # configuration callback function, if any. For options of the # form _