def initUI(self): self.parent.title("Rename file") self.pack(fill=BOTH, expand=1) originLabel = Label(self, text="File: " + self.filename) originLabel.grid(row=0, column=0, columnspan=2) renameLabel = Label(self, text="Rename to:") renameLabel.grid(row=1, column=0, columnspan=2) self.newName = StringVar() self.newName.set(self.filename) newName = Entry(self, textvariable=self.newName, width=80) endpos = self.filename.rfind('.') newName.selection_range(0, endpos if endpos > 0 else END) newName.grid(row=2, column=0, columnspan=2) newName.bind("<Return>", lambda event: self.doRename()) newName.bind("<Escape>", lambda event: self.parent.destroy()) newName.focus_set() okButton = Button(self, text="OK", command=self.doRename) okButton.grid(row=3, column=0) cancelButton = Button(self, text="Cancel", command=self.parent.destroy) cancelButton.grid(row=3, column=1)
def initUI(self): self.parent.title("Rename file") self.pack(fill=BOTH, expand=1) originLabel = Label(self, text="File: " + self.filename) originLabel.grid(row=0, column=0, columnspan=2) renameLabel = Label(self, text="Rename to:") renameLabel.grid(row=1, column=0, columnspan=2) self.newName = StringVar() self.newName.set(self.filename) newName = Entry(self, textvariable=self.newName, width=80) endpos = self.filename.rfind('.') newName.selection_range(0, endpos if endpos > 0 else END) newName.grid(row=2, column=0, columnspan=2) newName.bind("<Return>", lambda event: self.doRename()) newName.bind("<Escape>", lambda event: self.parent.destroy()) newName.focus_set() okButton = Button(self, text="OK", command=self.doRename) okButton.grid(row=3, column=0) cancelButton = Button(self, text="Cancel", command=self.parent.destroy) cancelButton.grid(row=3, column=1)
def __init__(self, parent, config): Frame.__init__(self, parent) self.loggedIn = None self.config = config self.pack(fill=BOTH, expand=1, padx=10, pady=10) self.bind("<Return>", self.login) self.message = StringVar() l = Label(self, textvariable=self.message) l.pack() l = Label(self, text="Email:") l.pack(anchor=W, pady=(10, 0)) self.email = StringVar() self.email.set(self.config.get("credentials", "email")) e = Entry(self, textvariable=self.email, width=40, font=("Helvetica", 16)) e.pack(fill=X) e.focus_set() e.icursor(END) e.selection_range(0, END) l = Label(self, text="Password:"******"credentials", "password")) e = Entry(self, show="*", textvariable=self.password, font=("Helvetica", 16)) e.pack(fill=X) self.submit = Button(self, text="Login", command=self.login) self.submit.pack(ipady=10, pady=10, fill=X)
class BrakeFrame(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self.initialize() def initialize(self): self.grid() self.entryVariable = StringVar() self.entry = Entry(self, textvariable=self.entryVariable) self.entry.grid(column=0,row=0,sticky='EW') self.entry.bind("<Return>", self.OnPressEnter) button = Button(self,text="Set Brake", command=self.OnButtonClick) button.grid(column=1,row=0) self.labelVariable = StringVar() label = Label(self,textvariable=self.labelVariable, anchor="w",fg="white",bg="red") label.grid(column=0,row=1,columnspan=1,sticky='EW') self.labelVariable.set("Start..") onButton = Button(self,text="Brake On", command=self.BrakeOn) onButton.grid(column=0,row=3) offButton = Button(self,text="Brake Off", command=self.BrakeOff) offButton.grid(column=1,row=3) self.brakeVariable = StringVar() brakeState = Label(self,textvariable=self.brakeVariable, anchor="w",fg="white",bg="red") brakeState.grid(column=0,row=2,columnspan=1,sticky='EW') self.brakeVariable.set("Start..") self.grid_columnconfigure(0,weight=1) self.update() #self.geometry(self.geometry()) # caused busy wait? self.entry.focus_set() #self.entry.selection_range(0, Tkinter.END) def OnButtonClick(self): brakePos = int(self.entryVariable.get()) brake.SetPositionMM(brakePos) self.labelVariable.set("Brake set: " + str(brakePos) ) self.entry.focus_set() self.entry.selection_range(0, END) def OnPressEnter(self,event): brakePos = int(self.entryVariable.get()) brake.SetPositionMM(brakePos) self.labelVariable.set("Brake set: " + str(brakePos) ) self.entry.focus_set() self.entry.selection_range(0, END) def BrakeOn(self): self.brakeVariable.set("Brake: ON") brake.SetFullOn() def BrakeOff(self): self.brakeVariable.set("Brake: OFF") brake.SetOff()
class PIDTune(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self.initialize() def initialize(self): self.grid() ##PID TUNING self.KpVar = StringVar() self.KiVar = StringVar() self.KdVar = StringVar() self.KscaleVar = StringVar() self.Kp = Entry(self, textvariable=self.KpVar) self.Ki = Entry(self, textvariable=self.KiVar) self.Kd = Entry(self, textvariable=self.KdVar) self.Kscale = Entry(self, textvariable=self.KscaleVar) self.Kp.grid(column=0,row=2,sticky='EW') self.Ki.grid(column=0,row=3,sticky='EW') self.Kd.grid(column=0,row=4,sticky='EW') self.Kscale.grid(column=0,row=5,sticky='EW') self.Kp.bind("<Return>", self.OnKp) self.Ki.bind("<Return>", self.OnKi) self.Kd.bind("<Return>", self.OnKd) self.Kscale.bind("<Return>", self.OnKscale) self.KpLabVar = StringVar() self.KiLabVar = StringVar() self.KdLabVar = StringVar() self.KscaleLabVar = StringVar() kpLabel = Label(self,textvariable=self.KpLabVar, anchor="w",fg="white",bg="blue") kpLabel.grid(column=1, row=2,columnspan=1,sticky='EW') self.KpLabVar.set("Kp") kiLabel = Label(self,textvariable=self.KiLabVar, anchor="w",fg="white",bg="blue") kiLabel.grid(column=1, row=3,columnspan=1,sticky='EW') self.KiLabVar.set("Ki") kdLabel = Label(self,textvariable=self.KdLabVar, anchor="w",fg="white",bg="blue") kdLabel.grid(column=1, row=4,columnspan=1,sticky='EW') self.KdLabVar.set("Kd") kscaleLabel= Label(self,textvariable=self.KscaleLabVar, anchor="w",fg="white",bg="blue") kscaleLabel.grid(column=1, row=5,columnspan=1,sticky='EW') self.KscaleLabVar.set("Kscale") def OnKp(self, event): kp = int(self.KpVar.get()) if (speed.SetKp(kp)): self.KpLabVar.set("Kp: " + str(kp)) self.Kp.focus_set() self.Kp.selection_range(0, END) def OnKi(self, event): ki = int(self.KiVar.get()) if (speed.SetKi(ki)): self.KiLabVar.set("Ki: " + str(ki)) self.Ki.focus_set() self.Ki.selection_range(0, END) def OnKd(self, event): kd = int(self.KdVar.get()) if (speed.SetKd(kd)): self.KdLabVar.set("Kd: " + str(kd)) self.Kd.focus_set() self.Kd.selection_range(0, END) def OnKscale(self, event): ks = int(self.KscaleVar.get()) if (speed.SetKscale(ks)): self.KscaleLabVar.set("Ks: " + str(ks)) self.Kscale.focus_set() self.Kscale.selection_range(0, END)
class TreeNode: def __init__(self, canvas, parent, item): self.canvas = canvas self.parent = parent self.item = item self.state = 'collapsed' self.selected = False self.children = [] self.x = self.y = None self.iconimages = {} # cache of PhotoImage instances for icons def destroy(self): for c in self.children[:]: self.children.remove(c) c.destroy() self.parent = None def geticonimage(self, name): try: return self.iconimages[name] except KeyError: pass file, ext = os.path.splitext(name) ext = ext or ".gif" fullname = os.path.join(ICONDIR, file + ext) image = PhotoImage(master=self.canvas, file=fullname) self.iconimages[name] = image return image def select(self, event=None): if self.selected: return self.deselectall() self.selected = True self.canvas.delete(self.image_id) self.drawicon() self.drawtext() def deselect(self, event=None): if not self.selected: return self.selected = False self.canvas.delete(self.image_id) self.drawicon() self.drawtext() def deselectall(self): if self.parent: self.parent.deselectall() else: self.deselecttree() def deselecttree(self): if self.selected: self.deselect() for child in self.children: child.deselecttree() def flip(self, event=None): if self.state == 'expanded': self.collapse() else: self.expand() self.item.OnDoubleClick() return "break" def expand(self, event=None): if not self.item._IsExpandable(): return if self.state != 'expanded': self.state = 'expanded' self.update() self.view() def collapse(self, event=None): if self.state != 'collapsed': self.state = 'collapsed' self.update() def view(self): top = self.y - 2 bottom = self.lastvisiblechild().y + 17 height = bottom - top visible_top = self.canvas.canvasy(0) visible_height = self.canvas.winfo_height() visible_bottom = self.canvas.canvasy(visible_height) if visible_top <= top and bottom <= visible_bottom: return x0, y0, x1, y1 = self.canvas._getints(self.canvas['scrollregion']) if top >= visible_top and height <= visible_height: fraction = top + height - visible_height else: fraction = top fraction = float(fraction) / y1 self.canvas.yview_moveto(fraction) def lastvisiblechild(self): if self.children and self.state == 'expanded': return self.children[-1].lastvisiblechild() else: return self def update(self): if self.parent: self.parent.update() else: oldcursor = self.canvas['cursor'] self.canvas['cursor'] = "watch" self.canvas.update() self.canvas.delete(ALL) # XXX could be more subtle self.draw(7, 2) x0, y0, x1, y1 = self.canvas.bbox(ALL) self.canvas.configure(scrollregion=(0, 0, x1, y1)) self.canvas['cursor'] = oldcursor def draw(self, x, y): # XXX This hard-codes too many geometry constants! self.x, self.y = x, y self.drawicon() self.drawtext() if self.state != 'expanded': return y + 17 # draw children if not self.children: sublist = self.item._GetSubList() if not sublist: # _IsExpandable() was mistaken; that's allowed return y + 17 for item in sublist: child = self.__class__(self.canvas, self, item) self.children.append(child) cx = x + 20 cy = y + 17 cylast = 0 for child in self.children: cylast = cy self.canvas.create_line(x + 9, cy + 7, cx, cy + 7, fill="gray50") cy = child.draw(cx, cy) if child.item._IsExpandable(): if child.state == 'expanded': iconname = "minusnode" callback = child.collapse else: iconname = "plusnode" callback = child.expand image = self.geticonimage(iconname) id = self.canvas.create_image(x + 9, cylast + 7, image=image) # XXX This leaks bindings until canvas is deleted: self.canvas.tag_bind(id, "<1>", callback) self.canvas.tag_bind(id, "<Double-1>", lambda x: None) id = self.canvas.create_line( x + 9, y + 10, x + 9, cylast + 7, ##stipple="gray50", # XXX Seems broken in Tk 8.0.x fill="gray50") self.canvas.tag_lower(id) # XXX .lower(id) before Python 1.5.2 return cy def drawicon(self): if self.selected: imagename = (self.item.GetSelectedIconName() or self.item.GetIconName() or "openfolder") else: imagename = self.item.GetIconName() or "folder" image = self.geticonimage(imagename) id = self.canvas.create_image(self.x, self.y, anchor="nw", image=image) self.image_id = id self.canvas.tag_bind(id, "<1>", self.select) self.canvas.tag_bind(id, "<Double-1>", self.flip) def drawtext(self): textx = self.x + 20 - 1 texty = self.y - 1 labeltext = self.item.GetLabelText() if labeltext: id = self.canvas.create_text(textx, texty, anchor="nw", text=labeltext) self.canvas.tag_bind(id, "<1>", self.select) self.canvas.tag_bind(id, "<Double-1>", self.flip) x0, y0, x1, y1 = self.canvas.bbox(id) textx = max(x1, 200) + 10 text = self.item.GetText() or "<no text>" try: self.entry except AttributeError: pass else: self.edit_finish() try: label = self.label except AttributeError: # padding carefully selected (on Windows) to match Entry widget: self.label = Label(self.canvas, text=text) if not TTK: self.label.configure(bd=0, padx=2, pady=2) theme = idleConf.GetOption('main', 'Theme', 'name') if self.selected: self.label.configure(idleConf.GetHighlight(theme, 'hilite')) else: self.label.configure(idleConf.GetHighlight(theme, 'normal')) id = self.canvas.create_window(textx, texty, anchor="nw", window=self.label) self.label.bind("<1>", self.select_or_edit) self.label.bind("<Double-1>", self.flip) self.text_id = id def select_or_edit(self, event=None): if self.selected and self.item.IsEditable(): self.edit(event) else: self.select(event) def edit(self, event=None): self.entry = Entry(self.label, bd=0, highlightthickness=1, width=0) self.entry.insert(0, self.label['text']) self.entry.selection_range(0, END) self.entry.pack(ipadx=5) self.entry.focus_set() self.entry.bind("<Return>", self.edit_finish) self.entry.bind("<Escape>", self.edit_cancel) def edit_finish(self, event=None): try: entry = self.entry del self.entry except AttributeError: return text = entry.get() entry.destroy() if text and text != self.item.GetText(): self.item.SetText(text) text = self.item.GetText() self.label['text'] = text self.drawtext() self.canvas.focus_set() def edit_cancel(self, event=None): try: entry = self.entry del self.entry except AttributeError: return entry.destroy() self.drawtext() self.canvas.focus_set()
class TreeNode: def __init__(self, canvas, parent, item): self.canvas = canvas self.parent = parent self.item = item self.state = 'collapsed' self.selected = False self.children = [] self.x = self.y = None self.iconimages = {} # cache of PhotoImage instances for icons def destroy(self): for c in self.children[:]: self.children.remove(c) c.destroy() self.parent = None def geticonimage(self, name): try: return self.iconimages[name] except KeyError: pass file, ext = os.path.splitext(name) ext = ext or ".gif" fullname = os.path.join(ICONDIR, file + ext) image = PhotoImage(master=self.canvas, file=fullname) self.iconimages[name] = image return image def select(self, event=None): if self.selected: return self.deselectall() self.selected = True self.canvas.delete(self.image_id) self.drawicon() self.drawtext() def deselect(self, event=None): if not self.selected: return self.selected = False self.canvas.delete(self.image_id) self.drawicon() self.drawtext() def deselectall(self): if self.parent: self.parent.deselectall() else: self.deselecttree() def deselecttree(self): if self.selected: self.deselect() for child in self.children: child.deselecttree() def flip(self, event=None): if self.state == 'expanded': self.collapse() else: self.expand() self.item.OnDoubleClick() return "break" def expand(self, event=None): if not self.item._IsExpandable(): return if self.state != 'expanded': self.state = 'expanded' self.update() self.view() def collapse(self, event=None): if self.state != 'collapsed': self.state = 'collapsed' self.update() def view(self): top = self.y - 2 bottom = self.lastvisiblechild().y + 17 height = bottom - top visible_top = self.canvas.canvasy(0) visible_height = self.canvas.winfo_height() visible_bottom = self.canvas.canvasy(visible_height) if visible_top <= top and bottom <= visible_bottom: return x0, y0, x1, y1 = self.canvas._getints(self.canvas['scrollregion']) if top >= visible_top and height <= visible_height: fraction = top + height - visible_height else: fraction = top fraction = float(fraction) / y1 self.canvas.yview_moveto(fraction) def lastvisiblechild(self): if self.children and self.state == 'expanded': return self.children[-1].lastvisiblechild() else: return self def update(self): if self.parent: self.parent.update() else: oldcursor = self.canvas['cursor'] self.canvas['cursor'] = "watch" self.canvas.update() self.canvas.delete(ALL) # XXX could be more subtle self.draw(7, 2) x0, y0, x1, y1 = self.canvas.bbox(ALL) self.canvas.configure(scrollregion=(0, 0, x1, y1)) self.canvas['cursor'] = oldcursor def draw(self, x, y): # XXX This hard-codes too many geometry constants! dy = 20 self.x, self.y = x, y self.drawicon() self.drawtext() if self.state != 'expanded': return y + dy # draw children if not self.children: sublist = self.item._GetSubList() if not sublist: # _IsExpandable() was mistaken; that's allowed return y+17 for item in sublist: child = self.__class__(self.canvas, self, item) self.children.append(child) cx = x+20 cy = y + dy cylast = 0 for child in self.children: cylast = cy self.canvas.create_line(x+9, cy+7, cx, cy+7, fill="gray50") cy = child.draw(cx, cy) if child.item._IsExpandable(): if child.state == 'expanded': iconname = "minusnode" callback = child.collapse else: iconname = "plusnode" callback = child.expand image = self.geticonimage(iconname) id = self.canvas.create_image(x+9, cylast+7, image=image) # XXX This leaks bindings until canvas is deleted: self.canvas.tag_bind(id, "<1>", callback) self.canvas.tag_bind(id, "<Double-1>", lambda x: None) id = self.canvas.create_line(x+9, y+10, x+9, cylast+7, ##stipple="gray50", # XXX Seems broken in Tk 8.0.x fill="gray50") self.canvas.tag_lower(id) # XXX .lower(id) before Python 1.5.2 return cy def drawicon(self): if self.selected: imagename = (self.item.GetSelectedIconName() or self.item.GetIconName() or "openfolder") else: imagename = self.item.GetIconName() or "folder" image = self.geticonimage(imagename) id = self.canvas.create_image(self.x, self.y, anchor="nw", image=image) self.image_id = id self.canvas.tag_bind(id, "<1>", self.select) self.canvas.tag_bind(id, "<Double-1>", self.flip) def drawtext(self): textx = self.x+20-1 texty = self.y-4 labeltext = self.item.GetLabelText() if labeltext: id = self.canvas.create_text(textx, texty, anchor="nw", text=labeltext) self.canvas.tag_bind(id, "<1>", self.select) self.canvas.tag_bind(id, "<Double-1>", self.flip) x0, y0, x1, y1 = self.canvas.bbox(id) textx = max(x1, 200) + 10 text = self.item.GetText() or "<no text>" try: self.entry except AttributeError: pass else: self.edit_finish() try: self.label except AttributeError: # padding carefully selected (on Windows) to match Entry widget: self.label = Label(self.canvas, text=text, bd=0, padx=2, pady=2) theme = idleConf.CurrentTheme() if self.selected: self.label.configure(idleConf.GetHighlight(theme, 'hilite')) else: self.label.configure(idleConf.GetHighlight(theme, 'normal')) id = self.canvas.create_window(textx, texty, anchor="nw", window=self.label) self.label.bind("<1>", self.select_or_edit) self.label.bind("<Double-1>", self.flip) self.text_id = id def select_or_edit(self, event=None): if self.selected and self.item.IsEditable(): self.edit(event) else: self.select(event) def edit(self, event=None): self.entry = Entry(self.label, bd=0, highlightthickness=1, width=0) self.entry.insert(0, self.label['text']) self.entry.selection_range(0, END) self.entry.pack(ipadx=5) self.entry.focus_set() self.entry.bind("<Return>", self.edit_finish) self.entry.bind("<Escape>", self.edit_cancel) def edit_finish(self, event=None): try: entry = self.entry del self.entry except AttributeError: return text = entry.get() entry.destroy() if text and text != self.item.GetText(): self.item.SetText(text) text = self.item.GetText() self.label['text'] = text self.drawtext() self.canvas.focus_set() def edit_cancel(self, event=None): try: entry = self.entry del self.entry except AttributeError: return entry.destroy() self.drawtext() self.canvas.focus_set()
class Tk_Table(Frame, object): def __init__(self, master, columns, data=None, command=None, editable=True, sort=True, select_mode=None, autoscroll=True, vscrollbar=True, hscrollbar=False, heading_anchor = CENTER, cell_anchor=W, style=None, scrollbar_background=None, scrollbar_troughcolor=None, height=None, padding=None, adjust_heading_to_content=False, stripped_rows=None, selection_background=None, selection_foreground=None, cell_background=None, cell_foreground=None, cell_font=None, field_background=None, heading_font= None, heading_background=None, heading_foreground=None, cell_pady=2, column_header=True, row_numbers=True, entry_background="#d6d6d6", entry_foreground=None, entry_validatecommand=None, entry_selectbackground="#1BA1E2", entry_selectborderwidth=None, entry_selectforeground=None, entry_font = "TkDefaultFont", rowlabel_anchor=E, rowlabel_minwidth=0, rowlabel_hoverbackground="#FFFFFF",frame_relief=None, frame_borderwidth=None, frame_background=None): frame_kwargs = {} if frame_relief is not None: frame_kwargs["relief"] = frame_relief if frame_borderwidth is not None: frame_kwargs["borderwidth"] = frame_borderwidth if frame_background is not None: frame_kwargs["background"] = frame_background Frame.__init__(self, master, class_="Multicolumn_Listbox", **frame_kwargs) self.grid_rowconfigure(0, weight=1) self.grid_columnconfigure(1, weight=1) self._multicolumn_listbox = Multicolumn_Listbox(self, columns, data=data, command=command, sort=sort, select_mode=select_mode, heading_anchor = heading_anchor, cell_anchor=cell_anchor, style=style, height=height, padding=padding, adjust_heading_to_content=adjust_heading_to_content, stripped_rows=stripped_rows, selection_background=selection_background, selection_foreground=selection_foreground, cell_background=cell_background, cell_foreground=cell_foreground, cell_font=cell_font, field_background=field_background, heading_font=heading_font, heading_background=heading_background, heading_foreground=heading_foreground, cell_pady=cell_pady, headers=column_header) self._multicolumn_listbox.interior.grid(row=0, column=1, sticky= N+E+W+S) self._mousewheel_detection = True if row_numbers: self._row_numbers = Row_Header(self, font=self._multicolumn_listbox.font, row_height=self._multicolumn_listbox.row_height, row_minwidth=rowlabel_minwidth, hover_background = rowlabel_hoverbackground, anchor=rowlabel_anchor, onclick=self._on_click_row_label) self._row_numbers.grid(row=0, column=0, sticky= N+S+E) self._multicolumn_listbox.interior.bind("<Map>", self._place_vertically_row_numbers) else: self._row_numbers = None if editable: self._selected_cell = None self._entry_popup = None self._multicolumn_listbox.interior.bind("<1>", self._edit_cell) def configure(event): """ if self._entry_popup: self._entry_popup.destroy() return """ self._multicolumn_listbox.interior.update_idletasks() self._update_position_of_entry() self._multicolumn_listbox.interior.bind("<Configure>", configure) self._entry_kwargs = entry_kwargs = {} if entry_background is not None: entry_kwargs["background"] = entry_background if entry_foreground is not None: entry_kwargs["foreground"] = entry_foreground if entry_validatecommand is not None: entry_kwargs["validatecommand"] = entry_validatecommand if entry_selectbackground is not None: entry_kwargs["selectbackground"] = entry_selectbackground if entry_selectforeground is not None: entry_kwargs["selectforeground"] = entry_selectforeground if entry_font is not None: entry_kwargs["font"] = entry_font if command is not None: self._command = command self._multicolumn_listbox.interior.bind("<<TreeviewSelect>>", self._on_select) scrollbar_kwargs = {} if scrollbar_background is not None: scrollbar_kwargs["background"] = scrollbar_background if scrollbar_troughcolor is not None: scrollbar_kwargs["throughcolor"] = scrollbar_troughcolor if vscrollbar: if editable: if row_numbers: def yview_command(*args): self._multicolumn_listbox.interior.yview(*args) self._row_numbers.yview(*args) self._update_position_of_entry() else: def yview_command(*args): self._multicolumn_listbox.interior.yview(*args) self._update_position_of_entry() else: if row_numbers: def yview_command(*args): self._multicolumn_listbox.interior.yview(*args) self._row_numbers.yview(*args) else: yview_command = self._multicolumn_listbox.interior.yview self._vbar=Scrollbar(self,takefocus=0, command=yview_command, **scrollbar_kwargs) self._vbar.grid(row=0, column=2, sticky= N+S) def yscrollcommand(first,last): first, last = float(first), float(last) if first <= 0 and last >= 1: if self._mousewheel_detection: if autoscroll: self._vbar.grid_remove() if row_numbers: unbind_function_onMouseWheel(self._multicolumn_listbox.interior) self._mousewheel_detection = False else: if not self._mousewheel_detection: if autoscroll: self._vbar.grid() if row_numbers: bind_function_onMouseWheel(self._row_numbers, "y", binding_widget=self._multicolumn_listbox.interior, unit="pages") self._mousewheel_detection = True self._vbar.set(first, last) if editable: self._update_position_of_entry() self._multicolumn_listbox.interior.config(yscrollcommand=yscrollcommand) if hscrollbar: if editable: def xview_command(*args): self._multicolumn_listbox.interior.xview(*args) self._update_position_of_entry() else: xview_command = self._multicolumn_listbox.interior.xview self._hbar=Scrollbar(self,takefocus=0, command=xview_command, **scrollbar_kwargs) self._hbar.grid(row=1, column=1, sticky= E+W) if autoscroll: if editable: def xscrollcommand(f,l, self=self): make_autoscroll(self._hbar, f, l) self._update_position_of_entry() else: def xscrollcommand(f,l, hbar=self._hbar): make_autoscroll(hbar, f, l) self._multicolumn_listbox.interior.config(xscrollcommand=xscrollcommand) else: self._multicolumn_listbox.interior.config(xscrollcommand=self._hbar.set) def _place_vertically_row_numbers(self, event): self._multicolumn_listbox.interior.unbind("<Map>") item_ID = self._multicolumn_listbox.interior.insert('', 0, values=[""]*self._multicolumn_listbox.number_of_columns) self._multicolumn_listbox.interior.update() x,y,w,h = self._multicolumn_listbox.interior.bbox(item_ID) self._multicolumn_listbox.interior.delete(item_ID) self._row_numbers.grid_configure(pady=(y,0)) def _edit_cell(self, event): '''Executed, when a row is clicked. Opens an entry popup above the cell, so it is possible to select text ''' # close previous popups if self._entry_popup: self._destroy_entry() # what row and column was clicked on item_ID = self._multicolumn_listbox.interior.identify_row(event.y) if not item_ID: return column = self._multicolumn_listbox.interior.identify_column(event.x) if column == "": return # get column position info x,y,width,height = self._multicolumn_listbox.interior.bbox(item_ID, column) # place Entry popup properly column_number = int(column[1:])-1 cell_data = self._multicolumn_listbox.item_ID_to_row_data(item_ID)[column_number] self._entry_popup = Entry(self._multicolumn_listbox.interior, exportselection=True, borderwidth=0, **self._entry_kwargs) self._entry_popup.place(x=x, y=y, width=width, height=height) self._entry_popup.insert(0, cell_data) self._entry_popup.focus_force() self._entry_popup.bind("<Control-a>", lambda event: self._select_all_entry_data) self._entry_popup.bind("<Escape>", lambda event: self._destroy_entry()) self._entry_popup.bind("<FocusOut>", lambda event: self._destroy_entry()) bind_function_onMouseWheel(self._multicolumn_listbox.interior, "y", binding_widget=self._entry_popup, callback=self._update_position_of_entry, unit="pages") if self._row_numbers: bind_function_onMouseWheel(self._row_numbers, "y", binding_widget=self._entry_popup, unit="pages") self._entry_popup.bind("<Return>", self._on_update_cell) self._selected_cell = item_ID, column, column_number def _on_click_row_label(self, index): if self._selected_cell and self._multicolumn_listbox.item_ID(index) == self._selected_cell[0]: self._destroy_entry() self._multicolumn_listbox.toogle_selection(index) def _select_all_entry_data(self): ''' Set selection on the whole text ''' self._entry_popup.selection_range(0, 'end') # returns 'break' to interrupt default key-bindings return 'break' def _destroy_entry(self): self._entry_popup.destroy() self._entry_popup = None self._selected_cell = None def _on_update_cell(self, event): item_ID, column, column_number = self._selected_cell data = self._entry_popup.get() row_data = self._multicolumn_listbox.item_ID_to_row_data(item_ID) row_data[column_number] = data self._multicolumn_listbox.interior.item(item_ID, values=row_data) self._destroy_entry() def _update_position_of_entry(self): if self._selected_cell: bbox = self._multicolumn_listbox.interior.bbox(self._selected_cell[0], self._selected_cell[1]) if bbox == "": self._entry_popup.place_forget() else: x,y,width,height = bbox self._entry_popup.place(x=x, y=y, width=width, height=height) def configure_column(self, index, width=None, minwidth=None, anchor=None, stretch=None): self._multicolumn_listbox.configure_column(self, index, width=None, minwidth=None, anchor=None, stretch=None) def row_data(self, index): return self._multicolumn_listbox.row_data(index) def update_row(self, index, data): self._multicolumn_listbox.update_row(index,data) def delete_row(self, index): self._multicolumn_listbox.delete_row(index) if self._row_numbers: self._row_numbers.pop() def insert_row(self, data, index=None): self._multicolumn_listbox.insert_row(data, index) if self._row_numbers: self._row_numbers.new_label() def column_data(self, index): return self._multicolumn_listbox.column_data(index) def update_column(self, index, data): self._multicolumn_listbox.update_column(index, data) def clear(self): self._multicolumn_listbox.clear() if self._row_numbers: self._row_numbers.delete_labels() def update(self, data): current_number_of_rows = self._multicolumn_listbox.number_of_rows self._multicolumn_listbox.update(data) if self._row_numbers: number_of_rows = len(data) if current_number_of_rows < number_of_rows: for i in range(number_of_rows - current_number_of_rows): self._row_numbers.new_label() else: n_labels = current_number_of_rows - number_of_rows self._row_numbers.pop(n_labels =n_labels) def focus(self, index=None): self._multicolumn_listbox.focus(index) def state(self, state=None): self._multicolumn_listbox.state(state) @property def number_of_rows(self): return self._multicolumn_listbox.number_of_rows @property def number_of_columns(self): return self._multicolumn_listbox.number_of_columns def toogle_selection(self, index): self._multicolumn_listbox.toogle_selection(index) def select_row(self, index): self._multicolumn_listbox.select_row(index) def deselect_row(self, index): self._multicolumn_listbox.deselect_row(index) def deselect_all(self): self._multicolumn_listbox.deselect_all() def set_selection(self, indices): self._multicolumn_listbox.set_selection(indices) @property def selected_rows(self): return self._multicolumn_listbox.selected_rows @property def indices_of_selected_rows(self): return self._multicolumn_listbox.indices_of_selected_rows def delete_all_selected_rows(self): number_of_deleted_rows = self._multicolumn_listbox.delete_all_selected_rows() if self._row_numbers: self._row_numbers.pop(n_labels=number_of_deleted_rows) @property def table_data(self): return self._multicolumn_listbox.table_data @table_data.setter def table_data(self, data): self.update(data) def cell_data(self, row, column): return self._multicolumn_listbox.cell_data(row, column) def update_cell(self, row, column, value): self._multicolumn_listbox.update_cell(row, column, value) def __getitem__(self, index): return self._multicolumn_listbox[index] def __setitem__(self, index, value): self._multicolumn_listbox[index] = value def bind(self, event, handler): self._multicolumn_listbox.bind(event, handler) def sort_by(self, col, descending): self._multicolumn_listbox.sort_by(col, descending)
class MyPoti(Tkinter.Tk): def __init__(self, master): Tkinter.Tk.__init__(self,master) self.master = master self.initialize() def initialize(self): #create canvas with specified size and add w = Canvas(self, width=700, height=600) w.pack() #Declare two lists, one for front labels, anthoer for answer labels self.flabels = [] self.alabels = [] #Define x and y cordinates for lables self.flblx = 280 self.flbly = 40 self.alblx = 380 self.albly = 40 #Dummy list1 self.my_list = [] #Text to set on front lables self.str_label = ['POTI0', 'POTI1','POTI2','POTI3','POTI4'] #Trigger to check if we want to program or pause self.running = True #Define environment varibales for input text fields #We can change/update this during runtime self.entry_pot_var = Tkinter.StringVar() self.entry_res_var = Tkinter.StringVar() #Define text areas for input onr for poti selection and one for resistence value self.entry_pot = Entry(self,textvariable=self.entry_pot_var, validate="focusout") self.entry_res = Entry(self,textvariable=self.entry_res_var, validate="focusout") #Initial text to display on above text fields self.entry_pot_var.set("Enter Pot selection") self.entry_res_var.set("Enter resistor value - 2000 to 100000") #Set pot selection entry as highlighted self.entry_pot.selection_range(0,Tkinter.END) #self.entry_res.selection_range(0,Tkinter.END) #Set keyboard focus on pot text field self.entry_pot.focus_set() #Add pot text field to canvas self.entry_pot.pack() #ToDO #validate input for pot selection #self.entry_pot["validatecommand"] = (self.register(self.check_pot), "%P") #Add resistence text field to canvas self.entry_res.pack() #Create two text on the canvas with x and y coodrinates w.create_window(120, 40, window=self.entry_pot) w.create_window(120, 70,window=self.entry_res) #We declare 5 front lables and add them to canvas with x and y co ordinates for x in range(5): print self.str_label[x] self.label = Label(self, text=self.str_label[x], fg='white', bg='black') self.label.pack() self.flabels.append(self.label) #We declare 5 answer lables and add them to canvas with x and y co ordinates for x in range(5): self.label = Label(self, text='values', fg='white', bg='blue') self.label.pack() self.alabels.append(self.label) #Create front label in canvas for label in self.flabels: w.create_window(self.flblx,self.flbly,window=label) self.flbly = self.flbly + 19 #Create answer label in cavas for label in self.alabels: w.create_window(self.alblx,self.albly,window=label) self.albly = self.albly + 20 ### #Button definitions ### #Start button, and add callback to start_app function when this button is clicked self.start_button = Button(self, text="Set", height=2, width=10, command=self.start_app) self.start_button.pack() #Clear button, and add callback to clear_app function when this button is clicked self.clear_button = Button(self, text="Clear", height=2, width=10, command=self.clear_app, state="disabled") self.clear_button.pack() #Clear button, and add quit function of tkinter master when this button is clicked self.close_button = Button(self, text="Close", height=2, width=10, command=self.quit) self.close_button.pack() #Add buttons to canvas w.create_window(70, 170, window=self.start_button) w.create_window(190, 170, window=self.close_button) w.create_window(310, 170, window=self.clear_button) #Input validation for pot selection text field def check_pot(self, txt): print("POT validate!") #pot = self.entry_pot_var.get() if int(txt): if txt < 0 or txt > 4 : return False else: return True else: print("Not integer") self.entry_pot.focus_set() self.entry_pot.delete(0, END) return False #Input validation for resistence text field def check_res(self): print("Greetings!") def start_app(self): """ Start the application when start button pressed """ #Disable start button after presed global running self.running = True #self.start_button.config(state="disabled") self.clear_button.config(state="normal") print "Starting app!" #call update values function self.update_values() def clear_app(self): """ Clear the answer lable fields """ print "Clear" global running self.running = False self.start_button.config(state="normal") self.clear_button.config(state="disabled") for i in range(5): self.alabels[i].config(text=str("values")) #Clear the text fields and set default vaule self.entry_pot_var.set("Enter Pot selection") self.entry_res_var.set("Enter resistor value - 2000 to 100000") #set keyboard focus self.entry_pot.focus_set() def stop_app(self): """ Stop the app """ print "Stopping" self.quit() def update_values(self): """ Helper function to trigger label values after reading pot and res values """ #if self.running: # self.after(1000, self.update_values) #Read input value given for pot selection text field pot = self.entry_pot.get() ###if pot < 0 or pot > 4 : ### if int(pot) < 0 or int(pot) > 4 : tkMessageBox.showerror("wrong input","wrong input, pot selection must be 0-4, current selection: %s" % pot) return res = self.entry_res.get() #Read input value given for resistence text field res = self.entry_res.get() #call update text value function which converts values and send data to MCP self.update_text_values(pot, res) def update_text_values(self, pot, res): """ Update the answer lables values with resistence """ #resisitor to data conversion byte = 256 local_pot = 100000 local_res = 125 #rw = int(res) * 1000 #rw = int(rw) - int(local_res) #lev = float((rw * byte) / local_pot) #level =round(lev) #level = int(level) #level = int(res) - int(local_res) if float(res): level = float(res) - int(local_res) else: level = int(res) - int(local_res) level = (level * byte) / local_pot level = int(level) print(level) b = 0 if int(pot) == 0: b = "0001" "0001" "{0:08b}".format(level) if int(pot) == 1: b = "0001" "0001" "{0:08b}" '{0:016b}'.format(level) if int(pot) == 2: b = "0001" "0001" "{0:08b}" '{0:032b}'.format(level) if int(pot) == 3: b = "0001" "0001" "{0:08b}" '{0:048b}'.format(level) if int(pot) == 4: b = "0001" "0001" "{0:08b}" '{0:064b}'.format(level) print b #update answer label based on poti selection self.alabels[int(pot)].config(text=str(level)) for x in b: GPIO.output(SPI_SDI_PIN, int(x)) print(int(x)) GPIO.output(SPI_CLK_PIN, True) GPIO.output(SPI_CLK_PIN, False) GPIO.output(SPI_CS_PIN, True) self.update_idletasks()
class TreeNode: def __init__(self, canvas, parent, item, menuList=[]): self.canvas = canvas self.parent = parent self.item = item self.state = 'collapsed' self.selected = 0 self.children = {} self.kidKeys = [] self.x = self.y = None self.iconimages = {} # cache of PhotoImage instances for icons self.menuList = menuList self.menuVar = IntVar() self.menuVar.set(0) self._popupMenu = None self.image_id = None if self.menuList: if self.menuList[-1] == 'Separator': self.menuList = self.menuList[:-1] self._popupMenu = Menu(self.canvas, tearoff=0) for i in range(len(self.menuList)): item = self.menuList[i] if item == 'Separator': self._popupMenu.add_separator() else: self._popupMenu.add_radiobutton( label=item, variable=self.menuVar, value=i, indicatoron=0, command=self.popupMenuCommand) def destroy(self): for key in self.kidKeys: c = self.children[key] del self.children[key] c.destroy() self.parent = None def geticonimage(self, name): try: return self.iconimages[name] except KeyError: pass file, ext = os.path.splitext(name) ext = ext or ".gif" fullname = os.path.join(ICONDIR, file + ext) image = PhotoImage(master=self.canvas, file=fullname) self.iconimages[name] = image return image def select(self, event=None): if self.selected: return self.deselectall() self.selected = 1 if self.parent != None: if self.parent.state == 'expanded': self.canvas.delete(self.image_id) self.drawicon() self.drawtext() self.item.OnSelect(event) def deselect(self, event=None): if not self.selected: return self.selected = 0 if self.parent != None: if self.parent.state == 'expanded': self.canvas.delete(self.image_id) self.drawicon() self.drawtext() def deselectall(self): if self.parent: self.parent.deselectall() else: self.deselecttree() def deselecttree(self): if self.selected: self.deselect() for key in self.kidKeys: child = self.children[key] child.deselecttree() def flip(self, event=None): if self.state == 'expanded': self.collapse() else: self.expand() self.item.OnDoubleClick() return "break" def popupMenu(self, event=None): if self._popupMenu: self._popupMenu.post(event.widget.winfo_pointerx(), event.widget.winfo_pointery()) return "break" def popupMenuCommand(self): command = self.menuList[self.menuVar.get()] self.item.MenuCommand(command) if self.parent and (command != 'Update Explorer'): # Update parent to try to keep explorer up to date self.parent.update() def expand(self, event=None): if not self.item.IsExpandable(): return if self.state != 'expanded': self.state = 'expanded' self.update() self.view() def collapse(self, event=None): if self.state != 'collapsed': self.state = 'collapsed' self.update() def view(self): top = self.y - 2 bottom = self.lastvisiblechild().y + 17 height = bottom - top visible_top = self.canvas.canvasy(0) visible_height = self.canvas.winfo_height() visible_bottom = self.canvas.canvasy(visible_height) if visible_top <= top and bottom <= visible_bottom: return x0, y0, x1, y1 = self.canvas._getints(self.canvas['scrollregion']) if top >= visible_top and height <= visible_height: fraction = top + height - visible_height else: fraction = top fraction = float(fraction) / y1 self.canvas.yview_moveto(fraction) def reveal(self): # Make sure all parent nodes are marked as expanded parent = self.parent while parent: if parent.state == 'collapsed': parent.state = 'expanded' parent = parent.parent else: break # Redraw tree accordingly self.update() # Bring this item into view self.view() def lastvisiblechild(self): if self.kidKeys and self.state == 'expanded': return self.children[self.kidKeys[-1]].lastvisiblechild() else: return self def update(self): if self.parent: self.parent.update() else: oldcursor = self.canvas['cursor'] self.canvas['cursor'] = "watch" self.canvas.update() self.canvas.delete(Tkinter.ALL) # XXX could be more subtle self.draw(7, 2) x0, y0, x1, y1 = self.canvas.bbox(Tkinter.ALL) self.canvas.configure(scrollregion=(0, 0, x1, y1)) self.canvas['cursor'] = oldcursor def draw(self, x, y): # XXX This hard-codes too many geometry constants! self.x, self.y = x, y self.drawicon() self.drawtext() if self.state != 'expanded': return y + 17 # draw children sublist = self.item._GetSubList() if not sublist: # IsExpandable() was mistaken; that's allowed return y + 17 self.kidKeys = [] for item in sublist: key = item.GetKey() if self.children.has_key(key): child = self.children[key] else: child = TreeNode(self.canvas, self, item, self.menuList) self.children[key] = child self.kidKeys.append(key) # Remove unused children for key in self.children.keys(): if key not in self.kidKeys: del (self.children[key]) cx = x + 20 cy = y + 17 cylast = 0 for key in self.kidKeys: child = self.children[key] cylast = cy self.canvas.create_line(x + 9, cy + 7, cx, cy + 7, fill="gray50") cy = child.draw(cx, cy) if child.item.IsExpandable(): if child.state == 'expanded': iconname = "minusnode" callback = child.collapse else: iconname = "plusnode" callback = child.expand image = self.geticonimage(iconname) id = self.canvas.create_image(x + 9, cylast + 7, image=image) # XXX This leaks bindings until canvas is deleted: self.canvas.tag_bind(id, "<1>", callback) self.canvas.tag_bind(id, "<Double-1>", lambda x: None) id = self.canvas.create_line( x + 9, y + 10, x + 9, cylast + 7, ##stipple="gray50", # XXX Seems broken in Tk 8.0.x fill="gray50") self.canvas.tag_lower(id) # XXX .lower(id) before Python 1.5.2 return cy def drawicon(self): if self.selected: imagename = (self.item.GetSelectedIconName() or self.item.GetIconName() or "openfolder") else: imagename = self.item.GetIconName() or "folder" image = self.geticonimage(imagename) id = self.canvas.create_image(self.x, self.y, anchor="nw", image=image) self.image_id = id self.canvas.tag_bind(id, "<1>", self.select) self.canvas.tag_bind(id, "<Double-1>", self.flip) self.canvas.tag_bind(id, "<3>", self.popupMenu) def drawtext(self, text=None): textx = self.x + 20 - 1 texty = self.y - 1 labeltext = self.item.GetLabelText() if labeltext: id = self.canvas.create_text(textx, texty, anchor="nw", text=labeltext) self.canvas.tag_bind(id, "<1>", self.select) self.canvas.tag_bind(id, "<Double-1>", self.flip) x0, y0, x1, y1 = self.canvas.bbox(id) textx = max(x1, 200) + 10 if text == None: text = self.item.GetText() or "<no text>" try: self.entry except AttributeError: pass else: self.edit_finish() try: label = self.label except AttributeError: # padding carefully selected (on Windows) to match Entry widget: self.label = Label(self.canvas, text=text, bd=0, padx=2, pady=2) if self.selected: self.label.configure(fg="white", bg="darkblue") else: fg = self.item.GetTextFg() self.label.configure(fg=fg, bg="white") id = self.canvas.create_window(textx, texty, anchor="nw", window=self.label) self.label.bind("<1>", self.select_or_edit) self.label.bind("<Double-1>", self.flip) self.label.bind("<3>", self.popupMenu) # Update text if necessary if text != self.label['text']: self.label['text'] = text self.text_id = id def select_or_edit(self, event=None): if self.selected and self.item.IsEditable(): text = self.item.GetTextForEdit() self.label['text'] = text self.drawtext(text) self.edit(event) else: self.select(event) def edit(self, event=None): self.entry = Entry(self.label, bd=0, highlightthickness=1, width=0) self.entry.insert(0, self.label['text']) self.entry.selection_range(0, Tkinter.END) self.entry.pack(ipadx=5) self.entry.focus_set() self.entry.bind("<Return>", self.edit_finish) self.entry.bind("<Escape>", self.edit_cancel) def edit_finish(self, event=None): try: entry = self.entry del self.entry except AttributeError: return text = entry.get() entry.destroy() if text and text != self.item.GetText(): self.item.SetText(text) text = self.item.GetText() self.label['text'] = text self.drawtext() self.canvas.focus_set() def edit_cancel(self, event=None): self.drawtext() self.canvas.focus_set() def find(self, searchKey): # Search for a node who's key matches the given key # Is it this node if searchKey == self.item.GetKey(): return self # Nope, check the children sublist = self.item._GetSubList() for item in sublist: key = item.GetKey() # Use existing child or create new TreeNode if none exists if self.children.has_key(key): child = self.children[key] else: child = TreeNode(self.canvas, self, item, self.menuList) # Update local list of children and keys self.children[key] = child self.kidKeys.append(key) # See if node is child (or one of child's descendants) retVal = child.find(searchKey) if retVal: return retVal # Not here return None
class TreeNode: def __init__(self, canvas, parent, item, colortheme, vspace=20): self.canvas = canvas self.parent = parent self.item = item self.state = 'collapsed' self.selected = False self.edited = False self.children = [] self.colortheme = colortheme self.x = self.y = None self.vspace = vspace self.halfvspace = int(round(self.vspace / 2)) self.evenodd = 0 if not self.parent: self.canvas.bind('<Configure>', self.reconfig) def reconfig(self, *args): if len(self.canvas['scrollregion']) > 0: w, n, e, s = self.canvas._getints(self.canvas['scrollregion']) if e < self.canvas.winfo_width(): e = self.canvas.winfo_width() for item in self.canvas.windows: win, x = item rightside = x + self.canvas._getints( self.canvas.itemcget(win, 'width'))[0] if rightside < e: self.canvas.itemconfigure(win, width=e - x) def destroy(self): for c in self.children[:]: self.children.remove(c) c.destroy() self.parent = None def geticonimage(self, name): return name def select(self, event=None): if self.selected: return self.deselectall() self.selected = True # self.canvas.delete(self.image_id) self.drawicon() self.drawtext() self.item.OnClick() def deselect(self, event=None): if not self.selected: return self.selected = False # self.canvas.delete(self.image_id) self.drawicon() self.drawtext() def deselectall(self): if self.parent: self.parent.deselectall() else: self.deselecttree() def deselecttree(self): if self.selected: self.deselect() for child in self.children: child.deselecttree() def flip(self, event=None): if self.state == 'expanded': self.collapse() else: self.expand() self.item.OnDoubleClick() return "break" def expand(self, event=None): if not self.item._IsExpandable(): return if self.state != 'expanded': self.state = 'expanded' self.update() self.view() def collapse(self, event=None): self.deselecttree() if self.state != 'collapsed': self.state = 'collapsed' self.update() def view(self): top = self.y bottom = self.lastvisiblechild().y + self.vspace height = bottom - top visible_top = self.canvas.canvasy(0) visible_height = self.canvas.winfo_height() visible_bottom = self.canvas.canvasy(visible_height) if visible_top <= top and bottom <= visible_bottom: return x0, y0, x1, y1 = self.canvas._getints(self.canvas['scrollregion']) if top >= visible_top and height <= visible_height: fraction = top + height - visible_height else: fraction = top fraction = float(fraction) / y1 self.canvas.yview_moveto(fraction) def lastvisiblechild(self): if self.children and self.state == 'expanded': return self.children[-1].lastvisiblechild() else: return self def update(self): if self.parent: self.parent.update() else: self.canvas.evenodd = 1 self.canvas.windows = [] oldcursor = self.canvas['cursor'] self.canvas['cursor'] = "watch" self.canvas.update() self.canvas.delete(ALL) self.draw(5, 3) x0, y0, x1, y1 = self.canvas.bbox(ALL) self.canvas.configure(scrollregion=(0, 0, x1, y1)) self.canvas['cursor'] = oldcursor self.reconfig() def draw(self, x, y): if self.canvas.evenodd: self.evenodd = 0 self.canvas.evenodd = 0 else: self.evenodd = 1 self.canvas.evenodd = 1 self.x, self.y = x, y self.drawicon() self.drawtext() if self.state != 'expanded': return y + self.vspace # draw children if not self.children: sublist = self.item._GetSubList() if not sublist: # _IsExpandable() was mistaken; that's allowed return y + self.vspace for item in sublist: child = self.__class__(self.canvas, self, item, self.colortheme, self.vspace) self.children.append(child) cx = x + self.vspace cy = y + self.vspace cylast = 0 for child in self.children: cylast = cy self.canvas.create_line(x + self.halfvspace, cy + self.halfvspace, cx, cy + self.halfvspace, fill=self.colortheme.treelinescolor, stipple="gray50") cy = child.draw(cx, cy) if child.item._IsExpandable(): if child.state == 'expanded': iconname = "tree_minus" callback = child.collapse else: iconname = "tree_plus" callback = child.expand image = self.geticonimage(iconname) id = self.canvas.create_image(x + self.halfvspace, cylast + self.halfvspace, image=image) self.canvas.tag_bind(id, "<1>", callback) self.canvas.tag_bind(id, "<Double-1>", lambda x: None) id = self.canvas.create_line(x + self.halfvspace, y + self.halfvspace, x + self.halfvspace, cylast + self.halfvspace, stipple="gray50", fill=self.colortheme.treelinescolor) self.canvas.tag_lower(id) return cy def drawicon(self): return def drawtext(self): textx = self.x texty = self.y labeltext = self.item.GetLabelText() if labeltext: id = self.canvas.create_text(textx, texty, anchor="nw", text=labeltext) self.canvas.tag_bind(id, "<1>", self.select) self.canvas.tag_bind(id, "<Double-1>", self.flip) x0, y0, x1, y1 = self.canvas.bbox(id) textx = max(x1, 200) + self.halfvspace text = self.item.GetText() or "<no text>" if self.selected: imagename = (self.item.GetSelectedIconName() or self.item.GetIconName() or "tree_node") else: imagename = self.item.GetIconName() or "tree_node" image = self.geticonimage(imagename) try: self.entry except AttributeError: pass else: self.edit_finish() try: label = self.label except AttributeError: self.frame = Frame(self.canvas, border=1, relief='flat') self.iconlabel = Label(self.frame, image=image, bd=0, padx=1, pady=1, anchor=W) self.label = Label(self.frame, text=text, bd=0, padx=3, pady=1, anchor=W) self.iconlabel.pack(side='left') self.label.pack(side='left', fill='y') widgets = [self.label, self.iconlabel, self.frame] if self.evenodd: bgcolor = self.colortheme.evencolor else: bgcolor = self.colortheme.editfieldbackground for widget in widgets: if self.selected: widget['bg'] = self.colortheme.selectbackground else: widget['bg'] = bgcolor if self.selected: self.label['fg'] = self.colortheme.selectforeground else: self.label['fg'] = self.colortheme.foreground width = self.frame.winfo_reqwidth() if width < self.canvas.winfo_width() - textx: width = self.canvas.winfo_width() - textx id = self.canvas.create_window(textx, texty, anchor=NW, window=self.frame, width=width) self.canvas.windows.append((id, textx)) self.label.bind("<1>", self.select_or_edit) self.label.bind("<Double-1>", self.flip) self.iconlabel.bind("<1>", self.select_or_edit) self.iconlabel.bind("<Double-1>", self.flip) self.frame.bind("<1>", self.select_or_edit) self.frame.bind("<Double-1>", self.flip) self.label.bind("<Button-4>", self.unit_up) self.label.bind("<Button-5>", self.unit_down) self.iconlabel.bind("<Button-4>", self.unit_up) self.iconlabel.bind("<Button-5>", self.unit_down) self.frame.bind("<Button-4>", self.unit_up) self.frame.bind("<Button-5>", self.unit_down) self.text_id = id def unit_up(self, event): first, last = self.canvas.yview() if first <= 0 and last >= 1: return "break" self.canvas.yview_scroll(-1, "unit") return "break" def unit_down(self, event): first, last = self.canvas.yview() if first <= 0 and last >= 1: return "break" self.canvas.yview_scroll(1, "unit") return "break" def select_or_edit(self, event=None): if self.selected and self.item.IsEditable(): self.edit(event) else: self.select(event) def edit(self, event=None): if self.edited: return self.edited = True self.entry = Entry(self.label, bd=0, highlightthickness=1, width=0) self.entry.insert(0, self.label['text']) self.entry.selection_range(0, END) self.entry.pack(ipadx=5) self.entry.focus_set() self.entry.bind("<Return>", self.edit_finish) self.entry.bind("<Escape>", self.edit_cancel) def edit_finish(self, event=None): try: entry = self.entry del self.entry self.edited = False except AttributeError: return text = entry.get() entry.destroy() if text and text != self.item.GetText(): self.item.SetText(text) text = self.item.GetText() self.label['text'] = text self.drawtext() self.canvas.focus_set() def edit_cancel(self, event=None): try: entry = self.entry del self.entry self.edited = False except AttributeError: return entry.destroy() self.drawtext() self.canvas.focus_set()
class editPool(Frame): font_decorations = ("italic", "bold", "subscript", "superscript") font_decorations_to_names = { "italic": _("italic"), "bold": _("bold"), "subscript": _("subscript"), "superscript": _("superscript"), } font_decorations_to_html = {"italic": "i", "bold": "b", "subscript": "sub", "superscript": "sup"} def __init__(self, master, buttons=("interpret", "asis"), **kw): Frame.__init__(self, master, **kw) self.text = "" self.interpret = 1 self.editPool = Entry(self, width=50, state="disabled", font="Helvetica 12") self.editPool.pack(side="left") self.editPool.bind("<Return>", self._interpretButtonPressed) self.editPool.bind("<Escape>", self._cancel) self.editPool.bind("<Control-s>", lambda e: self._tag_it("sub")) self.editPool.bind("<Control-S>", lambda e: self._tag_it("sup")) self.editPool.bind("<Control-i>", lambda e: self._tag_it("i")) self.editPool.bind("<Control-b>", lambda e: self._tag_it("b")) self.editPool.bind("<KeyPress>", self._key) if "interpret" in buttons: pix = Store.app.request("pixmap", name="interpret") self.interpretButton = Button( self, text=_("Interpret"), image=pix, command=self._interpretButtonPressed, state="disabled", bd=config.border_width, ) Store.app.balloon.bind(self.interpretButton, _("Interpret text (where applicable)")) self.interpretButton.pack(side="left") else: self.interpretButton = None if "asis" in buttons: pix = Store.app.request("pixmap", name="asis") self.setButton = Button( self, image=pix, text=_("As is"), command=self._setButtonPressed, state="disabled", bd=config.border_width, ) Store.app.balloon.bind(self.setButton, _("Leave text as is - do not interpret")) self.setButton.pack(side="left") else: self.setButton = None pix = Store.app.request("pixmap", name="subnum") self.numbersToSubButton = Button( self, image=pix, text=_("Sub numbers"), command=self._numbersToSubButtonPressed, state="disabled", bd=config.border_width, ) Store.app.balloon.bind(self.numbersToSubButton, _("Convert numbers to subscript")) self.numbersToSubButton.pack(side="left") # text decoration decorFrame = Frame(self) decorFrame.pack(padx=5, side="left") for i in self.font_decorations: pix = Store.app.request("pixmap", name=i) self.__dict__[i] = Button( self, image=pix, command=misc.lazy_apply(self._tag_it, (self.font_decorations_to_html[i],)), state="disabled", text=self.font_decorations_to_names[i], bd=config.border_width, ) Store.app.balloon.bind(self.__dict__[i], self.font_decorations_to_names[i]) self.__dict__[i].pack(side="left") # special characters pix = Store.app.request("pixmap", name="specialchar") self.specialCharButton = Button( self, image=pix, text=_("Special Character"), command=self._specialCharButtonPressed, state="disabled", bd=config.border_width, ) Store.app.balloon.bind(self.specialCharButton, _("Insert a special character")) self.specialCharButton.pack(side="left") self.active = False def _interpretButtonPressed(self, *e): t = self.editPool.get() if string.lower(t) in groups_table: self._setText(t) # self._setText( groups_table[ string.lower(t)]['text']) # self.editPool.insert(0, self.text) else: self._setText(t) self.text = re.sub("\\\\n", "\n", self.text) self._quit() def _setButtonPressed(self, *e): self._setText(self.editPool.get()) self.interpret = 0 self._quit() def _numbersToSubButtonPressed(self, *e): self._setText(re.sub("\d+", "<sub>\g<0></sub>", self.editPool.get())) self._quit() def _cancel(self, e): self._setText(None) self.active = False self._quit() def _quit(self): self.grab_release() self._disable() self._normaly_terminated = 1 self.active = False self.quit() def _disable(self): self.interpretButton.configure(state="disabled") self.numbersToSubButton.configure(state="disabled") self.setButton.configure(state="disabled") self.editPool.configure(state="disabled") self.italic.configure(state="disabled") self.bold.configure(state="disabled") self.superscript.configure(state="disabled") self.subscript.configure(state="disabled") self.specialCharButton.configure(state="disabled") def _enable(self): self.interpretButton.configure(state="normal") self.numbersToSubButton.configure(state="normal") self.setButton.configure(state="normal") self.editPool.configure(state="normal") self.italic.configure(state="normal") self.bold.configure(state="normal") self.superscript.configure(state="normal") self.subscript.configure(state="normal") self.specialCharButton.configure(state="normal") def _setText(self, text): self.text = text self._update() def _update(self): self.editPool.delete(0, last="end") if self.text: self.editPool.insert(0, self.text) def activate(self, text=None, select=1): """activates edit_pool and returns inserted value (None if cancel occured), if parameter text is None it preserves the old one, use text='' to delete old text""" self.active = True self.interpret = 1 self.focus_set() self.grab_set() self._enable() # this is because I need to distinguish whether the mainloop was terminated "from inside" # or from outside (this most of the time means the application was killed and the widgets are no longer available) self._normaly_terminated = 0 if text != None: self._setText(text) self.editPool.focus_set() if select: self.editPool.selection_range(0, "end") self.mainloop() if self._normaly_terminated: return self.text else: return None def _tag_it(self, tag): if self.editPool.selection_present(): self.editPool.insert(Tkinter.SEL_FIRST, "<%s>" % tag) self.editPool.insert(Tkinter.SEL_LAST, "</%s>" % tag) else: self.editPool.insert(Tkinter.INSERT, "<%s></%s>" % (tag, tag)) self.editPool.icursor(self.editPool.index(Tkinter.INSERT) - len(tag) - 3) def _key(self, event): if len(event.keysym) > 1 and event.keysym in keysyms: if self.editPool.selection_present(): self.editPool.delete("anchor", "insert") self.editPool.insert("insert", unicode(keysyms[event.keysym])) return "break" def _specialCharButtonPressed(self): dialog = special_character_menu(self._insertText) dialog.post(self.specialCharButton.winfo_rootx(), self.specialCharButton.winfo_rooty()) def _insertText(self, text): if text != None: self.editPool.insert(Tkinter.INSERT, text) self.grab_set()
class TreeNode: def __init__(self, canvas, parent, item, menuList = []): self.canvas = canvas self.parent = parent self.item = item self.state = 'collapsed' self.selected = 0 self.children = {} self.kidKeys = [] self.x = self.y = None self.iconimages = {} # cache of PhotoImage instances for icons self.menuList = menuList self.menuVar = IntVar() self.menuVar.set(0) self._popupMenu = None self.image_id = None if self.menuList: if self.menuList[-1] == 'Separator': self.menuList = self.menuList[:-1] self._popupMenu = Menu(self.canvas, tearoff = 0) for i in range(len(self.menuList)): item = self.menuList[i] if item == 'Separator': self._popupMenu.add_separator() else: self._popupMenu.add_radiobutton( label = item, variable = self.menuVar, value = i, indicatoron = 0, command = self.popupMenuCommand) def destroy(self): for key in self.kidKeys: c = self.children[key] del self.children[key] c.destroy() self.parent = None def geticonimage(self, name): try: return self.iconimages[name] except KeyError: pass file, ext = os.path.splitext(name) ext = ext or ".gif" fullname = os.path.join(ICONDIR, file + ext) image = PhotoImage(master=self.canvas, file=fullname) self.iconimages[name] = image return image def select(self, event=None): if self.selected: return self.deselectall() self.selected = 1 if self.parent != None: if self.parent.state == 'expanded': self.canvas.delete(self.image_id) self.drawicon() self.drawtext() self.item.OnSelect(event) def deselect(self, event=None): if not self.selected: return self.selected = 0 if self.parent != None: if self.parent.state == 'expanded': self.canvas.delete(self.image_id) self.drawicon() self.drawtext() def deselectall(self): if self.parent: self.parent.deselectall() else: self.deselecttree() def deselecttree(self): if self.selected: self.deselect() for key in self.kidKeys: child = self.children[key] child.deselecttree() def flip(self, event=None): if self.state == 'expanded': self.collapse() else: self.expand() self.item.OnDoubleClick() return "break" def popupMenu(self, event=None): if self._popupMenu: self._popupMenu.post(event.widget.winfo_pointerx(), event.widget.winfo_pointery()) return "break" def popupMenuCommand(self): command = self.menuList[self.menuVar.get()] self.item.MenuCommand(command) if self.parent and (command != 'Update Explorer'): # Update parent to try to keep explorer up to date self.parent.update() def expand(self, event=None): if not self.item.IsExpandable(): return if self.state != 'expanded': self.state = 'expanded' self.update() self.view() def collapse(self, event=None): if self.state != 'collapsed': self.state = 'collapsed' self.update() def view(self): top = self.y - 2 bottom = self.lastvisiblechild().y + 17 height = bottom - top visible_top = self.canvas.canvasy(0) visible_height = self.canvas.winfo_height() visible_bottom = self.canvas.canvasy(visible_height) if visible_top <= top and bottom <= visible_bottom: return x0, y0, x1, y1 = self.canvas._getints(self.canvas['scrollregion']) if top >= visible_top and height <= visible_height: fraction = top + height - visible_height else: fraction = top fraction = float(fraction) / y1 self.canvas.yview_moveto(fraction) def reveal(self): # Make sure all parent nodes are marked as expanded parent = self.parent while parent: if parent.state == 'collapsed': parent.state = 'expanded' parent = parent.parent else: break # Redraw tree accordingly self.update() # Bring this item into view self.view() def lastvisiblechild(self): if self.kidKeys and self.state == 'expanded': return self.children[self.kidKeys[-1]].lastvisiblechild() else: return self def update(self): if self.parent: self.parent.update() else: oldcursor = self.canvas['cursor'] self.canvas['cursor'] = "watch" self.canvas.update() self.canvas.delete(Tkinter.ALL) # XXX could be more subtle self.draw(7, 2) x0, y0, x1, y1 = self.canvas.bbox(Tkinter.ALL) self.canvas.configure(scrollregion=(0, 0, x1, y1)) self.canvas['cursor'] = oldcursor def draw(self, x, y): # XXX This hard-codes too many geometry constants! self.x, self.y = x, y self.drawicon() self.drawtext() if self.state != 'expanded': return y+17 # draw children sublist = self.item._GetSubList() if not sublist: # IsExpandable() was mistaken; that's allowed return y+17 self.kidKeys = [] for item in sublist: key = item.GetKey() if self.children.has_key(key): child = self.children[key] else: child = TreeNode(self.canvas, self, item, self.menuList) self.children[key] = child self.kidKeys.append(key) # Remove unused children for key in self.children.keys(): if key not in self.kidKeys: del(self.children[key]) cx = x+20 cy = y+17 cylast = 0 for key in self.kidKeys: child = self.children[key] cylast = cy self.canvas.create_line(x+9, cy+7, cx, cy+7, fill="gray50") cy = child.draw(cx, cy) if child.item.IsExpandable(): if child.state == 'expanded': iconname = "minusnode" callback = child.collapse else: iconname = "plusnode" callback = child.expand image = self.geticonimage(iconname) id = self.canvas.create_image(x+9, cylast+7, image=image) # XXX This leaks bindings until canvas is deleted: self.canvas.tag_bind(id, "<1>", callback) self.canvas.tag_bind(id, "<Double-1>", lambda x: None) id = self.canvas.create_line(x+9, y+10, x+9, cylast+7, ##stipple="gray50", # XXX Seems broken in Tk 8.0.x fill="gray50") self.canvas.tag_lower(id) # XXX .lower(id) before Python 1.5.2 return cy def drawicon(self): if self.selected: imagename = (self.item.GetSelectedIconName() or self.item.GetIconName() or "openfolder") else: imagename = self.item.GetIconName() or "folder" image = self.geticonimage(imagename) id = self.canvas.create_image(self.x, self.y, anchor="nw", image=image) self.image_id = id self.canvas.tag_bind(id, "<1>", self.select) self.canvas.tag_bind(id, "<Double-1>", self.flip) self.canvas.tag_bind(id, "<3>", self.popupMenu) def drawtext(self, text=None): textx = self.x+20-1 texty = self.y-1 labeltext = self.item.GetLabelText() if labeltext: id = self.canvas.create_text(textx, texty, anchor="nw", text=labeltext) self.canvas.tag_bind(id, "<1>", self.select) self.canvas.tag_bind(id, "<Double-1>", self.flip) x0, y0, x1, y1 = self.canvas.bbox(id) textx = max(x1, 200) + 10 if text==None: text = self.item.GetText() or "<no text>" try: self.entry except AttributeError: pass else: self.edit_finish() try: label = self.label except AttributeError: # padding carefully selected (on Windows) to match Entry widget: self.label = Label(self.canvas, text=text, bd=0, padx=2, pady=2) if self.selected: self.label.configure(fg="white", bg="darkblue") else: fg = self.item.GetTextFg() self.label.configure(fg=fg, bg="white") id = self.canvas.create_window(textx, texty, anchor="nw", window=self.label) self.label.bind("<1>", self.select_or_edit) self.label.bind("<Double-1>", self.flip) self.label.bind("<3>", self.popupMenu) # Update text if necessary if text != self.label['text']: self.label['text'] = text self.text_id = id def select_or_edit(self, event=None): if self.selected and self.item.IsEditable(): text = self.item.GetTextForEdit() self.label['text'] = text self.drawtext(text) self.edit(event) else: self.select(event) def edit(self, event=None): self.entry = Entry(self.label, bd=0, highlightthickness=1, width=0) self.entry.insert(0, self.label['text']) self.entry.selection_range(0, Tkinter.END) self.entry.pack(ipadx=5) self.entry.focus_set() self.entry.bind("<Return>", self.edit_finish) self.entry.bind("<Escape>", self.edit_cancel) def edit_finish(self, event=None): try: entry = self.entry del self.entry except AttributeError: return text = entry.get() entry.destroy() if text and text != self.item.GetText(): self.item.SetText(text) text = self.item.GetText() self.label['text'] = text self.drawtext() self.canvas.focus_set() def edit_cancel(self, event=None): self.drawtext() self.canvas.focus_set() def find(self, searchKey): # Search for a node who's key matches the given key # Is it this node if searchKey == self.item.GetKey(): return self # Nope, check the children sublist = self.item._GetSubList() for item in sublist: key = item.GetKey() # Use existing child or create new TreeNode if none exists if self.children.has_key(key): child = self.children[key] else: child = TreeNode(self.canvas, self, item, self.menuList) # Update local list of children and keys self.children[key] = child self.kidKeys.append(key) # See if node is child (or one of child's descendants) retVal = child.find(searchKey) if retVal: return retVal # Not here return None
class editPool(Frame): font_decorations = ('italic', 'bold', 'subscript', 'superscript') font_decorations_to_names = { 'italic': _('italic'), 'bold': _('bold'), 'subscript': _('subscript'), 'superscript': _('superscript') } font_decorations_to_html = { 'italic': 'i', 'bold': 'b', 'subscript': 'sub', 'superscript': 'sup' } def __init__(self, master, buttons=('interpret', 'asis'), **kw): Frame.__init__(self, master, **kw) self.text = '' self.interpret = 1 self.editPool = Entry(self, width=50, state='disabled', font="Helvetica 12") self.editPool.pack(side='left') self.editPool.bind('<Return>', self._interpretButtonPressed) self.editPool.bind('<Escape>', self._cancel) self.editPool.bind('<Control-s>', lambda e: self._tag_it("sub")) self.editPool.bind('<Control-S>', lambda e: self._tag_it("sup")) self.editPool.bind('<Control-i>', lambda e: self._tag_it("i")) self.editPool.bind('<Control-b>', lambda e: self._tag_it("b")) self.editPool.bind("<KeyPress>", self._key) if 'interpret' in buttons: pix = Store.app.request('pixmap', name='interpret') self.interpretButton = Button(self, text=_('Interpret'), image=pix, command=self._interpretButtonPressed, state='disabled', bd=config.border_width) Store.app.balloon.bind(self.interpretButton, _('Interpret text (where applicable)')) self.interpretButton.pack(side='left') else: self.interpretButton = None if 'asis' in buttons: pix = Store.app.request('pixmap', name='asis') self.setButton = Button(self, image=pix, text=_('As is'), command=self._setButtonPressed, state='disabled', bd=config.border_width) Store.app.balloon.bind(self.setButton, _('Leave text as is - do not interpret')) self.setButton.pack(side='left') else: self.setButton = None pix = Store.app.request('pixmap', name='subnum') self.numbersToSubButton = Button( self, image=pix, text=_('Sub numbers'), command=self._numbersToSubButtonPressed, state='disabled', bd=config.border_width) Store.app.balloon.bind(self.numbersToSubButton, _('Convert numbers to subscript')) self.numbersToSubButton.pack(side='left') # text decoration decorFrame = Frame(self) decorFrame.pack(padx=5, side="left") for i in self.font_decorations: pix = Store.app.request('pixmap', name=i) self.__dict__[i] = Button( self, image=pix, command=misc.lazy_apply(self._tag_it, (self.font_decorations_to_html[i], )), state='disabled', text=self.font_decorations_to_names[i], bd=config.border_width) Store.app.balloon.bind(self.__dict__[i], self.font_decorations_to_names[i]) self.__dict__[i].pack(side="left") # special characters pix = Store.app.request('pixmap', name='specialchar') self.specialCharButton = Button(self, image=pix, text=_('Special Character'), command=self._specialCharButtonPressed, state='disabled', bd=config.border_width) Store.app.balloon.bind(self.specialCharButton, _('Insert a special character')) self.specialCharButton.pack(side='left') self.active = False def _interpretButtonPressed(self, *e): t = self.editPool.get() if string.lower(t) in groups_table: self._setText(t) #self._setText( groups_table[ string.lower(t)]['text']) #self.editPool.insert(0, self.text) else: self._setText(t) self.text = re.sub("\\\\n", "\n", self.text) self._quit() def _setButtonPressed(self, *e): self._setText(self.editPool.get()) self.interpret = 0 self._quit() def _numbersToSubButtonPressed(self, *e): self._setText(re.sub("\d+", '<sub>\g<0></sub>', self.editPool.get())) self._quit() def _cancel(self, e): self._setText(None) self.active = False self._quit() def _quit(self): self.grab_release() self._disable() self._normaly_terminated = 1 self.active = False self.quit() def _disable(self): self.interpretButton.configure(state='disabled') self.numbersToSubButton.configure(state='disabled') self.setButton.configure(state='disabled') self.editPool.configure(state='disabled') self.italic.configure(state='disabled') self.bold.configure(state='disabled') self.superscript.configure(state='disabled') self.subscript.configure(state='disabled') self.specialCharButton.configure(state='disabled') def _enable(self): self.interpretButton.configure(state='normal') self.numbersToSubButton.configure(state='normal') self.setButton.configure(state='normal') self.editPool.configure(state='normal') self.italic.configure(state='normal') self.bold.configure(state='normal') self.superscript.configure(state='normal') self.subscript.configure(state='normal') self.specialCharButton.configure(state='normal') def _setText(self, text): self.text = text self._update() def _update(self): self.editPool.delete(0, last='end') if self.text: self.editPool.insert(0, self.text) def activate(self, text=None, select=1): """activates edit_pool and returns inserted value (None if cancel occured), if parameter text is None it preserves the old one, use text='' to delete old text""" self.active = True self.interpret = 1 self.focus_set() self.grab_set() self._enable() # this is because I need to distinguish whether the mainloop was terminated "from inside" # or from outside (this most of the time means the application was killed and the widgets are no longer available) self._normaly_terminated = 0 if text != None: self._setText(text) self.editPool.focus_set() if select: self.editPool.selection_range(0, 'end') self.mainloop() if self._normaly_terminated: return self.text else: return None def _tag_it(self, tag): if self.editPool.selection_present(): self.editPool.insert(Tkinter.SEL_FIRST, '<%s>' % tag) self.editPool.insert(Tkinter.SEL_LAST, '</%s>' % tag) else: self.editPool.insert(Tkinter.INSERT, '<%s></%s>' % (tag, tag)) self.editPool.icursor( self.editPool.index(Tkinter.INSERT) - len(tag) - 3) def _key(self, event): if len(event.keysym) > 1 and event.keysym in keysyms: if self.editPool.selection_present(): self.editPool.delete("anchor", "insert") self.editPool.insert('insert', unicode(keysyms[event.keysym])) return "break" def _specialCharButtonPressed(self): dialog = special_character_menu(self._insertText) dialog.post(self.specialCharButton.winfo_rootx(), self.specialCharButton.winfo_rooty()) def _insertText(self, text): if text != None: self.editPool.insert(Tkinter.INSERT, text) self.grab_set()
class SteeringFrame(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self.initialize() def initialize(self): self.grid() self.entryVariable = StringVar() self.entry = Entry(self, textvariable=self.entryVariable) self.entry.grid(column=0,row=0,sticky='EW') self.entry.bind("<Return>", self.OnPressEnter) button = Button(self,text="Set Steering", command=self.OnButtonClick) button.grid(column=1,row=0) self.labelVariable = StringVar() label = Label(self,textvariable=self.labelVariable, anchor="w",fg="white",bg="green") label.grid(column=0,row=1,columnspan=1,sticky='EW') self.labelVariable.set("Start..") left = Button(self,text="Left", command=self.Left) left.grid(column=0,row=2) right = Button(self,text="Right", command=self.Right) right.grid(column=1,row=2) centre = Button(self,text="Centre", command=self.Centre) centre.grid(column=3,row=2) self.steerVariable = StringVar() steerState = Label(self,textvariable=self.steerVariable, anchor="w",fg="white",bg="green") steerState.grid(column=0,row=3,columnspan=1,sticky='EW') self.steerVariable.set("Start..") self.turn_angle = steering.GetTurnAngle(); self.slider = Scale(self, from_=-self.turn_angle, to=self.turn_angle, orient=HORIZONTAL, command=self.setSteerState) self.slider.grid(column=0, row=4, columnspan=3, sticky='EW') self.grid_columnconfigure(0,weight=1) self.update() #self.geometry(self.geometry()) # caused busy wait? self.entry.focus_set() #self.entry.selection_range(0, Tkinter.END) # caused busy wait? def OnButtonClick(self): steerAngle = int(self.entryVariable.get()) steering.SetAngle(steerAngle) self.slider.set(steerAngle) self.labelVariable.set("Steering set: " + str(steerAngle) ) self.entry.focus_set() self.entry.selection_range(0, END) def OnPressEnter(self,event): steerAngle = int(self.entryVariable.get()) steering.SetAngle(steerAngle) self.slider.set(steerAngle) self.labelVariable.set("Steering set: " + str(steerAngle) ) self.entry.focus_set() self.entry.selection_range(0, END) def Left(self): self.steerVariable.set("LEFT") steering.TurnLeft() self.slider.set(-self.turn_angle) def Right(self): self.steerVariable.set("RIGHT") steering.TurnRight() self.slider.set(self.turn_angle) def Centre(self): self.steerVariable.set("CENTRE") steering.TurnStraight() self.slider.set(0) def setSteerState(self, val): val = self.slider.get() steering.SetAngle(val) steerAngle = val; self.steerVariable.set("Steering: " + str(val) )
class Tk_Table(Frame, object): def __init__(self, master, columns, data=None, command=None, editable=True, sort=True, select_mode=None, autoscroll=True, vscrollbar=True, hscrollbar=False, heading_anchor = CENTER, cell_anchor=W, style=None, scrollbar_background=None, scrollbar_troughcolor=None, height=None, padding=None, adjust_heading_to_content=False, stripped_rows=None, selection_background=None, selection_foreground=None, cell_background=None, cell_foreground=None, cell_font=None, field_background=None, heading_font= None, heading_background=None, heading_foreground=None, cell_pady=2, column_header=True, row_numbers=True, entry_background="#d6d6d6", entry_foreground=None, entry_validatecommand=None, entry_selectbackground="#1BA1E2", entry_selectborderwidth=None, entry_selectforeground=None, entry_font = "TkDefaultFont", rowlabel_anchor=E, rowlabel_minwidth=0, rowlabel_hoverbackground="#FFFFFF",frame_relief=None, frame_borderwidth=None, frame_background=None): frame_kwargs = {} if frame_relief is not None: frame_kwargs["relief"] = frame_relief if frame_borderwidth is not None: frame_kwargs["borderwidth"] = frame_borderwidth if frame_background is not None: frame_kwargs["background"] = frame_background Frame.__init__(self, master, class_="Multicolumn_Listbox", **frame_kwargs) self.grid_rowconfigure(0, weight=1) self.grid_columnconfigure(1, weight=1) self._multicolumn_listbox = Multicolumn_Listbox(self, columns, data=data, command=command, sort=sort, select_mode=select_mode, heading_anchor = heading_anchor, cell_anchor=cell_anchor, style=style, height=height, padding=padding, adjust_heading_to_content=adjust_heading_to_content, stripped_rows=stripped_rows, selection_background=selection_background, selection_foreground=selection_foreground, cell_background=cell_background, cell_foreground=cell_foreground, cell_font=cell_font, field_background=field_background, heading_font=heading_font, heading_background=heading_background, heading_foreground=heading_foreground, cell_pady=cell_pady, headers=column_header) self._multicolumn_listbox.interior.grid(row=0, column=1, sticky= N+E+W+S) self._mousewheel_detection = True if row_numbers: self._row_numbers = Row_Header(self, font=self._multicolumn_listbox.font, row_height=self._multicolumn_listbox.row_height, row_minwidth=rowlabel_minwidth, hover_background = rowlabel_hoverbackground, anchor=rowlabel_anchor, onclick=self._on_click_row_label) self._row_numbers.grid(row=0, column=0, sticky= N+S+E) self._multicolumn_listbox.interior.bind("<Map>", self._place_vertically_row_numbers) else: self._row_numbers = None if editable: self._selected_cell = None self._entry_popup = None self._multicolumn_listbox.interior.bind("<1>", self._edit_cell) def configure(event): """ if self._entry_popup: self._entry_popup.destroy() return """ self._multicolumn_listbox.interior.update_idletasks() self._update_position_of_entry() self._multicolumn_listbox.interior.bind("<Configure>", configure) self._entry_kwargs = entry_kwargs = {} if entry_background is not None: entry_kwargs["background"] = entry_background if entry_foreground is not None: entry_kwargs["foreground"] = entry_foreground if entry_validatecommand is not None: entry_kwargs["validatecommand"] = entry_validatecommand if entry_selectbackground is not None: entry_kwargs["selectbackground"] = entry_selectbackground if entry_selectforeground is not None: entry_kwargs["selectforeground"] = entry_selectforeground if entry_font is not None: entry_kwargs["font"] = entry_font if command is not None: self._command = command self._multicolumn_listbox.interior.bind("<<TreeviewSelect>>", self._on_select) scrollbar_kwargs = {} if scrollbar_background is not None: scrollbar_kwargs["background"] = scrollbar_background if scrollbar_troughcolor is not None: scrollbar_kwargs["throughcolor"] = scrollbar_troughcolor if vscrollbar: if editable: if row_numbers: def yview_command(*args): self._multicolumn_listbox.interior.yview(*args) self._row_numbers.yview(*args) self._update_position_of_entry() else: def yview_command(*args): self._multicolumn_listbox.interior.yview(*args) self._update_position_of_entry() else: if row_numbers: def yview_command(*args): self._multicolumn_listbox.interior.yview(*args) self._row_numbers.yview(*args) else: yview_command = self._multicolumn_listbox.interior.yview self._vbar=Scrollbar(self,takefocus=0, command=yview_command, **scrollbar_kwargs) self._vbar.grid(row=0, column=2, sticky= N+S) def yscrollcommand(first,last): first, last = float(first), float(last) if first <= 0 and last >= 1: if self._mousewheel_detection: if autoscroll: self._vbar.grid_remove() if row_numbers: unbind_function_onMouseWheel(self._multicolumn_listbox.interior) self._mousewheel_detection = False else: if not self._mousewheel_detection: if autoscroll: self._vbar.grid() if row_numbers: bind_function_onMouseWheel(self._row_numbers, "y", binding_widget=self._multicolumn_listbox.interior, unit="pages") self._mousewheel_detection = True self._vbar.set(first, last) if editable: self._update_position_of_entry() self._multicolumn_listbox.interior.config(yscrollcommand=yscrollcommand) if hscrollbar: if editable: def xview_command(*args): self._multicolumn_listbox.interior.xview(*args) self._update_position_of_entry() else: xview_command = self._multicolumn_listbox.interior.xview self._hbar=Scrollbar(self,takefocus=0, command=xview_command, **scrollbar_kwargs) self._hbar.grid(row=1, column=1, sticky= E+W) if autoscroll: if editable: def xscrollcommand(f,l, self=self): make_autoscroll(self._hbar, f, l) self._update_position_of_entry() else: def xscrollcommand(f,l, hbar=self._hbar): make_autoscroll(hbar, f, l) self._multicolumn_listbox.interior.config(xscrollcommand=xscrollcommand) else: self._multicolumn_listbox.interior.config(xscrollcommand=self._hbar.set) def _place_vertically_row_numbers(self, event): self._multicolumn_listbox.interior.unbind("<Map>") item_ID = self._multicolumn_listbox.interior.insert('', 0, values=[""]*self._multicolumn_listbox.number_of_columns) self._multicolumn_listbox.interior.update() x,y,w,h = self._multicolumn_listbox.interior.bbox(item_ID) self._multicolumn_listbox.interior.delete(item_ID) self._row_numbers.grid_configure(pady=(y,0)) def _edit_cell(self, event): '''Executed, when a row is clicked. Opens an entry popup above the cell, so it is possible to select text ''' # close previous popups if self._entry_popup: self._destroy_entry() # what row and column was clicked on item_ID = self._multicolumn_listbox.interior.identify_row(event.y) if not item_ID: return column = self._multicolumn_listbox.interior.identify_column(event.x) if column == "": return # get column position info x,y,width,height = self._multicolumn_listbox.interior.bbox(item_ID, column) # place Entry popup properly column_number = int(column[1:])-1 cell_data = self._multicolumn_listbox.item_ID_to_row_data(item_ID)[column_number] self._entry_popup = Entry(self._multicolumn_listbox.interior, exportselection=True, borderwidth=0, **self._entry_kwargs) self._entry_popup.place(x=x, y=y, width=width, height=height) self._entry_popup.insert(0, cell_data) self._entry_popup.focus_force() self._entry_popup.bind("<Control-a>", lambda event: self._select_all_entry_data) self._entry_popup.bind("<Escape>", lambda event: self._destroy_entry()) self._entry_popup.bind("<FocusOut>", lambda event: self._destroy_entry()) bind_function_onMouseWheel(self._multicolumn_listbox.interior, "y", binding_widget=self._entry_popup, callback=self._update_position_of_entry, unit="pages") if self._row_numbers: bind_function_onMouseWheel(self._row_numbers, "y", binding_widget=self._entry_popup, unit="pages") self._entry_popup.bind("<Return>", self._on_update_cell) self._selected_cell = item_ID, column, column_number def _on_click_row_label(self, index): if self._selected_cell and self._multicolumn_listbox.item_ID(index) == self._selected_cell[0]: self._destroy_entry() self._multicolumn_listbox.toogle_selection(index) def _select_all_entry_data(self): ''' Set selection on the whole text ''' self._entry_popup.selection_range(0, 'end') # returns 'break' to interrupt default key-bindings return 'break' def _destroy_entry(self): self._entry_popup.destroy() self._entry_popup = None self._selected_cell = None def _on_update_cell(self, event): item_ID, column, column_number = self._selected_cell data = self._entry_popup.get() row_data = self._multicolumn_listbox.item_ID_to_row_data(item_ID) row_data[column_number] = data self._multicolumn_listbox.interior.item(item_ID, values=row_data) self._destroy_entry() def _update_position_of_entry(self): if self._selected_cell: bbox = self._multicolumn_listbox.interior.bbox(self._selected_cell[0], self._selected_cell[1]) if bbox == "": self._entry_popup.place_forget() else: x,y,width,height = bbox self._entry_popup.place(x=x, y=y, width=width, height=height) def configure_column(self, index, width=None, minwidth=None, anchor=None, stretch=None): self._multicolumn_listbox.configure_column(self, index, width=None, minwidth=None, anchor=None, stretch=None) def row_data(self, index): return self._multicolumn_listbox.row_data(index) def update_row(self, index, data): self._multicolumn_listbox.update_row(index,data) def delete_row(self, index): self._multicolumn_listbox.delete_row(index) if self._row_numbers: self._row_numbers.pop() def insert_row(self, data, index=None): self._multicolumn_listbox.insert_row(data, index) if self._row_numbers: self._row_numbers.new_label() def column_data(self, index): return self._multicolumn_listbox.column_data(index) def update_column(self, index, data): self._multicolumn_listbox.update_column(index, data) def clear(self): self._multicolumn_listbox.clear() if self._row_numbers: self._row_numbers.delete_labels() def update(self, data): current_number_of_rows = self._multicolumn_listbox.number_of_rows self._multicolumn_listbox.update(data) if self._row_numbers: number_of_rows = len(data) if current_number_of_rows < number_of_rows: for i in range(number_of_rows - current_number_of_rows): self._row_numbers.new_label() else: n_labels = current_number_of_rows - number_of_rows self._row_numbers.pop(n_labels =n_labels) def focus(self, index=None): self._multicolumn_listbox.focus(index) def state(self, state=None): self._multicolumn_listbox.state(state) @property def number_of_rows(self): return self._multicolumn_listbox.number_of_rows @property def number_of_columns(self): return self._multicolumn_listbox.number_of_columns def toogle_selection(self, index): self._multicolumn_listbox.toogle_selection(index) def select_row(self, index): self._multicolumn_listbox.select_row(index) def deselect_row(self, index): self._multicolumn_listbox.deselect_row(index) def deselect_all(self): self._multicolumn_listbox.deselect_all() def set_selection(self, indices): self._multicolumn_listbox.set_selection(indices) @property def selected_rows(self): return self._multicolumn_listbox.selected_rows @property def indices_of_selected_rows(self): return self._multicolumn_listbox.indices_of_selected_rows def delete_all_selected_rows(self): number_of_deleted_rows = self._multicolumn_listbox.delete_all_selected_rows() if self._row_numbers: self._row_numbers.pop(n_labels=number_of_deleted_rows) @property def table_data(self): return self._multicolumn_listbox.table_data @table_data.setter def table_data(self, data): self.update(data) def cell_data(self, row, column): return self._multicolumn_listbox.cell_data(row, column) def update_cell(self, row, column, value): self._multicolumn_listbox.update_cell(row, column, value) def __getitem__(self, index): return self._multicolumn_listbox[index] def __setitem__(self, index, value): self._multicolumn_listbox[index] = value def bind(self, event, handler): self._multicolumn_listbox.bind(event, handler) def sort_by(self, col, descending): self._multicolumn_listbox.sort_by(col, descending)
class SPIFrame(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self.initialize() def initialize(self): self.grid() self.entryVariable = StringVar() self.entry = Entry(self, textvariable=self.entryVariable) self.entry.grid(column=0,row=0,sticky='EW') self.entry.bind("<Return>", self.OnPressEnter) button = Button(self,text="SPI send", command=self.OnButtonClick) button.grid(column=1,row=0) #ramp = Button(self,text="RAMP", command=self.setlabvar) #ramp.grid(column=1,row=1) self.labelVariable = StringVar() label = Label(self,textvariable=self.labelVariable, anchor="w",fg="white",bg="blue") label.grid(column=0,row=1,columnspan=1,sticky='EW') self.labelVariable.set("Start..") self.slider = Scale(self, from_=0, to=80, orient=HORIZONTAL, command=self.setlabvar) self.slider.grid(column=0, row=2, columnspan=3, sticky='EW') self.PID = PIDTune(self) self.PID.grid(column=0, row=3, columnspan=3, sticky='EW') self.grid_columnconfigure(0,weight=1) self.update() #self.geometry(self.geometry()) # caused busy wait? self.entry.focus_set() #self.entry.selection_range(0, Tkinter.END) # caused busy wait? def setlabvar(self, val): val = self.slider.get() speed.SetAcceleration(val) accel = val; self.labelVariable.set("Duty set: " + str(val) ) def OnButtonClick(self): accel = int(self.entryVariable.get()) self.slider.set(accel) speed.SetAcceleration(accel) self.labelVariable.set("Duty set: " + str(accel) ) self.entry.focus_set() self.entry.selection_range(0, END) def OnPressEnter(self,event): accel = int(self.entryVariable.get()) self.slider.set(accel) speed.SetAcceleration(accel) self.labelVariable.set("Duty set: " + str(accel) ) self.entry.focus_set() self.entry.selection_range(0, END)
class TreeNode: def __init__(self, canvas, parent, item, colortheme, vspace=20): self.canvas = canvas self.parent = parent self.item = item self.state = 'collapsed' self.selected = False self.edited = False self.children = [] self.colortheme =colortheme self.x = self.y = None self.vspace=vspace self.halfvspace=int(round(self.vspace/2)) self.evenodd=0 if not self.parent: self.canvas.bind('<Configure>',self.reconfig) def reconfig(self,*args): if len(self.canvas['scrollregion']) >0: w,n,e,s = self.canvas._getints(self.canvas['scrollregion']) if e < self.canvas.winfo_width(): e=self.canvas.winfo_width() for item in self.canvas.windows: win,x=item rightside=x+self.canvas._getints(self.canvas.itemcget(win,'width'))[0] if rightside<e: self.canvas.itemconfigure(win,width=e-x) def destroy(self): for c in self.children[:]: self.children.remove(c) c.destroy() self.parent = None def geticonimage(self, name): return name def select(self, event=None): if self.selected: return self.deselectall() self.selected = True # self.canvas.delete(self.image_id) self.drawicon() self.drawtext() self.item.OnClick() def deselect(self, event=None): if not self.selected: return self.selected = False # self.canvas.delete(self.image_id) self.drawicon() self.drawtext() def deselectall(self): if self.parent: self.parent.deselectall() else: self.deselecttree() def deselecttree(self): if self.selected: self.deselect() for child in self.children: child.deselecttree() def flip(self, event=None): if self.state == 'expanded': self.collapse() else: self.expand() self.item.OnDoubleClick() return "break" def expand(self, event=None): if not self.item._IsExpandable(): return if self.state != 'expanded': self.state = 'expanded' self.update() self.view() def collapse(self, event=None): self.deselecttree() if self.state != 'collapsed': self.state = 'collapsed' self.update() def view(self): top = self.y bottom = self.lastvisiblechild().y + self.vspace height = bottom - top visible_top = self.canvas.canvasy(0) visible_height = self.canvas.winfo_height() visible_bottom = self.canvas.canvasy(visible_height) if visible_top <= top and bottom <= visible_bottom: return x0, y0, x1, y1 = self.canvas._getints(self.canvas['scrollregion']) if top >= visible_top and height <= visible_height: fraction = top + height - visible_height else: fraction = top fraction = float(fraction) / y1 self.canvas.yview_moveto(fraction) def lastvisiblechild(self): if self.children and self.state == 'expanded': return self.children[-1].lastvisiblechild() else: return self def update(self): if self.parent: self.parent.update() else: self.canvas.evenodd=1 self.canvas.windows=[] oldcursor = self.canvas['cursor'] self.canvas['cursor'] = "watch" self.canvas.update() self.canvas.delete(ALL) self.draw(5, 3) x0, y0, x1, y1 = self.canvas.bbox(ALL) self.canvas.configure(scrollregion=(0, 0, x1, y1)) self.canvas['cursor'] = oldcursor self.reconfig() def draw(self, x, y): if self.canvas.evenodd: self.evenodd=0 self.canvas.evenodd=0 else: self.evenodd=1 self.canvas.evenodd=1 self.x, self.y = x, y self.drawicon() self.drawtext() if self.state != 'expanded': return y+self.vspace # draw children if not self.children: sublist = self.item._GetSubList() if not sublist: # _IsExpandable() was mistaken; that's allowed return y+self.vspace for item in sublist: child = self.__class__(self.canvas, self, item, self.colortheme, self.vspace) self.children.append(child) cx = x+self.vspace cy = y+self.vspace cylast = 0 for child in self.children: cylast = cy self.canvas.create_line(x+self.halfvspace, cy+self.halfvspace, cx, cy+self.halfvspace, fill=self.colortheme.treelinescolor, stipple="gray50") cy = child.draw(cx, cy) if child.item._IsExpandable(): if child.state == 'expanded': iconname = "tree_minus" callback = child.collapse else: iconname = "tree_plus" callback = child.expand image = self.geticonimage(iconname) id = self.canvas.create_image(x+self.halfvspace, cylast+self.halfvspace, image=image) self.canvas.tag_bind(id, "<1>", callback) self.canvas.tag_bind(id, "<Double-1>", lambda x: None) id = self.canvas.create_line(x+self.halfvspace, y+self.halfvspace, x+self.halfvspace, cylast+self.halfvspace, stipple="gray50", fill=self.colortheme.treelinescolor) self.canvas.tag_lower(id) return cy def drawicon(self): return def drawtext(self): textx = self.x texty = self.y labeltext = self.item.GetLabelText() if labeltext: id = self.canvas.create_text(textx, texty, anchor="nw", text=labeltext) self.canvas.tag_bind(id, "<1>", self.select) self.canvas.tag_bind(id, "<Double-1>", self.flip) x0, y0, x1, y1 = self.canvas.bbox(id) textx = max(x1, 200) + self.halfvspace text = self.item.GetText() or "<no text>" if self.selected: imagename = (self.item.GetSelectedIconName() or self.item.GetIconName() or "tree_node") else: imagename = self.item.GetIconName() or "tree_node" image = self.geticonimage(imagename) try: self.entry except AttributeError: pass else: self.edit_finish() try: label = self.label except AttributeError: self.frame = Frame(self.canvas, border=1, relief='flat') self.iconlabel = Label(self.frame, image=image, bd=0, padx=1, pady=1, anchor=W) self.label = Label(self.frame, text=text, bd=0, padx=3, pady=1, anchor=W) self.iconlabel.pack(side='left') self.label.pack(side='left', fill='y') widgets=[self.label,self.iconlabel, self.frame] if self.evenodd: bgcolor=self.colortheme.evencolor else: bgcolor=self.colortheme.editfieldbackground for widget in widgets: if self.selected: widget['bg']=self.colortheme.selectbackground else: widget['bg']=bgcolor if self.selected: self.label['fg']=self.colortheme.selectforeground else: self.label['fg']=self.colortheme.foreground width=self.frame.winfo_reqwidth() if width < self.canvas.winfo_width()-textx: width = self.canvas.winfo_width()-textx id = self.canvas.create_window(textx, texty, anchor=NW, window=self.frame, width=width) self.canvas.windows.append((id,textx)) self.label.bind("<1>", self.select_or_edit) self.label.bind("<Double-1>", self.flip) self.iconlabel.bind("<1>", self.select_or_edit) self.iconlabel.bind("<Double-1>", self.flip) self.frame.bind("<1>", self.select_or_edit) self.frame.bind("<Double-1>", self.flip) self.label.bind("<Button-4>", self.unit_up) self.label.bind("<Button-5>", self.unit_down) self.iconlabel.bind("<Button-4>", self.unit_up) self.iconlabel.bind("<Button-5>", self.unit_down) self.frame.bind("<Button-4>", self.unit_up) self.frame.bind("<Button-5>", self.unit_down) self.text_id = id def unit_up(self, event): first,last=self.canvas.yview() if first <= 0 and last >= 1: return "break" self.canvas.yview_scroll(-1, "unit") return "break" def unit_down(self, event): first,last=self.canvas.yview() if first <= 0 and last >= 1: return "break" self.canvas.yview_scroll(1, "unit") return "break" def select_or_edit(self, event=None): if self.selected and self.item.IsEditable(): self.edit(event) else: self.select(event) def edit(self, event=None): if self.edited: return self.edited = True self.entry = Entry(self.label, bd=0, highlightthickness=1, width=0) self.entry.insert(0, self.label['text']) self.entry.selection_range(0, END) self.entry.pack(ipadx=5) self.entry.focus_set() self.entry.bind("<Return>", self.edit_finish) self.entry.bind("<Escape>", self.edit_cancel) def edit_finish(self, event=None): try: entry = self.entry del self.entry self.edited = False except AttributeError: return text = entry.get() entry.destroy() if text and text != self.item.GetText(): self.item.SetText(text) text = self.item.GetText() self.label['text'] = text self.drawtext() self.canvas.focus_set() def edit_cancel(self, event=None): try: entry = self.entry del self.entry self.edited = False except AttributeError: return entry.destroy() self.drawtext() self.canvas.focus_set()