component_src_gen.py


directory : D:\2018_py_proj\TkGridGUI\tkgridgui
Line Count : 555
Line Clip Size : No Clipping

tab_of_notebook_changed  Word MatchCase (0) 
1 #!/usr/bin/env python 2 # -*- coding: ascii -*- 3 from __future__ import print_function 4 from __future__ import unicode_literals 5 6 from builtins import object 7 from tkgridgui.src_templates import createWidget, gridWidget, makeStringVar, \ 8 makeOptionString, traceStringVar, bindWidget 9 10 create_callD = {} # index=widget_type: value=Tk call 11 create_callD['Button'] = 'Button' 12 create_callD['Canvas'] = 'Canvas' 13 create_callD['Checkbutton'] = 'Checkbutton' 14 create_callD['Combobox'] = 'Combobox' 15 create_callD['Entry'] = 'Entry' 16 create_callD['Frame'] = 'Frame' 17 create_callD['Label'] = 'Label' 18 create_callD['LabelFrame'] = 'LabelFrame' 19 create_callD['Listbox'] = 'Listbox' 20 create_callD['Message'] = 'Message' 21 create_callD['Menubutton'] = 'Menubutton' 22 create_callD['Notebook'] = 'Notebook ' 23 create_callD['OptionMenu'] = 'OptionMenu' 24 create_callD['Progressbar'] = 'Progressbar' 25 create_callD['Radiobutton'] = 'Radiobutton' 26 create_callD['RadioGroup'] = 'LabelFrame' # <== note that RadioGroup is a LabelFrame 27 create_callD['Scale'] = 'Scale' 28 create_callD['Separator'] = 'Separator' 29 create_callD['Spinbox'] = 'Spinbox' 30 create_callD['Text'] = 'Text' 31 create_callD['Treeview'] = 'Treeview' 32 33 create_callD['Tab'] = 'Frame' 34 35 36 # widget with bind events don't also have traceStringVar 37 widget_bindD = {} # index=widget_type: value=bind option (e.g. "<ButtonRelease-1>" ) 38 widget_bindD['Button'] = "ButtonRelease-1" # left click release 39 widget_bindD['Canvas'] = "ButtonRelease-1" # left click release 40 widget_bindD['Listbox'] = "ButtonRelease-1" # left click release 41 widget_bindD['Treeview'] = "ButtonRelease-1" # left click release 42 43 stringvar_set = set(['Entry', 'OptionMenu', 'Combobox', 'Checkbutton', 44 'Menubutton', 'Radiobutton', 'Scale', 'Spinbox']) 45 46 sv_monikerD = {} # option name of StringVar. either 'textvariable' or 'variable' 47 sv_monikerD['Entry'] = 'textvariable' 48 sv_monikerD['OptionMenu'] = 'textvariable' 49 sv_monikerD['Combobox'] = 'textvariable' 50 sv_monikerD['Checkbutton'] = 'variable' 51 sv_monikerD['Menubutton'] = 'textvariable' 52 sv_monikerD['Radiobutton'] = 'variable' 53 sv_monikerD['Scale'] = 'variable' 54 sv_monikerD['Spinbox'] = 'textvariable' 55 56 sv_config_D = {} # index=widget_type: value=dict of config statements. e.g. ('onvalue="yes"', 'offvalue="no"') 57 sv_config_D['Entry'] = {} 58 sv_config_D['OptionMenu'] = {} 59 sv_config_D['Combobox'] = {} 60 sv_config_D['Checkbutton'] = {'onvalue':"yes", 'offvalue':"no"} 61 sv_config_D['Menubutton'] = {'text':"Select"} 62 sv_config_D['Radiobutton'] = {} 63 sv_config_D['Scale'] = {} 64 sv_config_D['Spinbox'] = {'from_':"1", 'to':'10'} 65 66 class CompSrcGen( object ): 67 68 def __init__(self, widget_name, widget_type, guiType, parent_name, 69 row, col, opDict=None, target_app=None): 70 """Source Generation for individual Widgets""" 71 72 self.widget_name = widget_name 73 self.widget_type = widget_type 74 self.guiType = guiType 75 self.parent_name = parent_name 76 self.target_app = target_app # holds application data 77 78 if guiType=='dialog': 79 if parent_name=="Main": 80 self.master = 'self.dialogframe' 81 else: 82 self.master = 'self.'+parent_name 83 else: 84 if parent_name=="Main": 85 self.master = 'self.grid_frame' 86 else: 87 self.master = 'self.'+parent_name 88 89 90 self.row = row 91 self.col = col 92 93 if opDict is None: 94 opDict = {} 95 self.opDict = opDict 96 97 if widget_type in stringvar_set: 98 self.svar_name = widget_name + '_StringVar' 99 else: 100 self.svar_name = '' 101 102 def set_stringvar_name( self, svar_name ): 103 """Radiobutton widgets need a common svar_name.""" 104 self.svar_name = svar_name 105 106 def get_call_make_stmt(self): 107 """Use this like: self.make_Button_1() in Tk app __init__ """ 108 s = ' self.make_%s( %s )'%(self.widget_name, self.master) 109 if len(s) < 55: 110 s = s + " "*(55-len(s)) 111 112 docstring = self.target_app.compObjD[self.widget_name].get_docstring() 113 114 s = s + '#%s\n'%docstring 115 return s 116 117 def get_top_of_make_def(self): 118 s = ' def make_%s(self, frame):\n'%self.widget_name 119 ansL = [s] 120 121 docstring = self.target_app.compObjD[self.widget_name].get_docstring() 122 ansL.append(' """%s"""\n'%docstring) 123 124 # need special logic for OptionMenu 125 if self.widget_type == "OptionMenu": 126 ansL.append( makeStringVar( self.widget_name ) ) 127 ansL.append( ' choicesT = ("Pie", "Cake", "Kale")\n' ) 128 s = self.get_create_widget() 129 s = s.replace(')',', self.%s, *choicesT)'%(self.svar_name,) ) 130 ansL.append( s ) 131 132 opstr = makeOptionString( {'width':self.opDict.get('width','20'), 133 'height':self.opDict.get('height','2')}, startComma=0 ) 134 s = ' self.%s.configure( %s )\n'%( self.widget_name, opstr) 135 ansL.append( s ) 136 137 ansL.append( self.get_grid_stmt() ) 138 139 elif self.widget_type == "Radiobutton": 140 ansL.append( self.get_create_widget() ) 141 ansL.append( self.get_grid_stmt() ) 142 # assume that common svar_name is placed elsewhere 143 144 elif self.widget_type == "Tab": 145 ansL.append( self.get_create_widget() ) 146 ansL.append( ' self.{parent_name}.add( self.{widget_name}, text="{tab_label}" )'.\ 147 format(parent_name=self.parent_name, widget_name=self.widget_name, tab_label=self.opDict['text'] )) 148 149 else: 150 ansL.append( self.get_create_widget() ) 151 152 if self.opDict.get('scrolly',''): 153 ansL[-1] = ansL[-1].replace(', scrolly="yes"', '') 154 155 ansL.append( self.get_grid_stmt() ) 156 157 if self.svar_name: 158 ansL.append( makeStringVar( self.widget_name ) ) 159 160 ansL.append('\n') 161 return ansL 162 163 def get_callback_name(self): 164 """for bind options, need a callback method""" 165 return '%s_Callback'%self.svar_name 166 167 def get_user_part_of_make_def(self): 168 ansL = ['\n'] 169 170 if self.widget_type == "OptionMenu": 171 172 ansL.append( " self.%s.set('')\n"%self.svar_name ) 173 ansL.append( " self.%s['menu'].delete(0, 'end')\n"%self.widget_name ) 174 ansL.append( " \n" ) 175 ansL.append( " new_choiceT = ('Pop1','Pop2','Weasel')\n" ) 176 ansL.append( " for choice in new_choiceT:\n" ) 177 ansL.append( " self.%s['menu'].add_command(label=choice, "%self.widget_name +\ 178 "command=set_command(self.%s, choice))\n"%self.svar_name ) 179 180 ansL.append( " self.%s.set('%%s'%%new_choiceT[0])\n"%(self.svar_name, ) ) 181 182 ansL.append("\n") 183 ansL.append(" # add trace last so above changes do not trigger trace\n") 184 ansL.append( traceStringVar( self.widget_name ) ) 185 186 elif self.widget_type == "Radiobutton": 187 # connect widget to StringVar and configure any StringVar options (e.g. onvalue, from_, etc.) 188 wn, wt = self.widget_name, self.widget_type 189 opDict = sv_config_D[wt] 190 opstr = makeOptionString( opDict ) 191 s = ' self.%s.configure(%s=self.%s%s)\n'%(wn, sv_monikerD[wt], self.svar_name, opstr) 192 ansL.append( s ) 193 194 # trace is done with common StringVar 195 196 elif self.svar_name: 197 wn, wt = self.widget_name, self.widget_type 198 199 # connect widget to StringVar and configure any StringVar options (e.g. onvalue, from_, etc.) 200 opDict = sv_config_D[wt] 201 opstr = makeOptionString( opDict ) 202 s = ' self.%s.configure(%s=self.%s%s)\n'%(wn, sv_monikerD[wt], self.svar_name, opstr) 203 ansL.append( s ) 204 205 # may want to set StringVar before traceStringVar is enabled. 206 s = self.get_string_var_set_stmt() 207 if s: 208 ansL.append( s ) 209 210 # set StringVar for Combobox 211 if wt=="Combobox": 212 val = self.target_app.compObjD[wn].user_tkOptionD.get('selection','') 213 if not val: 214 val = self.target_app.compObjD[wn].user_tkOptionD['values'].split()[0] 215 216 ansL.append( ' self.%s.set( "%s" )\n'%(self.svar_name, val) ) 217 218 # set trace option on StringVar to call xxx_Callback whenever StringVar changes 219 ansL.append( traceStringVar( self.widget_name ) ) 220 221 if self.widget_type == "Listbox": 222 wn, wt = self.widget_name, self.widget_type 223 ansL.extend(['\n',' # Edit the Listbox Entries\n', 224 ''' self.%s.insert(END, "apples")\n'''%wn, 225 ''' self.%s.insert(END, "oranges")\n'''%wn, 226 ''' self.%s.insert(END, "grapes")\n'''%wn, '\n'] ) 227 228 elif self.widget_type == "Canvas": 229 ansL.append( " self.%s.config(bg='#ffffcc')\n"%self.widget_name ) 230 231 elif self.widget_type == "Treeview": 232 wn, wt = self.widget_name, self.widget_type 233 234 ansL.extend(['\n', 235 """ self.%s.insert('', 'end', 'widgets', text='Widget Tour')\n"""%wn, 236 """ # Same thing, but inserted as first child:\n""", 237 """ self.%s.insert('', 0, 'gallery', text='%s')\n"""%(wn,wn), 238 """ # Inserted underneath an existing node:\n"""]) 239 240 for item_name in sorted( create_callD.keys() ): 241 ansL.append( """ self.%s.insert('widgets', 'end', text='%s')\n"""%(wn, item_name) ) 242 243 ansL.extend(['\n', 244 """ # Treeview chooses the id:\n""", 245 """ id = self.%s.insert('', 'end', text='Tutorial')\n"""%wn, 246 """ self.%s.insert(id, 'end', text='Tree')\n"""%wn, 247 '\n']) 248 249 # maybe attach a bind statement 250 s = self.get_bind_stmt() 251 if s: 252 ansL.append( s ) 253 254 if len(ansL)>1: 255 ansL.append('\n') 256 return ansL 257 258 def get_create_widget(self): 259 """initial widget creation statement e.g. b=Button(frame)""" 260 261 s = createWidget(self.widget_name, create_callD[self.widget_type], 262 self.guiType, self.parent_name, self.opDict) 263 return s.replace( self.master, 'frame' ) 264 265 def get_click_name(self): 266 """for bind options, need a callback method""" 267 return '%s_Click'%self.widget_name 268 269 def get_bind_stmt(self): 270 if self.widget_type in widget_bindD: 271 wn, wt = self.widget_name, self.widget_type 272 return bindWidget( wn, widget_bindD[wt] , self.get_click_name() ) 273 else: 274 return '' 275 276 277 def get_grid_stmt(self): 278 """create grid statement e.g. self.Canvas.grid(row=1, column=1)""" 279 280 sticky = self.opDict.get('sticky','') 281 rowspan = self.opDict.get('rowspan','') 282 columnspan = self.opDict.get('columnspan','') 283 284 # gridWidget(wName, row, col, is_gridWidgetFrame, sticky='', rowspan='', columnspan='') 285 if (self.opDict.get('scrolly','')=='yes') or (self.opDict.get('scrollx','')=='yes'): 286 return gridWidget(self.widget_name+'_frame', self.row, self.col, False, 287 sticky, rowspan, columnspan) 288 else: 289 return gridWidget(self.widget_name, self.row, self.col, False, 290 sticky, rowspan, columnspan) 291 292 def get_string_var_set_stmt(self): 293 294 if self.svar_name: 295 wn, wt = self.widget_name, self.widget_type 296 opDict = sv_config_D[wt] 297 if opDict: 298 keyL = sorted( opDict.keys() ) 299 val = opDict[keyL[0]] # take 1st option in alphabetically sorted keys 300 return ' self.%s.set("%s")\n'%(self.svar_name, val) 301 else: 302 return '' 303 else: 304 return '' 305 306 def get_string_var_stmts(self): 307 """""" 308 ansL = [] 309 310 if self.svar_name: 311 wn, wt = self.widget_name, self.widget_type 312 313 # create a StringVar 314 ansL.append( makeStringVar( wn ) ) 315 316 # connect widget to StringVar and configure any StringVar options (e.g. onvalue, from_, etc.) 317 opDict = sv_config_D[wt] 318 opstr = makeOptionString( opDict ) 319 s = ' self.%s.configure(%s=self.%s%s)\n'%(wn, sv_monikerD[wt], self.svar_name, opstr) 320 ansL.append( s ) 321 322 # may want to set StringVar before traceStringVar is enabled. 323 s = self.get_string_var_set_stmt() 324 if s: 325 ansL.append( s ) 326 327 # set trace option on StringVar to call xxx_Callback whenever StringVar changes 328 ansL.append( traceStringVar( self.widget_name ) ) 329 return ansL 330 331 332 def get_top_of_bind_def(self): 333 """get the top code for the bind method def statement """ 334 335 if self.widget_type in widget_bindD: 336 ansL = [] 337 wn, wt = self.widget_name, self.widget_type 338 methodName = self.get_click_name() 339 340 ansL.append(' def %s(self, event): #bind method for component ID=%s\n'%(methodName, wn)) 341 342 docstring = self.target_app.compObjD[self.widget_name].get_docstring() 343 ansL.append(' """%s"""\n'%docstring) 344 345 ansL.append(' pass\n') 346 347 return ansL 348 else: 349 return [] 350 351 352 def get_user_part_of_bind_def(self): 353 """get the user code for the bind method def statement """ 354 ansL = [] 355 356 if self.widget_type in widget_bindD: 357 ansL = [] 358 wn, wt = self.widget_name, self.widget_type 359 methodName = self.get_click_name() 360 361 ansL.append(' # replace, delete, or comment-out the following\n') 362 ansL.append(' print( "executed method %s" )\n'%methodName) 363 364 if self.target_app.getSpecialOption('hasstatusbar')=='yes': 365 ansL.append(' self.statusMessage.set("executed method %s")\n'%methodName ) 366 367 ansL.append('\n') 368 369 if self.widget_type == 'Listbox': 370 ansL.append(' print( "current selection(s) =",self.%s.curselection() )\n'%wn ) 371 ansL.append(' labelL = []\n' ) 372 ansL.append(' for i in self.%s.curselection():\n'%wn ) 373 ansL.append(' labelL.append( self.%s.get(i))\n'%wn ) 374 ansL.append(' print( "current label(s) =",labelL )\n') 375 ansL.append(' # use self.%s.insert(0, "item zero")\n'%wn) 376 ansL.append(' # self.%s.insert(index, "item i")\n'%wn) 377 ansL.append(' # OR\n') 378 ansL.append(' # self.%s.insert(END, "item end")\n'%wn) 379 ansL.append(' # to insert items into the list box\n') 380 381 elif self.widget_type == 'Canvas': 382 ansL.append(' print( "clicked in canvas at x,y =",event.x,event.y )\n') 383 ansL.append(' w = int(self.%s.cget("width"))\n'%(wn,)) 384 ansL.append(' h = int(self.%s.cget("height"))\n'%(wn,)) 385 ansL.append(' self.%s.create_rectangle((2, 2, w+1, h+1), outline="blue")\n'%(wn,)) 386 ansL.append(' self.%s.create_line(0, 0, w+2, h+2, fill="red")\n'%(wn,)) 387 ansL.append(' x = int(event.x)\n') 388 ansL.append(' y = int(event.y)\n') 389 ansL.append(' print( "event x,y=",x,y )\n') 390 ansL.append(' self.%s.create_text(x,y, text="NE", fill="green", anchor=NE)\n'%(wn,)) 391 ansL.append(' self.%s.create_text(x,y, text="SW", fill="magenta", anchor=SW)\n'%(wn,)) 392 393 394 elif self.widget_type == 'Treeview': 395 ansL.append(' curItem = self.%s.focus()\n'%wn ) 396 ansL.append(' print( "current Treeview item(s) =",self.%s.item( curItem ) )\n'%wn ) 397 398 399 return ansL 400 401 402 def get_trace_name(self): 403 return '%s_StringVar_traceName'%self.widget_name 404 405 def get_top_of_trace_def(self): 406 """get the top code for the trace method def statement """ 407 408 if self.svar_name: 409 ansL = [] 410 411 methodName = self.get_callback_name() 412 ansL.append(' def %s(self, varName, index, mode):\n'%methodName) 413 414 docstring = self.target_app.compObjD[self.widget_name].get_docstring() 415 ansL.append(' """%s"""\n'%docstring) 416 417 ansL.append(' pass\n') 418 419 ansL.append('\n') 420 return ansL 421 else: 422 return [] 423 424 425 def get_user_part_of_trace_def(self): 426 """get the user code for the trace method def statement """ 427 428 if self.svar_name: 429 ansL = [] 430 431 methodName = self.get_callback_name() 432 ansL.append(' # replace, delete, or comment-out the following\n') 433 ansL.append(' print( "%s varName, index, mode",varName, index, mode )\n'%methodName) 434 435 if self.target_app.getSpecialOption('hasstatusbar')=='yes': 436 ansL.append(' self.statusMessage.set(" %s = "+self.%s.get())\n'%(self.svar_name,self.svar_name)) 437 ansL.append(' print( " new StringVar value =",self.%s.get() )\n\n'%self.svar_name ) 438 439 440 ansL.append('\n') 441 return ansL 442 else: 443 return [] 444 445 446 447 if __name__ == '__main__': 448 import sys 449 from tkgridgui.target_tk_app_def import TargetTkAppDef 450 from tkgridgui.src_templates import beginSourceFile, get_top_imports, endSourceFile 451 import tkgridgui.SourceCode as SourceCode 452 sourceFile = SourceCode.SourceFile( 'component_src_gen_test.py' ) 453 454 tkOptionD = {} 455 456 class Dummy(object): 457 def __init__(self): 458 self.user_tkOptionD = {'values':'One Two Three'} 459 def get_docstring(self): 460 return 'ima_docstring' 461 dummy = Dummy() 462 463 target_app = TargetTkAppDef( 'myTestApp' ) 464 target_app.tkOptionD['background']='yellow' 465 target_app.app_attrD = {'hasstatusbar':'no'} 466 467 468 # make import section 469 sourceFile.addSection('imports', get_top_imports(1,1,1), defaultUserCodeL='# Place any user import statements here\n\n') 470 471 # body of __init__ 472 classInitL = [beginSourceFile('_MyApp', 400, 300, tkOptionD)] 473 classInitL.append(' self.master.title("%s")\n'%"MyApp" ) 474 475 classInitUserSectionL = [] 476 477 widget_typeL = sorted( create_callD.keys() ) 478 sortL = [] 479 for i,widget_type in enumerate(widget_typeL): 480 guiType = 'main' 481 parent_name = 'Main' 482 opDict = [ {}, {'sticky':'se'}, {'sticky':'nw'}][i % 3] 483 opDict['text'] = 'text' 484 row, col = divmod( i, 5 ) 485 486 c = CompSrcGen(widget_type+'_1', widget_type, guiType, parent_name, row, col, opDict, 487 target_app=target_app) 488 sortL.append( c ) 489 target_app.compObjD[ widget_type+'_1' ] = dummy # simulate an active target_app 490 491 classInitL.append( c.get_call_make_stmt() ) 492 sourceFile.addSection('top_of_init', classInitL, defaultUserCodeL=classInitUserSectionL) 493 494 # add make widget routines 495 for c in sortL: 496 sourceFile.addSection( 'make_%s'%c.widget_name, c.get_top_of_make_def(), 497 defaultUserCodeL=c.get_user_part_of_make_def() ) 498 499 # add any bind routines 500 for c in sortL: 501 topL = c.get_top_of_bind_def() 502 if topL: 503 methodName = c.get_click_name() 504 sourceFile.addSection( methodName, topL, 505 defaultUserCodeL=c.get_user_part_of_bind_def() ) 506 507 # add any StringVar trace routines 508 for c in sortL: 509 topL = c.get_top_of_trace_def() 510 if topL: 511 methodName = c.get_trace_name() 512 sourceFile.addSection( methodName, topL, 513 defaultUserCodeL=c.get_user_part_of_trace_def() ) 514 515 516 517 sourceFile.addSection('end', endSourceFile('_MyApp') , allowUserCode=0) 518 519 520 sourceFile.saveToFile( sys.stdout ) # simulate a save with stdout 521 522 523 sys.exit() 524 # ==================================================================================== 525 def show_create( widget_name, widget_type, guiType, parent_name, row, col, opDict ): 526 c = CompSrcGen(widget_name, widget_type, guiType, parent_name, row, col, opDict, target_app=target_app) 527 528 print( c.get_call_make_stmt().rstrip() ) 529 print( c.get_create_widget().rstrip() ) 530 print( c.get_grid_stmt().rstrip() ) 531 532 s = c.get_bind_stmt() 533 if s: 534 print( s.rstrip() ) 535 536 ansL = c.get_string_var_stmts() 537 for line in ansL: 538 print( line.rstrip() ) 539 print(' - - - - - - - ') 540 541 #show_create('Button_1', 'Button', 'main','Main', 1,2,{'sticky':'se'}) 542 #show_create('RadioGroup_1','RadioGroup','main','Frame_1', 3,4,None) 543 #show_create('Entry_1', 'Entry', 'main','Frame_1', 5,6,None) 544 545 cL = sorted( create_callD.keys() ) 546 for ic,c in enumerate(cL): 547 548 guiType = ['main','dialog'][ic % 2] 549 parent_name = ['Main','Frame_1'][ic % 2] 550 opDict = [None, {}, {'sticky':'se'}][ic % 3] 551 552 row, col = divmod( ic, 5 ) 553 show_create( c+'_1', c, guiType, parent_name, row, col, opDict ) 554 555 556