Package pyraf :: Module msgiobuffer
[hide private]
[frames] | no frames]

Source Code for Module pyraf.msgiobuffer

  1  """module 'msgiobuffer.py' -- module containing the MsgIOBuffer class.  This 
  2     class creates a scrolling canvas composed of a message box and an I/O 
  3     frame.  The message box contains the history of I/O messages; the I/O 
  4     frame contains the latest I/O from the interactive program. 
  5   
  6  M.D. De La Pena, 2000 June 28 
  7  $Id: msgiobuffer.py 1187 2010-04-22 13:32:44Z sontag $ 
  8  """ 
  9  from __future__ import division # confidence high 
 10   
 11  # System level modules 
 12  from Tkinter import * 
 13  import string 
 14   
15 -class MsgIOBuffer(Frame):
16 17 """MsgIOBuffer class""" 18
19 - def __init__(self, parent, width = 100, viewHeight = None, 20 text = ""):
21 22 """Constructor for the MsgIOBuffer class""" 23 24 Frame.__init__(self) 25 26 # Initialize class attributes 27 self.messageText = "" 28 self.currentText = text 29 self.minHgt = 25 # try 65 with Tk8.5 on OSX 30 self.viewHeight = viewHeight 31 self.entrySetting = StringVar() 32 self.entrySetting.set("") 33 self.entryValue = self.entrySetting.get() 34 35 self.waitFlag = BooleanVar() 36 self.waitFlag.set(TRUE) 37 38 # Set up the frame to hold the message and the I/O 39 self.parent = parent 40 self.msgIO = Frame(self.parent, bd = 2, relief = FLAT, 41 takefocus = FALSE) 42 43 # Overlay a canvas on the frame 44 self.msgIO.canvas = Canvas(self.msgIO, 45 takefocus = FALSE, 46 highlightthickness = 0) 47 48 # Attach a vertical scrollbar to the canvas 49 self.msgIO.vscroll = Scrollbar(self.msgIO, 50 orient = VERTICAL, 51 width = 11, 52 relief = SUNKEN, 53 activerelief = RAISED, 54 takefocus = FALSE) 55 self.msgIO.canvas['yscrollcommand'] = self.msgIO.vscroll.set 56 self.msgIO.vscroll['command'] = self.msgIO.canvas.yview 57 self.msgIO.vscroll.pack(side = RIGHT, fill = Y) 58 59 # Pack the canvas 60 self.msgIO.canvas.pack(side = LEFT, fill = X, expand = TRUE, padx = 4) 61 62 ### Do not pack the frame here. Do it in the application. ### 63 #self.msgIO.pack(side = TOP, fill = X, expand = TRUE) 64 65 # Define a frame that will sit on the canvas 66 # This frame will hold a message box and a small I/O frame 67 self.msgIO.canvas.f = Frame(self.msgIO.canvas) 68 self.msgIO.canvas.f.pack(fill = X, expand = TRUE) 69 70 # Generate the window for the canvas 71 self.msgIO.canvas.create_window(0, 0, 72 anchor = NW, 73 window = self.msgIO.canvas.f) 74 75 # Define a frame for I/O to be placed on the canvas 76 self.msgIO.canvas.f.iomb = Frame(self.msgIO.canvas.f, 77 relief = FLAT, 78 bd = 0) 79 80 # Frame may contain message and a label, or message, label and entry. 81 self.msgIO.canvas.f.iomb.label = Label(self.msgIO.canvas.f.iomb, 82 text = self.currentText, 83 bd = 5, 84 takefocus = FALSE) 85 86 self.msgIO.canvas.f.iomb.entry = Entry(self.msgIO.canvas.f.iomb, 87 highlightthickness = 0, 88 bg = "#d9d9d9", 89 relief = FLAT, 90 textvariable = self.entrySetting, 91 state = DISABLED, 92 insertwidth = 2, 93 takefocus = FALSE) 94 95 # Bind the carriage return to the entry 96 self.msgIO.canvas.f.iomb.entry.bind('<Return>', self.__getEntryValue) 97 98 # Define a message box to be placed in the frame 99 self.msgIO.canvas.f.iomb.msg = Message(self.msgIO.canvas.f.iomb, 100 bd = 0, 101 relief = FLAT, 102 text = self.messageText, 103 anchor = SW, 104 width = width, 105 takefocus = FALSE) 106 107 # Pack the widgets in the frame 108 self.msgIO.canvas.f.iomb.msg.pack(side = TOP, 109 fill = X, 110 expand = TRUE) 111 self.msgIO.canvas.f.iomb.label.pack(side = LEFT) 112 self.msgIO.canvas.f.iomb.entry.pack(side = LEFT, 113 fill = X, 114 expand = TRUE) 115 self.msgIO.canvas.f.iomb.pack(side = TOP, 116 fill = X, 117 expand = TRUE) 118 119 # The full scrolling region is the width of the parent and 120 # the height of the label/entry (25) and the message box (18) 121 # combined. Hardcoded to avoid too much updating which causes 122 # redraws in PyRAF. 123 scrollHgt = 43 124 self.msgIO.canvas.itemconfigure(1, height = scrollHgt) 125 self.msgIO.canvas.configure(scrollregion = (0, 0, 0, scrollHgt)) 126 127 # The displayed portion of the window on the canvas is primarily 128 # the label/entry region. 129 if (self.viewHeight == None or self.viewHeight < self.minHgt): 130 self.msgIO.canvas.configure(height = self.minHgt) 131 else: 132 self.msgIO.canvas.configure(height = self.viewHeight) 133 134 # View is to show the information just moved into the message area 135 self.msgIO.canvas.yview_moveto(1)
136 137
138 - def updateIO(self, text = ""):
139 140 """Method to update the I/O portion of the scrolling canvas""" 141 142 # Move the current contents of the I/O frame to the message box 143 self.__updateMsg(self.currentText) 144 145 # Update the class variable with the latest text 146 self.currentText = text 147 148 # Now reconfigure the I/O frame 149 self.msgIO.canvas.f.iomb.label.configure(text = text)
150 151
152 - def readline(self):
153 154 """Method to set focus to the Entry widget and XXX""" 155 156 self.__enableEntry() 157 self.msgIO.canvas.f.iomb.entry.wait_variable(self.waitFlag) 158 self.waitFlag.set(TRUE) 159 160 # Important to have the "\n" on the returned value 161 return (self.entryValue + "\n")
162 163
164 - def __getEntryValue(self, event = None):
165 166 """Private method to obtain any value entered in the Entry""" 167 168 self.entryValue = self.entrySetting.get() 169 self.msgIO.canvas.f.iomb.entry.delete(0, END) 170 171 # Combine any label value and the entry value in order 172 # to update the current text 173 self.currentText = self.currentText + " " + self.entryValue 174 175 # Disable the entry 176 self.msgIO.canvas.f.iomb.entry.configure(state = DISABLED) 177 self.waitFlag.set(FALSE) 178 if self.lastFocus: 179 self.lastFocus.focus_set()
180 181
182 - def __enableEntry(self):
183 184 """Private method to put the Entry into a normal state for input.""" 185 186 # Input is requested, so enable the entry box 187 f = self.focus_displayof() 188 if f: 189 self.lastFocus = f.focus_lastfor() 190 else: 191 self.lastFocus = None 192 self.msgIO.canvas.f.iomb.entry.configure(state = NORMAL) 193 self.msgIO.canvas.f.iomb.entry.focus_set()
194 195
196 - def __updateMsg(self, text = ""):
197 198 """Private method to update the message box of the scrolling canvas.""" 199 200 # Ensure there is a new line 201 text = "\n" + text 202 203 # Append the new text to the previous message text 204 self.messageText = self.messageText + text 205 self.msgIO.canvas.f.iomb.msg.configure(text = self.messageText) 206 self.msgIO.canvas.f.update_idletasks() 207 208 # Reconfigure the canvas size/scrollregion based upon the message box 209 mbHgt = self.msgIO.canvas.f.iomb.msg.winfo_height() 210 scrollHgt = mbHgt + self.minHgt 211 self.msgIO.canvas.itemconfigure(1, height = scrollHgt) 212 self.msgIO.canvas.configure(scrollregion = (0, 0, 0, scrollHgt)) 213 self.msgIO.canvas.yview_moveto(1)
214 215 216 217 # Test the MsgIOBuffer class 218 if __name__ == '__main__': 219 220 width = 500 221 height = 300 222 vheight = 50 223 text = "Tiptop" 224 225 top = Toplevel() 226 f = Frame(top, width = width, height = height, bg = "red") 227 m = MsgIOBuffer(top, width, vheight, text) 228 m.msgIO.pack(side=BOTTOM, fill = X) 229 f.pack(side = TOP, fill = BOTH, expand = TRUE) 230 for i in range(10): 231 t = "Text " + str(i) 232 m.updateIO(t) 233 m.updateIO("The quick brown fox jumps over the lazy dog with ease.") 234 m.updateIO("What is your quest?") 235 #inputValue = m.readline() 236 #print "inputValue = ", inputValue 237 238 top.mainloop() 239