Package nMOLDYN :: Package GUI :: Module Widgets
[hide private]
[frames] | no frames]

Source Code for Module nMOLDYN.GUI.Widgets

   1  """This module implements all classes used for the generation of combo widgets.  
   2   
   3  A combo widget can be defined as a label frame encapsulating several other Tkinter widgets. 
   4   
   5  Classes: 
   6      * ValidatingEntry   : sets up a Tkinter Entry widget that checks its contents whenever it is changed. 
   7      * IntegerEntry      : sets up a Tkinter Entry widget that checks that the input is an integer. 
   8      * FloatEntry        : sets up a Tkinter Entry widget that checks that the input is a float. 
   9      * StringEntry       : sets up a Tkinter Entry widget that checks that the input is a string matching a given pattern. 
  10      * ComboLabelEntry   : sets up a combo widget made of a Tkinter Label widget embedded in a Tkinter LabelFrame widget. 
  11      * ComboIntegerEntry : sets up a combo widget made of a Tkinter Label widget and IntegerEntry combo widget embedded  
  12        in a Tkinter LabelFrame widget. 
  13      * ComboFloatEntry   : sets up a combo widget made of a Tkinter Label widget and FloatEntry embedded in a Tkinter  
  14        LabelFrame widget. 
  15      * ComboStringEntry  : sets up a combo widget made of a Tkinter Label widget and StringEntry embedded in a Tkinter  
  16        LabelFrame widget. 
  17      * ComboRadiobutton  : sets up a combo widget made of a Tkinter Label widget and a set of Tkinter RadioButton widgets  
  18        embedded in a Tkinter LabelFrame widget. 
  19      * ComboCheckbutton  : sets up a combo widget made of a Tkinter Label widget and a Tkinter CheckButton widget embedded  
  20        in a Tkinter LabelFrame widget. 
  21      * ComboOptionMenu   : sets up a combo widget made of a Tkinter Label widget and a Tkinter OptionMenu widget embedded  
  22        in a Tkinter LabelFrame widget. 
  23      * ComboSpinbox      : sets up a combo widget made of a Tkinter Label widget and a Tkinter Spinbox widget embedded in  
  24        a Tkinter LabelFrame widget. 
  25      * ComboScale        : sets up a combo widget made of a Tkinter Label widget and a Tkinter Scale widget embedded in  
  26        a Tkinter LabelFrame widget. 
  27      * ComboButton       : sets up a combo widget made of a Tkinter Button widget and optionnally a Tkinter Entry widget embedded  
  28        in a Tkinter LabelFrame widget. 
  29      * ComboFileBrowser  : sets up a combo widget made of a Tkinter Label widget, a StringEntry widget and a Tkinter Button  
  30        widget for file browsing embedded in a Tkinter LabelFrame widget. 
  31      * ComboText         : sets up a combo widget made of a Tkinter Text and a vertical Tkinter Scrollbar widget widget embedded in a  
  32        Tkinter LabelFrame widget. 
  33      * ComboListbox      : sets up a combo widget made of a Tkinter Listbox widget and a vertical Tkinter Scrollbar widget embedded  
  34        in a Tkinter LabelFrame widget. 
  35      * StatusBar         : sets up a combo widget made of a Tkinter Scale widget embedded in a Tkinter Frame  
  36        widget. 
  37   
  38   
  39  The following classes were adapted from the implementation of Frederic Lundh: 
  40      - ValidatingEntry 
  41      - IntegerEntry 
  42      - FloatEntry 
  43  """ 
  44   
  45  # The python distribution modules 
  46  import os 
  47  import re 
  48  import subprocess 
  49  import sys 
  50  import xml.dom.minidom 
  51   
  52  # The Tcl/Tk modules 
  53  from Tkinter import * 
  54  from tkFileDialog import askopenfilename, asksaveasfilename 
  55  import tkMessageBox 
  56   
  57  # The nMOLDYN modules 
  58  from nMOLDYN.Core.Error import Error 
  59  from nMOLDYN.Core.Logger import LogMessage 
  60  from nMOLDYN.Core.Preferences import PREFERENCES 
  61  from nMOLDYN.GUI.HTMLReader.tkhtml import tkHTMLViewer 
  62  from nMOLDYN.GUI.Tags import tags 
  63   
  64  # Package path 
  65  nmoldyn_package_path = os.path.dirname(os.path.split(__file__)[0]) 
  66   
