Package topo :: Package tkgui
[hide private]
[frames] | no frames]

Source Code for Package topo.tkgui

  1  """ 
  2  Tk-based graphical user interface (GUI). 
  3   
  4  This package implements a Topographica GUI based on the Tk toolkit, 
  5  through the Tkinter interface to Python.  The rest of Topographica 
  6  does not depend on this package or any module in it, and thus other 
  7  GUIs or other types of interfaces can also be used. 
  8   
  9  $Id: __init__.py 9257 2008-09-20 16:41:12Z ceball $ 
 10  """ 
 11  __version__='$Revision: 9257 $' 
 12   
 13  import sys 
 14  import os 
 15  import platform 
 16  import Tkinter 
 17   
 18  import topo 
 19   
 20  from topoconsole import TopoConsole,ControllableMenu 
 21   
 22  #### notes about tkgui #### 
 23  # 
 24  ## Geometry management 
 25  # In several places we use pack() when grid() would probably be 
 26  # simpler. Check you know which fits a task better rather than copying 
 27  # existing code. 
 28  # 
 29  ## Dialogs 
 30  # Don't know how to theme them (can't make them inherit from 
 31  # our own class, for instance). Consider making our own dialog 
 32  # boxes (subclass of Tkguiwindow) using transient and grab_set: 
 33  # http://thread.gmane.org/gmane.comp.python.tkinter/657/focus=659 
 34  # 
 35  ## Mainloop 
 36  # Because we don't call mainloop(), it's necessary to call 
 37  # update() or update_idletasks() sometimes. Also, I think that sometimes 
 38  # current graphics do not update properly (but I'm not sure - I don't 
 39  # have a specific example yet). Need to clean up all the scattered 
 40  # update() and update_idletasks()... 
 41  # 
 42  ## Window or Frame? 
 43  # Maybe one day everything (PlotGroupPanels, ParametersFrameWithApplys, 
 44  # ModelEditor, ...) will be Frames inside one master window (for 
 45  # e.g. a matlab-like workspace).  Nobody's been worrying too much 
 46  # about whether something's a Frame or a window when they've been 
 47  # implementing things, so 'close' buttons, title methods, and so on 
 48  # are a bit of a mix. This needs to be cleaned up when we have a 
 49  # final window organization method in mind. 
 50   
 51   
 52  # When not using the GUI, Topographica does not ordinarily import any of 
 53  # the classes in the separate Topographica packages. For example, none 
 54  # of the pattern types in topo.patterns is imported in Topographica by 
 55  # default.  But for the GUI, we want all such things to be available 
 56  # as lists from which the user can select.  To do this, we import all 
 57  # pattern types and other such classes here. User-defined classes will 
 58  # also appear in the GUI menus if they are derived from any class 
 59  # derived from the one specified in each widget, and imported before 
 60  # the relevant GUI window starts. 
 61  from topo.coordmapper import * 
 62  from topo.ep import * 
 63  from topo.learningfn import * 
 64  from topo.outputfn import * 
 65  from topo.pattern import * 
 66  from topo.projection import * 
 67  from topo.responsefn import * 
 68  from topo.sheet import * 
 69   
 70   
 71   
 72  ########## 
 73  ### Which os is being used (for gui purposes)? 
 74  # 
 75  # system_plaform can be: 
 76  # "linux" 
 77  # "mac" 
 78  # "win" 
 79  # "unknown" 
 80  # 
 81  # If you are programming tkgui and need to do something special 
 82  # for some other platform (or to further distinguish the above 
 83  # platforms), please modify this code. 
 84  # 
 85  # Right now tkgui only needs to detect if the platform is linux (do I 
 86  # mean any kind of non-OS X unix*?) or mac, because there is some 
 87  # special-purpose code for both those two: the mac code below, and the 
 88  # menu-activating code in topoconsole.  We might have some Windows- 
 89  # specific code for the window icons later on, too. 
 90  # * actually it's the window manager that's important, right? 
 91  # Does tkinter/tk itself give any useful information? 
 92  # What about root.tk.call("tk","windowingsystem")? 
 93   
 94  system_platform = 'unknown' 
 95  if platform.system()=='Linux': 
 96      system_platform = 'linux' 
 97  elif platform.system()=='Darwin' or platform.mac_ver()[0]: 
 98      system_platform = 'mac' 
 99  elif platform.system()=='Windows': 
