|
@@ -4,12 +4,38 @@ This is an adaption of AppShell.py found in Python and Tkinter Programming
|
|
|
by John E. Grayson which is a streamlined adaptation of GuiAppD.py, originally
|
|
by John E. Grayson which is a streamlined adaptation of GuiAppD.py, originally
|
|
|
created by Doug Hellmann ([email protected]).
|
|
created by Doug Hellmann ([email protected]).
|
|
|
"""
|
|
"""
|
|
|
-
|
|
|
|
|
from PandaObject import *
|
|
from PandaObject import *
|
|
|
from Tkinter import *
|
|
from Tkinter import *
|
|
|
|
|
+from tkFileDialog import *
|
|
|
import Pmw
|
|
import Pmw
|
|
|
|
|
+import Dial
|
|
|
|
|
+import Floater
|
|
|
|
|
+import EntryScale
|
|
|
|
|
+import VectorWidgets
|
|
|
import sys, string
|
|
import sys, string
|
|
|
import ProgressBar
|
|
import ProgressBar
|
|
|
|
|
+import __builtin__
|
|
|
|
|
+
|
|
|
|
|
+"""
|
|
|
|
|
+TO FIX:
|
|
|
|
|
+Radiobutton ordering change
|
|
|
|
|
+"""
|
|
|
|
|
+
|
|
|
|
|
+# Create toplevel widget dictionary
|
|
|
|
|
+try:
|
|
|
|
|
+ __builtin__.widgetDict
|
|
|
|
|
+except AttributeError:
|
|
|
|
|
+ __builtin__.widgetDict = {}
|
|
|
|
|
+# Create toplevel variable dictionary
|
|
|
|
|
+try:
|
|
|
|
|
+ __builtin__.variableDict
|
|
|
|
|
+except AttributeError:
|
|
|
|
|
+ __builtin__.variableDict = {}
|
|
|
|
|
+
|
|
|
|
|
+def resetWidgetDict():
|
|
|
|
|
+ __builtin__.widgetDict = {}
|
|
|
|
|
+def resetVariableDict():
|
|
|
|
|
+ __builtin__.variableDict = {}
|
|
|
|
|
|
|
|
# Inherit from MegaWidget instead of Toplevel so you can pass in a toplevel
|
|
# Inherit from MegaWidget instead of Toplevel so you can pass in a toplevel
|
|
|
# to use as a container if you wish. If no toplevel passed in, create one
|
|
# to use as a container if you wish. If no toplevel passed in, create one
|
|
@@ -29,6 +55,7 @@ class AppShell(Pmw.MegaWidget, PandaObject):
|
|
|
usecommandarea = 0
|
|
usecommandarea = 0
|
|
|
usestatusarea = 0
|
|
usestatusarea = 0
|
|
|
balloonState = 'none'
|
|
balloonState = 'none'
|
|
|
|
|
+ panelCount = 0
|
|
|
|
|
|
|
|
def __init__(self, parent = None, **kw):
|
|
def __init__(self, parent = None, **kw):
|
|
|
optiondefs = (
|
|
optiondefs = (
|
|
@@ -51,6 +78,13 @@ class AppShell(Pmw.MegaWidget, PandaObject):
|
|
|
# Set window size
|
|
# Set window size
|
|
|
self.parent.geometry('%dx%d' % (self.frameWidth, self.frameHeight))
|
|
self.parent.geometry('%dx%d' % (self.frameWidth, self.frameHeight))
|
|
|
self.parent.title(self['title'])
|
|
self.parent.title(self['title'])
|
|
|
|
|
+ # Create unique id
|
|
|
|
|
+ AppShell.panelCount += 1
|
|
|
|
|
+ self.id = self.appname + '-' + `AppShell.panelCount`
|
|
|
|
|
+ # Create a dictionary in the widgetDict to hold this panel's widgets
|
|
|
|
|
+ self.widgetDict = widgetDict[self.id] = {}
|
|
|
|
|
+ # And one to hold this panel's variables
|
|
|
|
|
+ self.variableDict = variableDict[self.id] = {}
|
|
|
# Get handle to the toplevels hull
|
|
# Get handle to the toplevels hull
|
|
|
self._hull = self.component('hull')
|
|
self._hull = self.component('hull')
|
|
|
# Initialize the application
|
|
# Initialize the application
|
|
@@ -219,6 +253,23 @@ class AppShell(Pmw.MegaWidget, PandaObject):
|
|
|
label='Quit',
|
|
label='Quit',
|
|
|
command=self.quit)
|
|
command=self.quit)
|
|
|
|
|
|
|
|
|
|
+ # Getters
|
|
|
|
|
+ def interior(self):
|
|
|
|
|
+ # Retrieve the interior site where widgets should go.
|
|
|
|
|
+ return self.dataArea
|
|
|
|
|
+
|
|
|
|
|
+ def balloon(self):
|
|
|
|
|
+ # Retrieve the panel's balloon widget
|
|
|
|
|
+ return self.__balloon
|
|
|
|
|
+
|
|
|
|
|
+ def buttonBox(self):
|
|
|
|
|
+ # Retrieve the button box.
|
|
|
|
|
+ return self.__buttonBox
|
|
|
|
|
+
|
|
|
|
|
+ def messageBar(self):
|
|
|
|
|
+ # Retieve the message bar
|
|
|
|
|
+ return self.__messageBar
|
|
|
|
|
+
|
|
|
# Utility functions
|
|
# Utility functions
|
|
|
def buttonAdd(self, buttonName, helpMessage=None,
|
|
def buttonAdd(self, buttonName, helpMessage=None,
|
|
|
statusMessage=None, **kw):
|
|
statusMessage=None, **kw):
|
|
@@ -241,22 +292,212 @@ class AppShell(Pmw.MegaWidget, PandaObject):
|
|
|
# Used to update progress bar
|
|
# Used to update progress bar
|
|
|
self.__progressBar.updateProgress(newValue, newMax)
|
|
self.__progressBar.updateProgress(newValue, newMax)
|
|
|
|
|
|
|
|
- # Getters
|
|
|
|
|
- def interior(self):
|
|
|
|
|
- # Retrieve the interior site where widgets should go.
|
|
|
|
|
- return self.dataArea
|
|
|
|
|
|
|
+ ## WIDGET UTILITY FUNCTIONS ##
|
|
|
|
|
+ def addWidget(self, category, text, widget):
|
|
|
|
|
+ self.widgetDict[category + '-' + text] = widget
|
|
|
|
|
+
|
|
|
|
|
+ def getWidget(self, category, text):
|
|
|
|
|
+ return self.widgetDict.get(category + '-' + text, None)
|
|
|
|
|
|
|
|
- def balloon(self):
|
|
|
|
|
- # Retrieve the panel's balloon widget
|
|
|
|
|
- return self.__balloon
|
|
|
|
|
|
|
+ def addVariable(self, category, text, variable):
|
|
|
|
|
+ self.variableDict[category + '-' + text] = variable
|
|
|
|
|
+
|
|
|
|
|
+ def getVariable(self, category, text):
|
|
|
|
|
+ return self.variableDict.get(category + '-' + text, None)
|
|
|
|
|
|
|
|
- def buttonBox(self):
|
|
|
|
|
- # Retrieve the button box.
|
|
|
|
|
- return self.__buttonBox
|
|
|
|
|
|
|
+ def createWidget(self, parent, category, text, widgetClass,
|
|
|
|
|
+ help, command, side, fill, expand, kw):
|
|
|
|
|
+ # Update kw to reflect user inputs
|
|
|
|
|
+ kw['text'] = text
|
|
|
|
|
+ # Create widget
|
|
|
|
|
+ widget = apply(widgetClass, (parent,), kw)
|
|
|
|
|
+ # Do this after so command isn't called on widget creation
|
|
|
|
|
+ widget['command'] = command
|
|
|
|
|
+ # Pack widget
|
|
|
|
|
+ widget.pack(side = side, fill = fill, expand = expand)
|
|
|
|
|
+ # Bind help
|
|
|
|
|
+ self.bind(widget, help)
|
|
|
|
|
+ # Record widget
|
|
|
|
|
+ self.addWidget(category, text, widget)
|
|
|
|
|
+ return widget
|
|
|
|
|
|
|
|
- def messageBar(self):
|
|
|
|
|
- # Retieve the message bar
|
|
|
|
|
- return self.__messageBar
|
|
|
|
|
|
|
+ def newCreateLabeledEntry(self, parent, category, text, help = '',
|
|
|
|
|
+ command = None, initialValue = '',
|
|
|
|
|
+ width = 12, relief = SUNKEN,
|
|
|
|
|
+ side = LEFT, fill = X, expand = 0):
|
|
|
|
|
+ """ createLabeledEntry(parent, category, text, [options]) """
|
|
|
|
|
+ # Create labeled entry
|
|
|
|
|
+ frame = Frame(parent)
|
|
|
|
|
+ variable = StringVar()
|
|
|
|
|
+ variable.set(initialValue)
|
|
|
|
|
+ label = Label(frame, text = text)
|
|
|
|
|
+ label.pack(side = LEFT, fill = X, expand = 0)
|
|
|
|
|
+ entry = Entry(frame, width = width, relief = relief,
|
|
|
|
|
+ textvariable = variable)
|
|
|
|
|
+ entry.pack(side = LEFT, fill = X, expand = 1)
|
|
|
|
|
+ frame.pack(side = side, fill = X, expand = expand)
|
|
|
|
|
+ if command:
|
|
|
|
|
+ entry.bind('<Return>', command)
|
|
|
|
|
+ # Add balloon help
|
|
|
|
|
+ self.bind(label, help)
|
|
|
|
|
+ self.bind(entry, help)
|
|
|
|
|
+ # Record widgets and variable
|
|
|
|
|
+ self.addWidget(category, text, entry)
|
|
|
|
|
+ self.addWidget(category, text + '-Label', label)
|
|
|
|
|
+ self.addVariable(category, text, variable)
|
|
|
|
|
+ return entry
|
|
|
|
|
+
|
|
|
|
|
+ def newCreateButton(self, parent, category, text,
|
|
|
|
|
+ help = '', command = None,
|
|
|
|
|
+ side = LEFT, fill = X, expand = 0, **kw):
|
|
|
|
|
+ """ createButton(parent, category, text, [options]) """
|
|
|
|
|
+ # Create the widget
|
|
|
|
|
+ widget = self.createWidget(parent, category, text, Button,
|
|
|
|
|
+ help, command, side, fill, expand, kw)
|
|
|
|
|
+ return widget
|
|
|
|
|
+
|
|
|
|
|
+ def newCreateCheckbutton(self, parent, category, text,
|
|
|
|
|
+ help = '', command = None,
|
|
|
|
|
+ initialState = 0, anchor = W,
|
|
|
|
|
+ side = LEFT, fill = X, expand = 0, **kw):
|
|
|
|
|
+ """ createCheckbutton(parent, category, text, [options]) """
|
|
|
|
|
+ # Create the widget
|
|
|
|
|
+ widget = self.createWidget(parent, category, text, Checkbutton,
|
|
|
|
|
+ help, command, side, fill, expand, kw)
|
|
|
|
|
+ # Perform extra customization
|
|
|
|
|
+ widget['anchor'] = anchor
|
|
|
|
|
+ variable = BooleanVar()
|
|
|
|
|
+ variable.set(initialState)
|
|
|
|
|
+ self.addVariable(category, text, variable)
|
|
|
|
|
+ widget['variable'] = variable
|
|
|
|
|
+ return widget
|
|
|
|
|
+
|
|
|
|
|
+ def newCreateRadiobutton(self, parent, category, text, variable, value,
|
|
|
|
|
+ command = None, help = '', anchor = W,
|
|
|
|
|
+ side = LEFT, fill = X, expand = 0, **kw):
|
|
|
|
|
+ """
|
|
|
|
|
+ createRadiobutton(parent, category, text, variable, value, [options])
|
|
|
|
|
+ """
|
|
|
|
|
+ # Create the widget
|
|
|
|
|
+ widget = self.createWidget(parent, category, text, Radiobutton,
|
|
|
|
|
+ help, command, side, fill, expand, kw)
|
|
|
|
|
+ # Perform extra customization
|
|
|
|
|
+ widget['anchor'] = anchor
|
|
|
|
|
+ widget['value'] = value
|
|
|
|
|
+ widget['variable'] = variable
|
|
|
|
|
+ return widget
|
|
|
|
|
+
|
|
|
|
|
+ def newCreateFloater(self, parent, category, text,
|
|
|
|
|
+ help = '', command = None,
|
|
|
|
|
+ side = LEFT, fill = X, expand = 0, **kw):
|
|
|
|
|
+ # Create the widget
|
|
|
|
|
+ widget = self.createWidget(parent, category, text,
|
|
|
|
|
+ Floater.Floater,
|
|
|
|
|
+ help, command, side, fill, expand, kw)
|
|
|
|
|
+ return widget
|
|
|
|
|
+
|
|
|
|
|
+ def newCreateDial(self, parent, category, text,
|
|
|
|
|
+ help = '', command = None,
|
|
|
|
|
+ side = LEFT, fill = X, expand = 0, **kw):
|
|
|
|
|
+ # Create the widget
|
|
|
|
|
+ widget = self.createWidget(parent, category, text,
|
|
|
|
|
+ Dial.Dial,
|
|
|
|
|
+ help, command, side, fill, expand, kw)
|
|
|
|
|
+ return widget
|
|
|
|
|
+
|
|
|
|
|
+ def newCreateEntryScale(self, parent, category, text,
|
|
|
|
|
+ help = '', command = None,
|
|
|
|
|
+ side = LEFT, fill = X, expand = 0, **kw):
|
|
|
|
|
+ # Create the widget
|
|
|
|
|
+ widget = self.createWidget(parent, category, text,
|
|
|
|
|
+ EntryScale.EntryScale,
|
|
|
|
|
+ help, command, side, fill, expand, kw)
|
|
|
|
|
+ return widget
|
|
|
|
|
+
|
|
|
|
|
+ def newCreateVector2Entry(self, parent, category, text,
|
|
|
|
|
+ help = '', command = None,
|
|
|
|
|
+ side = LEFT, fill = X, expand = 0, **kw):
|
|
|
|
|
+ # Create the widget
|
|
|
|
|
+ widget = self.createWidget(parent, category, text,
|
|
|
|
|
+ VectorWidgets.Vector2Entry,
|
|
|
|
|
+ help, command, side, fill, expand, kw)
|
|
|
|
|
+
|
|
|
|
|
+ def newCreateVector3Entry(self, parent, category, text,
|
|
|
|
|
+ help = '', command = None,
|
|
|
|
|
+ side = LEFT, fill = X, expand = 0, **kw):
|
|
|
|
|
+ # Create the widget
|
|
|
|
|
+ widget = self.createWidget(parent, category, text,
|
|
|
|
|
+ VectorWidgets.Vector3Entry,
|
|
|
|
|
+ help, command, side, fill, expand, kw)
|
|
|
|
|
+ return widget
|
|
|
|
|
+
|
|
|
|
|
+ def newCreateColorEntry(self, parent, category, text,
|
|
|
|
|
+ help = '', command = None,
|
|
|
|
|
+ side = LEFT, fill = X, expand = 0, **kw):
|
|
|
|
|
+ # Create the widget
|
|
|
|
|
+ widget = self.createWidget(parent, category, text,
|
|
|
|
|
+ VectorWidgets.ColorEntry,
|
|
|
|
|
+ help, command, side, fill, expand, kw)
|
|
|
|
|
+ return widget
|
|
|
|
|
+
|
|
|
|
|
+ def newCreateOptionMenu(self, parent, category, text,
|
|
|
|
|
+ help = '', command = None, items = [],
|
|
|
|
|
+ labelpos = W, label_anchor = W,
|
|
|
|
|
+ label_width = 16, menu_tearoff = 1,
|
|
|
|
|
+ side = LEFT, fill = X, expand = 0, **kw):
|
|
|
|
|
+ # Create variable
|
|
|
|
|
+ variable = StringVar()
|
|
|
|
|
+ if len(items) > 0:
|
|
|
|
|
+ variable.set(items[0])
|
|
|
|
|
+ # Update kw to reflect user inputs
|
|
|
|
|
+ kw['items'] = items
|
|
|
|
|
+ kw['label_text'] = text
|
|
|
|
|
+ kw['labelpos'] = labelpos
|
|
|
|
|
+ kw['label_anchor'] = label_anchor
|
|
|
|
|
+ kw['label_width'] = label_width
|
|
|
|
|
+ kw['menu_tearoff'] = menu_tearoff
|
|
|
|
|
+ kw['menubutton_textvariable'] = variable
|
|
|
|
|
+ # Create widget
|
|
|
|
|
+ widget = apply(Pmw.OptionMenu, (parent,), kw)
|
|
|
|
|
+ # Do this after so command isn't called on widget creation
|
|
|
|
|
+ widget['command'] = command
|
|
|
|
|
+ # Pack widget
|
|
|
|
|
+ widget.pack(side = side, fill = fill, expand = expand)
|
|
|
|
|
+ # Bind help
|
|
|
|
|
+ self.bind(widget.component('menubutton'), help)
|
|
|
|
|
+ # Record widget and variable
|
|
|
|
|
+ self.addWidget(category, text, widget)
|
|
|
|
|
+ self.addVariable(category, text, variable)
|
|
|
|
|
+ return widget
|
|
|
|
|
+
|
|
|
|
|
+ def newCreateComboBox(self, parent, category, text,
|
|
|
|
|
+ help = '', command = None,
|
|
|
|
|
+ items = [], state = DISABLED, history = 0,
|
|
|
|
|
+ labelpos = W, label_anchor = W,
|
|
|
|
|
+ label_width = 16, entry_width = 16,
|
|
|
|
|
+ side = LEFT, fill = X, expand = 0, **kw):
|
|
|
|
|
+ # Update kw to reflect user inputs
|
|
|
|
|
+ kw['label_text'] = text
|
|
|
|
|
+ kw['labelpos'] = labelpos
|
|
|
|
|
+ kw['label_anchor'] = label_anchor
|
|
|
|
|
+ kw['label_width'] = label_width
|
|
|
|
|
+ kw['entry_width'] = entry_width
|
|
|
|
|
+ kw['scrolledlist_items'] = items
|
|
|
|
|
+ kw['entryfield_entry_state'] = state
|
|
|
|
|
+ # Create widget
|
|
|
|
|
+ widget = apply(Pmw.ComboBox, (parent,), kw)
|
|
|
|
|
+ # Bind selection command
|
|
|
|
|
+ widget['selectioncommand'] = command
|
|
|
|
|
+ # Select first item if it exists
|
|
|
|
|
+ if len(items) > 0:
|
|
|
|
|
+ widget.selectitem(items[0])
|
|
|
|
|
+ # Pack widget
|
|
|
|
|
+ widget.pack(side = side, fill = fill, expand = expand)
|
|
|
|
|
+ # Bind help
|
|
|
|
|
+ self.bind(widget, help)
|
|
|
|
|
+ # Record widget
|
|
|
|
|
+ self.addWidget(category, text, widget)
|
|
|
|
|
+ return widget
|
|
|
|
|
|
|
|
class TestAppShell(AppShell):
|
|
class TestAppShell(AppShell):
|
|
|
# Override class variables here
|
|
# Override class variables here
|