1#!/usr/bin/env python 2 3# ------------------------------------------------------------------ 4# Display a splash screen as quickly as possible (before importing 5# modules and initialising Pmw). 6 7import Tkinter 8root = Tkinter.Tk(className = 'Demo') 9root.withdraw() 10 11splash = Tkinter.Toplevel() 12splash.withdraw() 13splash.title('Welcome to the Pmw demos') 14text = Tkinter.Label(splash, 15 font=('Helvetica', 16, 'bold'), 16 relief = 'raised', 17 borderwidth = 2, 18 padx=50, pady=50, 19 text = 20 'Welcome to the Pmw megawidgets demo.\n' 21 '\n' 22 'In a moment the main window will appear.\n' 23 'Please enjoy yourself while you wait.\n' 24 'You may be interested to know that splash screens\n' 25 '(as this window is called) were first devised to draw\n' 26 'attention away from the fact the certain applications\n' 27 'are slow to start. They are normally flashier and more\n' 28 'entertaining than this one. This is a budget model.' 29) 30text.pack(fill = 'both', expand = 1) 31splash.update_idletasks() 32 33width = splash.winfo_reqwidth() 34height = splash.winfo_reqheight() 35x = (root.winfo_screenwidth() - width) / 2 - root.winfo_vrootx() 36y = (root.winfo_screenheight() - height) / 3 - root.winfo_vrooty() 37if x < 0: 38 x = 0 39if y < 0: 40 y = 0 41geometry = '%dx%d+%d+%d' % (width, height, x, y) 42 43splash.geometry(geometry) 44splash.update_idletasks() 45splash.deiconify() 46root.update() 47 48# ------------------------------------------------------------------ 49 50# Now crank up the application windows. 51 52import imp 53import os 54import re 55import string 56import sys 57import types 58import Tkinter 59import DemoVersion 60import Args 61 62# Find where the other scripts are, so they can be listed. 63if __name__ == '__main__': 64 script_name = sys.argv[0] 65else: 66 script_name = imp.find_module('DemoVersion')[1] 67 68script_name = os.path.normpath(script_name) 69script_name = DemoVersion.expandLinks(script_name) 70script_dir = os.path.dirname(script_name) 71script_dir = DemoVersion.expandLinks(script_dir) 72 73# Add the '../../..' directory to the path. 74package_dir = os.path.dirname(script_dir) 75package_dir = DemoVersion.expandLinks(package_dir) 76package_dir = os.path.dirname(package_dir) 77package_dir = DemoVersion.expandLinks(package_dir) 78package_dir = os.path.dirname(package_dir) 79package_dir = DemoVersion.expandLinks(package_dir) 80sys.path[:0] = [package_dir] 81 82# Import Pmw after modifying sys.path (it may not be in the default path). 83import Pmw 84DemoVersion.setPmwVersion() 85 86class Demo(Pmw.MegaWidget): 87 88 def __init__(self, parent=None, **kw): 89 90 # Define the megawidget options. 91 optiondefs = () 92 self.defineoptions(kw, optiondefs) 93 94 # Initialise the base class (after defining the options). 95 Pmw.MegaWidget.__init__(self, parent) 96 97 # Create the contents. 98 top = self.interior() 99 100 panes = Pmw.PanedWidget(top, orient = 'horizontal') 101 panes.pack(fill = 'both', expand = 1) 102 103 panes.add('widgetlist') 104 self._widgetlist = Pmw.ScrolledListBox(panes.pane('widgetlist'), 105 selectioncommand = Pmw.busycallback(self.startDemo), 106 label_text = 'Select a widget:', 107 labelpos = 'nw', 108 vscrollmode = 'dynamic', 109 hscrollmode = 'none', 110 listbox_exportselection = 0) 111 self._widgetlist.pack(fill = 'both', expand = 1, padx = 8) 112 113 panes.add('info') 114 self._status = Tkinter.Label(panes.pane('info')) 115 self._status.pack(padx = 8, anchor = 'w') 116 117 self._example = Tkinter.Frame(panes.pane('info'), 118 borderwidth = 2, 119 relief = 'sunken', 120 background = 'white') 121 self._example.pack(fill = 'both', expand = 1, padx = 8) 122 123 self.buttonBox = Pmw.ButtonBox(top) 124 self.buttonBox.pack(fill = 'x') 125 126 # Add the buttons and make them all the same width. 127 self._traceText = 'Trace tk calls' 128 self._stopTraceText = 'Stop trace' 129 self.buttonBox.add('Trace', text = self._traceText, 130 command = self.trace) 131 self.buttonBox.add('Code', text = 'Show code', command = self.showCode) 132 self.buttonBox.add('Exit', text = 'Exit', command = root.destroy) 133 self.buttonBox.alignbuttons() 134 135 # Create the window to display the python code. 136 self.codeWindow = Pmw.TextDialog(parent, 137 title = 'Python source', 138 buttons = ('Dismiss',), 139 scrolledtext_labelpos = 'n', 140 label_text = 'Source') 141 self.codeWindow.withdraw() 142 self.codeWindow.insert('end', '') 143 144 self.demoName = None 145 self._loadDemos() 146 147 # Check keywords and initialise options. 148 self.initialiseoptions() 149 150 def startDemo(self): 151 # Import the selected module and create and instance of the module's 152 # Demo class. 153 154 sels = self._widgetlist.getcurselection() 155 if len(sels) == 0: 156 print 'No demonstrations to display' 157 return 158 demoName = sels[0] 159 160 # Ignore if this if it is a sub title. 161 if demoName[0] != ' ': 162 self._widgetlist.bell() 163 return 164 165 # Strip the leading two spaces. 166 demoName = demoName[2:] 167 168 # Ignore if this demo is already being shown. 169 if self.demoName == demoName: 170 return 171 172 self.demoName = demoName 173 174 self.showStatus('Loading ' + demoName) 175 # Busy cursor 176 self.update_idletasks() 177 178 for window in self._example.winfo_children(): 179 window.destroy() 180 181 frame = Tkinter.Frame(self._example) 182 frame.pack(expand = 1) 183 exec 'import ' + demoName 184 # Need to keep a reference to the widget, so that variables, etc 185 # are not deleted. 186 self.widget = eval(demoName + '.Demo(frame)') 187 title = eval(demoName + '.title') 188 self.showStatus(title) 189 190 if self.codeWindow.state() == 'normal': 191 self.insertCode() 192 193 def showStatus(self, text): 194 self._status.configure(text = text) 195 196 def showCode(self): 197 if self.codeWindow.state() != 'normal': 198 if self.demoName is None: 199 print 'No demonstration selected' 200 return 201 self.insertCode() 202 203 self.codeWindow.show() 204 205 def insertCode(self): 206 self.codeWindow.clear() 207 fileName = os.path.join(script_dir, self.demoName + '.py') 208 self.codeWindow.importfile(fileName) 209 self.codeWindow.configure(label_text = self.demoName + ' source') 210 211 def trace(self): 212 text = self.buttonBox.component('Trace').cget('text') 213 if text == self._traceText: 214 self.buttonBox.configure(Trace_text = self._stopTraceText) 215 Pmw.tracetk(root, 1) 216 self.showStatus('Trace will appear on standard output') 217 else: 218 self.buttonBox.configure(Trace_text = self._traceText) 219 Pmw.tracetk(root, 0) 220 self.showStatus('Tk call tracing stopped') 221 222 def _loadDemos(self): 223 files = os.listdir(script_dir) 224 files.sort() 225 megawidgets = [] 226 others = [] 227 for file in files: 228 if re.search('.py$', file) is not None and \ 229 file not in ['All.py', 'DemoVersion.py', 'Args.py']: 230 demoName = file[:-3] 231 index = string.find(demoName, '_') 232 if index < 0: 233 testattr = demoName 234 else: 235 testattr = demoName[:index] 236 if hasattr(Pmw, testattr): 237 megawidgets.append(demoName) 238 else: 239 others.append(demoName) 240 241 self._widgetlist.insert('end', 'Megawidget demos:') 242 for name in megawidgets: 243 self._widgetlist.insert('end', ' ' + name) 244 self._widgetlist.insert('end', 'Other demos:') 245 for name in others: 246 self._widgetlist.insert('end', ' ' + name) 247 self._widgetlist.select_set(1) 248 249class StdOut: 250 def __init__(self, displayCommand): 251 self.displayCommand = displayCommand 252 self.text = '\n' 253 254 def write(self, text): 255 if self.text[-1] == '\n': 256 self.text = text 257 else: 258 self.text = self.text + text 259 if self.text[-1] == '\n': 260 text = self.text[:-1] 261 else: 262 text = self.text 263 self.displayCommand(text) 264 265if os.name == 'nt': 266 defaultFontSize = 16 267else: 268 defaultFontSize = 12 269 270commandLineArgSpecs = ( 271 ('fontscheme', 0, 'scheme', 'fonts to use [eg pmw2] (Tk defaults)'), 272 ('fontsize', 0, 'num', 'size of fonts to use with fontscheme', defaultFontSize), 273 ('stdout', 0, Args.Bool, 'print messages rather than display in label'), 274) 275 276program = 'All.py' 277msg = Args.parseArgs(program, sys.argv, commandLineArgSpecs, 0) 278if msg is not None: 279 print msg 280 sys.exit() 281 282size = Args.get('fontsize') 283fontScheme = Args.get('fontscheme') 284Pmw.initialise(root, size = size, fontScheme = fontScheme, useTkOptionDb = 1) 285 286root.title('Pmw ' + Pmw.version() + ' megawidget demonstration') 287if size < 18: 288 geometry = '800x550' 289else: 290 geometry = '1000x700' 291root.geometry(geometry) 292 293demo = Demo(root) 294demo.pack(fill = 'both', expand = 1) 295demo.focus() 296 297# Redirect standard output from demos to status line (unless -stdout 298# option given on command line). 299if not Args.get('stdout'): 300 sys.stdout = StdOut(demo.showStatus) 301 302# Start the first demo. 303demo.startDemo() 304 305# Get rid of the splash screen 306root.deiconify() 307root.update() 308splash.destroy() 309 310root.mainloop() 311