67 -class ValidatingEntry(Entry):
68 """Base class for |IntegerEntry|, |FloatEntry| and |StringEntry| widgets 69 """ 70
71 - def __init__(self, master, contents = '', **kwargs):
72 """The constructor. 73 74 @param master: the parent widget. 75 76 @param contents: the contents of the Tkinter Entry widget. 77 @type contents: string 78 """ 79 80 Entry.__init__(self, master, **kwargs) 81 self.variable = StringVar() 82 self.variable.trace('w', self.__callback) 83 self.variable.set(contents) 84 self._contents = contents 85 86 self.config(textvariable = self.variable, bg = 'white') 87 88 self.bind('<Return>', lambda event: self.checkValue(event, self.variable.get())) 89 self.bind('<Tab>', lambda event : self.checkValue(event, self.variable.get()))
90
91 - def __callback(self, *dummy):
92 contents = self.variable.get() 93 newContents = self.checkValue(contents = contents) 94 if newContents is not None: 95 self._contents = newContents 96 self.variable.set(self._contents)
97
98 - def checkValue(self, event = None, contents = None):
99 pass
100
101 - def setValue(self, value):
102 """Sets the value of the control variable linked to the Tkinter Entry widget. 103 """ 104 105 self.variable.set(value)
106
107 - def getValue(self):
108 """Returns the value of the control variable linked to the Tkinter Entry widget. 109 """ 110 return self.variable.get()
111
112 -class IntegerEntry(ValidatingEntry):
113 """Sets up a Tkinter Entry widget that accepts only integer values. 114 115 @note: subclass of nMOLDYN.GUI.Widgets.ValidatingEntry class. 116 """ 117
118 - def checkValue(self, event = None, contents = None):
119 """Check that the contents of the Tkinter Entry widget is actually an integer. 120 121 @param event: the keyboard event that triggers the checking of the contents of the Tkinter Entry widget. 122 @type event: a Tkinter.Event object 123 124 @param contents: the contents of the Tkinter Entry widget to check. 125 @type contents: integer 126 """ 127 128 if contents == '': 129 return '' 130 131 try: 132 return int(contents) 133 except: 134 return None
135
136 - def setValue(self, value = None):
137 """Sets the value of the control variable linked to the Tkinter Entry widget. 138 """ 139 140 v = self.checkValue(contents = value) 141 if v is not None: 142 self.variable.set(v)
143
144 - def getValue(self):
145 """Returns the value of the control variable linked to the Tkinter Entry widget if it is an integer otherwise 146 throws an error. 147 """ 148 try: 149 return int(self.variable.get()) 150 except ValueError: 151 raise Error('%s is not an integer' % self.variable.get())
152
153 -class FloatEntry(ValidatingEntry):
154 """Sets up a Tkinter Entry widget that accepts only float values. 155 156 @note: subclass of nMOLDYN.GUI.Widgets.ValidatingEntry class. 157 """ 158
159 - def checkValue(self, event = None, contents = None):
160 """Check that the contents of the Tkinter Entry widget is actually a float. 161 162 @param event: the keyboard event that triggers the checking of the contents of the Tkinter Entry widget. 163 @type event: a Tkinter.Event object 164 165 @param contents: the contents of the Tkinter Entry widget to check. 166 @type contents: float 167 """ 168 169 if contents == '': 170 return '' 171 172 try: 173 return float(contents) 174 except: 175 return None
176
177 - def setValue(self, value):
178 """Sets the value of the control variable linked to the Tkinter Entry widget. 179 """ 180 181 v = self.checkValue(contents = value) 182 if v is not None: 183 self.variable.set(v)
184
185 - def getValue(self):
186 """Returns the value of the control variable linked to the Tkinter Entry widget if it is a float otherwise 187 throws an error. 188 """ 189 try: 190 return float(self.variable.get()) 191 except ValueError: 192 raise Error('%s is not a float' % self.variable.get())
193
194 -class StringEntry(ValidatingEntry):
195 """Sets up a Tkinter Entry widget that accepts only string values. 196 197 @note: subclass of nMOLDYN.GUI.Widgets.ValidatingEntry class. 198 """ 199
200 - def __init__(self, master, contents = '', pattern = None, **kwargs):
201 """The constructor. 202 203 @param master: the parent widget. 204 205 @param contents: the contents of the Tkinter Entry widget. 206 @type contents: string 207 208 @param pattern: if not None, a string specifying a pattern the contents of the Tkinter Entry widget has to 209 fulfill. 210 @type pattern:string 211 """ 212 213 self.pattern = pattern 214 ValidatingEntry.__init__(self, master, contents, **kwargs)
215
216 - def checkValue(self, event = None, contents = None):
217 """Check that the contents of the Tkinter Entry widget is actually a string that possibly match the 218 |self.pattern| pattern it is not None.. 219 220 @param event: the keyboard event that triggers the checking of the contents of the Tkinter Entry widget. 221 @type event: a Tkinter.Event object 222 223 @param contents: the contents of the Tkinter Entry widget to check. 224 @type contents: string 225 """ 226 if self.pattern is None: 227 return contents 228 229 if self.variable.get(): 230 if not re.findall(self.pattern, self.variable.get()): 231 LogMessage('warning','%s does not math the pattern %s' % (self.variable.get(), self.pattern),['gui']) 232 return None 233 else: 234 return contents
235
236 - def getValue(self):
237 """Returns the value of the control variable linked to the Tkinter Entry widget if it is a string otherwise 238 throws an error. 239 """ 240 try: 241 if self.variable.get(): 242 return str(self.variable.get()) 243 else: 244 return None 245 except: 246 raise Error('%s is not a string' % self.variable.get())
247
248 -class ComboFrame(LabelFrame):
249 """Sets up a Tkinter LabelFrame widget. 250 251 Some bindings are set by default: 252 - Tkinter '<Motion>' Event will change the mouse cursor to 'question_arrow' symbol. 253 - Tkinter '<Leave>' Event will change the mouse cursor to 'arrow' symbol when leaving the widget. 254 - Tkinter '<Button-1>' Event will give some information about the widget when clicking on it. 255 """ 256
257 - def __init__(self, master, frameLabel = '', tagName = ''):
258 """The constructor. 259 """ 260 LabelFrame.__init__(self, master, relief = GROOVE, bd = 2) 261 self.frameLabel = frameLabel 262 self.tagName = tagName 263 if self.frameLabel: 264 # The label of the LabelFrame is a Label widget. 265 self.label = Label(self, text = self.frameLabel) 266 self.config(labelwidget = self.label) 267 # Some bindings for the Label widget of the LabelFrame. 268 self.label.bind('<Motion>', lambda event : changeMouseCursor(event,'question_arrow')) 269 self.label.bind('<Leave>', lambda event : changeMouseCursor(event,'arrow')) 270 self.label.bind('<Button-1>', informationAboutWidget)
271
272 -class ComboLabel(ComboFrame):
273 """Sets up a combo widget made of a Tkinter Label widget embedded in a Tkinter LabelFrame widget. 274 """ 275
276 - def __init__(self, master, frameLabel = '', tagName = '', contents = ''):
277 """The constructor. 278 279 @param master: the parent widget of the combo widget. 280 281 @param frameLabel: the label for the Tkinter LabelFrame widget. 282 @type frameLabel: string or Tkinter.StringVar object. 283 284 @param tagLabel: the tag used for to document the widget. If set to '', the widget will not be documented. 285 @type tagLabel: string. 286 287 @param contents: the contents of the Tkinter Label widget. 288 @type contents: string 289 """ 290 291 # The comboframe is set up. 292 ComboFrame.__init__(self, master, frameLabel, tagName) 293 294 self.labelVar = StringVar() 295 self.labelVar.set(str(contents)) 296 297 # The label is set up. 298 self.label = Label(self, textvariable = self.labelVar, bd = 2, relief = GROOVE, anchor = W, width = len(self.labelVar.get())) 299 self.label.grid(row = 0, column = 0, sticky = E, padx = 3)
300
301 - def getValue(self):
302 """Returns the value of the Tkinter Label widget. 303 """ 304 return self.labelVar.get()
305
306 - def setValue(self, value):
307 """Returns the value of the Tkinter Label widget. 308 """ 309 return self.labelVar.set(value)
310
311 -class ComboIntegerEntry(ComboFrame):
312 """Sets up a combo widget made of a Tkinter Label widget and a IntegerEntry widget embedded in a Tkinter LabelFrame 313 widget. 314 """ 315
316 - def __init__(self, master, frameLabel = '', tagName = '', contents = ''):
317 """The constructor. 318 319 @param master: the parent widget of the combo widget. 320 321 @param frameLabel: the label for the Tkinter LabelFrame widget. 322 @type frameLabel: string or Tkinter.StringVar object. 323 324 @param tagLabel: the tag used for to document the widget. If set to '', the widget will not be documented. 325 @type tagLabel: string. 326 327 @param contents: the contents of the IntegerEntry widget. 328 @type contents: integer 329 """ 330 331 # The comboframe is set up. 332 ComboFrame.__init__(self, master, frameLabel, tagName) 333 334 self.entry = IntegerEntry(self, contents, width = 10) 335 self.entry.grid(row = 0, column = 0, sticky = E, padx = 3)
336
337 - def getValue(self):
338 """Returns the value of the IntegerEntry widget. 339 """ 340 return self.entry.getValue()
341
342 - def setValue(self, value):
343 """Sets the value of the IntegerEntry widget to |value| (integer). 344 345 @param value: the contents to insert in the IntegerEntry widget. 346 @type value: integer 347 """ 348 self.entry.setValue(value)
349
350 -class ComboFloatEntry(ComboFrame):
351 """Sets up a combo widget made of a Tkinter Label widget and a FloatEntry widget embedded in a Tkinter LabelFrame 352 widget. 353 """
354 - def __init__(self, master, frameLabel = '', tagName = '', contents = ''):
355 """The constructor. 356 357 @param master: the parent widget of the combo widget. 358 359 @param frameLabel: the label for the Tkinter LabelFrame widget. 360 @type frameLabel: string or Tkinter.StringVar object. 361 362 @param tagLabel: the tag used for to document the widget. If set to '', the widget will not be documented. 363 @type tagLabel: string. 364 365 @param contents: the contents of the FloatEntry widget. 366 @type contents: float 367 """ 368 369 # The comboframe is set up. 370 ComboFrame.__init__(self, master, frameLabel, tagName) 371 372 self.entry = FloatEntry(self, contents, width = 10) 373 self.entry.grid(row = 0, column = 0, sticky = E, padx = 3)
374
375 - def getValue(self):
376 """Returns the value of the FloatEntry widget. 377 """ 378 return self.entry.getValue()
379
380 - def setValue(self, value):
381 """Sets the value of the FloatEntry widget to |value| (float). 382 383 @param value: the contents to insert in the FloatEntry widget. 384 @type value: float 385 """ 386 self.entry.setValue(value)
387
388 -class ComboStringEntry(ComboFrame):
389 """Sets up a combo widget made of a Tkinter Label widget and a StringEntry widget embedded in a Tkinter LabelFrame 390 widget. 391 """
392 - def __init__(self, master, frameLabel = '', tagName = '', contents = '', pattern = None):
393 """The constructor. 394 395 @param master: the parent widget of the combo widget. 396 397 @param frameLabel: the label for the Tkinter LabelFrame widget. 398 @type frameLabel: string or Tkinter.StringVar object. 399 400 @param tagLabel: the tag used for to document the widget. If set to '', the widget will not be documented. 401 @type tagLabel: string. 402 403 @param contents: the contents of the StringEntry widget. 404 @type contents: string 405 406 @param pattern: if not None, a string specifying a pattern the contents of the Tkinter Entry widget has 407 to fulfill. 408 @type pattern:string 409 """ 410 411 # The comboframe is set up. 412 ComboFrame.__init__(self, master, frameLabel, tagName) 413 414 self.entry = StringEntry(self, contents, pattern, width = 30) 415 self.entry.grid(row = 0, column = 0, sticky = E, padx = 3)
416
417 - def getValue(self):
418 """Returns the value of the StringEntry widget. 419 """ 420 return self.entry.getValue()
421
422 - def setValue(self, value):
423 """Sets the value of the StringEntry widget to |value| (string). 424 425 @param value: the contents to insert in the StringEntry widget. 426 @type value: string 427 """ 428 self.entry.setValue(value)
429
430 -class ComboRadiobutton(ComboFrame):
431 """Sets up a combo widget made of a Tkinter Label widget and a set of Tkinter RadioButton widgets 432 embedded in a Tkinter LabelFrame widget. 433 """ 434
435 - def __init__(self, master, frameLabel = '', tagName = '', contents = [], default = 0, layout = None):
436 """The constructor. 437 438 @param master: the parent widget of the combo widget. 439 440 @param frameLabel: the label for the Tkinter LabelFrame widget. 441 @type frameLabel: string or Tkinter.StringVar object. 442 443 @param tagLabel: the tag used for to document the widget. If set to '', the widget will not be documented. 444 @type tagLabel: string. 445 446 @param contents: a list (string) specifying the names of each Tkinter Radiobutton widget. 447 @type contents: list 448 449 @param default: an integer specifying which Tkinter Radiobutton widget will be switched on by default. 450 @type default: integer 451 452 @param layout: a tuple (integer) of the form (nrows,ncolumns) specifying the way the set of Tkinter Radiobutton widget will be displayed. 453 @type layout: tuple 454 """ 455 456 # The comboframe is set up. 457 ComboFrame.__init__(self, master, frameLabel, tagName) 458 459 # At least one radiobutton must be provided. 460 if len(contents) == 0: 461 raise Error('No radiobutton given to set up.') 462 463 self.contents = contents 464 self.radioVar = StringVar() 465 self.radioVar.set(self.contents[default]) 466 467 radioFrame = Frame(self) 468 radioFrame.grid(row = 0, column = 0, sticky = E, padx = 3) 469 470 self.radio = [] 471 # If no |layout| argument is given, then build the radiobutton on a single row. 472 if layout is None: 473 row = 0 474 for v in contents: 475 self.radio.append(Radiobutton(radioFrame,\ 476 text = v,\ 477 variable = self.radioVar,\ 478 value = v,\ 479 width = 14,\ 480 justify = LEFT,\ 481 anchor = W)) 482 self.radio[-1].radio.grid(row = row, sticky = W) 483 row += 1 484 else: 485 nrows, ncols = layout 486 for r in range(nrows): 487 for c in range(ncols): 488 ind = r*ncols + c 489 if ind < len(contents): 490 self.radio.append(Radiobutton(radioFrame,\ 491 text = contents[r*ncols + c],\ 492 variable = self.radioVar,\ 493 value = contents[r*ncols + c],\ 494 width = 14,\ 495 justify = LEFT,\ 496 anchor = W)) 497 self.radio[-1].grid(row = r, column = c, sticky = W)
498
499 - def getValue(self):
500 """Returns the value of the control variable linked to the set of Tkinter Radiobutton widgets. 501 """ 502 return str(self.radioVar.get())
503
504 - def setValue(self, value):
505 """Sets the value of the control variable linked to the set of Tkinter Radiobutton widgets. 506 507 @param value: the value the control variable linked to the set of Tkinter Radiobutton widgets will take. 508 Must be an element of |self.contents| 509 @type value: string 510 """ 511 if value in self.contents: 512 self.radioVar.set(value) 513 else: 514 self.radioVar.set(self.contents[0])
515
516 -class ComboCheckbutton(ComboFrame):
517 """Sets up a combo widget made of a Tkinter Label widget and a set of Tkinter Checkbutton widget 518 embedded in a Tkinter LabelFrame widget. 519 """ 520
521 - def __init__(self, master, frameLabel = '', tagName = '', contents = '', onvalue = True, offvalue = False, default = False):
522 """The constructor. 523 524 @param master: the parent widget of the combo widget. 525 526 @param frameLabel: the label for the Tkinter LabelFrame widget. 527 @type frameLabel: string or Tkinter.StringVar object. 528 529 @param tagLabel: the tag used for to document the widget. If set to '', the widget will not be documented. 530 @type tagLabel: string. 531 532 @param contents: the name of the Tkinter Checkbutton widget. 533 @type contents: string 534 535 @param onvalue: the value of the Tkinter Checkbutton widget when switched on. 536 @type onvalue: boolean, integer or string 537 538 @param offvalue: the value of the Tkinter Checkbutton widget when switched off. 539 @type offvalue: boolean, integer or string 540 541 @param default: a boolean specifying whether the Tkinter Checkbutton widget is switched on (True) or switched off (False) 542 by default. 543 @type default: boolean 544 """ 545 546 # The comboframe is set up. 547 ComboFrame.__init__(self, master, frameLabel, tagName, ) 548 549 checkFrame = Frame(self) 550 checkFrame.grid(row = 0, column = 0, sticky = E, padx = 3) 551 552 self.offvalue = offvalue 553 self.onvalue = onvalue 554 555 if isinstance(self.onvalue, str): 556 self.checkVar = StringVar() 557 558 elif isinstance(self.onvalue, bool): 559 self.checkVar = BooleanVar() 560 561 elif isinstance(self.onvalue, int): 562 self.checkVar = IntVar() 563 564 else: 565 raise Error('%s can not be used to define the state of a checkbutton.' % onvalue) 566 567 if onvalue.__class__ != offvalue.__class__: 568 raise Error('%s and %s must be of the same class to setup properly the checkbutton.' % (offvalue, onvalue)) 569 570 if default: 571 self.checkVar.set(self.onvalue) 572 573 else: 574 self.checkVar.set(self.offvalue) 575 576 self.check = Checkbutton(checkFrame,\ 577 text = contents,\ 578 textvariable = self.checkVar,\ 579 variable = self.checkVar,\ 580 onvalue = onvalue,\ 581 offvalue = offvalue,\ 582 width = 8,\ 583 justify = LEFT) 584 self.check.grid(sticky = E)
585
586 - def getValue(self):
587 """Returns the value of the control variable linked to the Tkinter Checkbutton widget. 588 """ 589 return self.checkVar.get()
590
591 - def setValue(self, value):
592 """Sets the value of the control variable linked to the Tkinter Checkbutton widget. 593 594 @param value: the value the control variable linked to the Tkinter Checkbutton widget will take. 595 Must be an element of |self.contents| 596 @type value: string 597 """ 598 try: 599 self.checkVar.set(value) 600 601 except: 602 self.checkVar.set(self.offvalue)
603
604 -class ComboOptionMenu(ComboFrame):
605 """Sets up a combo widget made of a Tkinter Label widget and a Tkinter OptionMenu widget embedded 606 in a Tkinter LabelFrame widget. 607 """ 608
609 - def __init__(self, master, frameLabel = '', tagName = '', contents = [], default = 0):
610 """The constructor. 611 612 @param master: the parent widget of the combo widget. 613 614 @param frameLabel: the label for the Tkinter LabelFrame widget. 615 @type frameLabel: string or Tkinter.StringVar object. 616 617 @param tagLabel: the tag used for to document the widget. If set to '', the widget will not be documented. 618 @type tagLabel: string. 619 620 @param contents: a list (string) specifying the names of for the entries each Tkinter OptionMenu widget. 621 @type contents: list 622 623 @param default: an integer specifying which entry of the Tkinter optionMenu widget will be displayed by default. 624 @type default: integer 625 """ 626 627 # The comboframe is set up. 628 ComboFrame.__init__(self, master, frameLabel, tagName) 629 630 # At least one option must be provided. 631 if len(contents) == 0: 632 raise Error('No option given to set up this combowidget.') 633 634 # The frame that will host the option menu widget is set up. 635 optionFrame = Frame(self) 636 optionFrame.grid(row = 0, column = 1, sticky = E, padx = 3) 637 638 self.contents = contents 639 self.optionVar = StringVar() 640 self.optionVar.set(self.contents[default]) 641 642 self.option = OptionMenu(optionFrame, self.optionVar, *contents) 643 self.option.grid(sticky = E)
644
645 - def getValue(self):
646 """Returns the value of the control variable linked to the Tkinter OptionMenu widget. 647 """ 648 return str(self.optionVar.get())
649
650 - def setValue(self, value):
651 """Sets the value of the control variable linked to the Tkinter OptionMenu widget. 652 653 @param value: the value the control variable linked to the Tkinter OptionMenu widget will take. 654 Must be an element of |self.contents| 655 @type value: string 656 """ 657 if value in self.contents: 658 self.optionVar.set(value) 659 else: 660 self.optionVar.set(self.contents[0])
661
662 -class ComboSpinbox(ComboFrame):
663 """Sets up a combo widget made of a Tkinter Label widget and a Tkinter Spinbox widget embedded 664 in a Tkinter LabelFrame widget. 665 """ 666
667 - def __init__(self, master, frameLabel = '', tagName = '', contents = [], default = 0):
668 """The constructor. 669 670 @param master: the parent widget of the combo widget. 671 672 @param frameLabel: the label for the Tkinter LabelFrame widget. 673 @type frameLabel: string or Tkinter.StringVar object. 674 675 @param tagLabel: the tag used for to document the widget. If set to '', the widget will not be documented. 676 @type tagLabel: string. 677 678 @param contents: a tuple (string) specifying the names of for the entries to insert in the Tkinter Spinbox widget. 679 @type contents: tuple 680 681 @param default: an integer specifying which entry of the Tkinter Spinbox widget will be displayed by default. 682 @type default: integer 683 """ 684 685 # The comboframe is set up. 686 ComboFrame.__init__(self, master, frameLabel, tagName) 687 688 # At least one option must be provided. 689 if len(contents) == 0: 690 raise Error('No option given to set up this combowidget.') 691 692 self.type = type(contents[0]) 693 for v in contents: 694 if type(v) != self.type: 695 self.type = str 696 697 # The frame that will host the option menu widget is set up. 698 spinboxFrame = Frame(self) 699 spinboxFrame.grid(row = 0, column = 1, sticky = E, padx = 3) 700 701 self.contents = contents 702 self.default = default 703 704 self.spinbox = Spinbox(spinboxFrame, values = self.contents, wrap = True, width = 4, bg = 'white') 705 self.spinbox.grid(sticky = E) 706 707 self.setValue(self.contents[self.default])
708
709 - def getValue(self):
710 """Returns the value of the control variable linked to the Tkinter Spinbox widget. 711 """ 712 return self.type(self.spinbox.get())
713
714 - def setValue(self, value):
715 """Sets the value of the control variable linked to the Tkinter Spinbox widget. 716 717 @param value: the value the control variable linked to the Tkinter Spinbox widget will take. 718 Must be an element of |self.contents| 719 @type value: string 720 """ 721 722 if value in self.contents: 723 v = self.type(self.spinbox.get()) 724 while v != value: 725 self.spinbox.invoke('buttonup') 726 v = self.type(self.spinbox.get())
727
728 -class ComboScale(ComboFrame):
729 """Sets up a combo widget made of a Tkinter Label widget and a Tkinter Scale widget embedded 730 in a Tkinter LabelFrame widget. 731 """ 732
733 - def __init__(self, master, frameLabel = '', tagName = '', contents = []):
734 """The constructor. 735 736 @param master: the parent widget of the combo widget. 737 738 @param frameLabel: the label for the Tkinter LabelFrame widget. 739 @type frameLabel: string or Tkinter.StringVar object. 740 741 @param tagLabel: the tag used for to document the widget. If set to '', the widget will not be documented. 742 @type tagLabel: string. 743 744 @param contents: a 3 elements list (integer) specifying respectively the first, the last and the resolution values 745 for the Tkinter Scale widget. 746 @type contents: list 747 """ 748 749 # The comboframe is set up. 750 ComboFrame.__init__(self, master, frameLabel, tagName) 751 752 # At least one option must be provided. 753 if len(contents) == 0: 754 raise Error('No values given to set up this combowidget.') 755 756 self.from_, self.to, self.resolution = contents 757 758 self.scale = Scale(self, from_ = self.from_, to = self.to, resolution = self.resolution, length = 200, orient = HORIZONTAL) 759 self.scale.grid(row = 0, column = 0, sticky = E, padx = 3)
760
761 - def getValue(self):
762 """Returns the value of the control variable linked to the Tkinter Scale widget. 763 """ 764 return self.scale.get()
765
766 - def setValue(self, value):
767 """Sets the value of the control variable linked to the Tkinter Scale widget. 768 769 @param value: the value the Tkinter Scale widget will take. 770 @type value: integer 771 """ 772 self.scale.set(value)
773
774 -class ComboButton(ComboFrame):
775 """Sets up a combo widget made of a Tkinter Button widget and optionnally a Tkinter Entry widget embedded 776 in a Tkinter LabelFrame widget. 777 """ 778
779 - def __init__(self, master, frameLabel = '', tagName = '', contents = '', withEntry = None, command = None):
780 """The constructor. 781 782 @param master: the parent widget of the combo widget. 783 784 @param frameLabel: the label for the Tkinter LabelFrame widget. 785 @type frameLabel: string or Tkinter.StringVar object. 786 787 @param tagLabel: the tag used for to document the widget. If set to '', the widget will not be documented. 788 @type tagLabel: string. 789 790 @param contents: string specifying the label of the Tkinter Button widget. 791 @type contents: string 792 793 @param withEntry: if not None, a Tkinter Entry widget will be placed beside the Tkinter Button 794 with |withEntry| as contents. 795 @type withEntry: boolean 796 797 @param command: the function to call when clicking on the Tkinter Button widget. 798 @type command: function 799 """ 800 801 # The comboframe is set up. 802 ComboFrame.__init__(self, master, frameLabel, tagName) 803 804 self.withEntry = withEntry 805 806 self.results = None 807 self.command = command 808 809 if self.withEntry: 810 # The entry widget is set up. 811 self.entry = StringEntry(self, self.withEntry, width = 60) 812 self.entry.grid(row = 0, column = 0, sticky = E) 813 814 self.button = Button(self, text = contents, command = self.pushButton, width = 8) 815 self.button.grid(row = 0, column = 1, sticky = E, padx = 3)
816
817 - def pushButton(self):
818 """Executes the command linked to the Tkinter Button widget. 819 """ 820 821 if self.command is not None: 822 self.results = self.command() 823 if self.withEntry: 824 self.entry.setValue(str(self.results.getValue()))
825
826 - def getValue(self):
827 """Returns the output value of the |self.command| function. 828 """ 829 830 if self.withEntry: 831 val = self.entry.getValue() 832 else: 833 # Case where |self.results| is instance of a ComboWidget having the getValue method. 834 try: 835 val = self.results.getValue() 836 except: 837 val = self.results 838 839 return val
840
841 - def setValue(self):
842 pass
843
844 -class ComboFileBrowser(ComboFrame):
845 """Sets up a combo widget made of a Tkinter Label widget, a StringEntry widget and a Tkinter Button 846 widget for file browsing embedded in a Tkinter LabelFrame widget. 847 """ 848
849 - def __init__(self, master, frameLabel = '', tagName = '', contents = '', save = False, command = None, filetypes = []):
850 """The constructor. 851 852 @param master: the parent widget of the combo widget. 853 854 @param frameLabel: the label for the Tkinter LabelFrame widget. 855 @type frameLabel: string or Tkinter.StringVar object. 856 857 @param tagLabel: the tag used for to document the widget. If set to '', the widget will not be documented. 858 @type tagLabel: string. 859 860 @param contents: string specifying the contents of the Tkinter Entry widget. 861 @type contents: string 862 863 @param save: boolean specifying whether the file browser is for saving (True) or for loading (False). 864 @type save: boolean 865 866 @param command: the function to call when browsing the file. 867 @type command: function 868 """ 869 870 # The comboframe is set up. 871 ComboFrame.__init__(self, master, frameLabel, tagName) 872 873 self.save = save 874 self.filetypes = filetypes 875 self.command = command 876 877 # The entry widget is set up. 878 self.entry = StringEntry(self, contents, width = 60) 879 self.entry.grid(row = 0, column = 0, sticky = E) 880 881 self.button = Button(self, bitmap = "@"+os.path.join(nmoldyn_package_path, 'GUI', 'Images', 'openfile.xbm'), command = self.browse) 882 self.button.grid(row = 0, column = 1, sticky = E)
883
884 - def browse(self):
885 """Executes the command linked to the Tkinter Button widget. 886 """ 887 888 # No command has been given when the instance of the ComboFileBrowser was created so just launch 889 # a classical TkFileDialog browser and sets the entry of the Combo FileBrowser to the filename. 890 if self.command is None: 891 if self.save: 892 filename = asksaveasfilename(parent = self,\ 893 title = 'Save file as',\ 894 filetypes = self.filetypes,\ 895 initialdir = PREFERENCES.outputfile_path) 896 else: 897 filename = askopenfilename(parent = self, title = 'Open file', filetypes = self.filetypes) 898 self.entry.setValue(filename) 899 else: 900 self.command()
901
902 - def getValue(self):
903 """Returns the value of the StringEntry widget. 904 """ 905 return self.entry.getValue()
906
907 - def setValue(self, value):
908 """Sets the value of the StringEntry widget to |value| (string). 909 910 @param value: the contents to insert in the StringEntry widget. 911 @type value: string 912 """ 913 self.entry.setValue(value)
914
915 -class ComboText(ComboFrame):
916 """Sets up a combo widget made of a Tkinter Text widget and a vertical Tkinter Scrollbar widget embedded in a Tkinter LabelFrame 917 widget. 918 """ 919
920 - def __init__(self, master = None, frameLabel = '', tagName = '', contents = None):
921 """The constructor. 922 923 @param master: the parent widget of the combo widget. 924 925 @param frameLabel: the label for the Tkinter LabelFrame widget. 926 @type frameLabel: string or Tkinter.StringVar object. 927 928 @param tagLabel: the tag used for to document the widget. If set to '', the widget will not be documented. 929 @type tagLabel: string. 930 931 @param contents: string specifying the contents to insert in the Tkinter Text widget. 932 @type contents: string 933 """ 934 935 # The comboframe is set up. 936 ComboFrame.__init__(self, master, frameLabel, tagName) 937 938 # The text widget and its associated scrollbar. 939 sb = Scrollbar(self, orient = VERTICAL) 940 sb.grid(row = 0, column = 1, sticky = NSEW) 941 942 self.text = Text(self,\ 943 state = DISABLED,\ 944 yscrollcommand = sb.set,\ 945 bg = 'white') 946 self.text.grid(row = 0, column = 0, sticky = "NSEW") 947 sb['command'] = self.text.yview 948 949 self.insert(contents = contents)
950
951 - def cleanup(self):
952 """Deletes the contents of the Tkinter Text widget. 953 """ 954 955 self.text.config(state = NORMAL) 956 self.text.delete('0.0', END) 957 self.text.config(state = DISABLED)
958
959 - def insert(self, cursor = END, contents = None, tag = None):
960 """Inserts |contents| text in the Tkinter Text widget. 961 962 @param contents: a string specifying the text to insert in the Tkinter Text widget. 963 @type contents: string 964 965 @param tag: if not None, a string specifying the tag name to associate with the inserted text. 966 @type tag: string 967 """ 968 969 # If the contents is None, then do nothing. 970 if contents is None: 971 return 972 973 # Activate the text widget for writing. 974 self.text.config(state = NORMAL) 975 976 # Insert the contents with a tag eventually. 977 self.text.insert(cursor, contents, tag) 978 979 # Desactivates the text widget for safety reason. 980 self.text.config(state = DISABLED)
981
982 - def tag(self, pattern, tag):
983 """Searches and tags all the occurences of a given pattern. 984 985 @param pattern: the pattern to search and tag. 986 @type pattern: string 987 988 @param tag: the tag to associate with |pattern|. 989 @type tag: string 990 """ 991 992 self.patternLength = IntVar() 993 start = '1.0' 994 # Loop over all the text widget contents to find all the coocurences of |pattern|. 995 # Each time an occurence is found, it is tagged with the given tag |tag|. 996 while 1: 997 match1 = self.text.search(pattern, index = start, stopindex = END, count = self.patternLength) 998 # The break condition of the infinite loop. No pattern has been found anymore. 999 if not match1: 1000 break 1001 match2 = '%s+%sc' % (match1, self.patternLength.get()) 1002 if not self.text.tag_names(match1): 1003 self.text.tag_add(tag, match1, match2) 1004 start = match2
1005
1006 -class ComboListbox(ComboFrame):
1007 """Sets up a combo widget made of a Tkinter Listbox widget and a vertical Tkinter Scrollbar widget embedded in a Tkinter LabelFrame 1008 widget. 1009 """ 1010
1011 - def __init__(self, master = None, frameLabel = '', tagName = '', contents = []):
1012 """The constructor. 1013 1014 @param master: the parent widget of the combo widget. 1015 1016 @param frameLabel: the label for the Tkinter LabelFrame widget. 1017 @type frameLabel: string or Tkinter.StringVar object. 1018 1019 @param tagLabel: the tag used for to document the widget. If set to '', the widget will not be documented. 1020 @type tagLabel: string. 1021 1022 @param contents: a list (string) specifying the items to insert in the Tkinter Listbox widget. 1023 @type contents: list 1024 """ 1025 1026 # The comboframe is set up. 1027 ComboFrame.__init__(self, master, frameLabel, tagName) 1028 1029 # The listbox that will display and its associated scrollbar. 1030 sb = Scrollbar(self, orient = VERTICAL) 1031 sb.grid(row = 0, column = 1, sticky = "NSEW") 1032 1033 self.lb = Listbox(self, yscrollcommand = sb.set, bg = 'white') 1034 self.lb.grid(row = 0, column = 0, sticky = "NSEW") 1035 1036 sb['command'] = self.lb.yview 1037 self.lb.bind('<ButtonRelease-1>', self.onListboxEntrySelection) 1038 self.lb.bind('<Motion>', self.focus) 1039 1040 self.insert(contents)
1041
1042 - def focus(self, event):
1043 """Sets the focus to the Tkinter Listbox widget. 1044 1045 @param event: the event triggering the focus. 1046 @type event: a Tkinter.Event object 1047 """ 1048 self.lb.focus_set()
1049
1050 - def insert(self, contents = []):
1051 """Inserts a list of items (string) in the Tkinter Listbox widget. 1052 1053 @param contents: a list (string) specifying the items to insert in the Tkinter Listbox widget. 1054 @type contents: list 1055 """ 1056 1057 # Some checkings. 1058 if not isinstance(contents, (list, tuple, dict)): 1059 raise Error('The object of type %s cannot be inserted into a listbox.' % contents.__class__.__name__) 1060 1061 self.cleanup() 1062 1063 # Loop over list to insert in the listbox. 1064 for c in contents: 1065 self.lb.insert(END, c)
1066
1067 - def cleanup(self):
1068 """Deletes all the items of the Tkinter Listbox widget. 1069 """ 1070 1071 self.lb.delete(0, END)
1072
1073 - def onListboxEntrySelection(self, event):
1074 """Updates the selection of the Tkinter Listbox widget when |event| Tkinter Event occurs. 1075 1076 @param event: the event triggering the callback. 1077 @type event: a Tkinter.Event object 1078 """ 1079 index = self.lb.nearest(event.y) 1080 if index == -1: 1081 return 1082 1083 if not self.lb.selection_includes(index): 1084 self.lb.selection_clear(index) 1085 else: 1086 self.lb.selection_set(index)
1087
1088 -class StatusBar(Frame):
1089 """Sets up a combo widget made of a Tkinter Scale widget embedded in a Tkinter Frame widget. 1090 """ 1091
1092 - def __init__(self, master = None):
1093 """The constructor. 1094 1095 @param master: the parent widget of the combo widget. 1096 """ 1097 1098 Frame.__init__(self, master, bd = 2, relief = RAISED) 1099 1100 self.status = Scale(self,\ 1101 orient = HORIZONTAL,\ 1102 from_ = 0,\ 1103 to = 100,\ 1104 state = DISABLED,\ 1105 troughcolor = 'red') 1106 1107 self.status.grid(row = 0, column = 0, padx = 3, pady = 3)
1108
1109 - def setValue(self, text):
1110 """Sets the text that will be displayed within the status bar. 1111 1112 @param text: the value to display in the Status Bar. 1113 @type text: string or float 1114 """ 1115 1116 self.status.config(state = NORMAL) 1117 self.status.set(text) 1118 self.status.config(state = DISABLED) 1119 self.status.update()
1120
1121 -def changeMouseCursor(event, cursor):
1122 """Changes the mouse cursor aspect. 1123 1124 @param event: the event triggering the change of mouse cursor. 1125 @type event: a Tkinter.Event object 1126 1127 @param cursor: the Tkinter name of the mouse cursor. 1128 @type cursor: string 1129 """ 1130 1131 event.widget.config(cursor = cursor)
1132
1133 -def loadHelpTree():
1134 """ 1135 This method will load the XML file that stores the pdf and html links for the help file and store its contents 1136 into the _helptree nMOLDYN global variables.. 1137 """ 1138 help = xml.dom.minidom.parse(os.path.join(nmoldyn_package_path, 'Doc', 'UsersGuide', 'Hyperlinks.xml')) 1139 1140 for node in help.getElementsByTagName('Widget'): 1141 nodeName = str(node.attributes['id'].value) 1142 nmoldyn_xml_tree[nodeName] = {'pdf' : None, 'html' : None} 1143 pdf = node.getElementsByTagName('PDF')[0] 1144 html = node.getElementsByTagName('HTML')[0] 1145 nmoldyn_xml_tree[nodeName]['pdf'] = str(pdf.firstChild.data.strip()) 1146 nmoldyn_xml_tree[nodeName]['html'] = str(html.firstChild.data.strip())
1147 1148 nmoldyn_xml_tree = {} 1149 # Load the XML file that stores the PDF and HTML links for the help file. 1150 loadHelpTree() 1151
1152 -def informationAboutWidget(event):
1153 """Checks the label of the Tkinter LabelFrame of a combo widget and displays the corresponding informations 1154 documented in nMOLDYN users guide. 1155 1156 @param event: the event triggering the request for information about the combo widget. 1157 @type event: a Tkinter.Event object 1158 """ 1159 1160 tagName = event.widget.nametowidget(event.widget.winfo_parent()).tagName 1161 1162 if tags.has_key(tagName): 1163 if PREFERENCES.documentation_style.lower() == 'html': 1164 url = os.path.join(nmoldyn_package_path, 'Doc', 'UsersGuide', 'HTML', tags[tagName]['html']) 1165 1166 top = Toplevel() 1167 top.title('Information') 1168 1169 top.wm_minsize(400, 200) 1170 1171 viewer = tkHTMLViewer(top) 1172 viewer.display(url) 1173 1174 top.wait_visibility() 1175 top.grab_set() 1176 top.focus_set() 1177 1178 top.wait_window(top) 1179 1180 elif PREFERENCES.documentation_style.lower() == 'pdf': 1181 # The name of the users guide pdf file. 1182 pdfFile = os.path.join(nmoldyn_package_path, 'GUI', 'Documentation', 'UsersGuide', 'PDF', 'nMOLDYN_ug.pdf') 1183 1184 if sys.platform == 'win32': 1185 try: 1186 subprocess.call([PREFERENCES.acroread_path, '/a nameddest=%s' % tags[tagName]['pdf'], pdfFile]) 1187 except: 1188 os.startfile(pdfFile) 1189 1190 elif sys.platform == 'darwin': 1191 try: 1192 os.system('osascript -e \'tell application "Adobe Reader"\nopen "%s" options "nameddest=%s"\nend tell\'' % (pdfFile, tags[tagName]['pdf'])) 1193 except: 1194 subprocess.call(['open', pdfFile]) 1195 1196 else: 1197 try: 1198 subprocess.call([PREFERENCES.acroread_path, '/a nameddest=%s' % tags[tagName]['pdf'], pdfFile]) 1199 except: 1200 LogMessage('warning','Unable to read the file %s\nwith the acrobat reader located in %s.' % (pdfFile, PREFERENCES.acroread_path),['gui']) 1201 pass 1202 else: 1203 return 1204 1205 else: 1206 tkMessageBox.showinfo("nMOLDYN help", "Not documented.")
1207