1*4c8945a0SNathan Whitehorn# $Id: dialog.py,v 1.3 2004/09/21 00:52:15 tom Exp $ 2*4c8945a0SNathan Whitehorn# Module: dialog.py 3*4c8945a0SNathan Whitehorn# Copyright (c) 2000 Robb Shecter <robb@acm.org> 4*4c8945a0SNathan Whitehorn# All rights reserved. 5*4c8945a0SNathan Whitehorn# This source is covered by the GNU GPL. 6*4c8945a0SNathan Whitehorn# 7*4c8945a0SNathan Whitehorn# This module is a Python wrapper around the Linux "dialog" utility 8*4c8945a0SNathan Whitehorn# by Savio Lam and Stuart Herbert. My goals were to make dialog as 9*4c8945a0SNathan Whitehorn# easy to use from Python as possible. The demo code at the end of 10*4c8945a0SNathan Whitehorn# the module is a good example of how to use it. To run the demo, 11*4c8945a0SNathan Whitehorn# execute: 12*4c8945a0SNathan Whitehorn# 13*4c8945a0SNathan Whitehorn# python dialog.py 14*4c8945a0SNathan Whitehorn# 15*4c8945a0SNathan Whitehorn# This module has one class in it, "Dialog". An application typically 16*4c8945a0SNathan Whitehorn# creates an instance of it, and possibly sets the background title option. 17*4c8945a0SNathan Whitehorn# Then, methods can be called on it for interacting with the user. 18*4c8945a0SNathan Whitehorn# 19*4c8945a0SNathan Whitehorn# I wrote this because I want to use my 486-33 laptop as my main 20*4c8945a0SNathan Whitehorn# development computer (!), and I wanted a way to nicely interact with the 21*4c8945a0SNathan Whitehorn# user in console mode. There are apparently other modules out there 22*4c8945a0SNathan Whitehorn# with similar functionality, but they require the Python curses library. 23*4c8945a0SNathan Whitehorn# Writing this module from scratch was easier than figuring out how to 24*4c8945a0SNathan Whitehorn# recompile Python with curses enabled. :) 25*4c8945a0SNathan Whitehorn# 26*4c8945a0SNathan Whitehorn# One interesting feature is that the menu and selection windows allow 27*4c8945a0SNathan Whitehorn# *any* objects to be displayed and selected, not just strings. 28*4c8945a0SNathan Whitehorn# 29*4c8945a0SNathan Whitehorn# TO DO: 30*4c8945a0SNathan Whitehorn# Add code so that the input buffer is flushed before a dialog box is 31*4c8945a0SNathan Whitehorn# shown. This would make the UI more predictable for users. This 32*4c8945a0SNathan Whitehorn# feature could be turned on and off through an instance method. 33*4c8945a0SNathan Whitehorn# Drop using temporary files when interacting with 'dialog' 34*4c8945a0SNathan Whitehorn# (it's possible -- I've already tried :-). 35*4c8945a0SNathan Whitehorn# Try detecting the terminal window size in order to make reasonable 36*4c8945a0SNathan Whitehorn# height and width defaults. Hmmm - should also then check for 37*4c8945a0SNathan Whitehorn# terminal resizing... 38*4c8945a0SNathan Whitehorn# Put into a package name to make more reusable - reduce the possibility 39*4c8945a0SNathan Whitehorn# of name collisions. 40*4c8945a0SNathan Whitehorn# 41*4c8945a0SNathan Whitehorn# NOTES: 42*4c8945a0SNathan Whitehorn# there is a bug in (at least) Linux-Mandrake 7.0 Russian Edition 43*4c8945a0SNathan Whitehorn# running on AMD K6-2 3D that causes core dump when 'dialog' 44*4c8945a0SNathan Whitehorn# is running with --gauge option; 45*4c8945a0SNathan Whitehorn# in this case you'll have to recompile 'dialog' program. 46*4c8945a0SNathan Whitehorn# 47*4c8945a0SNathan Whitehorn# Modifications: 48*4c8945a0SNathan Whitehorn# Jul 2000, Sultanbek Tezadov (http://sultan.da.ru) 49*4c8945a0SNathan Whitehorn# Added: 50*4c8945a0SNathan Whitehorn# - 'gauge' widget *) 51*4c8945a0SNathan Whitehorn# - 'title' option to some widgets 52*4c8945a0SNathan Whitehorn# - 'checked' option to checklist dialog; clicking "Cancel" is now 53*4c8945a0SNathan Whitehorn# recognizable 54*4c8945a0SNathan Whitehorn# - 'selected' option to radiolist dialog; clicking "Cancel" is now 55*4c8945a0SNathan Whitehorn# recognizable 56*4c8945a0SNathan Whitehorn# - some other cosmetic changes and improvements 57*4c8945a0SNathan Whitehorn# 58*4c8945a0SNathan Whitehorn 59*4c8945a0SNathan Whitehornimport os 60*4c8945a0SNathan Whitehornfrom tempfile import mktemp 61*4c8945a0SNathan Whitehornfrom string import split 62*4c8945a0SNathan Whitehornfrom time import sleep 63*4c8945a0SNathan Whitehorn 64*4c8945a0SNathan Whitehorn# 65*4c8945a0SNathan Whitehorn# Path of the dialog executable 66*4c8945a0SNathan Whitehorn# 67*4c8945a0SNathan WhitehornDIALOG = os.getenv("DIALOG"); 68*4c8945a0SNathan Whitehornif DIALOG is None: 69*4c8945a0SNathan Whitehorn DIALOG="../dialog"; 70*4c8945a0SNathan Whitehorn 71*4c8945a0SNathan Whitehornclass Dialog: 72*4c8945a0SNathan Whitehorn def __init__(self): 73*4c8945a0SNathan Whitehorn self.__bgTitle = '' # Default is no background title 74*4c8945a0SNathan Whitehorn 75*4c8945a0SNathan Whitehorn 76*4c8945a0SNathan Whitehorn def setBackgroundTitle(self, text): 77*4c8945a0SNathan Whitehorn self.__bgTitle = '--backtitle "%s"' % text 78*4c8945a0SNathan Whitehorn 79*4c8945a0SNathan Whitehorn 80*4c8945a0SNathan Whitehorn def __perform(self, cmd): 81*4c8945a0SNathan Whitehorn """Do the actual work of invoking dialog and getting the output.""" 82*4c8945a0SNathan Whitehorn fName = mktemp() 83*4c8945a0SNathan Whitehorn rv = os.system('%s %s %s 2> %s' % (DIALOG, self.__bgTitle, cmd, fName)) 84*4c8945a0SNathan Whitehorn f = open(fName) 85*4c8945a0SNathan Whitehorn output = f.readlines() 86*4c8945a0SNathan Whitehorn f.close() 87*4c8945a0SNathan Whitehorn os.unlink(fName) 88*4c8945a0SNathan Whitehorn return (rv, output) 89*4c8945a0SNathan Whitehorn 90*4c8945a0SNathan Whitehorn 91*4c8945a0SNathan Whitehorn def __perform_no_options(self, cmd): 92*4c8945a0SNathan Whitehorn """Call dialog w/out passing any more options. Needed by --clear.""" 93*4c8945a0SNathan Whitehorn return os.system(DIALOG + ' ' + cmd) 94*4c8945a0SNathan Whitehorn 95*4c8945a0SNathan Whitehorn 96*4c8945a0SNathan Whitehorn def __handleTitle(self, title): 97*4c8945a0SNathan Whitehorn if len(title) == 0: 98*4c8945a0SNathan Whitehorn return '' 99*4c8945a0SNathan Whitehorn else: 100*4c8945a0SNathan Whitehorn return '--title "%s" ' % title 101*4c8945a0SNathan Whitehorn 102*4c8945a0SNathan Whitehorn 103*4c8945a0SNathan Whitehorn def yesno(self, text, height=10, width=30, title=''): 104*4c8945a0SNathan Whitehorn """ 105*4c8945a0SNathan Whitehorn Put a Yes/No question to the user. 106*4c8945a0SNathan Whitehorn Uses the dialog --yesno option. 107*4c8945a0SNathan Whitehorn Returns a 1 or a 0. 108*4c8945a0SNathan Whitehorn """ 109*4c8945a0SNathan Whitehorn (code, output) = self.__perform(self.__handleTitle(title) +\ 110*4c8945a0SNathan Whitehorn '--yesno "%s" %d %d' % (text, height, width)) 111*4c8945a0SNathan Whitehorn return code == 0 112*4c8945a0SNathan Whitehorn 113*4c8945a0SNathan Whitehorn 114*4c8945a0SNathan Whitehorn def msgbox(self, text, height=10, width=30, title=''): 115*4c8945a0SNathan Whitehorn """ 116*4c8945a0SNathan Whitehorn Pop up a message to the user which has to be clicked 117*4c8945a0SNathan Whitehorn away with "ok". 118*4c8945a0SNathan Whitehorn """ 119*4c8945a0SNathan Whitehorn self.__perform(self.__handleTitle(title) +\ 120*4c8945a0SNathan Whitehorn '--msgbox "%s" %d %d' % (text, height, width)) 121*4c8945a0SNathan Whitehorn 122*4c8945a0SNathan Whitehorn 123*4c8945a0SNathan Whitehorn def infobox(self, text, height=10, width=30): 124*4c8945a0SNathan Whitehorn """Make a message to the user, and return immediately.""" 125*4c8945a0SNathan Whitehorn self.__perform('--infobox "%s" %d %d' % (text, height, width)) 126*4c8945a0SNathan Whitehorn 127*4c8945a0SNathan Whitehorn 128*4c8945a0SNathan Whitehorn def inputbox(self, text, height=10, width=30, init='', title=''): 129*4c8945a0SNathan Whitehorn """ 130*4c8945a0SNathan Whitehorn Request a line of input from the user. 131*4c8945a0SNathan Whitehorn Returns the user's input or None if cancel was chosen. 132*4c8945a0SNathan Whitehorn """ 133*4c8945a0SNathan Whitehorn (c, o) = self.__perform(self.__handleTitle(title) +\ 134*4c8945a0SNathan Whitehorn '--inputbox "%s" %d %d "%s"' % (text, height, width, init)) 135*4c8945a0SNathan Whitehorn try: 136*4c8945a0SNathan Whitehorn return o[0] 137*4c8945a0SNathan Whitehorn except IndexError: 138*4c8945a0SNathan Whitehorn if c == 0: # empty string entered 139*4c8945a0SNathan Whitehorn return '' 140*4c8945a0SNathan Whitehorn else: # canceled 141*4c8945a0SNathan Whitehorn return None 142*4c8945a0SNathan Whitehorn 143*4c8945a0SNathan Whitehorn 144*4c8945a0SNathan Whitehorn def textbox(self, filename, height=20, width=60, title=None): 145*4c8945a0SNathan Whitehorn """Display a file in a scrolling text box.""" 146*4c8945a0SNathan Whitehorn if title is None: 147*4c8945a0SNathan Whitehorn title = filename 148*4c8945a0SNathan Whitehorn self.__perform(self.__handleTitle(title) +\ 149*4c8945a0SNathan Whitehorn ' --textbox "%s" %d %d' % (filename, height, width)) 150*4c8945a0SNathan Whitehorn 151*4c8945a0SNathan Whitehorn 152*4c8945a0SNathan Whitehorn def menu(self, text, height=15, width=54, list=[]): 153*4c8945a0SNathan Whitehorn """ 154*4c8945a0SNathan Whitehorn Display a menu of options to the user. This method simplifies the 155*4c8945a0SNathan Whitehorn --menu option of dialog, which allows for complex arguments. This 156*4c8945a0SNathan Whitehorn method receives a simple list of objects, and each one is assigned 157*4c8945a0SNathan Whitehorn a choice number. 158*4c8945a0SNathan Whitehorn The selected object is returned, or None if the dialog was canceled. 159*4c8945a0SNathan Whitehorn """ 160*4c8945a0SNathan Whitehorn menuheight = height - 8 161*4c8945a0SNathan Whitehorn pairs = map(lambda i, item: (i + 1, item), range(len(list)), list) 162*4c8945a0SNathan Whitehorn choices = reduce(lambda res, pair: res + '%d "%s" ' % pair, pairs, '') 163*4c8945a0SNathan Whitehorn (code, output) = self.__perform('--menu "%s" %d %d %d %s' %\ 164*4c8945a0SNathan Whitehorn (text, height, width, menuheight, choices)) 165*4c8945a0SNathan Whitehorn try: 166*4c8945a0SNathan Whitehorn return list[int(output[0]) - 1] 167*4c8945a0SNathan Whitehorn except IndexError: 168*4c8945a0SNathan Whitehorn return None 169*4c8945a0SNathan Whitehorn 170*4c8945a0SNathan Whitehorn 171*4c8945a0SNathan Whitehorn def checklist(self, text, height=15, width=54, list=[], checked=None): 172*4c8945a0SNathan Whitehorn """ 173*4c8945a0SNathan Whitehorn Returns a list of the selected objects. 174*4c8945a0SNathan Whitehorn Returns an empty list if nothing was selected. 175*4c8945a0SNathan Whitehorn Returns None if the window was canceled. 176*4c8945a0SNathan Whitehorn checked -- a list of boolean (0/1) values; len(checked) must equal 177*4c8945a0SNathan Whitehorn len(list). 178*4c8945a0SNathan Whitehorn """ 179*4c8945a0SNathan Whitehorn if checked is None: 180*4c8945a0SNathan Whitehorn checked = [0]*len(list) 181*4c8945a0SNathan Whitehorn menuheight = height - 8 182*4c8945a0SNathan Whitehorn triples = map( 183*4c8945a0SNathan Whitehorn lambda i, item, onoff, fs=('off', 'on'): (i + 1, item, fs[onoff]), 184*4c8945a0SNathan Whitehorn range(len(list)), list, checked) 185*4c8945a0SNathan Whitehorn choices = reduce(lambda res, triple: res + '%d "%s" %s ' % triple, 186*4c8945a0SNathan Whitehorn triples, '') 187*4c8945a0SNathan Whitehorn (c, o) = self.__perform('--checklist "%s" %d %d %d %s' %\ 188*4c8945a0SNathan Whitehorn (text, height, width, menuheight, choices)) 189*4c8945a0SNathan Whitehorn try: 190*4c8945a0SNathan Whitehorn output = o[0] 191*4c8945a0SNathan Whitehorn indexList = map(lambda x: int(x[1:-1]), split(output)) 192*4c8945a0SNathan Whitehorn objectList = filter(lambda item, list=list, indexList=indexList: 193*4c8945a0SNathan Whitehorn list.index(item) + 1 in indexList, 194*4c8945a0SNathan Whitehorn list) 195*4c8945a0SNathan Whitehorn return objectList 196*4c8945a0SNathan Whitehorn except IndexError: 197*4c8945a0SNathan Whitehorn if c == 0: # Nothing was selected 198*4c8945a0SNathan Whitehorn return [] 199*4c8945a0SNathan Whitehorn return None # Was canceled 200*4c8945a0SNathan Whitehorn 201*4c8945a0SNathan Whitehorn 202*4c8945a0SNathan Whitehorn def radiolist(self, text, height=15, width=54, list=[], selected=0): 203*4c8945a0SNathan Whitehorn """ 204*4c8945a0SNathan Whitehorn Return the selected object. 205*4c8945a0SNathan Whitehorn Returns empty string if no choice was selected. 206*4c8945a0SNathan Whitehorn Returns None if window was canceled. 207*4c8945a0SNathan Whitehorn selected -- the selected item (must be between 1 and len(list) 208*4c8945a0SNathan Whitehorn or 0, meaning no selection). 209*4c8945a0SNathan Whitehorn """ 210*4c8945a0SNathan Whitehorn menuheight = height - 8 211*4c8945a0SNathan Whitehorn triples = map(lambda i, item: (i + 1, item, 'off'), 212*4c8945a0SNathan Whitehorn range(len(list)), list) 213*4c8945a0SNathan Whitehorn if selected: 214*4c8945a0SNathan Whitehorn i, item, tmp = triples[selected - 1] 215*4c8945a0SNathan Whitehorn triples[selected - 1] = (i, item, 'on') 216*4c8945a0SNathan Whitehorn choices = reduce(lambda res, triple: res + '%d "%s" %s ' % triple, 217*4c8945a0SNathan Whitehorn triples, '') 218*4c8945a0SNathan Whitehorn (c, o) = self.__perform('--radiolist "%s" %d %d %d %s' %\ 219*4c8945a0SNathan Whitehorn (text, height, width, menuheight, choices)) 220*4c8945a0SNathan Whitehorn try: 221*4c8945a0SNathan Whitehorn return list[int(o[0]) - 1] 222*4c8945a0SNathan Whitehorn except IndexError: 223*4c8945a0SNathan Whitehorn if c == 0: 224*4c8945a0SNathan Whitehorn return '' 225*4c8945a0SNathan Whitehorn return None 226*4c8945a0SNathan Whitehorn 227*4c8945a0SNathan Whitehorn 228*4c8945a0SNathan Whitehorn def clear(self): 229*4c8945a0SNathan Whitehorn """ 230*4c8945a0SNathan Whitehorn Clear the screen. Equivalent to the dialog --clear option. 231*4c8945a0SNathan Whitehorn """ 232*4c8945a0SNathan Whitehorn self.__perform_no_options('--clear') 233*4c8945a0SNathan Whitehorn 234*4c8945a0SNathan Whitehorn 235*4c8945a0SNathan Whitehorn def scrollbox(self, text, height=20, width=60, title=''): 236*4c8945a0SNathan Whitehorn """ 237*4c8945a0SNathan Whitehorn This is a bonus method. The dialog package only has a function to 238*4c8945a0SNathan Whitehorn display a file in a scrolling text field. This method allows any 239*4c8945a0SNathan Whitehorn string to be displayed by first saving it in a temp file, and calling 240*4c8945a0SNathan Whitehorn --textbox. 241*4c8945a0SNathan Whitehorn """ 242*4c8945a0SNathan Whitehorn fName = mktemp() 243*4c8945a0SNathan Whitehorn f = open(fName, 'w') 244*4c8945a0SNathan Whitehorn f.write(text) 245*4c8945a0SNathan Whitehorn f.close() 246*4c8945a0SNathan Whitehorn self.__perform(self.__handleTitle(title) +\ 247*4c8945a0SNathan Whitehorn '--textbox "%s" %d %d' % (fName, height, width)) 248*4c8945a0SNathan Whitehorn os.unlink(fName) 249*4c8945a0SNathan Whitehorn 250*4c8945a0SNathan Whitehorn 251*4c8945a0SNathan Whitehorn def gauge_start(self, perc=0, text='', height=8, width=54, title=''): 252*4c8945a0SNathan Whitehorn """ 253*4c8945a0SNathan Whitehorn Display gauge output window. 254*4c8945a0SNathan Whitehorn Gauge normal usage (assuming that there is an instace of 'Dialog' 255*4c8945a0SNathan Whitehorn class named 'd'): 256*4c8945a0SNathan Whitehorn d.gauge_start() 257*4c8945a0SNathan Whitehorn # do something 258*4c8945a0SNathan Whitehorn d.gauge_iterate(10) # passed throgh 10% 259*4c8945a0SNathan Whitehorn # ... 260*4c8945a0SNathan Whitehorn d.gauge_iterate(100, 'any text here') # work is done 261*4c8945a0SNathan Whitehorn d.stop_gauge() # clean-up actions 262*4c8945a0SNathan Whitehorn """ 263*4c8945a0SNathan Whitehorn cmd = self.__handleTitle(title) +\ 264*4c8945a0SNathan Whitehorn '--gauge "%s" %d %d %d' % (text, height, width, perc) 265*4c8945a0SNathan Whitehorn cmd = '%s %s %s 2> /dev/null' % (DIALOG, self.__bgTitle, cmd) 266*4c8945a0SNathan Whitehorn self.pipe = os.popen(cmd, 'w') 267*4c8945a0SNathan Whitehorn #/gauge_start() 268*4c8945a0SNathan Whitehorn 269*4c8945a0SNathan Whitehorn 270*4c8945a0SNathan Whitehorn def gauge_iterate(self, perc, text=''): 271*4c8945a0SNathan Whitehorn """ 272*4c8945a0SNathan Whitehorn Update percentage point value. 273*4c8945a0SNathan Whitehorn 274*4c8945a0SNathan Whitehorn See gauge_start() function above for the usage. 275*4c8945a0SNathan Whitehorn """ 276*4c8945a0SNathan Whitehorn if text: 277*4c8945a0SNathan Whitehorn text = 'XXX\n%d\n%s\nXXX\n' % (perc, text) 278*4c8945a0SNathan Whitehorn else: 279*4c8945a0SNathan Whitehorn text = '%d\n' % perc 280*4c8945a0SNathan Whitehorn self.pipe.write(text) 281*4c8945a0SNathan Whitehorn self.pipe.flush() 282*4c8945a0SNathan Whitehorn #/gauge_iterate() 283*4c8945a0SNathan Whitehorn 284*4c8945a0SNathan Whitehorn 285*4c8945a0SNathan Whitehorn def gauge_stop(self): 286*4c8945a0SNathan Whitehorn """ 287*4c8945a0SNathan Whitehorn Finish previously started gauge. 288*4c8945a0SNathan Whitehorn 289*4c8945a0SNathan Whitehorn See gauge_start() function above for the usage. 290*4c8945a0SNathan Whitehorn """ 291*4c8945a0SNathan Whitehorn self.pipe.close() 292*4c8945a0SNathan Whitehorn #/gauge_stop() 293*4c8945a0SNathan Whitehorn 294*4c8945a0SNathan Whitehorn 295*4c8945a0SNathan Whitehorn 296*4c8945a0SNathan Whitehorn# 297*4c8945a0SNathan Whitehorn# DEMO APPLICATION 298*4c8945a0SNathan Whitehorn# 299*4c8945a0SNathan Whitehornif __name__ == '__main__': 300*4c8945a0SNathan Whitehorn """ 301*4c8945a0SNathan Whitehorn This demo tests all the features of the class. 302*4c8945a0SNathan Whitehorn """ 303*4c8945a0SNathan Whitehorn d = Dialog() 304*4c8945a0SNathan Whitehorn d.setBackgroundTitle('dialog.py demo') 305*4c8945a0SNathan Whitehorn 306*4c8945a0SNathan Whitehorn d.infobox( 307*4c8945a0SNathan Whitehorn "One moment... Just wasting some time here to test the infobox...") 308*4c8945a0SNathan Whitehorn sleep(3) 309*4c8945a0SNathan Whitehorn 310*4c8945a0SNathan Whitehorn if d.yesno("Do you like this demo?"): 311*4c8945a0SNathan Whitehorn d.msgbox("Excellent! Here's the source code:") 312*4c8945a0SNathan Whitehorn else: 313*4c8945a0SNathan Whitehorn d.msgbox("Send your complaints to /dev/null") 314*4c8945a0SNathan Whitehorn 315*4c8945a0SNathan Whitehorn d.textbox("dialog.py") 316*4c8945a0SNathan Whitehorn 317*4c8945a0SNathan Whitehorn name = d.inputbox("What's your name?", init="Snow White") 318*4c8945a0SNathan Whitehorn fday = d.menu("What's your favorite day of the week?", 319*4c8945a0SNathan Whitehorn list=["Monday", "Tuesday", "Wednesday", "Thursday", 320*4c8945a0SNathan Whitehorn "Friday (The best day of all)", "Saturday", "Sunday"]) 321*4c8945a0SNathan Whitehorn food = d.checklist("What sandwich toppings do you like?", 322*4c8945a0SNathan Whitehorn list=["Catsup", "Mustard", "Pesto", "Mayonaise", "Horse radish", 323*4c8945a0SNathan Whitehorn "Sun-dried tomatoes"], checked=[0,0,0,1,1,1]) 324*4c8945a0SNathan Whitehorn sand = d.radiolist("What's your favorite kind of sandwich?", 325*4c8945a0SNathan Whitehorn list=["Hamburger", "Hotdog", "Burrito", "Doener", "Falafel", 326*4c8945a0SNathan Whitehorn "Bagel", "Big Mac", "Whopper", "Quarter Pounder", 327*4c8945a0SNathan Whitehorn "Peanut Butter and Jelly", "Grilled cheese"], selected=4) 328*4c8945a0SNathan Whitehorn 329*4c8945a0SNathan Whitehorn # Prepare the message for the final window 330*4c8945a0SNathan Whitehorn bigMessage = "Here are some vital statistics about you:\n\nName: " + name +\ 331*4c8945a0SNathan Whitehorn "\nFavorite day of the week: " + fday +\ 332*4c8945a0SNathan Whitehorn "\nFavorite sandwich toppings:\n" 333*4c8945a0SNathan Whitehorn for topping in food: 334*4c8945a0SNathan Whitehorn bigMessage = bigMessage + " " + topping + "\n" 335*4c8945a0SNathan Whitehorn bigMessage = bigMessage + "Favorite sandwich: " + str(sand) 336*4c8945a0SNathan Whitehorn 337*4c8945a0SNathan Whitehorn d.scrollbox(bigMessage) 338*4c8945a0SNathan Whitehorn 339*4c8945a0SNathan Whitehorn #<># Gauge Demo 340*4c8945a0SNathan Whitehorn d.gauge_start(0, 'percentage: 0', title='Gauge Demo') 341*4c8945a0SNathan Whitehorn for i in range(1, 101): 342*4c8945a0SNathan Whitehorn if i < 50: 343*4c8945a0SNathan Whitehorn msg = 'percentage: %d' % i 344*4c8945a0SNathan Whitehorn elif i == 50: 345*4c8945a0SNathan Whitehorn msg = 'Over 50%' 346*4c8945a0SNathan Whitehorn else: 347*4c8945a0SNathan Whitehorn msg = '' 348*4c8945a0SNathan Whitehorn d.gauge_iterate(i, msg) 349*4c8945a0SNathan Whitehorn sleep(0.1) 350*4c8945a0SNathan Whitehorn d.gauge_stop() 351*4c8945a0SNathan Whitehorn #<># 352*4c8945a0SNathan Whitehorn 353*4c8945a0SNathan Whitehorn d.clear() 354