100      system_platform = 'win' 
101  ########## 
102   
103   
104   
105  # 
106  # Define up the right click (context menu) events. These variables can 
107  # be appended or overridden in .topographicarc, if the user has some 
108  # crazy input device. 
109  # 
110   
111  if system_platform=='mac': 
112      # if it's on the mac, these are the context-menu events 
113      right_click_events = ['<Button-2>','<Control-Button-1>'] 
114      right_click_release_events = ['ButtonRelease-2', 'Control-ButtonRelease-1'] 
115  else: 
116      # everywhere else (I think) it's Button-3 
117      right_click_events = ['<Button-3>'] 
118      right_click_release_events = ['ButtonRelease-2'] 
119       
120   
121  global TK_SUPPORTS_DOCK 
122  TK_SUPPORTS_DOCK = True 
123   
124   
125  # CEBALERT: this function needs some cleaning up. 
126  # Some stuff should be moved out to topo.param.tk, 
127  # which could also make this file much simpler. 
128   
129  # gets set to the TopoConsole instance created by start. 
130  console = None 
131 -def start(mainloop=False,banner=True,root=None,console_has_console=False):
132 """ 133 Start Tk and read in an options_database file (if present), then 134 open a TopoConsole. 135 136 Does nothing if the method has previously been called (i.e. the 137 module-level console variable is not None). 138 139 mainloop: If True, then the command-line is frozen while the GUI 140 is open. If False, then commands can be entered at the command-line 141 even while the GUI is operational. Default is False. 142 """ 143 global console 144 145 ### Return immediately if console already set 146 # (console itself might have been destroyed but we still want to 147 # quit this function before starting another Tk instance, etc) 148 if console is not None: return 149 150 if banner: print 'Launching GUI' 151 152 # Creating an initial Tk() instance and then withdrawing the 153 # window is a common technique. Instead of doing this, having 154 # TopoConsole itself be a subclass of Tk would make sense - since 155 # it is the main application window - but then we could not have a 156 # hierarchy in which all windows are given some common properties. 157 if root is None: 158 root = Tkinter.Tk() 159 root.withdraw() 160 161 if Tkinter.TkVersion < 8.5: 162 root.tk.call("package","require","tile") 163 164 # allow tcl/tk to find extras on special platforms 165 import topo.misc.filepath 166 if system_platform=='mac': 167 pack_path = os.path.join(topo.misc.filepath.application_path, 168 "lib") 169 root.tk.call("lappend","auto_path",pack_path) 170 elif system_platform=='win': 171 # for win/msys; win/bin has packages put in its tcl dir 172 pack_paths = [os.path.join(topo.misc.filepath.application_path, 173 "Lib"), 174 os.path.join(topo.misc.filepath.application_path, 175 "share")] 176 177 for path in pack_paths: 178 root.tk.call("lappend","auto_path",path) 179 180 181 182 # tcl equivalent of 'if not hasattr(wm,forget)' would be better 183 if system_platform=='mac' or Tkinter.TkVersion<8.5: 184 global TK_SUPPORTS_DOCK 185 TK_SUPPORTS_DOCK=False 186 187 root.menubar = ControllableMenu(root) 188 root.configure(menu=root.menubar) 189 190 # default,clam,alt,classic 191 root.tk.call("ttk::style","theme","use","classic") 192 193 # Try to read in options from an options_database file 194 # (see http://www.itworld.com/AppDev/1243/UIR000616regex/ 195 # or p. 49 Grayson) 196 try: 197 options_database = os.path.join(sys.path[0],"topo","tkgui","options_database") 198 root.option_readfile(options_database) 199 print "Read options database from",options_database 200 except Tkinter.TclError: 201 pass 202 203 # CEBALERT: console_has_console is a temporary hack 204 topoconsole = TopoConsole(root,console=console_has_console) 205 console = topoconsole 206 207 # Provide a way for other code to access the GUI when necessary 208 # CEBALERT: why is this import necessary? Need to cleanup this method. 209 import topo 210 topo.guimain=console 211 212 213 # This alows context menus to work on the Mac. Widget code should bind 214 # contextual menus to the virtual event <<right-click>>, not 215 # <Button-3>. 216 topoconsole.event_add('<<right-click>>',*right_click_events) 217 topoconsole.event_add('<<right-click-release>>',*right_click_release_events) 218 219 220 # GUI/threads: 221 # http://thread.gmane.org/gmane.comp.python.scientific.user/4153 222 # (inc. ipython info) 223 # (Also http://mail.python.org/pipermail/python-list/2000-January/021250.html) 224 225 # mainloop() freezes the commandline until the GUI window exits. 226 # Without this line the command-line remains responsive. 227 if mainloop: root.mainloop() 228 229 return root
230 231 232 233 234 235 ####################### 236 237 if __name__ == '__main__': 238 start(mainloop=True) 239