예제 #1
0
    def init_ui(self):
        self.rowconfigure(3, weight=1)
        self.columnconfigure(0, weight=1)
        self.button_load_type = Button(self, text="Load Type JSON", command=lambda: browse_file(self, 1, ))
        self.button_load_type.grid(
            row=0, columnspan=2, sticky=W + E, pady=4, padx=5)
        self.button_load_color = Button(
            self, text="Load Color JSON", command=lambda: browse_file(self, 2))
        self.button_load_color.grid(
            row=1, columnspan=2, sticky=W + E, pady=4, padx=5)
        button_load = Button(
            self, text="Load Images", command=lambda: browse_images(self))
        button_load.grid(row=2, columnspan=2, sticky=W + E, pady=4, padx=5)
        button_learn = Button(
            self,
            text="Test",
            command=
            lambda: start_testing(self.dtype, self.dcolor, self.picture_frames)
        )
        button_learn.grid(row=4, columnspan=2, sticky=W + E, pady=4, padx=5)

        canvas = Canvas(self)
        canvas.grid(row=3, sticky=W + E + N + S, column=0, pady=4, padx=5)

        frame = self.picture_frame = Frame(canvas)
        canvas.create_window(0, 0, window=frame, anchor='nw')

        scroll_bar = Scrollbar(self, orient="vertical", command=canvas.yview)
        scroll_bar.grid(sticky=E + N + S, padx=5, row=3, column=1)

        canvas.configure(yscrollcommand=scroll_bar.set)

        # track changes to the canvas and frame width and sync them,
        # also updating the scrollbar
        def _configure_interior(event):
            # update the scrollbars to match the size of the inner frame
            size = (frame.winfo_reqwidth(), frame.winfo_reqheight())
            canvas.config(scrollregion="0 0 %s %s" % size)
            if frame.winfo_reqwidth() != canvas.winfo_width():
                # update the canvas's width to fit the inner frame
                canvas.config(width=frame.winfo_reqwidth())

        frame.bind('<Configure>', _configure_interior)

        def _configure_canvas(event):
            if frame.winfo_reqwidth() != canvas.winfo_width():
                # update the inner frame's width to fill the canvas
                canvas.itemconfigure(frame, width=canvas.winfo_width())

        canvas.bind('<Configure>', _configure_canvas)
예제 #2
0
    def _init_ui(self):
        """
        Composes the UI and associates the appropriate
        handler for the actions to catch.
        """
        self._parent.title("Events")
        self._style = Style()
        self._style.theme_use("default")
        self.pack(fill=BOTH, expand=1)

        self.columnconfigure(1, weight=1)
        self.columnconfigure(3, pad=7)
        self.rowconfigure(3, weight=1)
        self.rowconfigure(5, pad=7)

        label = Label(self, text="Actions")
        label.grid(sticky=W, pady=4, padx=5)

        self._text_area = self.ReadOnlyText(self)
        self._text_area.grid(row=1,
                             column=0,
                             columnspan=2,
                             rowspan=4,
                             padx=5,
                             sticky=E + W + S + N)
        scrollbar = Scrollbar(self, command=self._text_area.yview)
        scrollbar.grid(row=1, column=2, rowspan=4, sticky=N + S)
        self._text_area['yscrollcommand'] = scrollbar.set

        start_button = Button(self, text="Start", command=self._rec_start)
        start_button.grid(row=1, column=3)

        stop_button = Button(self, text="Stop", command=self._rec_stop)
        stop_button.grid(row=2, column=3, pady=4)

        save_button = Button(
            self,
            text="Save",
        )
        save_button.grid(row=5, column=3)

        quit_button = Button(self, text="Quit", command=self._exit)
        quit_button.grid(row=5, column=0, padx=5)
예제 #3
0
 def create_scrollable_text_area(self):
     """ Creates main text area with scrollbars"""
     xscrollbar = Scrollbar(self, orient=HORIZONTAL)
     xscrollbar.grid(row=2, column=1, columnspan=5, sticky=E + W)
     yscrollbar = Scrollbar(self, orient=VERTICAL)
     yscrollbar.grid(row=1, column=6, sticky=N + S)
     self.textarea = Text(self,
                          wrap=NONE,
                          bd=0,
                          xscrollcommand=xscrollbar.set,
                          yscrollcommand=yscrollbar.set)
     self.textarea.grid(row=1,
                        column=1,
                        columnspan=5,
                        rowspan=1,
                        padx=0,
                        sticky=E + W + S + N)
     xscrollbar.config(command=self.textarea.xview)
     yscrollbar.config(command=self.textarea.yview)
예제 #4
0
파일: random3.py 프로젝트: harshn05/WIP
	def _init_ui(self):
		# Load an image
		self.img = ImageTk.PhotoImage(Image.open(r"images\dna5.png"))
		# Define a canvas in a frame
		frame = Frame(self)
		c = Canvas(frame, bg="white", height=475, width=475)
		# Display the image in the canvas
		c.create_image(0, 0, image=self.img, anchor=NW)
		# Y-scrollbar
		yscrollbar = Scrollbar(frame, command=c.yview)
		c.configure(yscrollcommand=yscrollbar.set)
		# X-scrollbar
		xscrollbar = Scrollbar(frame, orient=HORIZONTAL, command=c.xview)
		c.configure(xscrollcommand=xscrollbar.set)
		# Display widgets using grid layout.
		frame.grid(row=0, column=0)
		yscrollbar.grid(row=0, column=2, sticky=S + N)
		xscrollbar.grid(row=2, column=0, sticky=W + E)
		c.grid(row=0, column=0)
		self.pack(fill=BOTH, expand=1)
예제 #5
0
파일: wanda.py 프로젝트: jeiros/JmsScripts
class TextWindow(Frame):
   """ A basic, scrollable text window that can either be editable or not """
   def __init__(self, master):
      """ Make a scrollable, resizeable text """
      Frame.__init__(self, master)
      # Add a horizontal and vertical scroller
      self.hscroller = Scrollbar(self, orient=HORIZONTAL)
      self.vscroller = Scrollbar(self, orient=VERTICAL)
      # Make the text box
      self.text = Text(self, width=90, state=DISABLED, height=15, wrap=NONE,
                       xscrollcommand=self.hscroller.set,
                       yscrollcommand=self.vscroller.set)
      # Pack everything in there, nice and tight. Let the text expand and the
      # scroll bars lengthen, but do not let the scroll bars thicken.
      self.text.grid(column=0, row=0, sticky=N+S+E+W)
      self.hscroller.grid(column=0, row=1, sticky=N+S+E+W)
      self.vscroller.grid(column=1, row=0, sticky=N+S+E+W)
      self.columnconfigure(0, weight=1)
      self.columnconfigure(1, weight=0)
      self.rowconfigure(0, weight=1)
      self.rowconfigure(1, weight=0)
      # Now make the scroll bars actually work
      self.hscroller.configure(command=self.text.xview)
      self.vscroller.configure(command=self.text.yview)

   def write(self, s):
      """ 
      Writes 's' to the window, such that it will emulate a file.  We have to
      change the state to ACTIVE in order to add text, but then change it back
      to the original state afterwards
      """
      self.text.configure(state=NORMAL)
      self.text.insert(END, s)
      self.text.configure(state=DISABLED)

   def clear(self, event=None):
      """ Clears all text from this window """
      self.text.config(state=NORMAL)
      self.text.delete('0.0', END)
      self.text.config(state=DISABLED)
예제 #6
0
    def __init__(self, master, mixer):
        Frame.__init__(self, master)

        scrollbar_h = Scrollbar(self, orient='horizontal')
        scrollbar_v = Scrollbar(self, orient='vertical')
        self.canvas = Canvas(self,
                             background='gray',
                             scrollregion=(0, 0, (3 + len(mixer) * FADER_WIDTH), FADER_HEIGHT),
                             yscrollcommand=scrollbar_v.set,
                             xscrollcommand=scrollbar_h.set)

        scrollbar_v.config(command=self.canvas.yview)
        scrollbar_h.config(command=self.canvas.xview)

        master.bind("<MouseWheel>",
                         lambda e: self.canvas.yview_scroll(-e.delta, 'units'))
        master.bind("<Shift-MouseWheel>",
                         lambda e: self.canvas.xview_scroll(-e.delta, 'units'))

        Sizegrip(self).grid(column=2, row=1, sticky='se')
        self.canvas.grid(column=0, row=0, sticky='nwes')
        scrollbar_h.grid(column=0, row=1, sticky='we')
        scrollbar_v.grid(column=1, row=0, sticky='sn')

        master_fader = AudioFader(self, mixer.getVolume, mixer.setVolume, "Master")
        master_fader.grid(column=2, row=0, sticky='nwes')

        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)

        for i, channel in enumerate(mixer):
            if channel.device.id_variable is not None:
                name = channel.device.id_variable
            else:
                name = channel.device.name_id

            fader = AudioFader(self.canvas, channel.get_gain, channel.set_gain, name)
            self.canvas.create_window(i * FADER_WIDTH, 0, anchor='nw', window=fader)
예제 #7
0
파일: inputrecorder.py 프로젝트: 01org/pem
    def _init_ui(self):
        """
        Composes the UI and associates the appropriate
        handler for the actions to catch.
        """
        self._parent.title("Events")
        self._style = Style()
        self._style.theme_use("default")
        self.pack(fill=BOTH, expand=1)

        self.columnconfigure(1, weight=1)
        self.columnconfigure(3, pad=7)
        self.rowconfigure(3, weight=1)
        self.rowconfigure(5, pad=7)

        label = Label(self, text="Actions")
        label.grid(sticky=W, pady=4, padx=5)

        self._text_area = self.ReadOnlyText(self)
        self._text_area.grid(row=1, column=0, columnspan=2, rowspan=4, padx=5,
                             sticky=E+W+S+N)
        scrollbar = Scrollbar(self, command=self._text_area.yview)
        scrollbar.grid(row=1, column=2, rowspan=4, sticky=N+S)
        self._text_area['yscrollcommand'] = scrollbar.set

        start_button = Button(self, text="Start", command=self._rec_start)
        start_button.grid(row=1, column=3)

        stop_button = Button(self, text="Stop", command=self._rec_stop)
        stop_button.grid(row=2, column=3, pady=4)

        save_button = Button(self, text="Save",)
        save_button.grid(row=5, column=3)

        quit_button = Button(self, text="Quit", command=self._exit)
        quit_button.grid(row=5, column=0, padx=5)
예제 #8
0
class Ordered_Listbox(Frame):
    def __init__(self, master, data=None, ascending_order = True, ignore_case=False, autoscroll=False, vscrollbar=True, hscrollbar=False, scrollbar_background=None, scrollbar_troughcolor=None, **kwargs):
        Frame.__init__(self, master)

        self._ignore_case = ignore_case
        self._ascending_order = ascending_order

        master.grid_rowconfigure(0, weight=1)
        master.grid_columnconfigure(0, weight=1)

        self._listbox = Listbox(self, *kwargs)        
        self._listbox.grid(row=0, column=0, sticky= N+E+W+S)

        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:
            self._vbar=Scrollbar(self,takefocus=0, command=self._listbox.yview, **scrollbar_kwargs)
            self._vbar.grid(row=0, column=1, sticky= N+S)
            
            if autoscroll:
                self._listbox.config(yscrollcommand=lambda f, l: make_autoscroll(self._vbar, f, l))
            else:
                self._listbox.config(yscrollcommand=self._vbar.set)

        if hscrollbar:
            self._hbar=Scrollbar(self,takefocus=0, command=self._listbox.xview, **scrollbar_kwargs)
            self._hbar.grid(row=0, column=1, sticky= E+W)
            
            if autoscroll:
                self._listbox.config(xscrollcommand=lambda f, l: make_autoscroll(self._hbar, f, l))
            else:
                self._listbox.config(xscrollcommand=self._hbar.set)

        if data is not None:
            for item in data:
                self.add_item(item)

    def add_item(self, item):
        list_of_items = self._listbox.get(0, END)

        index = bisect(list_of_items, item, ignore_case=self._ignore_case, ascending_order=self._ascending_order)
        self._listbox.insert(index, item)

    def delete_item(self, item):
        list_of_items = self._listbox.get(0, END)
        index = bisect(list_of_items, item, ignore_case=self._ignore_case, ascending_order=self._ascending_order)
        self._listbox.delete(index-1)
        
    def selected_items(self):
        list_of_items = []

        for index in self._listbox.curselection():
            list_of_items.append(self._listbox.get(index))
            
        return list_of_items
        
    def selected_item(self):
        return self._listbox.curselection()[0]

    def deselect_all(self):
        self._listbox.selection_clear(0, END)
        
    def select(self, item):
        index = self.index(item)
        
        if index is None:
            return
        
        self._listbox.selection_set(index)

    def deselect(self, item):
        index = self.index(item)
        
        if index is None:
            return
        
        self._listbox.selection_clear(index)

    def index(self, item):
        list_of_items = self._listbox.get(0, END)

        try:
            index = list_of_items.index(item)
        except ValueError:
            return None

        return index

    def bind(self, event, handler):
        self._listbox.bind(event, handler)
    
    def clear(self):
        self._listbox.delete(1,END)

    def __iter__(self):
        return self.items
    
    @property
    def items(self):
        return self._listbox.get(0, END)
예제 #9
0
파일: gui.py 프로젝트: kelliott121/Octopod
class MacroFrame(Frame):

    def __init__(self, parent):
        Frame.__init__(self, parent, background="white")
        self.parent = parent
        self.numStates = 0
        self.initUI()

    def initUI(self):
        self.columnconfigure(0, weight=0)
        self.columnconfigure(1, weight=0)
        self.columnconfigure(2, weight=1)
        self.columnconfigure(3, weight=1)

        self.rowconfigure(0, weight=1)

        self.commandFrame = Frame(self, background="white")
        self.commandFrame.grid(row=0, column=0, columnspan=5, sticky=W+E)
        self.commandFrame.columnconfigure(1, weight=1)

        self.btnCommand = Button(self.commandFrame, text="Run")
        self.btnCommand.grid(row=0, column=0)

        self.strCommand = StringVar()
        self.entCommand = Entry(self.commandFrame, textvariable=self.strCommand)
        self.entCommand.grid(row=0, column=1, sticky=W+E)
        
        self.lstMacro = Listbox(self)
        self.lstMacro.grid(row=1, column=0, sticky=N+S+W+E)
        
        self.treeview = Treeview(self, columns=("Angle"), displaycolumns="#all", selectmode="browse")
        self.treeview.grid(row=1, column=1, columnspan=4, sticky=N+S+W+E)
        self.treeScrollbar = Scrollbar(self)
        self.treeScrollbar.grid(row=1, column=5, sticky=N+S)
        self.treeview.config(yscrollcommand=self.treeScrollbar.set)
        self.treeScrollbar.config(command=self.treeview.yview)

        self.btnFrame = Frame(self, background="white")
        self.btnFrame.grid(row=2, column=0, columnspan=5, sticky=W+E)

        self.btnRun = Button(self.btnFrame, text="Run", command=self.runMacro)
        self.btnRun.grid(row=0, column=0)
        
        self.btnStop = Button(self.btnFrame, text="Stop")
        self.btnStop.grid(row=0, column=1)

        self.btnSaveMacro = Button(self.btnFrame, text="Save Macro", command=self.saveMacro)
        self.btnSaveMacro.grid(row=0, column=2)

        self.btnDeleteMacro = Button(self.btnFrame, text="Delete Macro")
        self.btnDeleteMacro.grid(row=0, column=3)

        self.btnDeleteState = Button(self.btnFrame, text="Delete State")
        self.btnDeleteState.grid(row=0, column=4)

    def addState(self, robot):
        stateName = "state" + str(self.numStates)
        self.treeview.insert("", END, iid=stateName, text=stateName)
        limbNum = 0
        for limb in robot.getLimbs():
            limbName = "limb" + str(limbNum)
            self.treeview.insert(stateName, END, iid=stateName + "_" + limbName, text=limbName)
            partNum = 0
            for part in limb.getComponents():
                partName = "joint" + str(partNum)
                if isinstance(part, Joint):
                    self.treeview.insert(stateName + "_" + limbName,
                                         END,
                                         iid=stateName + "_" + limbName + "_" + partName,
                                         text=partName,
                                         values=[part.angle])
                    partNum += 1
            limbNum += 1
        self.numStates += 1

    def getState(self, stateNum, robot):
        stateName = "state" + str(stateNum)
        limbNum = 0
        for limb in robot.getLimbs():
            limbName = "limb" + str(limbNum)
            partNum = 0
            for part in limb.getComponents():
                partName = "joint" + str(partNum)
                if isinstance(part, Joint):
                    part.setAngle(int(self.treeview.item(stateName + "_" + limbName + "_" + partName, "values")[0]))
                    partNum += 1
            limbNum += 1

    def runMacro(self):
        thread = threading.Thread(target=self.updateState)
        thread.start()
            
    def updateState(self):
        for i in range(self.numStates):
            self.getState(i, self.parent.robotFrame.robot)
            time.sleep(.1)

    def saveMacro(self):
        pass
예제 #10
0
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)
예제 #11
0
    def __init__(self):
        Frame.__init__(self)
        self.style = Style()
        self.style.theme_use("default")
        self.master.title("Log viewer")
        self.pack(fill=BOTH, expand=True)

        self.used = []  # List of currently plotted series ([str])
        self.series = {}  # List of all series ({str -> [number]})
        self.names = []  # List of all nodes in tree view ([str])
        self.queues = [] # List of all queues ([str])
        self.logs = {} # List of all text logs ({str -> [str]})

        self.rowconfigure(1, weight=1)
        self.columnconfigure(6, weight=3)
        self.columnconfigure(11, weight=1)

        # Series selection takes row 1-2, col 0-2
        self.series_ui = Treeview(self)
        self.series_ui.grid(row=1, column=0, columnspan=2, rowspan=2, sticky=N+S)
        self.series_ui.configure(show="tree")
        self.series_ui.bind("<Double-Button-1>", self.onselect)
        self.series_ui.tag_configure("graphall", foreground="#070")
        self.series_ui.tag_configure("graphnone", foreground="#000")
        self.series_ui.tag_configure("graphsome", foreground="#007")
        series_ui_scroll = Scrollbar(self, command=self.series_ui.yview, orient=VERTICAL)
        series_ui_scroll.grid(row=1, column=2, rowspan=2, sticky=N+S)
        self.series_ui["yscrollcommand"] = series_ui_scroll.set

        # The plot takes row 1-2, col 3-6
        move_mode = StringVar()
        move_mode.set("pan")
        show_path = IntVar()
        show_path.set(0)
        event_bars = IntVar()
        event_bars.set(1)
        show_debug = IntVar()
        show_debug.set(1)
        show_error = IntVar()
        show_error.set(1)
        show_warning = IntVar()
        show_warning.set(1)
        show_info = IntVar()
        show_info.set(1)
        self.plot = HackPlot(self, move_mode, show_path, event_bars,
                [(show_debug, "[DEBUG]"), (show_error, "[ERROR]"), (show_warning, "[WARNING]"), (show_info, "[INFO]")])
        self.plot.canvas.grid(row=1, column=3, columnspan=4, rowspan=2, sticky=N+S+E+W)
        # Text logs take row 1-2, col 7-12
        self.plot.listbox.grid(row=1, column=7, columnspan=5, sticky=N+S+E+W)
        listbox_yscroll = Scrollbar(self, command=self.plot.listbox.yview, orient=VERTICAL)
        listbox_yscroll.grid(row=1, column=12, sticky=N+S)
        self.plot.listbox["yscrollcommand"] = listbox_yscroll.set
        listbox_xscroll = Scrollbar(self, command=self.plot.listbox.xview, orient=HORIZONTAL)
        listbox_xscroll.grid(row=2, column=7, columnspan=5, sticky=E+W)
        self.plot.listbox["xscrollcommand"] = listbox_xscroll.set


        # Controls take row 0, col 0-12
        Button(self, text="Load Directory", command=self.loaddir).grid(row=0, column=0)
        Button(self, text="Load File", command=self.loadfile).grid(row=0, column=1)
        Button(self, text="Fit X", command=self.plot.fit_x).grid(row=0, column=3, sticky=W)
        Button(self, text="Fit Y", command=self.plot.fit_y).grid(row=0, column=4, sticky=W)
        Button(self, text="Fit Auto", command=self.plot.fit_auto).grid(row=0, column=5, sticky=W)
        Button(self, text="Fit Tele", command=self.plot.fit_tele).grid(row=0, column=6, sticky=W)
        # Plot controls in a subframe to manage padding so it doesn't look awful
        move_mode_control = Frame(self, padx=10)
        Radiobutton(move_mode_control, text="Pan", value="pan", variable=move_mode).grid(row=0, column=0, sticky=W)
        Radiobutton(move_mode_control, text="Zoom In", value="zoomin", variable=move_mode).grid(row=0, column=1, sticky=W)
        Radiobutton(move_mode_control, text="Zoom Out", value="zoomout", variable=move_mode).grid(row=0, column=2, sticky=W)
        move_mode_control.grid(row=0, column=7, sticky=W)
        Checkbutton(self, text="Event Bars", variable=event_bars, command=self.plot.show_textlogs).grid(row=0, column=8, sticky=W)
        Checkbutton(self, text="Debug", variable=show_debug, command=self.plot.show_textlogs).grid(row=0, column=9, sticky=W)
        Checkbutton(self, text="Error", variable=show_error, command=self.plot.show_textlogs).grid(row=0, column=10, sticky=W)
        Checkbutton(self, text="Warning", variable=show_warning, command=self.plot.show_textlogs).grid(row=0, column=11, sticky=W)
        Checkbutton(self, text="Info", variable=show_info, command=self.plot.show_textlogs).grid(row=0, column=12, sticky=W)
        Checkbutton(self, text="Directories", variable=show_path, command=self.plot.show_textlogs).grid(row=0, column=13, sticky=E)
예제 #12
0
파일: form.py 프로젝트: Sheldan/screenPaper
    def create_gui_elements(self):
        top_frame = Frame(self)
        top_frame.grid(row=0, column=0, columnspan=9, rowspan=6)
        # top_frame.pack(fill=X)
        # image display
        photo2 = ImageTk.PhotoImage(Image.open('back.png'))
        image_display = Label(top_frame)
        image_display.configure(image=photo2)
        image_display.image = photo2
        image_display.grid(row=0, columnspan=9, column=1, rowspan=6)
        # image_lb.pack(side=TOP)
        self.add_gui_element(GUI_ELEMENT.IMAGE_DISPLAY_LABEL, image_display)
        close_button = Button(self, text='Close', command=close)
        close_button.grid(row=9, column=9)
        # close_button.pack(side=RIGHT, padx=5, pady=5)
        self.add_gui_element(GUI_ELEMENT.CLOSE_BTN, close_button)

        bottom_frame = Frame(self)
        bottom_frame.grid(row=5, column=0, columnspan=9, rowspan=3)
        # bottom_frame.pack(fill=X)
        config_frame = Frame(bottom_frame)
        config_frame.grid(row=5, column=6, columnspan=3, rowspan=3)
        # config_frame.pack(fill=X)

        list_box_frame = Frame(config_frame)
        list_box_frame.grid(row=5, column=6, columnspan=3, rowspan=3)
        # list_box_frame.pack(side=RIGHT)
        scrollbar = Scrollbar(list_box_frame)
        # scrollbar.pack(side=RIGHT, fill=Y)
        resolution_lb = Listbox(list_box_frame, selectmode=SINGLE, height=4, yscrollcommand=scrollbar.set)
        i = 0
        for resolution in ScreenPaper.get_resolution():
            resolution_lb.insert(i, '%dx%d' % (resolution[0], resolution[1]))
            i += 1
        scrollbar.grid(row=5, column=9, rowspan=9)
        resolution_lb.grid(row=5, column=6, rowspan=4, columnspan=3)
        scrollbar.config(command=resolution_lb.yview)
        # resolution_lb.pack(side=RIGHT)

        self.add_gui_element(GUI_ELEMENT.RESOLUTION_LB, resolution_lb)
        ok_btn = Button(self, text='Create', command=self.create_pape)
        ok_btn.grid(row=9, column=7)
        # ok_btn.pack(side=RIGHT)
        self.add_gui_element(GUI_ELEMENT.OK_BTN, ok_btn)
        save_btn = Button(self, text='Save', command=self.save_image_as)
        save_btn.grid(row=9, column=8)
        # save_btn.pack(side=RIGHT)
        self.add_gui_element(GUI_ELEMENT.SAVE_BTN, save_btn)

        checkbox_frame = Frame(config_frame)
        checkbox_frame.grid(row=5, column=0, rowspan=3, columnspan=6)
        auto_save_var = IntVar()
        auto_save_chk = Checkbutton(checkbox_frame, text="Save automatically", variable=auto_save_var, onvalue=1, offvalue=0)
        auto_save_chk.grid(row=5, column=1)
        # auto_save_chk.pack(side=BOTTOM)
        self.add_gui_element(GUI_ELEMENT.AUTOMATICALLY_SAVE_CK, {'element':auto_save_chk, 'var': auto_save_var})

        auto_upload_var = IntVar()
        auto_upload_chk = Checkbutton(checkbox_frame, text="Upload to imgur automatically", variable=auto_upload_var, onvalue=1, offvalue=0)
        auto_upload_chk.grid(row=6, column=1)
        # auto_upload_chk.pack(side=BOTTOM)
        self.add_gui_element(GUI_ELEMENT.AUTOMATICALLY_UPLOAD_CK, {'element': auto_upload_chk, 'var': auto_upload_var})
        # checkbox_frame.pack(side=RIGHT)
        message_lb = Label(self)
        message_lb.grid(row=7, column=1)
        # message_lb.pack(side=BOTTOM)
        self.add_gui_element(GUI_ELEMENT.MESSAGE_LABEL, message_lb)
예제 #13
0
class TreeTable(Frame):
    """
    A table based on :class:`ttk.Treeview`.

    :Parameters:
        **master** : Tkinter or ttk widget
            The widget in which the :class:`TableTree` will reside.
        **headers** : list of str
            The column headers for the table.
        **data** : list of tuples
            Table data. There must be as many elements in each tuple as there \
            are headers. Each tuple in the list corresponds to a row in the \
            table.
    """
    def __init__(self, master, headers, data, name=None):
        Frame.__init__(self, master, name=name)
        #: column headers
        self.headers = headers
        #: table data
        self.data = data
        #: :class:`~ttk.Treeview` that only shows "headings" not "tree columns"
        self.tree = Treeview(self,
                             columns=self.headers,
                             show="headings",
                             name='tabletree')
        #: vertical scrollbar
        self.yscroll = Scrollbar(self,
                                 orient="vertical",
                                 command=self.tree.yview,
                                 name='table_yscroll')
        #: horizontal scrollbar
        self.xscroll = Scrollbar(self,
                                 orient="horizontal",
                                 command=self.tree.xview,
                                 name='table_xscroll')
        self.tree['yscrollcommand'] = self.yscroll.set  # bind to scrollbars
        self.tree['xscrollcommand'] = self.xscroll.set
        # position widgets and set resize behavior
        self.tree.grid(column=0, row=0, sticky=(N + E + W + S))
        self.yscroll.grid(column=1, row=0, sticky=(N + S))
        self.xscroll.grid(column=0, row=1, sticky=(E + W))
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)
        # build tree
        for col in self.headers:
            # NOTE: Use col as column identifiers, crafty!
            # NOTE: Also change col to title case using str.title()
            # NOTE: make lambda behave nicely in a loop using default arg!
            callback = lambda c=col: self.sortby(c, False)
            self.tree.heading(col, text=col.title(), command=callback)
            # adjust the column's width to the header string
            self.tree.column(col, width=tkFont.Font().measure(col.title()))
        # insert a new top-level treeview item by suing an empty string
        for item in self.data:
            self.tree.insert('', END, values=item)
            # adjust column's width if necessary to fit each value
            for idx, val in enumerate(item):
                col_width = tkFont.Font().measure(val)
                # option can be specified at least 3 ways: as (a) width=None,
                # (b) option='width' or (c) 'width', where 'width' can be any
                # valid column option.
                if self.tree.column(self.headers[idx], 'width') < col_width:
                    self.tree.column(self.headers[idx], width=col_width)

    def sortby(self, col, descending):
        """
        Sort table contents when a column header is clicked.

        :Parameters:
            **col**
                The column identifier of the column to sort.
            **descending**
                False if ascending, True if descending, switches each time.
        """
        logging.debug('sortby %s, descending: %s', col, descending)
        # grab values to sort
        data = [(self.tree.set(child, col), child)
                for child in self.tree.get_children('')]
        # now sort the data in place
        data.sort(reverse=descending)
        for idx, item in enumerate(data):
            self.tree.move(item[1], '', idx)
        # switch the heading so it will sort in the opposite direction
        callback = lambda: self.sortby(col, not descending)
        self.tree.heading(col, command=callback)
예제 #14
0
class Scrolling_Area(Frame, object):

    def __init__(self, master, width=None, height=None, mousewheel_speed = 2, scroll_horizontally=True, xscrollbar=None, scroll_vertically=True, yscrollbar=None, outer_background=None, inner_frame=Frame, **kw):
        super(Scrolling_Area, self).__init__(master, **kw)

        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)

        self._clipper = Frame(self, background=outer_background, width=width, height=height)
        self._clipper.grid(row=0, column=0, sticky=N+E+W+S)
        
        self._width = width
        self._height = height

        self.innerframe = inner_frame(self._clipper, padx=0, pady=0, highlightthickness=0)
        self.innerframe.place(in_=self._clipper, x=0, y=0)

        if scroll_vertically:
            if yscrollbar is not None:
                self.yscrollbar = yscrollbar
            else:
                self.yscrollbar = Scrollbar(self, orient=VERTICAL)
                self.yscrollbar.grid(row=0, column=1,sticky=N+S)
                
            self.yscrollbar.set(0.0, 1.0)
            self.yscrollbar.config(command=self.yview)
        else:
            self.yscrollbar = None
            
        self._scroll_vertically = scroll_vertically

        if scroll_horizontally:
            if xscrollbar is not None:
                self.xscrollbar = xscrollbar
            else:
                self.xscrollbar = Scrollbar(self, orient=HORIZONTAL)
                self.xscrollbar.grid(row=1, column=0, sticky=E+W)
            
            self.xscrollbar.set(0.0, 1.0)
            self.xscrollbar.config(command=self.xview)
        else:
            self.xscrollbar = None
            
        self._scroll_horizontally = scroll_horizontally

        self._jfraction=0.05
        self._startX = 0
        self._startY = 0       

        # Whenever the clipping window or scrolled frame change size,
        # update the scrollbars.
        self.innerframe.bind('<Configure>', self._on_configure)
        self._clipper.bind('<Configure>',  self._on_configure)
        
        self.innerframe.xview = self.xview
        self.innerframe.yview = self.yview

        Mousewheel_Support(self).add_support_to(self.innerframe, xscrollbar=self.xscrollbar, yscrollbar=self.yscrollbar)

    def update_viewport(self):
        # compute new height and width
        self.update()
        frameHeight = float(self.innerframe.winfo_reqheight())
        frameWidth = float(self.innerframe.winfo_reqwidth())
        
        if self._width is not None:
            width = min(self._width, frameWidth)
        else:
            width = self._frameWidth

        if self._height is not None:
            height = min(self._height, frameHeight)
        else:
            height = self._frameHeight
        
        self._clipper.configure(width=width, height=height)

    def _on_configure(self, event):
        self._frameHeight = float(self.innerframe.winfo_reqheight())
        self._frameWidth = float(self.innerframe.winfo_reqwidth())

        # resize the visible part
        if self._scroll_horizontally:
            self.xview("scroll", 0, "unit")
            
        if self._scroll_vertically:
            self.yview("scroll", 0, "unit")       

    def xview(self, mode = None, value = None, units = None):
        value = float(value)

        clipperWidth = self._clipper.winfo_width()
        frameWidth = self._frameWidth 
        
        _startX = self._startX

        if mode is None:
            return self.xscrollbar.get()
        elif mode == 'moveto':
            # absolute movement
            self._startX = int(value * frameWidth)
        else: 
            # mode == 'scroll'
            # relative movement
            if units == 'units':
                jump = int(clipperWidth * self._jfraction)
            else:
                jump = clipperWidth
            self._startX = self._startX + value * jump

        if frameWidth <= clipperWidth:
            # The scrolled frame is smaller than the clipping window.

            self._startX = 0
            hi = 1.0
            #use expand by default
            relwidth = 1
        else:
            # The scrolled frame is larger than the clipping window.
            #use expand by default
            if self._startX + clipperWidth > frameWidth:
                self._startX = frameWidth - clipperWidth
                hi = 1.0
            else:
                if self._startX < 0:
                    self._startX = 0
                hi = (self._startX + clipperWidth) / frameWidth
            relwidth = ''

        if self._startX != _startX:
            # Position frame relative to clipper.
            self.innerframe.place(x = -self._startX, relwidth = relwidth)
        
        lo = self._startX / frameWidth
        self.xscrollbar.set(lo, hi)

    def yview(self, mode = None, value = None, units = None):
        value = float(value)
        clipperHeight = self._clipper.winfo_height()
        frameHeight = self._frameHeight
        
        _startY = self._startY

        if mode is None:
            return self.yscrollbar.get()
        elif mode == 'moveto':
            self._startY = value * frameHeight
        else: # mode == 'scroll'
            if units == 'units':
                jump = int(clipperHeight * self._jfraction)
            else:
                jump = clipperHeight
            self._startY = self._startY + value * jump

        if frameHeight <= clipperHeight:
            # The scrolled frame is smaller than the clipping window.

            self._startY = 0
            hi = 1.0
            # use expand by default
            relheight = 1
        else:
            # The scrolled frame is larger than the clipping window.
            # use expand by default 
            if self._startY + clipperHeight > frameHeight:
                self._startY = frameHeight - clipperHeight
                hi = 1.0
            else:
                if self._startY < 0:
                    self._startY = 0
                hi = (self._startY + clipperHeight) / frameHeight
            relheight = ''

        if self._startY != _startY:
            # Position frame relative to clipper.
            self.innerframe.place(y = -self._startY, relheight = relheight)

        lo = self._startY / frameHeight
        self.yscrollbar.set(lo, hi)
예제 #15
0
파일: view.py 프로젝트: oguntli/bugjar
class MainWindow(object):
    def __init__(self, root, debugger):
        '''
        -----------------------------------------------------
        | main button toolbar                               |
        -----------------------------------------------------
        |       < ma | in content area >      |             |
        |            |                        |             |
        | File list  | File name              | Inspector   |
        | (stack/    | Code area              |             |
        | breakpnts) |                        |             |
        |            |                        |             |
        |            |                        |             |
        -----------------------------------------------------
        |     status bar area                               |
        -----------------------------------------------------

        '''

        # Obtain and expand the current working directory.
        base_path = os.path.abspath(os.getcwd())
        base_path = os.path.normcase(base_path) + '/'

        # Create a filename normalizer based on the CWD.
        self.filename_normalizer = filename_normalizer(base_path)

        self.debugger = debugger
        # Associate the debugger with this view.
        self.debugger.view = self

        # Root window
        self.root = root
        self.root.title('Bugjar')
        self.root.geometry('1024x768')

        # Prevent the menus from having the empty tearoff entry
        self.root.option_add('*tearOff', False)
        # Catch the close button
        self.root.protocol("WM_DELETE_WINDOW", self.cmd_quit)
        # Catch the "quit" event.
        self.root.createcommand('exit', self.cmd_quit)

        # Setup the menu
        self._setup_menubar()

        # Set up the main content for the window.
        self._setup_button_toolbar()
        self._setup_main_content()
        self._setup_status_bar()

        # Now configure the weights for the root frame
        self.root.columnconfigure(0, weight=1)
        self.root.rowconfigure(0, weight=0)
        self.root.rowconfigure(1, weight=1)
        self.root.rowconfigure(2, weight=0)

        debugger.start()

    ######################################################
    # Internal GUI layout methods.
    ######################################################

    def _setup_menubar(self):
        # Menubar
        self.menubar = Menu(self.root)

        # self.menu_Apple = Menu(self.menubar, name='Apple')
        # self.menubar.add_cascade(menu=self.menu_Apple)

        self.menu_file = Menu(self.menubar)
        self.menubar.add_cascade(menu=self.menu_file, label='File')

        self.menu_program = Menu(self.menubar)
        self.menubar.add_cascade(menu=self.menu_program, label='Program')

        self.menu_help = Menu(self.menubar)
        self.menubar.add_cascade(menu=self.menu_help, label='Help')

        # self.menu_Apple.add_command(label='Test', command=self.cmd_dummy)

        # self.menu_file.add_command(label='New', command=self.cmd_dummy, accelerator="Command-N")
        self.menu_file.add_command(label='Open...',
                                   command=self.cmd_open_file,
                                   accelerator="Command-O")
        self.root.bind('<Command-o>', self.cmd_open_file)
        # self.menu_file.add_command(label='Close', command=self.cmd_dummy)

        self.menu_program.add_command(label='Run',
                                      command=self.cmd_run,
                                      accelerator="R")
        self.root.bind('<r>', self.cmd_run)
        self.menu_program.add_command(label='Step',
                                      command=self.cmd_step,
                                      accelerator="S")
        self.root.bind('<s>', self.cmd_step)
        self.menu_program.add_command(label='Next',
                                      command=self.cmd_next,
                                      accelerator="N")
        self.root.bind('<n>', self.cmd_next)
        self.menu_program.add_command(label='Return',
                                      command=self.cmd_return,
                                      accelerator="BackSpace")
        self.root.bind('<BackSpace>', self.cmd_return)

        self.menu_help.add_command(label='Open Documentation',
                                   command=self.cmd_bugjar_docs)
        self.menu_help.add_command(label='Open Bugjar project page',
                                   command=self.cmd_bugjar_page)
        self.menu_help.add_command(label='Open Bugjar on GitHub',
                                   command=self.cmd_bugjar_github)
        self.menu_help.add_command(label='Open BeeWare project page',
                                   command=self.cmd_beeware_page)

        # last step - configure the menubar
        self.root['menu'] = self.menubar

    def _setup_button_toolbar(self):
        '''
        The button toolbar runs as a horizontal area at the top of the GUI.
        It is a persistent GUI component
        '''

        # Main toolbar
        self.toolbar = Frame(self.root)
        self.toolbar.grid(column=0, row=0, sticky=(W, E))

        # Buttons on the toolbar
        self.run_button = Button(self.toolbar,
                                 text='Run',
                                 command=self.cmd_run)
        self.run_button.grid(column=0, row=0)

        self.step_button = Button(self.toolbar,
                                  text='Step',
                                  command=self.cmd_step)
        self.step_button.grid(column=1, row=0)

        self.next_button = Button(self.toolbar,
                                  text='Next',
                                  command=self.cmd_next)
        self.next_button.grid(column=2, row=0)

        self.return_button = Button(self.toolbar,
                                    text='Return',
                                    command=self.cmd_return)
        self.return_button.grid(column=3, row=0)

        self.toolbar.columnconfigure(0, weight=0)
        self.toolbar.rowconfigure(0, weight=0)

    def _setup_main_content(self):
        '''
        Sets up the main content area. It is a persistent GUI component
        '''

        # Main content area
        self.content = PanedWindow(self.root, orient=HORIZONTAL)
        self.content.grid(column=0, row=1, sticky=(N, S, E, W))

        # Create subregions of the content
        self._setup_file_lists()
        self._setup_code_area()
        self._setup_inspector()

        # Set up weights for the left frame's content
        self.content.columnconfigure(0, weight=1)
        self.content.rowconfigure(0, weight=1)

        self.content.pane(0, weight=1)
        self.content.pane(1, weight=2)
        self.content.pane(2, weight=1)

    def _setup_file_lists(self):

        self.file_notebook = Notebook(self.content, padding=(0, 5, 0, 5))
        self.content.add(self.file_notebook)

        self._setup_stack_frame_list()
        self._setup_breakpoint_list()

    def _setup_stack_frame_list(self):
        self.stack_frame = Frame(self.content)
        self.stack_frame.grid(column=0, row=0, sticky=(N, S, E, W))
        self.file_notebook.add(self.stack_frame, text='Stack')

        self.stack = StackView(self.stack_frame,
                               normalizer=self.filename_normalizer)
        self.stack.grid(column=0, row=0, sticky=(N, S, E, W))

        # # The tree's vertical scrollbar
        self.stack_scrollbar = Scrollbar(self.stack_frame, orient=VERTICAL)
        self.stack_scrollbar.grid(column=1, row=0, sticky=(N, S))

        # # Tie the scrollbar to the text views, and the text views
        # # to each other.
        self.stack.config(yscrollcommand=self.stack_scrollbar.set)
        self.stack_scrollbar.config(command=self.stack.yview)

        # Setup weights for the "stack" tree
        self.stack_frame.columnconfigure(0, weight=1)
        self.stack_frame.columnconfigure(1, weight=0)
        self.stack_frame.rowconfigure(0, weight=1)

        # Handlers for GUI events
        self.stack.bind('<<TreeviewSelect>>', self.on_stack_frame_selected)

    def _setup_breakpoint_list(self):
        self.breakpoints_frame = Frame(self.content)
        self.breakpoints_frame.grid(column=0, row=0, sticky=(N, S, E, W))
        self.file_notebook.add(self.breakpoints_frame, text='Breakpoints')

        self.breakpoints = BreakpointView(self.breakpoints_frame,
                                          normalizer=self.filename_normalizer)
        self.breakpoints.grid(column=0, row=0, sticky=(N, S, E, W))

        # The tree's vertical scrollbar
        self.breakpoints_scrollbar = Scrollbar(self.breakpoints_frame,
                                               orient=VERTICAL)
        self.breakpoints_scrollbar.grid(column=1, row=0, sticky=(N, S))

        # Tie the scrollbar to the text views, and the text views
        # to each other.
        self.breakpoints.config(yscrollcommand=self.breakpoints_scrollbar.set)
        self.breakpoints_scrollbar.config(command=self.breakpoints.yview)

        # Setup weights for the "breakpoint list" tree
        self.breakpoints_frame.columnconfigure(0, weight=1)
        self.breakpoints_frame.columnconfigure(1, weight=0)
        self.breakpoints_frame.rowconfigure(0, weight=1)

        # Handlers for GUI events
        self.breakpoints.tag_bind('breakpoint', '<Double-Button-1>',
                                  self.on_breakpoint_double_clicked)
        self.breakpoints.tag_bind('breakpoint', '<<TreeviewSelect>>',
                                  self.on_breakpoint_selected)
        self.breakpoints.tag_bind('file', '<<TreeviewSelect>>',
                                  self.on_breakpoint_file_selected)

    def _setup_code_area(self):
        self.code_frame = Frame(self.content)
        self.code_frame.grid(column=1, row=0, sticky=(N, S, E, W))

        # Label for current file
        self.current_file = StringVar()
        self.current_file_label = Label(self.code_frame,
                                        textvariable=self.current_file)
        self.current_file_label.grid(column=0, row=0, sticky=(W, E))

        # Code display area
        self.code = DebuggerCode(self.code_frame, debugger=self.debugger)
        self.code.grid(column=0, row=1, sticky=(N, S, E, W))

        # Set up weights for the code frame's content
        self.code_frame.columnconfigure(0, weight=1)
        self.code_frame.rowconfigure(0, weight=0)
        self.code_frame.rowconfigure(1, weight=1)

        self.content.add(self.code_frame)

    def _setup_inspector(self):
        self.inspector_frame = Frame(self.content)
        self.inspector_frame.grid(column=2, row=0, sticky=(N, S, E, W))

        self.inspector = InspectorView(self.inspector_frame)
        self.inspector.grid(column=0, row=0, sticky=(N, S, E, W))

        # The tree's vertical scrollbar
        self.inspector_scrollbar = Scrollbar(self.inspector_frame,
                                             orient=VERTICAL)
        self.inspector_scrollbar.grid(column=1, row=0, sticky=(N, S))

        # Tie the scrollbar to the text views, and the text views
        # to each other.
        self.inspector.config(yscrollcommand=self.inspector_scrollbar.set)
        self.inspector_scrollbar.config(command=self.inspector.yview)

        # Setup weights for the "breakpoint list" tree
        self.inspector_frame.columnconfigure(0, weight=1)
        self.inspector_frame.columnconfigure(1, weight=0)
        self.inspector_frame.rowconfigure(0, weight=1)

        self.content.add(self.inspector_frame)

    def _setup_status_bar(self):
        # Status bar
        self.statusbar = Frame(self.root)
        self.statusbar.grid(column=0, row=2, sticky=(W, E))

        # Current status
        self.run_status = StringVar()
        self.run_status_label = Label(self.statusbar,
                                      textvariable=self.run_status)
        self.run_status_label.grid(column=0, row=0, sticky=(W, E))
        self.run_status.set('Not running')

        # Main window resize handle
        self.grip = Sizegrip(self.statusbar)
        self.grip.grid(column=1, row=0, sticky=(S, E))

        # Set up weights for status bar frame
        self.statusbar.columnconfigure(0, weight=1)
        self.statusbar.columnconfigure(1, weight=0)
        self.statusbar.rowconfigure(0, weight=0)

    ######################################################
    # Utility methods for controlling content
    ######################################################

    def show_file(self, filename, line=None, breakpoints=None):
        """Show the content of the nominated file.

        If specified, line is the current line number to highlight. If the
        line isn't currently visible, the window will be scrolled until it is.

        breakpoints is a list of line numbers that have current breakpoints.

        If refresh is true, the file will be reloaded and redrawn.
        """
        # Set the filename label for the current file
        self.current_file.set(self.filename_normalizer(filename))

        # Update the code view; this means changing the displayed file
        # if necessary, and updating the current line.
        if filename != self.code.filename:
            self.code.filename = filename
            for bp in self.debugger.breakpoints(filename).values():
                if bp.enabled:
                    self.code.enable_breakpoint(bp.line)
                else:
                    self.code.disable_breakpoint(bp.line)

        self.code.line = line

    ######################################################
    # TK Main loop
    ######################################################

    def mainloop(self):
        self.root.mainloop()

    ######################################################
    # TK Command handlers
    ######################################################

    def cmd_quit(self):
        "Quit the debugger"
        self.debugger.stop()
        self.root.quit()

    def cmd_run(self, event=None):
        "Run until the next breakpoint, or end of execution"
        self.debugger.do_run()

    def cmd_step(self, event=None):
        "Step into the next line of code"
        self.debugger.do_step()

    def cmd_next(self, event=None):
        "Run the next line of code in the current frame"
        self.debugger.do_next()

    def cmd_return(self, event=None):
        "Return to the previous frame"
        self.debugger.do_return()

    def cmd_open_file(self, event=None):
        "Open a file in the breakpoint pane"
        filename = tkFileDialog.askopenfilename(
            initialdir=os.path.abspath(os.getcwd()))

        if filename:
            # Convert to canonical form
            filename = os.path.abspath(filename)
            filename = os.path.normcase(filename)

            # Show the file contents
            self.code.filename = filename

            # Ensure the file appears on the breakpoint list
            self.breakpoints.insert_filename(filename)

            # Show the breakpoint panel
            self.file_notebook.select(self.breakpoints_frame)

            # ... select the new filename
            self.breakpoints.selection_set(filename)

            # .. and clear any currently selected item on the stack tree
            self.stack.selection_remove(self.stack.selection())

    def cmd_bugjar_page(self):
        "Show the Bugjar project page"
        webbrowser.open_new('http://pybee.org/bugjar')

    def cmd_bugjar_github(self):
        "Show the Bugjar GitHub repo"
        webbrowser.open_new('http://github.com/pybee/bugjar')

    def cmd_bugjar_docs(self):
        "Show the Bugjar documentation"
        # If this is a formal release, show the docs for that
        # version. otherwise, just show the head docs.
        if len(NUM_VERSION) == 3:
            webbrowser.open_new('http://bugjar.readthedocs.org/en/v%s/' %
                                VERSION)
        else:
            webbrowser.open_new('http://bugjar.readthedocs.org/')

    def cmd_beeware_page(self):
        "Show the BeeWare project page"
        webbrowser.open_new('http://pybee.org/')

    ######################################################
    # Handlers for GUI actions
    ######################################################

    def on_stack_frame_selected(self, event):
        "When a stack frame is selected, highlight the file and line"
        if event.widget.selection():
            _, index = event.widget.selection()[0].split(':')
            line, frame = self.debugger.stack[int(index)]

            # Display the file in the code view
            self.show_file(filename=frame['filename'], line=line)

            # Display the contents of the selected frame in the inspector
            self.inspector.show_frame(frame)

            # Clear any currently selected item on the breakpoint tree
            self.breakpoints.selection_remove(self.breakpoints.selection())

    def on_breakpoint_selected(self, event):
        "When a breakpoint on the tree has been selected, show the breakpoint"
        if event.widget.selection():
            parts = event.widget.focus().split(':')
            bp = self.debugger.breakpoint((parts[0], int(parts[1])))
            self.show_file(filename=bp.filename, line=bp.line)

            # Clear any currently selected item on the stack tree
            self.stack.selection_remove(self.stack.selection())

    def on_breakpoint_file_selected(self, event):
        "When a file is selected on the breakpoint tree, show the file"
        if event.widget.selection():
            filename = event.widget.focus()
            self.show_file(filename=filename)

            # Clear any currently selected item on the stack tree
            self.stack.selection_remove(self.stack.selection())

    def on_breakpoint_double_clicked(self, event):
        "When a breakpoint on the tree is double clicked, toggle it's status"
        if event.widget.selection():
            parts = event.widget.focus().split(':')
            bp = self.debugger.breakpoint((parts[0], int(parts[1])))
            if bp.enabled:
                self.debugger.disable_breakpoint(bp)
            else:
                self.debugger.enable_breakpoint(bp)

            # Clear any currently selected item on the stack tree
            self.stack.selection_remove(self.stack.selection())

    ######################################################
    # Handlers for debugger responses
    ######################################################

    def on_stack(self, stack):
        "A report of a new stack"
        # Make sure the stack frame list is displayed
        self.file_notebook.select(self.stack_frame)

        # Update the stack list
        self.stack.update_stack(stack)

        if len(stack) > 0:
            # Update the display of the current file
            line = stack[-1][0]
            filename = stack[-1][1]['filename']
            self.show_file(filename=filename, line=line)

            # Select the current stack frame in the frame list
            self.stack.selection_set('frame:%s' % (len(stack) - 1))
        else:
            # No current frame (probably end of execution),
            # so clear the current line marker
            self.code.line = None

    def on_line(self, filename, line):
        "A single line of code has been executed"
        self.run_status.set('Line (%s:%s)' % (filename, line))

    def on_call(self, args):
        "A callable has been invoked"
        self.run_status.set('Call: %s' % args)

    def on_return(self, retval):
        "A callable has returned"
        self.run_status.set('Return: %s' % retval)

    def on_exception(self, name, value):
        "An exception has been raised"
        self.run_status.set('Exception: %s - %s' % (name, value))
        tkMessageBox.showwarning(message='%s: %s' % (name, value))

    def on_postmortem(self):
        "An exception has been raised"
        self.run_status.set('Post mortem mode')
        tkMessageBox.showerror(
            message='Entering post mortem mode. Step/Next will restart')

    def on_restart(self):
        "The code has finished running, and will start again"
        self.run_status.set('Not running')
        tkMessageBox.showinfo(
            message='Program has finished, and will restart.')

    def on_info(self, message):
        "The debugger needs to inform the user of something"
        tkMessageBox.showinfo(message=message)

    def on_warning(self, message):
        "The debugger needs to warn the user of something"
        tkMessageBox.showwarning(message=message)

    def on_error(self, message):
        "The debugger needs to report an error"
        tkMessageBox.showerror(message=message)

    def on_breakpoint_enable(self, bp):
        "A breakpoint has been enabled in the debugger"
        # If the breakpoint is in the currently displayed file, updated
        # the display of the breakpoint.
        if bp.filename == self.code.filename:
            self.code.enable_breakpoint(bp.line, temporary=bp.temporary)

        # ... then update the display of the breakpoint on the tree
        self.breakpoints.update_breakpoint(bp)

    def on_breakpoint_disable(self, bp):
        "A breakpoint has been disabled in the debugger"
        # If the breakpoint is in the currently displayed file, updated
        # the display of the breakpoint.
        if bp.filename == self.code.filename:
            self.code.disable_breakpoint(bp.line)

        # ... then update the display of the breakpoint on the tree
        self.breakpoints.update_breakpoint(bp)

    def on_breakpoint_ignore(self, bp, count):
        "A breakpoint has been ignored by the debugger"
        # If the breakpoint is in the currently displayed file, updated
        # the display of the breakpoint.
        if bp.filename == self.code.filename:
            self.code.ignore_breakpoint(bp.line)

        # ... then update the display of the breakpoint on the tree
        self.breakpoints.update_breakpoint(bp)

    def on_breakpoint_clear(self, bp):
        "A breakpoint has been cleared in the debugger"
        # If the breakpoint is in the currently displayed file, updated
        # the display of the breakpoint.
        if bp.filename == self.code.filename:
            self.code.clear_breakpoint(bp.line)

        # ... then update the display of the breakpoint on the tree
        self.breakpoints.update_breakpoint(bp)
예제 #16
0
class Scrolling_Area(Frame, object):

    def __init__(self, master, width=None, anchor=N, height=None, mousewheel_speed = 2, scroll_horizontally=True, xscrollbar=None, scroll_vertically=True, yscrollbar=None, outer_background=None, inner_frame=Frame, **kw):
        Frame.__init__(self, master, class_=self.__class__)

        if outer_background:
            self.configure(background=outer_background)

        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)
        
        self._width = width
        self._height = height

        self.canvas = Canvas(self, background=outer_background, highlightthickness=0, width=width, height=height)
        self.canvas.grid(row=0, column=0, sticky=N+E+W+S)

        if scroll_vertically:
            if yscrollbar is not None:
                self.yscrollbar = yscrollbar
            else:
                self.yscrollbar = Scrollbar(self, orient=VERTICAL)
                self.yscrollbar.grid(row=0, column=1,sticky=N+S)
        
            self.canvas.configure(yscrollcommand=self.yscrollbar.set)
            self.yscrollbar['command']=self.canvas.yview
        else:
            self.yscrollbar = None

        if scroll_horizontally:
            if xscrollbar is not None:
                self.xscrollbar = xscrollbar
            else:
                self.xscrollbar = Scrollbar(self, orient=HORIZONTAL)
                self.xscrollbar.grid(row=1, column=0, sticky=E+W)
            
            self.canvas.configure(xscrollcommand=self.xscrollbar.set)
            self.xscrollbar['command']=self.canvas.xview
        else:
            self.xscrollbar = None

        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)
        
        self.innerframe = inner_frame(self.canvas, **kw)
        self.innerframe.pack(anchor=anchor)
        
        self.canvas.create_window(0, 0, window=self.innerframe, anchor='nw', tags="inner_frame")

        self.canvas.bind('<Configure>', self._on_canvas_configure)

        Mousewheel_Support(self).add_support_to(self.canvas, xscrollbar=self.xscrollbar, yscrollbar=self.yscrollbar)

    @property
    def width(self):
        return self.canvas.winfo_width()

    @width.setter
    def width(self, width):
        self.canvas.configure(width= width)

    @property
    def height(self):
        return self.canvas.winfo_height()
        
    @height.setter
    def height(self, height):
        self.canvas.configure(height = height)
        
    def set_size(self, width, height):
        self.canvas.configure(width=width, height = height)

    def _on_canvas_configure(self, event):
        width = max(self.innerframe.winfo_reqwidth(), event.width)
        height = max(self.innerframe.winfo_reqheight(), event.height)

        self.canvas.configure(scrollregion="0 0 %s %s" % (width, height))
        self.canvas.itemconfigure("inner_frame", width=width, height=height)

    def update_viewport(self):
        self.update()

        window_width = self.innerframe.winfo_reqwidth()
        window_height = self.innerframe.winfo_reqheight()
        
        if self._width is None:
            canvas_width = window_width
        else:
            canvas_width = min(self._width, window_width)
            
        if self._height is None:
            canvas_height = window_height
        else:
            canvas_height = min(self._height, window_height)

        self.canvas.configure(scrollregion="0 0 %s %s" % (window_width, window_height), width=canvas_width, height=canvas_height)
        self.canvas.itemconfigure("inner_frame", width=window_width, height=window_height)
예제 #17
0
class Display(object):
	def __init__(self,image):
		self.map = SVG(image)
		self.width = self.map.width
		self.height = self.map.height
		self.font = "helvetica 16"
		self.col_bg = "#FFFFFE"
		self.col_text = "#CCCCCF"
		self.col_min = (255,14,47)
		self.col_max = (111,130,158)
		self.states = ['WA', 'DE', 'DC', 'WI', 'WV', 'HI', 'FL', 'WY', 'NH', 'NJ', 'NM', 'TX', 'LA', 'NC', 'ND', 'NE', 'TN', 'NY', 'PA', 'MT', 'RI', 'NV', 'VA', 'CO', 'AK', 'AL', 'AR', 'VT', 'GA', 'IN', 'IA', 'MA', 'AZ', 'CA', 'ID', 'CT', 'ME', 'MD', 'OH', 'UT', 'MO', 'MN', 'MI', 'KS', 'OK', 'MS', 'SC', 'KY', 'SD', 'OR', 'IL']
		self.colorDict = {key:"azure" for key in self.states}
		
	
	
	def init_interface(self,root):
		#widget declarations
		self.searchbar = Entry(root,font=self.font,bg=self.col_bg,foreground=self.col_text)
		self.execute = Button(root,text="Get Trends",command=self.query)
		self.scrolltime = Scrollbar(root,orient=HORIZONTAL,command=self.temp)
		#self.scrolltime.config(command=self.output.yview)
		
		#gridding of widgets
		self.space = Canvas(root,width=self.width,height=self.height,bg=self.col_bg)
		self.space.grid(row=2,column=2,rowspan=4,columnspan=4,sticky=W+E+N+S)
		self.searchbar.grid(row=1,column=2,columnspan=3,sticky=W+E+N+S,padx=20,pady=20)
		self.execute.grid(row=1,column=5,sticky=W)#,sticky=W+E+N+S)
		self.scrolltime.grid(row=6,column=2,columnspan=4,sticky=W+E+N+S)
		self.draw_map()
		
	def draw_map(self):
		self.space.delete(ALL)
		self.map.draw(self.space,self.colorDict)
		
	def temp(self,x,y):
		print "%s,%s"%(x,y)
		
	def convert(self,data):
		print data
		results = {}
		for pair in data:
			(state,factor) = (pair[0], pair[1])
			print (state, factor)
			(r,g,b) = tuple(map(lambda x, y: int((float(factor)/100)*x + (1 - float(factor)/100)*y), self.col_min, self.col_max))
			print (r,g,b)
			results[state] = "#%02x%02x%02x"%(r,g,b)
		return results
		
	def query(self):
		term = self.searchbar.get()
		if term !="":
			self.searchbar.delete(0,'end')
			colors = Data(term)
			if colors != []:
				self.colorDict = self.convert(colors.getData())
				self.draw_map()
		
		
	def run(self):
		root = Tk()
		self.init_interface(root)
		root.mainloop()
예제 #18
0
파일: view.py 프로젝트: adamchainz/bugjar
class MainWindow(object):
    def __init__(self, root, debugger):
        '''
        -----------------------------------------------------
        | main button toolbar                               |
        -----------------------------------------------------
        |       < ma | in content area >      |             |
        |            |                        |             |
        | File list  | File name              | Inspector   |
        | (stack/    | Code area              |             |
        | breakpnts) |                        |             |
        |            |                        |             |
        |            |                        |             |
        -----------------------------------------------------
        |     status bar area                               |
        -----------------------------------------------------

        '''

        # Obtain and expand the current working directory.
        base_path = os.path.abspath(os.getcwd())
        base_path = os.path.normcase(base_path) + '/'

        # Create a filename normalizer based on the CWD.
        self.filename_normalizer = filename_normalizer(base_path)

        self.debugger = debugger
        # Associate the debugger with this view.
        self.debugger.view = self

        # Root window
        self.root = root
        self.root.title('Bugjar')
        self.root.geometry('1024x768')

        # Prevent the menus from having the empty tearoff entry
        self.root.option_add('*tearOff', False)
        # Catch the close button
        self.root.protocol("WM_DELETE_WINDOW", self.cmd_quit)
        # Catch the "quit" event.
        self.root.createcommand('exit', self.cmd_quit)

        # Setup the menu
        self._setup_menubar()

        # Set up the main content for the window.
        self._setup_button_toolbar()
        self._setup_main_content()
        self._setup_status_bar()

        # Now configure the weights for the root frame
        self.root.columnconfigure(0, weight=1)
        self.root.rowconfigure(0, weight=0)
        self.root.rowconfigure(1, weight=1)
        self.root.rowconfigure(2, weight=0)

        debugger.start()

    ######################################################
    # Internal GUI layout methods.
    ######################################################

    def _setup_menubar(self):
        # Menubar
        self.menubar = Menu(self.root)

        # self.menu_Apple = Menu(self.menubar, name='Apple')
        # self.menubar.add_cascade(menu=self.menu_Apple)

        self.menu_file = Menu(self.menubar)
        self.menubar.add_cascade(menu=self.menu_file, label='File')

        self.menu_program = Menu(self.menubar)
        self.menubar.add_cascade(menu=self.menu_program, label='Program')

        self.menu_help = Menu(self.menubar)
        self.menubar.add_cascade(menu=self.menu_help, label='Help')

        # self.menu_Apple.add_command(label='Test', command=self.cmd_dummy)

        # self.menu_file.add_command(label='New', command=self.cmd_dummy, accelerator="Command-N")
        self.menu_file.add_command(label='Open...', command=self.cmd_open_file, accelerator="Command-O")
        self.root.bind('<Command-o>', self.cmd_open_file)
        # self.menu_file.add_command(label='Close', command=self.cmd_dummy)

        self.menu_program.add_command(label='Run', command=self.cmd_run, accelerator="R")
        self.root.bind('<r>', self.cmd_run)
        self.menu_program.add_command(label='Step', command=self.cmd_step, accelerator="S")
        self.root.bind('<s>', self.cmd_step)
        self.menu_program.add_command(label='Next', command=self.cmd_next, accelerator="N")
        self.root.bind('<n>', self.cmd_next)
        self.menu_program.add_command(label='Return', command=self.cmd_return, accelerator="BackSpace")
        self.root.bind('<BackSpace>', self.cmd_return)

        self.menu_help.add_command(label='Open Documentation', command=self.cmd_bugjar_docs)
        self.menu_help.add_command(label='Open Bugjar project page', command=self.cmd_bugjar_page)
        self.menu_help.add_command(label='Open Bugjar on GitHub', command=self.cmd_bugjar_github)
        self.menu_help.add_command(label='Open BeeWare project page', command=self.cmd_beeware_page)

        # last step - configure the menubar
        self.root['menu'] = self.menubar

    def _setup_button_toolbar(self):
        '''
        The button toolbar runs as a horizontal area at the top of the GUI.
        It is a persistent GUI component
        '''

        # Main toolbar
        self.toolbar = Frame(self.root)
        self.toolbar.grid(column=0, row=0, sticky=(W, E))

        # Buttons on the toolbar
        self.run_button = Button(self.toolbar, text='Run', command=self.cmd_run)
        self.run_button.grid(column=0, row=0)

        self.step_button = Button(self.toolbar, text='Step', command=self.cmd_step)
        self.step_button.grid(column=1, row=0)

        self.next_button = Button(self.toolbar, text='Next', command=self.cmd_next)
        self.next_button.grid(column=2, row=0)

        self.return_button = Button(self.toolbar, text='Return', command=self.cmd_return)
        self.return_button.grid(column=3, row=0)

        self.toolbar.columnconfigure(0, weight=0)
        self.toolbar.rowconfigure(0, weight=0)

    def _setup_main_content(self):
        '''
        Sets up the main content area. It is a persistent GUI component
        '''

        # Main content area
        self.content = PanedWindow(self.root, orient=HORIZONTAL)
        self.content.grid(column=0, row=1, sticky=(N, S, E, W))

        # Create subregions of the content
        self._setup_file_lists()
        self._setup_code_area()
        self._setup_inspector()

        # Set up weights for the left frame's content
        self.content.columnconfigure(0, weight=1)
        self.content.rowconfigure(0, weight=1)

        self.content.pane(0, weight=1)
        self.content.pane(1, weight=2)
        self.content.pane(2, weight=1)

    def _setup_file_lists(self):

        self.file_notebook = Notebook(self.content, padding=(0, 5, 0, 5))
        self.content.add(self.file_notebook)

        self._setup_stack_frame_list()
        self._setup_breakpoint_list()

    def _setup_stack_frame_list(self):
        self.stack_frame = Frame(self.content)
        self.stack_frame.grid(column=0, row=0, sticky=(N, S, E, W))
        self.file_notebook.add(self.stack_frame, text='Stack')

        self.stack = StackView(self.stack_frame, normalizer=self.filename_normalizer)
        self.stack.grid(column=0, row=0, sticky=(N, S, E, W))

        # # The tree's vertical scrollbar
        self.stack_scrollbar = Scrollbar(self.stack_frame, orient=VERTICAL)
        self.stack_scrollbar.grid(column=1, row=0, sticky=(N, S))

        # # Tie the scrollbar to the text views, and the text views
        # # to each other.
        self.stack.config(yscrollcommand=self.stack_scrollbar.set)
        self.stack_scrollbar.config(command=self.stack.yview)

        # Setup weights for the "stack" tree
        self.stack_frame.columnconfigure(0, weight=1)
        self.stack_frame.columnconfigure(1, weight=0)
        self.stack_frame.rowconfigure(0, weight=1)

        # Handlers for GUI events
        self.stack.bind('<<TreeviewSelect>>', self.on_stack_frame_selected)

    def _setup_breakpoint_list(self):
        self.breakpoints_frame = Frame(self.content)
        self.breakpoints_frame.grid(column=0, row=0, sticky=(N, S, E, W))
        self.file_notebook.add(self.breakpoints_frame, text='Breakpoints')

        self.breakpoints = BreakpointView(self.breakpoints_frame, normalizer=self.filename_normalizer)
        self.breakpoints.grid(column=0, row=0, sticky=(N, S, E, W))

        # The tree's vertical scrollbar
        self.breakpoints_scrollbar = Scrollbar(self.breakpoints_frame, orient=VERTICAL)
        self.breakpoints_scrollbar.grid(column=1, row=0, sticky=(N, S))

        # Tie the scrollbar to the text views, and the text views
        # to each other.
        self.breakpoints.config(yscrollcommand=self.breakpoints_scrollbar.set)
        self.breakpoints_scrollbar.config(command=self.breakpoints.yview)

        # Setup weights for the "breakpoint list" tree
        self.breakpoints_frame.columnconfigure(0, weight=1)
        self.breakpoints_frame.columnconfigure(1, weight=0)
        self.breakpoints_frame.rowconfigure(0, weight=1)

        # Handlers for GUI events
        self.breakpoints.tag_bind('breakpoint', '<Double-Button-1>', self.on_breakpoint_double_clicked)
        self.breakpoints.tag_bind('breakpoint', '<<TreeviewSelect>>', self.on_breakpoint_selected)
        self.breakpoints.tag_bind('file', '<<TreeviewSelect>>', self.on_breakpoint_file_selected)

    def _setup_code_area(self):
        self.code_frame = Frame(self.content)
        self.code_frame.grid(column=1, row=0, sticky=(N, S, E, W))

        # Label for current file
        self.current_file = StringVar()
        self.current_file_label = Label(self.code_frame, textvariable=self.current_file)
        self.current_file_label.grid(column=0, row=0, sticky=(W, E))

        # Code display area
        self.code = DebuggerCode(self.code_frame, debugger=self.debugger)
        self.code.grid(column=0, row=1, sticky=(N, S, E, W))

        # Set up weights for the code frame's content
        self.code_frame.columnconfigure(0, weight=1)
        self.code_frame.rowconfigure(0, weight=0)
        self.code_frame.rowconfigure(1, weight=1)

        self.content.add(self.code_frame)

    def _setup_inspector(self):
        self.inspector_frame = Frame(self.content)
        self.inspector_frame.grid(column=2, row=0, sticky=(N, S, E, W))

        self.inspector = InspectorView(self.inspector_frame)
        self.inspector.grid(column=0, row=0, sticky=(N, S, E, W))

        # The tree's vertical scrollbar
        self.inspector_scrollbar = Scrollbar(self.inspector_frame, orient=VERTICAL)
        self.inspector_scrollbar.grid(column=1, row=0, sticky=(N, S))

        # Tie the scrollbar to the text views, and the text views
        # to each other.
        self.inspector.config(yscrollcommand=self.inspector_scrollbar.set)
        self.inspector_scrollbar.config(command=self.inspector.yview)

        # Setup weights for the "breakpoint list" tree
        self.inspector_frame.columnconfigure(0, weight=1)
        self.inspector_frame.columnconfigure(1, weight=0)
        self.inspector_frame.rowconfigure(0, weight=1)

        self.content.add(self.inspector_frame)

    def _setup_status_bar(self):
        # Status bar
        self.statusbar = Frame(self.root)
        self.statusbar.grid(column=0, row=2, sticky=(W, E))

        # Current status
        self.run_status = StringVar()
        self.run_status_label = Label(self.statusbar, textvariable=self.run_status)
        self.run_status_label.grid(column=0, row=0, sticky=(W, E))
        self.run_status.set('Not running')

        # Main window resize handle
        self.grip = Sizegrip(self.statusbar)
        self.grip.grid(column=1, row=0, sticky=(S, E))

        # Set up weights for status bar frame
        self.statusbar.columnconfigure(0, weight=1)
        self.statusbar.columnconfigure(1, weight=0)
        self.statusbar.rowconfigure(0, weight=0)

    ######################################################
    # Utility methods for controlling content
    ######################################################

    def show_file(self, filename, line=None, breakpoints=None):
        """Show the content of the nominated file.

        If specified, line is the current line number to highlight. If the
        line isn't currently visible, the window will be scrolled until it is.

        breakpoints is a list of line numbers that have current breakpoints.

        If refresh is true, the file will be reloaded and redrawn.
        """
        # Set the filename label for the current file
        self.current_file.set(self.filename_normalizer(filename))

        # Update the code view; this means changing the displayed file
        # if necessary, and updating the current line.
        if filename != self.code.filename:
            self.code.filename = filename
            for bp in self.debugger.breakpoints(filename).values():
                if bp.enabled:
                    self.code.enable_breakpoint(bp.line)
                else:
                    self.code.disable_breakpoint(bp.line)

        self.code.line = line

    ######################################################
    # TK Main loop
    ######################################################

    def mainloop(self):
        self.root.mainloop()

    ######################################################
    # TK Command handlers
    ######################################################

    def cmd_quit(self):
        "Quit the debugger"
        self.debugger.stop()
        self.root.quit()

    def cmd_run(self, event=None):
        "Run until the next breakpoint, or end of execution"
        self.debugger.do_run()

    def cmd_step(self, event=None):
        "Step into the next line of code"
        self.debugger.do_step()

    def cmd_next(self, event=None):
        "Run the next line of code in the current frame"
        self.debugger.do_next()

    def cmd_return(self, event=None):
        "Return to the previous frame"
        self.debugger.do_return()

    def cmd_open_file(self, event=None):
        "Open a file in the breakpoint pane"
        filename = tkFileDialog.askopenfilename(initialdir=os.path.abspath(os.getcwd()))

        if filename:
            # Convert to canonical form
            filename = os.path.abspath(filename)
            filename = os.path.normcase(filename)

            # Show the file contents
            self.code.filename = filename

            # Ensure the file appears on the breakpoint list
            self.breakpoints.insert_filename(filename)

            # Show the breakpoint panel
            self.file_notebook.select(self.breakpoints_frame)

            # ... select the new filename
            self.breakpoints.selection_set(filename)

            # .. and clear any currently selected item on the stack tree
            self.stack.selection_remove(self.stack.selection())

    def cmd_bugjar_page(self):
        "Show the Bugjar project page"
        webbrowser.open_new('http://pybee.org/bugjar')

    def cmd_bugjar_github(self):
        "Show the Bugjar GitHub repo"
        webbrowser.open_new('http://github.com/pybee/bugjar')

    def cmd_bugjar_docs(self):
        "Show the Bugjar documentation"
        # If this is a formal release, show the docs for that
        # version. otherwise, just show the head docs.
        if len(NUM_VERSION) == 3:
            webbrowser.open_new('http://bugjar.readthedocs.org/en/v%s/' % VERSION)
        else:
            webbrowser.open_new('http://bugjar.readthedocs.org/')

    def cmd_beeware_page(self):
        "Show the BeeWare project page"
        webbrowser.open_new('http://pybee.org/')

    ######################################################
    # Handlers for GUI actions
    ######################################################

    def on_stack_frame_selected(self, event):
        "When a stack frame is selected, highlight the file and line"
        if event.widget.selection():
            _, index = event.widget.selection()[0].split(':')
            line, frame = self.debugger.stack[int(index)]

            # Display the file in the code view
            self.show_file(filename=frame['filename'], line=line)

            # Display the contents of the selected frame in the inspector
            self.inspector.show_frame(frame)

            # Clear any currently selected item on the breakpoint tree
            self.breakpoints.selection_remove(self.breakpoints.selection())

    def on_breakpoint_selected(self, event):
        "When a breakpoint on the tree has been selected, show the breakpoint"
        if event.widget.selection():
            parts = event.widget.focus().split(':')
            bp = self.debugger.breakpoint((parts[0], int(parts[1])))
            self.show_file(filename=bp.filename, line=bp.line)

            # Clear any currently selected item on the stack tree
            self.stack.selection_remove(self.stack.selection())

    def on_breakpoint_file_selected(self, event):
        "When a file is selected on the breakpoint tree, show the file"
        if event.widget.selection():
            filename = event.widget.focus()
            self.show_file(filename=filename)

            # Clear any currently selected item on the stack tree
            self.stack.selection_remove(self.stack.selection())

    def on_breakpoint_double_clicked(self, event):
        "When a breakpoint on the tree is double clicked, toggle it's status"
        if event.widget.selection():
            parts = event.widget.focus().split(':')
            bp = self.debugger.breakpoint((parts[0], int(parts[1])))
            if bp.enabled:
                self.debugger.disable_breakpoint(bp)
            else:
                self.debugger.enable_breakpoint(bp)

            # Clear any currently selected item on the stack tree
            self.stack.selection_remove(self.stack.selection())

    ######################################################
    # Handlers for debugger responses
    ######################################################

    def on_stack(self, stack):
        "A report of a new stack"
        # Make sure the stack frame list is displayed
        self.file_notebook.select(self.stack_frame)

        # Update the stack list
        self.stack.update_stack(stack)

        if len(stack) > 0:
            # Update the display of the current file
            line = stack[-1][0]
            filename = stack[-1][1]['filename']
            self.show_file(filename=filename, line=line)

            # Select the current stack frame in the frame list
            self.stack.selection_set('frame:%s' % (len(stack) - 1))
        else:
            # No current frame (probably end of execution),
            # so clear the current line marker
            self.code.line = None

    def on_line(self, filename, line):
        "A single line of code has been executed"
        self.run_status.set('Line (%s:%s)' % (filename, line))

    def on_call(self, args):
        "A callable has been invoked"
        self.run_status.set('Call: %s' % args)

    def on_return(self, retval):
        "A callable has returned"
        self.run_status.set('Return: %s' % retval)

    def on_exception(self, name, value):
        "An exception has been raised"
        self.run_status.set('Exception: %s - %s' % (name, value))
        tkMessageBox.showwarning(message='%s: %s' % (name, value))

    def on_postmortem(self):
        "An exception has been raised"
        self.run_status.set('Post mortem mode')
        tkMessageBox.showerror(message='Entering post mortem mode. Step/Next will restart')

    def on_restart(self):
        "The code has finished running, and will start again"
        self.run_status.set('Not running')
        tkMessageBox.showinfo(message='Program has finished, and will restart.')

    def on_info(self, message):
        "The debugger needs to inform the user of something"
        tkMessageBox.showinfo(message=message)

    def on_warning(self, message):
        "The debugger needs to warn the user of something"
        tkMessageBox.showwarning(message=message)

    def on_error(self, message):
        "The debugger needs to report an error"
        tkMessageBox.showerror(message=message)

    def on_breakpoint_enable(self, bp):
        "A breakpoint has been enabled in the debugger"
        # If the breakpoint is in the currently displayed file, updated
        # the display of the breakpoint.
        if bp.filename == self.code.filename:
            self.code.enable_breakpoint(bp.line, temporary=bp.temporary)

        # ... then update the display of the breakpoint on the tree
        self.breakpoints.update_breakpoint(bp)

    def on_breakpoint_disable(self, bp):
        "A breakpoint has been disabled in the debugger"
        # If the breakpoint is in the currently displayed file, updated
        # the display of the breakpoint.
        if bp.filename == self.code.filename:
            self.code.disable_breakpoint(bp.line)

        # ... then update the display of the breakpoint on the tree
        self.breakpoints.update_breakpoint(bp)

    def on_breakpoint_ignore(self, bp, count):
        "A breakpoint has been ignored by the debugger"
        # If the breakpoint is in the currently displayed file, updated
        # the display of the breakpoint.
        if bp.filename == self.code.filename:
            self.code.ignore_breakpoint(bp.line)

        # ... then update the display of the breakpoint on the tree
        self.breakpoints.update_breakpoint(bp)

    def on_breakpoint_clear(self, bp):
        "A breakpoint has been cleared in the debugger"
        # If the breakpoint is in the currently displayed file, updated
        # the display of the breakpoint.
        if bp.filename == self.code.filename:
            self.code.clear_breakpoint(bp.line)

        # ... then update the display of the breakpoint on the tree
        self.breakpoints.update_breakpoint(bp)
예제 #19
0
class Scrolling_Area(Frame, object):

    def __init__(self, master, width=None, anchor=N, height=None, mousewheel_speed = 2, scroll_horizontally=True, xscrollbar=None, scroll_vertically=True, yscrollbar=None, background=None, inner_frame=Frame, **kw):
        Frame.__init__(self, master, class_="Scrolling_Area", background=background)

        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)
        
        self._width = width
        self._height = height

        self.canvas = Canvas(self, background=background, highlightthickness=0, width=width, height=height)
        self.canvas.grid(row=0, column=0, sticky=N+E+W+S)

        if scroll_vertically:
            if yscrollbar is not None:
                self.yscrollbar = yscrollbar
            else:
                self.yscrollbar = Scrollbar(self, orient=VERTICAL)
                self.yscrollbar.grid(row=0, column=1,sticky=N+S)
        
            self.canvas.configure(yscrollcommand=self.yscrollbar.set)
            self.yscrollbar['command']=self.canvas.yview
        else:
            self.yscrollbar = None

        if scroll_horizontally:
            if xscrollbar is not None:
                self.xscrollbar = xscrollbar
            else:
                self.xscrollbar = Scrollbar(self, orient=HORIZONTAL)
                self.xscrollbar.grid(row=1, column=0, sticky=E+W)
            
            self.canvas.configure(xscrollcommand=self.xscrollbar.set)
            self.xscrollbar['command']=self.canvas.xview
        else:
            self.xscrollbar = None

        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)
        
        self.innerframe = inner_frame(self.canvas, **kw)
        self.innerframe.pack(anchor=anchor)
        
        self.canvas.create_window(0, 0, window=self.innerframe, anchor='nw', tags="inner_frame")

        self.canvas.bind('<Configure>', self._on_canvas_configure)

        Mousewheel_Support(self).add_support_to(self.canvas, xscrollbar=self.xscrollbar, yscrollbar=self.yscrollbar)

    @property
    def width(self):
        return self.canvas.winfo_width()

    @width.setter
    def width(self, width):
        self.canvas.configure(width= width)

    @property
    def height(self):
        return self.canvas.winfo_height()
        
    @height.setter
    def height(self, height):
        self.canvas.configure(height = height)
        
    def set_size(self, width, height):
        self.canvas.configure(width=width, height = height)

    def _on_canvas_configure(self, event):
        width = max(self.innerframe.winfo_reqwidth(), event.width)
        height = max(self.innerframe.winfo_reqheight(), event.height)

        self.canvas.configure(scrollregion="0 0 %s %s" % (width, height))
        self.canvas.itemconfigure("inner_frame", width=width, height=height)

    def update_viewport(self):
        self.update()

        window_width = self.innerframe.winfo_reqwidth()
        window_height = self.innerframe.winfo_reqheight()
        
        if self._width is None:
            canvas_width = window_width
        else:
            canvas_width = min(self._width, window_width)
            
        if self._height is None:
            canvas_height = window_height
        else:
            canvas_height = min(self._height, window_height)

        self.canvas.configure(scrollregion="0 0 %s %s" % (window_width, window_height), width=canvas_width, height=canvas_height)
        self.canvas.itemconfigure("inner_frame", width=window_width, height=window_height)
예제 #20
0
파일: gui.py 프로젝트: demetraux/Octopod
class MacroFrame(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent, background="white")
        self.parent = parent
        self.numStates = 0
        self.initUI()

    def initUI(self):
        self.columnconfigure(0, weight=0)
        self.columnconfigure(1, weight=0)
        self.columnconfigure(2, weight=1)
        self.columnconfigure(3, weight=1)

        self.rowconfigure(0, weight=1)

        self.commandFrame = Frame(self, background="white")
        self.commandFrame.grid(row=0, column=0, columnspan=5, sticky=W + E)
        self.commandFrame.columnconfigure(1, weight=1)

        self.btnCommand = Button(self.commandFrame, text="Run")
        self.btnCommand.grid(row=0, column=0)

        self.strCommand = StringVar()
        self.entCommand = Entry(self.commandFrame, textvariable=self.strCommand)
        self.entCommand.grid(row=0, column=1, sticky=W + E)

        self.lstMacro = Listbox(self)
        self.lstMacro.grid(row=1, column=0, sticky=N + S + W + E)

        self.treeview = Treeview(self, columns=("Angle"), displaycolumns="#all", selectmode="browse")
        self.treeview.grid(row=1, column=1, columnspan=4, sticky=N + S + W + E)
        self.treeScrollbar = Scrollbar(self)
        self.treeScrollbar.grid(row=1, column=5, sticky=N + S)
        self.treeview.config(yscrollcommand=self.treeScrollbar.set)
        self.treeScrollbar.config(command=self.treeview.yview)

        self.btnFrame = Frame(self, background="white")
        self.btnFrame.grid(row=2, column=0, columnspan=5, sticky=W + E)

        self.btnRun = Button(self.btnFrame, text="Run", command=self.runMacro)
        self.btnRun.grid(row=0, column=0)

        self.btnStop = Button(self.btnFrame, text="Stop")
        self.btnStop.grid(row=0, column=1)

        self.btnSaveMacro = Button(self.btnFrame, text="Save Macro", command=self.saveMacro)
        self.btnSaveMacro.grid(row=0, column=2)

        self.btnDeleteMacro = Button(self.btnFrame, text="Delete Macro")
        self.btnDeleteMacro.grid(row=0, column=3)

        self.btnDeleteState = Button(self.btnFrame, text="Delete State")
        self.btnDeleteState.grid(row=0, column=4)

    def addState(self, robot):
        stateName = "state" + str(self.numStates)
        self.treeview.insert("", END, iid=stateName, text=stateName)
        limbNum = 0
        for limb in robot.getLimbs():
            limbName = "limb" + str(limbNum)
            self.treeview.insert(stateName, END, iid=stateName + "_" + limbName, text=limbName)
            partNum = 0
            for part in limb.getComponents():
                partName = "joint" + str(partNum)
                if isinstance(part, Joint):
                    self.treeview.insert(
                        stateName + "_" + limbName,
                        END,
                        iid=stateName + "_" + limbName + "_" + partName,
                        text=partName,
                        values=[part.angle],
                    )
                    partNum += 1
            limbNum += 1
        self.numStates += 1

    def getState(self, stateNum, robot):
        stateName = "state" + str(stateNum)
        limbNum = 0
        for limb in robot.getLimbs():
            limbName = "limb" + str(limbNum)
            partNum = 0
            for part in limb.getComponents():
                partName = "joint" + str(partNum)
                if isinstance(part, Joint):
                    part.setAngle(int(self.treeview.item(stateName + "_" + limbName + "_" + partName, "values")[0]))
                    partNum += 1
            limbNum += 1

    def runMacro(self):
        thread = threading.Thread(target=self.updateState)
        thread.start()

    def updateState(self):
        for i in range(self.numStates):
            self.getState(i, self.parent.robotFrame.robot)
            time.sleep(0.1)

    def saveMacro(self):
        pass
예제 #21
0
파일: gui.py 프로젝트: ojobabs/ML
    def initUI(self):

        # Configures the GUI
        self.parent.title("Neural Networks for Handwritten Digit Recognition")
        self.style = Style()
        self.pack(fill=BOTH, expand=1)

        # Creates a grid 5x4 in to which we will place elements.
        self.columnconfigure(1, weight=1)
        self.columnconfigure(2, weight=0)
        self.columnconfigure(3, weight=0)
        self.columnconfigure(4, weight=0)
        self.columnconfigure(5, weight=0)
        self.columnconfigure(6, weight=0)
        self.columnconfigure(7, weight=0)
        self.columnconfigure(8, weight=0)
        self.rowconfigure(1, weight=1)
        self.rowconfigure(2, weight=0)
        self.rowconfigure(3, weight=0)
        self.rowconfigure(4, weight=0)

        # Create explanation text for app
        explanation = """
        "This program is capable of utilizing different learning algorithms as a mean to achieve a +90% accuracy in recognizing MNIST
    	digits based on Neural Networks as a way of detecting the different numbers and classifying them correctly" \n
        Select the checkboxes that you wish to utilize ([ ] Learn from starting random values, [X] Learn from preexisting data / [ ] Do not
        save the results [X] Save the final values of the Weights and Biases), Press the Run button to start the Neural Network\n"""

        self.exp = Label(self, text=explanation)
        self.exp.grid(
            row=2,
            column=1,
            columnspan=4,
            padx=2,
            pady=2,
        )

        # Creates the Y scrollbar that is spawned through the whole grid
        yscrollbar = Scrollbar(self, orient=VERTICAL)
        yscrollbar.grid(row=1, column=8, sticky=N + S)

        # Creates the text area and spawns it through the whole window
        self.textarea = Text(self,
                             wrap=NONE,
                             bd=0,
                             yscrollcommand=yscrollbar.set)

        self.textarea.grid(row=1,
                           column=1,
                           columnspan=4,
                           rowspan=1,
                           padx=0,
                           sticky=E + W + S + N)

        yscrollbar.config(command=self.textarea.yview)

        # Creates the run button in the lower row
        self.runButton = Button(self, text="Run Neural Network")
        self.runButton.grid(row=4, column=1, padx=5, pady=5, sticky=W)
        self.runButton.bind("<ButtonRelease-1>", self.runNN)

        # Creates the variable initialization checkbox in the lower row
        self.initvalVar = StringVar()
        initvalCheck = Checkbutton(self,
                                   text="Learn from Initial Values",
                                   variable=self.initvalVar,
                                   onvalue="-l",
                                   offvalue="")
        initvalCheck.grid(row=4, column=2, padx=5, pady=5)

        # Creates the save variables checkbox in the lower row
        self.saveValVar = StringVar()
        saveVal = Checkbutton(self,
                              text="Save final Weights & Biases",
                              variable=self.saveValVar,
                              onvalue="-s",
                              offvalue="")
        saveVal.grid(row=4, column=3, padx=5, pady=5)

        # Creates the clear button for the textbox
        self.clearButton = Button(self, text="Clear")
        self.clearButton.grid(row=4, column=4, padx=5, pady=5)
        self.clearButton.bind("<ButtonRelease-1>", self.clearText)

        # Defines the tags that are used to colorise the text added to the text widget.
        self.textarea.tag_config("errorstring",
                                 foreground="#CC0000")  # Red Color
        self.textarea.tag_config("infostring",
                                 foreground="#008800")  # Green Color
class wine_DB_manager:  #Class for wrapping TKinter widgets
    def __init__(self, master):  #Initilize the attributes of the class

        master.minsize(width=600, height=700)  #Set window size and title
        master.title("Member and Store Manager")

        master.grid_columnconfigure(
            0, weight=1
        )  #Configure first and last columns for centering columns 1-5
        master.grid_columnconfigure(6, weight=1)
        master.grid_rowconfigure(
            12, weight=1
        )  #Configure last row for filling left over space at the bottom

        self.imp_store_label = Label(
            master, text="Import Store Information (.CSV)"
        )  #Initilize lable, entry, and buttons for importing stores
        self.imp_store_entry = Entry(master, width=70)
        self.imp_store_browse_button = Button(
            master,
            text="Browse",
            command=lambda: self.browse_for_CSV("store"))
        self.imp_store_import_button = Button(
            master,
            text="Import",
            command=lambda: self.import_to_DB(self.imp_store_entry.get(),
                                              "store"))

        self.imp_member_label = Label(
            master, text="Import Member Information (.CSV)"
        )  #Initilize lable, entry, and buttons for importing members
        self.imp_member_entry = Entry(master, width=70)
        self.imp_member_browse_button = Button(
            master,
            text="Browse",
            command=lambda: self.browse_for_CSV("member"))
        self.imp_member_import_button = Button(
            master,
            text="Import",
            command=lambda: self.import_to_DB(self.imp_member_entry.get(),
                                              "member"))

        self.horz_divider = Frame(
            master, height=1, width=500, bg="black"
        )  #Initilize a frame shaped as a horizonal line as a divider

        self.view_all_members_button = Button(
            master,
            text="View All Members",
            width=17,
            command=lambda: self.select_all_members()
        )  #Initilize button for selecting all members and displaying them in tree

        self.zip_label = Label(
            master, text="Zip Code"
        )  #Initilize lable, entry, combobox, and buttons for
        self.zip_entry = Entry(
            master,
            width=10)  #finding who paid dues by zip code and month paid
        self.month_label = Label(master, text="Month")
        self.month_combobox = Combobox(master, width=10)
        self.month_combobox['values'] = ('January', 'February', 'March',
                                         'April', 'May', 'June', 'July',
                                         'August', 'September', 'October',
                                         'November', 'December')
        self.find_users_that_paid = Button(
            master,
            text="Current Paid Users",
            width=20,
            command=lambda: self.select_paid_dues_month(
                self.zip_entry.get(), self.month_combobox.current()))

        self.state_label = Label(
            master,
            text="State")  #Initilize lable, entry, combobox, and buttons for
        self.state_combobox = Combobox(
            master,
            width=3)  #finding users who have joined the club since a date
        self.state_combobox['values'] = ('MD', 'NC', 'PA', 'VA', 'WV'
                                         )  #and belong to a specific state
        self.date_label = Label(master, text="Date (YYYY-MM-DD)")
        self.date_entry = Entry(master, width=10)
        self.find_users_that_joined = Button(
            master,
            text="Users Joined Since",
            width=20,
            command=lambda: self.select_users_joined_since(
                self.state_combobox.get(), self.date_entry.get()))

        self.users_that_love_total_wine = Button(
            master,
            text="Users that Love Total Wine",
            width=20,
            command=lambda: self.select_users_love_Tot_Wine(
            ))  #Initilize button for finding users that love Total Wines

        self.users_favorite_stores = Button(
            master,
            text="User's Favorite Stores",
            width=20,
            command=lambda: self.select_users_fav_stores()
        )  #Initilize button for finding users, their favorite stores, and store locations

        self.table_tree = Treeview(
            master, selectmode="extended")  #Initilize tree for data viewing
        self.table_tree["columns"] = (
            "one", "two", "three", "four", "five", "six", "seven", "eight",
            "nine", "ten", "eleven")  #Provide max column count and identifiers
        for columns in self.table_tree[
                "columns"]:  #For loop to add all columns
            self.table_tree.column(columns, width=70, anchor=W)
        self.table_tree['show'] = 'headings'  #Remove empty identity column

        self.vert_scroll_bar = Scrollbar(
            orient="vertical",
            command=self.table_tree.yview)  #Initilize scroll bar
        self.table_tree.configure(yscrollcommand=self.vert_scroll_bar.set
                                  )  #Add scroll bar to table_tree

        self.imp_store_label.grid(
            sticky="W", row=1, column=1, padx=10,
            pady=(20, 0))  #Grid positioning for all initialized attributes
        self.imp_store_entry.grid(sticky="W",
                                  row=2,
                                  column=1,
                                  columnspan=3,
                                  padx=10)
        self.imp_store_browse_button.grid(row=2, column=4, padx=10)
        self.imp_store_import_button.grid(row=2, column=5)

        self.imp_member_label.grid(sticky="W", row=3, column=1, padx=10)
        self.imp_member_entry.grid(sticky="W",
                                   row=4,
                                   column=1,
                                   columnspan=3,
                                   padx=10)
        self.imp_member_browse_button.grid(row=4, column=4, padx=10)
        self.imp_member_import_button.grid(row=4, column=5)

        self.horz_divider.grid(row=5, column=0, columnspan=7, pady=20)

        self.view_all_members_button.grid(row=6, column=1, columnspan=5)

        self.zip_label.grid(sticky="W", row=7, column=1, pady=(15, 0))
        self.zip_entry.grid(sticky="W", row=8, column=1, pady=5)
        self.month_label.grid(sticky="W",
                              row=7,
                              column=1,
                              padx=(100, 0),
                              pady=(15, 0))
        self.month_combobox.grid(sticky="W",
                                 row=8,
                                 column=1,
                                 padx=(100, 0),
                                 pady=5)
        self.find_users_that_paid.grid(sticky="W",
                                       row=9,
                                       column=1,
                                       columnspan=3,
                                       pady=5)

        self.state_label.grid(sticky="W", row=7, column=4, pady=(15, 0))
        self.state_combobox.grid(sticky="W", row=8, column=4, pady=5)
        self.date_label.grid(sticky="W",
                             row=7,
                             column=4,
                             columnspan=3,
                             padx=(85, 0),
                             pady=(15, 0))
        self.date_entry.grid(sticky="W",
                             row=8,
                             column=4,
                             columnspan=2,
                             padx=(85, 0),
                             pady=5)
        self.find_users_that_joined.grid(sticky="W",
                                         row=9,
                                         column=4,
                                         columnspan=2,
                                         pady=5)

        self.users_that_love_total_wine.grid(sticky="W",
                                             row=10,
                                             column=1,
                                             columnspan=3,
                                             pady=(15, 0))

        self.users_favorite_stores.grid(sticky="W",
                                        row=10,
                                        column=4,
                                        columnspan=2,
                                        pady=(15, 0))

        self.table_tree.grid(sticky="NWES",
                             row=11,
                             column=0,
                             columnspan=7,
                             rowspan=2,
                             pady=10,
                             padx=(10, 0))
        self.vert_scroll_bar.grid(sticky="NWES",
                                  row=11,
                                  column=7,
                                  rowspan=2,
                                  pady=10,
                                  padx=(0, 10))

    def browse_for_CSV(
        self, CSV_type
    ):  #Class method for browse buttons. Used for passing file path to TKinter entries

        file = tkFileDialog.askopenfile(
            parent=root, mode='rb',
            title='Choose a file')  #Opens browse for file window

        if (file != None):  #If file exists read into data and close file

            data = file.read()
            file.close()

            if (
                    CSV_type == "store"
            ):  #In order to resuse code, this method works for both buttons
                self.imp_store_entry.delete(
                    0, END)  #through using a passed button identity variable
                self.imp_store_entry.insert(0, os.path.abspath(file.name))

            else:
                self.imp_member_entry.delete(0, END)  #Empties entry widget
                self.imp_member_entry.insert(
                    0, os.path.abspath(file.name)
                )  #Inserts file path into entry widget using os.path import
        else:  #Catches no file selected possibility
            tkMessageBox.showinfo("Error", "No File Selected")

        return None

    def create_DB_connection(
        self
    ):  #Class method for opening a database connection to the pythonsqlite.db file

        try:
            DB_file = "SQLite_db\pythonsqlite.db"
            conn = sqlite3.connect(DB_file)
            return conn

        except Error as e:  #Catches non-connectivity errors
            print(e)

        return None

    def import_to_DB(
        self, file_path, CSV_type
    ):  #Class method for import buttons. Used to open csv files from path string
        #in entry widgets. Then opens db connection to import data to db
        try:
            self.CSV_file = open(file_path, "r")  #Opens CSV file in read mode
        except IOError as e:  #Catches file not found error
            tkMessageBox.showinfo("Error", "File Not Found")
            return

        CSV_reader = csv.reader(
            self.CSV_file
        )  #Reads CSV file into CSV_reader using csv.reader import
        conn = self.create_DB_connection()  #Calls for DB connection to open

        cur = conn.cursor()

        if (
                CSV_type == "store"
        ):  #In order to resuse code, this method works for both buttons by passed type.
            if (next(CSV_reader)[0][0:8] !=
                    "Store id"):  #Checks CSV for proper store headings
                tkMessageBox.showinfo(
                    "CSV Type Error",
                    "Please Import a CSV file formated for store data.")
                self.CSV_file.close(
                )  #If not proper headings close file and display message
                return
            else:  #Create table Stores
                cur.execute(
                    '''CREATE TABLE IF NOT EXISTS Stores (                                                                                 
                                store_id INTEGER PRIMARY KEY, 
                                store_name VARCHAR, 
                                location VARCHAR)''')

                for row in CSV_reader:  #Insert new values for each row in CSV
                    cur.execute(
                        '''INSERT OR IGNORE INTO Stores (                                                                                  
                                    store_id, 
                                    store_name, 
                                    location) 
                                    VALUES (?, ?, ?)''', row)
                tkMessageBox.showinfo(
                    "Success!",
                    "Successfully Updated the Database")  #Display confirmation
                self.imp_store_entry.delete(0, END)  #Clear import entry

        else:
            if (next(CSV_reader)[0][0:6] !=
                    "Member"):  #Checks CSV for proper member headings
                tkMessageBox.showinfo(
                    "CSV Type Error",
                    "Please Import a CSV file formated for member data.")
                self.CSV_file.close(
                )  #If not proper headings close file and display message
                return
            else:  #Create table Members
                cur.execute('''CREATE TABLE IF NOT EXISTS Members (     
                                member_id INTEGER PRIMARY KEY, 
                                last_name VARCHAR, 
                                first_name VARCHAR, 
                                street VARCHAR, 
                                city VARCHAR, 
                                state VARCHAR, 
                                zip VARCHAR, 
                                phone VARCHAR, 
                                favorite_store INTEGER, 
                                date_joined DATE, 
                                dues_paid DATE, 
                                FOREIGN KEY(favorite_store) 
                                REFERENCES Stores(store_id))''')

                for row in CSV_reader:  #Insert new values for each row in CSV
                    cur.execute(
                        '''INSERT OR IGNORE INTO Members (
                                        member_id, 
                                        last_name, 
                                        first_name, 
                                        street, 
                                        city , 
                                        state, 
                                        zip, 
                                        phone, 
                                        favorite_store, 
                                        date_joined, 
                                        dues_paid) 
                                        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''',
                        row)
                tkMessageBox.showinfo("Success!",
                                      "Successfully Updated the Database")
                self.imp_member_entry.delete(0, END)

        self.CSV_file.close()  #Close CSV file
        conn.commit()  #Commit DB changes
        conn.close()  #Close DB Connection

        return None

    def generate_member_column_names(
            self
    ):  #Class utility method for adding member column headers to tree

        all_member_column_names = ("Member ID", "Last Name", "First Name",
                                   "Street", "City", "State", "Zip Code",
                                   "Phone", "Favorite Store", "Date Joined",
                                   "Dues Paid")

        for index, columns in enumerate(self.table_tree["columns"]
                                        ):  #For loop to add all column headers
            self.table_tree.heading(columns,
                                    text=all_member_column_names[index])

        return None

    def select_all_members(
        self
    ):  #Class method for View All Members Buttons and outputs new data to tree

        cur = self.create_DB_connection().cursor(
        )  #Calls for DB connection to open
        cur.execute("SELECT * FROM Members ORDER BY last_name ASC"
                    )  #SQL Statement to SELECT all members and their data.

        rows = cur.fetchall()  #Fetches data into rows

        self.table_tree.delete(*self.table_tree.get_children()
                               )  #Deletes old data in tree if present

        self.generate_member_column_names(
        )  #Call utility to generate column member headers

        for index, row in enumerate(
                rows):  #Inserts sql data into tree rows for viewing
            self.table_tree.insert('', index, values=(row))

        self.create_DB_connection().close()  #Close DB Connection
        return None

    def select_paid_dues_month(
        self, zip, month
    ):  #Class method for Current Paid User Button and outputs new data to tree

        month = month + 1  #Add 1 to month index count since it range is 0-11 and months are 1-12
        if (month < 10):
            self.month_string = "0" + str(month)

        cur = self.create_DB_connection().cursor(
        )  #Calls for DB connection to open

        if (month not in range(1, 12)):  #If no month selected display message
            tkMessageBox.showinfo("Error", "No Month Selected")
            return

        if (len(zip) != 5):  #If zip not 5 digits display message
            tkMessageBox.showinfo("Error", "Enter a Zip Code")
            return

        try:
            cur.execute("SELECT * FROM Members WHERE zip = " + zip +
                        " AND strftime('%m',dues_paid) = '" +
                        self.month_string +
                        "'")  #If zip is numeric execute Select Statement
        except Error as e:  #Catches error if zip not numeric
            tkMessageBox.showinfo("Error", "Enter a Zip Code")
            return

        rows = cur.fetchall()

        self.table_tree.delete(*self.table_tree.get_children()
                               )  #Deletes old data in tree if present

        self.generate_member_column_names(
        )  #Call utility to generate column member headers

        for index, row in enumerate(
                rows):  #Inserts sql data into tree rows for viewing
            self.table_tree.insert('', index, values=(row))

        self.create_DB_connection().close()  #Close DB Connection
        return None

    def select_users_joined_since(
        self, state, the_date
    ):  #Class method for Current Paid User Button and outputs new data to tree

        cur = self.create_DB_connection().cursor(
        )  #Calls for DB connection to open

        if state == "":  #if no state selected display message
            tkMessageBox.showinfo("Error", "No State Selected")
            return

        try:  #Checks date format YYYY-MM-DD
            datetime.datetime.strptime(the_date, '%Y-%m-%d')
        except ValueError:  #Catches invalid date format
            tkMessageBox.showinfo(
                "Error", "Incorrect data format, should be YYYY-MM-DD")
            return

        cur.execute(
            "SELECT * FROM Members WHERE state = '" + state +
            "' AND date_joined > '" + the_date + "'"
        )  #Execute Select members Where state and date are what user selected.

        rows = cur.fetchall()

        self.table_tree.delete(*self.table_tree.get_children()
                               )  #Deletes old data in tree if present

        self.generate_member_column_names(
        )  #Call utility to generate column member headers

        for index, row in enumerate(
                rows):  #Inserts sql data into tree rows for viewing
            self.table_tree.insert('', index, values=(row))

        self.create_DB_connection().close()  #Close DB Connection
        return None

    def select_users_love_Tot_Wine(
        self
    ):  #Class method for Users That Love Tot Wine and outputs new data to tree

        cur = self.create_DB_connection().cursor(
        )  #Calls for DB connection to open
        #Execute Select Where, and Join on foreign key values.
        cur.execute('''SELECT Members.last_name,
                            Members.first_name, 
                            Stores.store_name 
                            FROM Members 
                            JOIN Stores 
                            ON Members.favorite_store = Stores.store_id 
                            WHERE favorite_store = '3' ''')

        rows = cur.fetchall()

        self.table_tree.delete(*self.table_tree.get_children()
                               )  #Deletes old data in tree if present

        all_member_column_names = ("Last Name", "First Name", "Favorite Store",
                                   "", "", "", "", "", "", "", "")

        for index, columns in enumerate(
                self.table_tree["columns"]
        ):  #Generate *custom* column member headers
            self.table_tree.heading(columns,
                                    text=all_member_column_names[index])

        for index, row in enumerate(
                rows):  #Inserts sql data into tree rows for viewing
            self.table_tree.insert('', index, values=(row))

        self.create_DB_connection().close()  #Close DB Connection
        return None

    def select_users_fav_stores(
        self
    ):  #Class method for Users Favorite Stores and outputs new data to tree

        cur = self.create_DB_connection().cursor(
        )  #Calls for DB connection to open
        #Execute Select Where, and Join on foreign key values.
        cur.execute('''SELECT Members.last_name,
                    Members.first_name, 
                    Stores.store_name, 
                    Stores.location
                    FROM Members 
                    JOIN Stores 
                    ON Members.favorite_store = Stores.store_id ''')

        rows = cur.fetchall()

        self.table_tree.delete(*self.table_tree.get_children()
                               )  #Deletes old data in tree if present

        all_member_column_names = ("Last Name", "First Name", "Favorite Store",
                                   "Location", "", "", "", "", "", "", "")

        for index, columns in enumerate(
                self.table_tree["columns"]
        ):  #Generate *custom* column member headers
            self.table_tree.heading(columns,
                                    text=all_member_column_names[index])

        for index, row in enumerate(
                rows):  #Inserts sql data into tree rows for viewing
            self.table_tree.insert('', index, values=(row))

        self.create_DB_connection().close()  #Close DB Connection
        return None
예제 #23
0
class Ordered_Listbox(Frame):
    def __init__(self,
                 master,
                 data=None,
                 ascending_order=True,
                 ignore_case=False,
                 autoscroll=False,
                 vscrollbar=True,
                 hscrollbar=False,
                 scrollbar_background=None,
                 scrollbar_troughcolor=None,
                 **kwargs):
        Frame.__init__(self, master)

        self._ignore_case = ignore_case
        self._ascending_order = ascending_order

        master.grid_rowconfigure(0, weight=1)
        master.grid_columnconfigure(0, weight=1)

        self._listbox = Listbox(self, *kwargs)
        self._listbox.grid(row=0, column=0, sticky=N + E + W + S)

        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:
            self._vbar = Scrollbar(self,
                                   takefocus=0,
                                   command=self._listbox.yview,
                                   **scrollbar_kwargs)
            self._vbar.grid(row=0, column=1, sticky=N + S)

            if autoscroll:
                self._listbox.config(yscrollcommand=lambda f, l:
                                     make_autoscroll(self._vbar, f, l))
            else:
                self._listbox.config(yscrollcommand=self._vbar.set)

        if hscrollbar:
            self._hbar = Scrollbar(self,
                                   takefocus=0,
                                   command=self._listbox.xview,
                                   **scrollbar_kwargs)
            self._hbar.grid(row=0, column=1, sticky=E + W)

            if autoscroll:
                self._listbox.config(xscrollcommand=lambda f, l:
                                     make_autoscroll(self._hbar, f, l))
            else:
                self._listbox.config(xscrollcommand=self._hbar.set)

        if data is not None:
            for item in data:
                self.add_item(item)

    def add_item(self, item):
        list_of_items = self._listbox.get(0, END)

        index = bisect(list_of_items,
                       item,
                       ignore_case=self._ignore_case,
                       ascending_order=self._ascending_order)
        self._listbox.insert(index, item)

    def delete_item(self, item):
        list_of_items = self._listbox.get(0, END)
        index = bisect(list_of_items,
                       item,
                       ignore_case=self._ignore_case,
                       ascending_order=self._ascending_order)
        self._listbox.delete(index - 1)

    def selected_items(self):
        list_of_items = []

        for index in self._listbox.curselection():
            list_of_items.append(self._listbox.get(index))

        return list_of_items

    def selected_item(self):
        return self._listbox.curselection()[0]

    def deselect_all(self):
        self._listbox.selection_clear(0, END)

    def select(self, item):
        index = self.index(item)

        if index is None:
            return

        self._listbox.selection_set(index)

    def deselect(self, item):
        index = self.index(item)

        if index is None:
            return

        self._listbox.selection_clear(index)

    def index(self, item):
        list_of_items = self._listbox.get(0, END)

        try:
            index = list_of_items.index(item)
        except ValueError:
            return None

        return index

    def bind(self, event, handler):
        self._listbox.bind(event, handler)

    def clear(self):
        self._listbox.delete(1, END)

    def __iter__(self):
        return self.items

    @property
    def items(self):
        return self._listbox.get(0, END)
예제 #24
0
class Multicolumn_Listbox(object):
    _style_index = 0

    class List_Of_Rows(object):
        def __init__(self, multicolumn_listbox):
            self._multicolumn_listbox = multicolumn_listbox

        def data(self, index):
            return self._multicolumn_listbox.row_data(index)

        def get(self, index):
            return Row(self._multicolumn_listbox, index)

        def insert(self, data, index=None):
            self._multicolumn_listbox.insert_row(data, index)

        def delete(self, index):
            self._multicolumn_listbox.delete_row(index)

        def update(self, index, data):
            self._multicolumn_listbox.update_row(index, data)

        def select(self, index):
            self._multicolumn_listbox.select_row(index)

        def deselect(self, index):
            self._multicolumn_listbox.deselect_row(index)

        def set_selection(self, indices):
            self._multicolumn_listbox.set_selection(indices)

        def __getitem__(self, index):
            return self.get(index)

        def __setitem__(self, index, value):
            return self._multicolumn_listbox.update_row(index, value)

        def __delitem__(self, index):
            self._multicolumn_listbox.delete_row(index)

        def __len__(self):
            return self._multicolumn_listbox.number_of_rows

    class List_Of_Columns(object):
        def __init__(self, multicolumn_listbox):
            self._multicolumn_listbox = multicolumn_listbox

        def data(self, index):
            return self._multicolumn_listbox.get_column(index)

        def get(self, index):
            return Column(self._multicolumn_listbox, index)

        def delete(self, index):
            self._multicolumn_listbox.delete_column(index)

        def update(self, index, data):
            self._multicolumn_listbox.update_column(index, data)

        def __getitem__(self, index):
            return self.get(index)

        def __setitem__(self, index, value):
            return self._multicolumn_listbox.update_column(index, value)

        def __delitem__(self, index):
            self._multicolumn_listbox.delete_column(index)

        def __len__(self):
            return self._multicolumn_listbox.number_of_columns

    def __init__(self,
                 master,
                 columns,
                 data=None,
                 command=None,
                 sort=True,
                 select_mode=None,
                 heading_anchor=CENTER,
                 cell_anchor=W,
                 style=None,
                 height=None,
                 padding=None,
                 adjust_heading_to_content=False,
                 striped_rows=None,
                 selection_background=None,
                 selection_foreground=None,
                 field_background=None,
                 heading_font=None,
                 heading_background=None,
                 heading_foreground=None,
                 cell_pady=2,
                 cell_background=None,
                 cell_foreground=None,
                 cell_font=None,
                 headers=True,
                 right_click_command=None):

        self._striped_rows = striped_rows

        self._columns = columns

        self._number_of_rows = 0
        self._number_of_columns = len(columns)

        self.row = self.List_Of_Rows(self)
        self.column = self.List_Of_Columns(self)

        s = Style()

        if style is None:
            style_name = "Multicolumn_Listbox%s.Treeview" % self._style_index
            self._style_index += 1
        else:
            style_name = style

        style_map = {}
        if selection_background is not None:
            style_map["background"] = [('selected', selection_background)]

        if selection_foreground is not None:
            style_map["foreground"] = [('selected', selection_foreground)]

        if style_map:
            s.map(style_name, **style_map)

        style_config = {}
        if cell_background is not None:
            style_config["background"] = cell_background

        if cell_foreground is not None:
            style_config["foreground"] = cell_foreground

        if cell_font is None:
            font_name = s.lookup(style_name, "font")
            cell_font = nametofont(font_name)
        else:
            if not isinstance(cell_font, Font):
                if isinstance(cell_font, basestring):
                    cell_font = nametofont(cell_font)
                else:
                    if len(cell_font) == 1:
                        cell_font = Font(family=cell_font[0])
                    elif len(cell_font) == 2:
                        cell_font = Font(family=cell_font[0],
                                         size=cell_font[1])

                    elif len(cell_font) == 3:
                        cell_font = Font(family=cell_font[0],
                                         size=cell_font[1],
                                         weight=cell_font[2])
                    else:
                        raise ValueError(
                            "Not possible more than 3 values for font")

            style_config["font"] = cell_font

        self._cell_font = cell_font

        self._rowheight = cell_font.metrics("linespace") + cell_pady
        style_config["rowheight"] = self._rowheight

        if field_background is not None:
            style_config["fieldbackground"] = field_background

        s.configure(style_name, **style_config)

        heading_style_config = {}
        if heading_font is not None:
            heading_style_config["font"] = heading_font
        if heading_background is not None:
            heading_style_config["background"] = heading_background
        if heading_foreground is not None:
            heading_style_config["foreground"] = heading_foreground

        heading_style_name = style_name + ".Heading"
        s.configure(heading_style_name, **heading_style_config)

        treeview_kwargs = {"style": style_name}

        if height is not None:
            treeview_kwargs["height"] = height

        if padding is not None:
            treeview_kwargs["padding"] = padding

        if headers:
            treeview_kwargs["show"] = "headings"
        else:
            treeview_kwargs["show"] = ""

        if select_mode is not None:
            treeview_kwargs["selectmode"] = select_mode

        self.interior = Treeview(master, columns=columns, **treeview_kwargs)
        # tjw Scrollbar add
        self.scrollbar = Scrollbar(master,
                                   orient=VERTICAL,
                                   command=self.interior.yview)
        self.interior.configure(yscrollcommand=self.scrollbar.set)
        self.scrollbar.grid(row=1, column=len(columns), sticky='NSE')
        self.interior.grid(row=1, column=0)
        #master.grid_columnconfigure(0, weight=1)
        #master.grid_columnconfigure(1, weight=1)

        if command is not None:
            self._command = command
            self.interior.bind("<<TreeviewSelect>>", self._on_select)

        if right_click_command is not None:
            self._right_click_command = right_click_command
            self.interior.bind("<Button-3>", self._on_right_click)

        for i in range(0, self._number_of_columns):

            if sort:
                self.interior.heading(
                    i,
                    text=columns[i],
                    anchor=heading_anchor,
                    command=lambda col=i: self.sort_by(col, descending=False))
            else:
                self.interior.heading(i,
                                      text=columns[i],
                                      anchor=heading_anchor)

            if adjust_heading_to_content:
                self.interior.column(i, width=Font().measure(columns[i]))

            self.interior.column(i, anchor=cell_anchor)

        if data is not None:
            for row in data:
                self.insert_row(row)

    @property
    def row_height(self):
        return self._rowheight

    @property
    def font(self):
        return self._cell_font

    def configure_column(self,
                         index,
                         width=None,
                         minwidth=None,
                         anchor=None,
                         stretch=None):
        kwargs = {}
        for config_name in ("width", "anchor", "stretch", "minwidth"):
            config_value = locals()[config_name]
            if config_value is not None:
                kwargs[config_name] = config_value

        self.interior.column('#%s' % (index + 1), **kwargs)

    def row_data(self, index):
        try:
            item_ID = self.interior.get_children()[index]
        except IndexError:
            raise ValueError("Row index out of range: %d" % index)

        return self.item_ID_to_row_data(item_ID)

    def update_row(self, index, data):
        try:
            item_ID = self.interior.get_children()[index]
        except IndexError:
            raise ValueError("Row index out of range: %d" % index)

        if len(data) == len(self._columns):
            self.interior.item(item_ID, values=data)
        else:
            raise ValueError("The multicolumn listbox has only %d columns" %
                             self._number_of_columns)

    def delete_row(self, index):
        list_of_items = self.interior.get_children()

        try:
            item_ID = list_of_items[index]
        except IndexError:
            raise ValueError("Row index out of range: %d" % index)

        self.interior.delete(item_ID)
        self._number_of_rows -= 1

        if self._striped_rows:
            for i in range(index, self._number_of_rows):
                self.interior.tag_configure(list_of_items[i + 1],
                                            background=self._striped_rows[i %
                                                                          2])

    def insert_row(self, data, index=None):
        if len(data) != self._number_of_columns:
            raise ValueError("The multicolumn listbox has only %d columns" %
                             self._number_of_columns)

        if index is None:
            index = self._number_of_rows - 1

        item_ID = self.interior.insert('', index, values=data)
        self.interior.item(item_ID, tags=item_ID)

        self._number_of_rows += 1

        if self._striped_rows:
            list_of_items = self.interior.get_children()

            self.interior.tag_configure(item_ID,
                                        background=self._striped_rows[index %
                                                                      2])

            for i in range(index + 1, self._number_of_rows):
                self.interior.tag_configure(list_of_items[i],
                                            background=self._striped_rows[i %
                                                                          2])

    def column_data(self, index):
        return [
            self.interior.set(child_ID, index)
            for child_ID in self.interior.get_children('')
        ]

    def update_column(self, index, data):
        for i, item_ID in enumerate(self.interior.get_children()):
            data_row = self.item_ID_to_row_data(item_ID)
            data_row[index] = data[i]

            self.interior.item(item_ID, values=data_row)

        return data

    def clear(self):
        # Another possibility:
        #  self.interior.delete(*self.interior.get_children())

        for row in self.interior.get_children():
            self.interior.delete(row)

        self._number_of_rows = 0

    def update(self, data):
        self.clear()

        for row in data:
            self.insert_row(row)

    def focus(self, index=None):
        if index is None:
            return self.interior.item(self.interior.focus())
        else:
            item = self.interior.get_children()[index]
            self.interior.focus(item)

    def state(self, state=None):
        if state is None:
            return self.interior.state()
        else:
            self.interior.state(state)

    @property
    def number_of_rows(self):
        return self._number_of_rows

    @property
    def number_of_columns(self):
        return self._number_of_columns

    def toogle_selection(self, index):
        list_of_items = self.interior.get_children()

        try:
            item_ID = list_of_items[index]
        except IndexError:
            raise ValueError("Row index out of range: %d" % index)

        self.interior.selection_toggle(item_ID)

    def select_row(self, index):
        list_of_items = self.interior.get_children()

        try:
            item_ID = list_of_items[index]
        except IndexError:
            raise ValueError("Row index out of range: %d" % index)

        self.interior.selection_add(item_ID)

    def deselect_row(self, index):
        list_of_items = self.interior.get_children()

        try:
            item_ID = list_of_items[index]
        except IndexError:
            raise ValueError("Row index out of range: %d" % index)

        self.interior.selection_remove(item_ID)

    def deselect_all(self):
        self.interior.selection_remove(self.interior.selection())

    def set_selection(self, indices):
        list_of_items = self.interior.get_children()

        self.interior.selection_set(" ".join(list_of_items[row_index]
                                             for row_index in indices))

    @property
    def selected_rows(self):
        data = []
        for item_ID in self.interior.selection():
            data_row = self.item_ID_to_row_data(item_ID)
            data.append(data_row)

        return data

    @property
    def indices_of_selected_rows(self):
        list_of_indices = []
        for index, item_ID in enumerate(self.interior.get_children()):
            if item_ID in self.interior.selection():
                list_of_indices.append(index)

        return list_of_indices

    def delete_all_selected_rows(self):
        selected_items = self.interior.selection()
        for item_ID in selected_items:
            self.interior.delete(item_ID)

        number_of_deleted_rows = len(selected_items)
        self._number_of_rows -= number_of_deleted_rows

        return number_of_deleted_rows

    def _on_select(self, event):
        for item_ID in event.widget.selection():
            data_row = self.item_ID_to_row_data(item_ID)
            self._command(data_row)

    def _on_right_click(self, event):
        item_ID = event.widget.identify_row(event.y)
        data_row = self.item_ID_to_row_data(item_ID)
        if data_row:
            self._right_click_command(data_row)

    def item_ID_to_row_data(self, item_ID):
        item = self.interior.item(item_ID)
        return item["values"]

    @property
    def table_data(self):
        data = []

        for item_ID in self.interior.get_children():
            data_row = self.item_ID_to_row_data(item_ID)
            data.append(data_row)

        return data

    @table_data.setter
    def table_data(self, data):
        self.update(data)

    def cell_data(self, row, column):
        """Get the value of a table cell"""
        try:
            item = self.interior.get_children()[row]
        except IndexError:
            raise ValueError("Row index out of range: %d" % row)

        return self.interior.set(item, column)

    def update_cell(self, row, column, value):
        """Set the value of a table cell"""

        item_ID = self.interior.get_children()[row]

        data = self.item_ID_to_row_data(item_ID)

        data[column] = value
        self.interior.item(item_ID, values=data)

    def __getitem__(self, index):
        if isinstance(index, tuple):
            row, column = index
            return self.cell_data(row, column)
        else:
            raise Exception("Row and column indices are required")

    def __setitem__(self, index, value):
        if isinstance(index, tuple):
            row, column = index
            self.update_cell(row, column, value)
        else:
            raise Exception("Row and column indices are required")

    def bind(self, event, handler):
        self.interior.bind(event, handler)

    def sort_by(self, col, descending):
        """
        sort tree contents when a column header is clicked
        """
        # grab values to sort
        data = [(self.interior.set(child_ID, col), child_ID)
                for child_ID in self.interior.get_children('')]

        # if the data to be sorted is numeric change to float
        try:
            data = [(float(number), child_ID) for number, child_ID in data]
            # now sort the data in place
            data.sort(reverse=descending)
        except ValueError:
            # now sort the strings in place, ignoring case
            data.sort(reverse=descending, key=lambda x: x[0].lower())

        for idx, item in enumerate(data):
            self.interior.move(item[1], '', idx)

        # switch the heading so that it will sort in the opposite direction
        self.interior.heading(
            col, command=lambda col=col: self.sort_by(col, not descending))

        if self._striped_rows:
            list_of_items = self.interior.get_children('')
            for i in range(len(list_of_items)):
                self.interior.tag_configure(list_of_items[i],
                                            background=self._striped_rows[i %
                                                                          2])

    def destroy(self):
        self.interior.destroy()

    def item_ID(self, index):
        return self.interior.get_children()[index]
예제 #25
0
class JobList(Frame):
    # NOTE: job_params contains information about a Job in the Joblist
    # NOTE: plot_args contains information about plotting information, which occurs after the jobs have been and the data files have been created

    def __init__(self, parent=None, **kwargs):
        Frame.__init__(self, parent)
        self.parent = parent
        self.job_list_yscroll = Scrollbar(self, orient=Tkinter.VERTICAL)
        self.job_list_xscroll = Scrollbar(self, orient=Tkinter.HORIZONTAL)
        self.job_list = Listbox(self, xscrollcommand=self.job_list_xscroll, yscrollcommand=self.job_list_yscroll)
        self.job_list_xscroll['command'] = self.job_list.xview
        self.job_list_yscroll['command'] = self.job_list.yview
        self.new_job_frame = Frame(self)
        add_icon_filename = kwargs['add_icon_filename'] if 'add_icon_filename' in kwargs else None
        if add_icon_filename == None:
            self.add_job_button = Button(self.new_job_frame, text='Add Job', command=self.on_add)
        else:
            add_icon = PhotoImage(file=add_icon_filename)
            self.add_job_button = Button(self.new_job_frame, text='Add Job', compound='bottom', image=add_icon, command=self.on_add)
        self.remove_job_button = Button(self.new_job_frame, text='Remove Job', command=self.on_remove)
        self.progress_frame = Frame(self)
        self.progress_value = Tkinter.IntVar()
        self.progress_bar = Progressbar(self.progress_frame, variable=self.progress_value)
        self.button_frame = Frame(self)
        self.process_button = ProcessButton(parent=self.button_frame, start_jobs=self.start_jobs)
        self.quit_button = QuitButton(parent=self.button_frame, close_other_windows=self.close_top_level_windows)

        self.run_job = kwargs['run_job'] if 'run_job' in kwargs else None

        self.create_plots = kwargs['create_plots'] if 'create_plots' in kwargs else None

        self.log_filename = kwargs['log_filename'] if 'log_filename' in kwargs else None

        self.bind('<<AskToClearJobs>>', self.ask_to_clear_jobs)
        self.bind('<<AskToPlotGraphs>>', self.ask_to_plot_graphs)
        self.bind('<<CreatePlotGUI>>', self.create_plot_gui)
        self.parent.bind('<ButtonPress>', self.on_press)
        self.parent.bind('<Configure>', self.on_resize)

        self.reinit_variables()

        self.top_level_windows = list()

        # NOTE: Because there seems to be an issue resizing child widgets when the top level (Tk) widget is being resized,
        # the resize option will be disabled for this window
        self.parent.resizable(width=False, height=False)

        self.lift()

    def reinit_variables(self):
        self.job_params = dict()

        self.last_job_id = -1

        self.job_outcomes = list()

        self.plot_args = list()

        self.on_button = False

    def add_job_params(self, input_args):
        self.job_params = input_args
        # Add each element to the job list
        for job in self.job_params:
            self.add_job(job)

    def add_job(self, job):
        try:
            index_end = job['input_directory'].rindex('/')
            index_start = job['input_directory'].rindex('/', 0, index_end)
            input_directory_text = job['input_directory']
            list_text = 'Job ' + str(job['job_id']) + ' \'' + input_directory_text + '\''
            if job['start'] != None:
                list_text += ' ' + str(job['start'])
                if job['end'] != None:
                    list_text += ' to'
            if job['end'] != None:
                list_text += ' ' + str(job['end'])

            if job['job_id'] > self.last_job_id:
                self.last_job_id = job['job_id']

            self.job_list.insert(Tkinter.END, list_text)

            # Add the list text to the job params as an optional parameter to read later to display in a future Graph GUI (or for any other useful purpose)
            job['list_text'] = list_text

            # The line number is used wrt the GUI to indicate which job in the job list is being currently executed.
            job['line_number'] = self.job_list.size() - 1
            #print str(job['line_number'])

            self.job_params[job['job_id']] = job
        except KeyError as ke:
            # Should show some error message indicating that there is a problem.
            pass

        #print str(self.job_params)
        #print 'Added Job ' + str(job['job_id'])

    def ask_to_clear_jobs(self, event):
        for job in self.job_params.itervalues():
            line_number = job['line_number']
            self.job_list.itemconfig(line_number, foreground='black')

        # Update parent to refresh widget appearance
        self.parent.update()

        # Reactivate process button
        self.process_button.config(state = Tkinter.NORMAL)

        # Note: Display a pop-up that tells the user that the job is done and asks if the job list should be cleared.

        clearList = msg.askyesno(title='Jobs Finished', message='All jobs have been completed.  Would you like to clear the job list?', master=self)
        if clearList:
            self.clear_list()

    def ask_to_plot_graphs(self, event):
        # TODO: Add a dialog that also asks to create a graph of the 'Other Type Of Plot'
        plotGraphs = msg.askyesno(title='Plot Graphs', message='Create plots of data?', master=self)

        if not plotGraphs:
            return

        # TODO: Iterate through the jobs to display to the user an interface that asks if they want to graphs of the outputs
        if self.create_plots != None:
            output_files_list = list()
            for job_outcome in self.job_outcomes:
                for output_outcomes in job_outcome[2]:
                    (station, output_directory, output_files) = output_outcomes
                    for output_files_tuple in output_files:
                        for output_file_tuple in output_files_tuple:
                            (output_file, output_file_success) = output_file_tuple
                            if output_file_success:
                                # If there is a list text variable (the 4th (or 3rd by 0 based index) variable), then add it to our output list
                                if len(job_outcome) == 4:
                                    output_files_list.append([output_file, job_outcome[3]])
                                else:
                                    output_files_list.append([output_file])

            plots_thread = PlotsThread(self.create_plots, output_files_list, self)
            plots_thread.start()

    def add_plot(self, args=dict()):
        self.plot_args.append(args)

    def finished_adding_plots(self):
        self.event_generate('<<CreatePlotGUI>>', when='tail')

    def create_plot_gui(self, event):
        # TODO: This should be replaced with a new window that allows the user to drag and drop the icons from one frame to another
        graph_names = list()
        for args in self.plot_args:
            graph_name = args['output_file']
            graph_names.append(graph_name)
        dnd_graphs_frame = Dnd.createFrame(self, 'Drag and Drop Output Plots', graph_names, self.finish_creating_plot_gui)

    # This is the entry point for the
    def finish_creating_plot_gui(self, plot_labels):
        graph_count = 1
        for plot_label in plot_labels:
            for args in self.plot_args:
                #print 'Looking in ' + args['plot_title'] + ' for ' + plot_label
                #print 'The plot label is: ' + plot_label
                #print 'The output file is: ' + args['output_file']
                if plot_label == args['output_file']:
                    #print 'Creating graph ' + str(graph_count)
                    graph_count += 1
                    graph_window = ModelRunnerGraphGUI.GraphWindow(parent=self, title=args['window_title'], df=args['df'], plot=args['plot'], plot_title=args['plot_title'], y_label=args['y_label'], log_filename=self.log_filename)
                    graph_window.set_grid()
                    self.top_level_windows.append(graph_window)
        #print 'Creating plot GUI

        # Have to clear out list here instead of clear_list because clear_list() removes plot_args before this method has a chance to read
        # them and create the appropriate plot graph windows
        self.reinit_variables()

    # Clear all the elements in the list
    def clear_list(self):

        # Save plot args because they are need later in this run
        plot_args = self.plot_args
        self.reinit_variables()
        # Restore the plot args
        self.plot_args = plot_args

        self.job_list.delete(0, self.job_list.size())
        self.progress_value.set(0)
        # Update parent to refresh widget appearance
        self.parent.update()

    def on_add(self):
        single_job = JobParameters(parent=self.parent, beginning_year=1950, ending_year=2100, job_id=self.last_job_id + 1, entry=self)
        single_job.set_grid()

    def on_remove(self):
        selection = self.job_list.curselection()
        for line_number in selection:
            line_text = self.job_list.get(line_number)
            job_id = int(line_text[4:line_text.index(' ', 4)])
            job = self.job_params.pop(job_id)
            self.job_list.delete(line_number)
            print 'Removed Job ' + str(job['job_id'])
        # Fix line number
        for line_number in range(self.job_list.size()):
            line_text = self.job_list.get(line_number)
            job_id = int(line_text[4:line_text.index(' ', 4)])
            #print 'Job ' + str(job_id) + ' is now on line ' + str(line_number)
            self.job_params[job_id]['line_number'] = line_number

    def set_grid(self):
        self.grid(sticky=Tkinter.N + Tkinter.S + Tkinter.W + Tkinter.E, padx=4, pady=4)
        self.columnconfigure(0, minsize=600)
        self.rowconfigure(0, minsize=300)
        self.job_list.grid(row=0, column=0, sticky=Tkinter.N + Tkinter.S + Tkinter.E + Tkinter.W)
        self.job_list_yscroll.grid(row=0, column=1, sticky=Tkinter.N + Tkinter.S + Tkinter.W)
        self.job_list_xscroll.grid(row=1, column=0, sticky=Tkinter.E + Tkinter.W + Tkinter.N)
        self.new_job_frame.grid(row=2, column=0, pady=3, sticky=Tkinter.W)
        self.remove_job_button.grid(row=0, column=0)
        self.add_job_button.grid(row=0, column=1)
        self.progress_frame.grid(row=3, column=0, pady=3)
        self.progress_frame.columnconfigure(0, minsize=600)
        self.progress_bar.grid(row=0, column=0, sticky=Tkinter.E + Tkinter.W + Tkinter.N + Tkinter.S)
        self.button_frame.grid(row=4, column=0, sticky=Tkinter.E + Tkinter.W + Tkinter.N + Tkinter.S)
        self.button_frame.columnconfigure(0, minsize=300)
        self.button_frame.columnconfigure(1, minsize=300)
        self.process_button.pack(side=Tkinter.RIGHT)
        self.quit_button.pack(side=Tkinter.RIGHT)

    def start_jobs(self):
        # If there are no queued jobs then simply return
        if len(self.job_params) == 0 or len(self.job_list.get(0)) == 0:
            return
        # Deactivate the process button
        self.process_button.config(state = Tkinter.DISABLED)
        # Initialize the progress bar
        self.progress_value.set(0)
        # Update parent to refresh widget appearance
        self.parent.update()
        # Start process thread
        jobs_thread = JobsThread(self.job_params, self.run_job, self.on_update, self.on_resume)
        jobs_thread.start()
        self['cursor'] = 'wait'

    def on_update(self, status, line_number, step):
        if status == 'init':
            self.job_list.itemconfig(line_number, foreground='green')
            self.job_list.activate(line_number)
        elif status == 'success':
            self.job_list.itemconfig(line_number, foreground='blue')
        elif status == 'fail':
            self.job_list.itemconfig(line_number, foreground='red')
        self.progress_value.set(step)
        # Update parent to refresh widget appearance
        self.parent.update()

    def on_resume(self, job_outcomes=list()):
        self.progress_value.set(100)
        self.job_outcomes = job_outcomes
        self.event_generate('<<AskToClearJobs>>', when='tail')
        self.event_generate('<<AskToPlotGraphs>>', when='tail')
        self['cursor'] = 'arrow'

    def close_top_level_windows(self):
        #print 'Closing other top level windows'
        for top_level_window in self.top_level_windows:
            if top_level_window:
                top_level_window.withdraw()
                top_level_window.destroy()

    def notify_of_close(self, top_level_window):
        if top_level_window in self.top_level_windows:
            #print 'Removing top level window'
            self.top_level_windows.remove(top_level_window)

    def on_press(self, event):
        self.on_button = True
        self.release_pattern = "<B%d-ButtonRelease-%d>" % (event.num, event.num)
        self.parent.bind(self.release_pattern, self.on_release)

    def on_release(self, event):
        self.on_button = False

    def on_resize(self, event):
        self.parent.lift()

        if self.on_button:

            self.set_grid()

    def on_close(self):
        self.plot_args = list()
        self.withdraw()
        self.destroy()
예제 #26
0
class XML_Viwer(Frame):

    def __init__(self, master, xml=None, heading_text=None, heading_anchor=None, padding=None, cursor=None, takefocus=None, style=None):
        Frame.__init__(self, master, class_="XML_Viwer")

        self._vsb = Scrollbar(self, orient=VERTICAL)
        self._hsb = Scrollbar(self, orient=HORIZONTAL)

        kwargs = {}
        kwargs["yscrollcommand"] = lambda f, l: autoscroll(self._vsb, f, l)
        kwargs["xscrollcommand"] = lambda f, l: autoscroll(self._hsb, f, l)
       
        if style is not None:
            kwargs["style"] = style
            
        if padding is not None:
            kwargs["padding"] = padding
            
        if cursor is not None:
            kwargs["cursor"] = cursor
            
        if takefocus is not None:
            kwargs["takefocus"] = takefocus

        self._treeview = Treeview(self, **kwargs)
        
        if heading_text is not None:
            if heading_anchor is not None:
                self._treeview.heading("#0", text=heading_text, anchor=heading_anchor)
            else:
                self._treeview.heading("#0", text=heading_text)

        self._treeview.bind("<<TreeviewOpen>>", self._on_open)
        self._treeview.bind("<<TreeviewClose>>", self._on_close)
        
        # Without this line, horizontal scrolling doesn't work properly.
        self._treeview.column("#0", stretch= False)

        self._vsb['command'] = self._treeview.yview
        self._hsb['command'] = self._treeview.xview

        self._treeview.grid(column=0, row=0, sticky=N+S+W+E)
        self._vsb.grid(column=1, row=0, sticky=N+S)
        self._hsb.grid(column=0, row=1, sticky=E+W)
        
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)

        self._element_tree = None
        self._item_ID_to_element = {}

        if xml is not None:
            self.parse_xml(xml)

    def _on_open(self, event):
        item_ID = self._treeview.focus()
        if item_ID not in self._item_ID_to_element: return

        node = self._item_ID_to_element[item_ID]

        self._treeview.item(item_ID, text = self._repr_of_openning_tag(node))
        
    def _on_close(self, event):
        item_ID = self._treeview.focus()
        if item_ID not in self._item_ID_to_element: return

        node = self._item_ID_to_element[item_ID]
        
        text = self._repr_of_openning_tag(node) + self._repr_of_closing_tag(node)
        self._treeview.item(item_ID, text = text)

    def parse_xml(self, xml):
        self._element_tree = ET.ElementTree(ET.fromstring(xml))
        
        self.clear()
        self._walk_xml(self._element_tree.getroot())
        
    @property
    def element_tree(self):
        return self._element_tree
    
    @element_tree.setter
    def element_tree(self, element_tree):
        self._element_tree = element_tree
        
        self.clear()
        self._walk_xml(element_tree.getroot())   
        
    def clear(self):
        self._item_ID_to_element = {}
        self._treeview.delete(*self._treeview.get_children())
        
    def _repr_of_openning_tag(self, node):
        text = "<" + node.tag

        attrs = node.attrib
        
        # list function is here necessary to provide support to Python 3
        a_names = list(attrs.keys())
        a_names.sort()

        for a_name in a_names:
            text += ' %s="' % a_name
            text += attrs[a_name]
            text += '"'

        text += ">"
        return text
        
    def _repr_of_closing_tag(self, node):
        return "</%s>"%node.tag

    def _walk_xml(self, node, depth=0, parent=""):
        text = self._repr_of_openning_tag(node) + self._repr_of_closing_tag(node)

        item = self._treeview.insert(parent, END, text = text)
        self._item_ID_to_element[item] = node
        
        if node.text:
            text = node.text.strip()
            if text != "":
                for line in text.splitlines():
                    self._treeview.insert(item, END, text = line)

        child_nodes = sorted(list(node), key=attrgetter('tag'))
        for child_node in node:
            self._walk_xml(child_node, depth+1, parent=item)

        
        if node.tail:
            tail = node.tail.strip()
            if tail != "":
                for line in tail.splitlines():
                    self._treeview.insert(parent, END, text = line)
예제 #27
0
    def __init__(self, master, columns, column_weights=None, column_minwidths=None, height=500, minwidth=20, minheight=20, padx=5, pady=5, cell_font=None, cell_foreground="black", cell_background="white", cell_anchor=W, header_font=None, header_background="white", header_foreground="black", header_anchor=CENTER, bordercolor = "#999999", innerborder=True, outerborder=True, stripped_rows=("#EEEEEE", "white"), on_change_data=None, mousewheel_speed = 2, scroll_horizontally=True, scroll_vertically=True):
        outerborder_width = 1 if outerborder else 0

        Frame.__init__(self,master, bd= 0)

        self._cell_background = cell_background
        self._cell_foreground = cell_foreground
        self._cell_font = cell_font
        self._cell_anchor = cell_anchor
        
        self._stripped_rows = stripped_rows

        self._padx = padx
        self._pady = pady
        
        self._bordercolor = bordercolor
        self._innerborder_width = 1 if innerborder else 0

        self._data_vars = []

        self._columns = columns
        
        self._number_of_rows = 0
        self._number_of_columns = len(columns)

        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(1, weight=1)
        
        self._head = Frame(self, highlightbackground=bordercolor, highlightcolor=bordercolor, highlightthickness=outerborder_width, bd= 0)
        self._head.grid(row=0, column=0, sticky=E+W)

        header_separator = False if outerborder else True

        for j in range(len(columns)):
            column_name = columns[j]

            header_cell = Header_Cell(self._head, text=column_name, borderwidth=self._innerborder_width, font=header_font, background=header_background, foreground=header_foreground, padx=padx, pady=pady, bordercolor=bordercolor, anchor=header_anchor, separator=header_separator)
            header_cell.grid(row=0, column=j, sticky=N+E+W+S)

        add_scrollbars = scroll_horizontally or scroll_vertically
        if add_scrollbars:
            if scroll_horizontally:
                xscrollbar = Scrollbar(self, orient=HORIZONTAL)
                xscrollbar.grid(row=2, column=0, sticky=E+W)
            else:
                xscrollbar = None

            if scroll_vertically:
                yscrollbar = Scrollbar(self, orient=VERTICAL)
                yscrollbar.grid(row=1, column=1, sticky=N+S)
            else:
                yscrollbar = None

            scrolling_area = Scrolling_Area(self, width=self._head.winfo_reqwidth(), height=height, scroll_horizontally=scroll_horizontally, xscrollbar=xscrollbar, scroll_vertically=scroll_vertically, yscrollbar=yscrollbar)
            scrolling_area.grid(row=1, column=0, sticky=E+W)

            self._body = Frame(scrolling_area.innerframe, highlightbackground=bordercolor, highlightcolor=bordercolor, highlightthickness=outerborder_width, bd= 0)
            self._body.pack()
            
            def on_change_data():
                scrolling_area.update_viewport()

        else:
            self._body = Frame(self, height=height, highlightbackground=bordercolor, highlightcolor=bordercolor, highlightthickness=outerborder_width, bd= 0)
            self._body.grid(row=1, column=0, sticky=N+E+W+S)

        if column_weights is None:
            for j in range(len(columns)):
                self._body.grid_columnconfigure(j, weight=1)
        else:
            for j, weight in enumerate(column_weights):
                self._body.grid_columnconfigure(j, weight=weight)

        if column_minwidths is not None:
            for j, minwidth in enumerate(column_minwidths):
                if minwidth is None:
                    header_cell = self._head.grid_slaves(row=0, column=j)[0]
                    minwidth = header_cell.winfo_reqwidth()

                self._body.grid_columnconfigure(j, minsize=minwidth)
        else:
            for j in range(len(columns)):
                header_cell = self._head.grid_slaves(row=0, column=j)[0]
                minwidth = header_cell.winfo_reqwidth()

                self._body.grid_columnconfigure(j, minsize=minwidth)

        self._on_change_data = on_change_data
예제 #28
0
    def StartGui(self):
        self.tkRoot = Tk(baseName="")
        self.tkRoot.geometry("350x300+0+0")
        self.tkRoot.title("Engine SAPI GUI")
        self.GUIVisible = True

        frame = Frame(self.tkRoot)
        frame.style = Style()
        frame.style.theme_use("alt")
        frame.pack(fill=BOTH, expand=1)

        frame.columnconfigure(1, weight=1)
        frame.columnconfigure(7, pad=7)
        frame.rowconfigure(13, weight=1)
        frame.rowconfigure(13, pad=7)
        
        Label(frame, text="Start:").grid(row = 0, column=0)
        self.labelStart = Label(frame, text="0")
        self.labelStart.grid(row = 1, column=0)

        Label(frame, text="Length:").grid(row = 0, column=1)
        self.labelLength = Label(frame, text="0")
        self.labelLength.grid(row = 1, column=1)

        Label(frame, text="Total:").grid(row = 0, column=2)
        self.labelTotal = Label(frame, text="0")
        self.labelTotal.grid(row = 1, column=2)
        
        self.labelSentenceLeft = Label(frame, text="...")
        self.labelSentenceLeft.grid(row = 2, column=0, sticky=E)
        self.labelSentenceSpoken = Label(frame, text="...", foreground="red")
        self.labelSentenceSpoken.grid(row = 2, column=1)
        self.labelSentenceRight = Label(frame, text="...")
        self.labelSentenceRight.grid(row = 2, column=2, sticky=W, columnspan=2)   

        scrollbar = Scrollbar(frame, orient=VERTICAL)
        self.labelQueueToSpeak = Label(frame, text="Queue to speak:").grid(row = 3, column=0, pady=4, padx=5, sticky=W)
        self.listboxQueueToSpeak = Listbox(frame, width=50, height=3, yscrollcommand=scrollbar.set)
        
        scrollbar.config(command=self.listboxQueueToSpeak.yview)
        self.listboxQueueToSpeak.grid( sticky=N+S+E+W, row = 4, column = 0, columnspan = 2 ,rowspan = 3, padx=3)
        scrollbar.grid(sticky=N+S+W, row = 4, column = 2, rowspan = 3)

        self.buttonPauze = Button(frame, text="Pauze", command=self.communicationProtocal.handlePauze)
        self.buttonPauze.grid(row = 4, column=3)

        self.buttonStop = Button(frame, text="Stop", command=self.communicationProtocal.restartProcess)
        self.buttonStop.grid(row = 5, column=3)

        self.buttonResume = Button(frame, text="Resume", command=self.communicationProtocal.handleResume)
        self.buttonResume.grid(row = 6, column=3)

        Label(frame, text="Text to say:").grid(row = 7, column=0, padx=3, sticky=W)

        self.stringVarTextToSay = StringVar()
        self.entryTextToSay = Entry(frame, textvariable=self.stringVarTextToSay, width=500)
        self.entryTextToSay.grid(row=8, column=0, columnspan=3, padx=3, sticky=W)
        self.stringVarTextToSay.set("Hello SAPI Speak Engine")
        self.entryTextToSay.bind('<Return>', self.CallBackReturnSay)

        self.buttonSay = Button(frame, text="Say", command=self.CallBackButtonSay)
        self.buttonSay.grid(row = 8, column=3)

        Label(frame, text="Recover action:").grid(row = 9, column=0, padx=3, sticky=W)
        self.recoverActionLabelText = "None"
        self.labelRecoverAction = Label(frame, text=self.recoverActionLabelText, foreground="blue")
        self.labelRecoverAction.grid(row = 10, column=0)   

        Label(frame, text="Voice speed:").grid(row = 9, column=1, sticky=W)
        self.buttonSpeedDown = Button(frame, text="Speed down", command=self.communicationProtocal.handleSpeedDown)
        self.buttonSpeedDown.grid(row = 10, column=1, padx=3, sticky=E)

        self.speedValue = 0
        self.intVarSpeed = IntVar()
        vcmd = (self.tkRoot.register(self.OnValidateEntrySpeakSpeed), '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
        self.entrySpeakSpeed = Entry(frame, textvariable=self.intVarSpeed, validate="key", validatecommand=vcmd, width=5)
        self.entrySpeakSpeed.grid(row=10,column=2)
        self.entrySpeakSpeed.bind('<Return>', self.CallBackSetSpeed)

        self.buttonSpeedUp = Button(frame, text="Speed up", command=self.communicationProtocal.handleSpeedUp)
        self.buttonSpeedUp.grid(row = 10, column=3)

        Label(frame, text="voice:").grid(row = 11, column=0, padx=3, sticky=W)
        self.buttonPrevVoice = Button(frame, text="Prev voice", command=self.communicationProtocal.handlePrevVoice)
        self.buttonPrevVoice.grid(row = 12, column=0, padx=3, sticky=W)

        self.buttonNextVoice = Button(frame, text="Next voice", command=self.communicationProtocal.handleNextVoice)
        self.buttonNextVoice.grid(row = 12, column=3)

        self.currentVoice = StringVar(self.tkRoot)
        self.currentVoice.set(self.communicationProtocal.CurrentVoiceName)

        engine = pyttsx.init()
        voices = engine.getProperty("voices")
        voiceNames = list()
        for x in xrange(0, len(voices)):
            voiceNames.append(voices[x].name)
        self.optionMenuVoices = OptionMenu(frame, self.currentVoice, *tuple(voiceNames), command=self.CallBackOptionMenuVoices)
        self.optionMenuVoices.config(width=500)
        self.optionMenuVoices.grid(sticky=W, row = 12, column = 1)
     
        #hide if close button is clicked
        self.tkRoot.protocol("WM_DELETE_WINDOW", self.HideGui)
        self.tkRoot.after(1000/32, self.Update)
        self.tkRoot.mainloop()  
예제 #29
0
class XML_Viwer(Frame):
    def __init__(self,
                 master,
                 xml=None,
                 heading_text=None,
                 heading_anchor=None,
                 padding=None,
                 cursor=None,
                 takefocus=None,
                 style=None):
        Frame.__init__(self, master, class_="XML_Viwer")

        self._vsb = Scrollbar(self, orient=VERTICAL)
        self._hsb = Scrollbar(self, orient=HORIZONTAL)

        kwargs = {}
        kwargs["yscrollcommand"] = lambda f, l: autoscroll(self._vsb, f, l)
        kwargs["xscrollcommand"] = lambda f, l: autoscroll(self._hsb, f, l)

        if style is not None:
            kwargs["style"] = style

        if padding is not None:
            kwargs["padding"] = padding

        if cursor is not None:
            kwargs["cursor"] = cursor

        if takefocus is not None:
            kwargs["takefocus"] = takefocus

        self._treeview = Treeview(self, **kwargs)

        if heading_text is not None:
            if heading_anchor is not None:
                self._treeview.heading("#0",
                                       text=heading_text,
                                       anchor=heading_anchor)
            else:
                self._treeview.heading("#0", text=heading_text)

        self._treeview.bind("<<TreeviewOpen>>", self._on_open)
        self._treeview.bind("<<TreeviewClose>>", self._on_close)

        # Without this line, horizontal scrolling doesn't work properly.
        self._treeview.column("#0", stretch=False)

        self._vsb['command'] = self._treeview.yview
        self._hsb['command'] = self._treeview.xview

        self._treeview.grid(column=0, row=0, sticky=N + S + W + E)
        self._vsb.grid(column=1, row=0, sticky=N + S)
        self._hsb.grid(column=0, row=1, sticky=E + W)

        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)

        self._element_tree = None
        self._item_ID_to_element = {}

        if xml is not None:
            self.parse_xml(xml)

    def _on_open(self, event):
        item_ID = self._treeview.focus()
        if item_ID not in self._item_ID_to_element: return

        node = self._item_ID_to_element[item_ID]

        self._treeview.item(item_ID, text=self._repr_of_openning_tag(node))

    def _on_close(self, event):
        item_ID = self._treeview.focus()
        if item_ID not in self._item_ID_to_element: return

        node = self._item_ID_to_element[item_ID]

        text = self._repr_of_openning_tag(node) + self._repr_of_closing_tag(
            node)
        self._treeview.item(item_ID, text=text)

    def parse_xml(self, xml):
        self._element_tree = ET.ElementTree(ET.fromstring(xml))

        self.clear()
        self._walk_xml(self._element_tree.getroot())

    @property
    def element_tree(self):
        return self._element_tree

    @element_tree.setter
    def element_tree(self, element_tree):
        self._element_tree = element_tree

        self.clear()
        self._walk_xml(element_tree.getroot())

    def clear(self):
        self._item_ID_to_element = {}
        self._treeview.delete(*self._treeview.get_children())

    def _repr_of_openning_tag(self, node):
        text = "<" + node.tag

        attrs = node.attrib

        # list function is here necessary to provide support to Python 3
        a_names = list(attrs.keys())
        a_names.sort()

        for a_name in a_names:
            text += ' %s="' % a_name
            text += attrs[a_name]
            text += '"'

        text += ">"
        return text

    def _repr_of_closing_tag(self, node):
        return "</%s>" % node.tag

    def _walk_xml(self, node, depth=0, parent=""):
        text = self._repr_of_openning_tag(node) + self._repr_of_closing_tag(
            node)

        item = self._treeview.insert(parent, END, text=text)
        self._item_ID_to_element[item] = node

        if node.text:
            text = node.text.strip()
            if text != "":
                for line in text.splitlines():
                    self._treeview.insert(item, END, text=line)

        child_nodes = sorted(list(node), key=attrgetter('tag'))
        for child_node in node:
            self._walk_xml(child_node, depth + 1, parent=item)

        if node.tail:
            tail = node.tail.strip()
            if tail != "":
                for line in tail.splitlines():
                    self._treeview.insert(parent, END, text=line)
예제 #30
0
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)
예제 #31
0
class Scrolling_Area(Frame, object):
    def __init__(self,
                 master,
                 width=None,
                 height=None,
                 mousewheel_speed=2,
                 scroll_horizontally=True,
                 xscrollbar=None,
                 scroll_vertically=True,
                 yscrollbar=None,
                 outer_background=None,
                 inner_frame=Frame,
                 **kw):
        super(Scrolling_Area, self).__init__(master, **kw)

        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)

        self._clipper = Frame(self,
                              background=outer_background,
                              width=width,
                              height=height)
        self._clipper.grid(row=0, column=0, sticky=N + E + W + S)

        self._width = width
        self._height = height

        self.innerframe = inner_frame(self._clipper,
                                      padx=0,
                                      pady=0,
                                      highlightthickness=0)
        self.innerframe.place(in_=self._clipper, x=0, y=0)

        if scroll_vertically:
            if yscrollbar is not None:
                self.yscrollbar = yscrollbar
            else:
                self.yscrollbar = Scrollbar(self, orient=VERTICAL)
                self.yscrollbar.grid(row=0, column=1, sticky=N + S)

            self.yscrollbar.set(0.0, 1.0)
            self.yscrollbar.config(command=self.yview)
        else:
            self.yscrollbar = None

        self._scroll_vertically = scroll_vertically

        if scroll_horizontally:
            if xscrollbar is not None:
                self.xscrollbar = xscrollbar
            else:
                self.xscrollbar = Scrollbar(self, orient=HORIZONTAL)
                self.xscrollbar.grid(row=1, column=0, sticky=E + W)

            self.xscrollbar.set(0.0, 1.0)
            self.xscrollbar.config(command=self.xview)
        else:
            self.xscrollbar = None

        self._scroll_horizontally = scroll_horizontally

        self._jfraction = 0.05
        self._startX = 0
        self._startY = 0

        # Whenever the clipping window or scrolled frame change size,
        # update the scrollbars.
        self.innerframe.bind('<Configure>', self._on_configure)
        self._clipper.bind('<Configure>', self._on_configure)

        self.innerframe.xview = self.xview
        self.innerframe.yview = self.yview

        Mousewheel_Support(self).add_support_to(self.innerframe,
                                                xscrollbar=self.xscrollbar,
                                                yscrollbar=self.yscrollbar)

    def update_viewport(self):
        # compute new height and width
        self.update()
        frameHeight = float(self.innerframe.winfo_reqheight())
        frameWidth = float(self.innerframe.winfo_reqwidth())

        if self._width is not None:
            width = min(self._width, frameWidth)
        else:
            width = self._frameWidth

        if self._height is not None:
            height = min(self._height, frameHeight)
        else:
            height = self._frameHeight

        self._clipper.configure(width=width, height=height)

    def _on_configure(self, event):
        self._frameHeight = float(self.innerframe.winfo_reqheight())
        self._frameWidth = float(self.innerframe.winfo_reqwidth())

        # resize the visible part
        if self._scroll_horizontally:
            self.xview("scroll", 0, "unit")

        if self._scroll_vertically:
            self.yview("scroll", 0, "unit")

    def xview(self, mode=None, value=None, units=None):
        value = float(value)

        clipperWidth = self._clipper.winfo_width()
        frameWidth = self._frameWidth

        _startX = self._startX

        if mode is None:
            return self.xscrollbar.get()
        elif mode == 'moveto':
            # absolute movement
            self._startX = int(value * frameWidth)
        else:
            # mode == 'scroll'
            # relative movement
            if units == 'units':
                jump = int(clipperWidth * self._jfraction)
            else:
                jump = clipperWidth
            self._startX = self._startX + value * jump

        if frameWidth <= clipperWidth:
            # The scrolled frame is smaller than the clipping window.

            self._startX = 0
            hi = 1.0
            #use expand by default
            relwidth = 1
        else:
            # The scrolled frame is larger than the clipping window.
            #use expand by default
            if self._startX + clipperWidth > frameWidth:
                self._startX = frameWidth - clipperWidth
                hi = 1.0
            else:
                if self._startX < 0:
                    self._startX = 0
                hi = (self._startX + clipperWidth) / frameWidth
            relwidth = ''

        if self._startX != _startX:
            # Position frame relative to clipper.
            self.innerframe.place(x=-self._startX, relwidth=relwidth)

        lo = self._startX / frameWidth
        self.xscrollbar.set(lo, hi)

    def yview(self, mode=None, value=None, units=None):
        value = float(value)
        clipperHeight = self._clipper.winfo_height()
        frameHeight = self._frameHeight

        _startY = self._startY

        if mode is None:
            return self.yscrollbar.get()
        elif mode == 'moveto':
            self._startY = value * frameHeight
        else:  # mode == 'scroll'
            if units == 'units':
                jump = int(clipperHeight * self._jfraction)
            else:
                jump = clipperHeight
            self._startY = self._startY + value * jump

        if frameHeight <= clipperHeight:
            # The scrolled frame is smaller than the clipping window.

            self._startY = 0
            hi = 1.0
            # use expand by default
            relheight = 1
        else:
            # The scrolled frame is larger than the clipping window.
            # use expand by default
            if self._startY + clipperHeight > frameHeight:
                self._startY = frameHeight - clipperHeight
                hi = 1.0
            else:
                if self._startY < 0:
                    self._startY = 0
                hi = (self._startY + clipperHeight) / frameHeight
            relheight = ''

        if self._startY != _startY:
            # Position frame relative to clipper.
            self.innerframe.place(y=-self._startY, relheight=relheight)

        lo = self._startY / frameHeight
        self.yscrollbar.set(lo, hi)
예제 #32
0
    def __init__(self, master, columns, column_weights=None, column_minwidths=None, height=500, minwidth=20, minheight=20, padx=5, pady=5, cell_font=None, cell_foreground="black", cell_background="white", cell_anchor=W, header_font=None, header_background="white", header_foreground="black", header_anchor=CENTER, bordercolor = "#999999", innerborder=True, outerborder=True, stripped_rows=("#EEEEEE", "white"), on_change_data=None, mousewheel_speed = 2, scroll_horizontally=False, scroll_vertically=True):
        outerborder_width = 1 if outerborder else 0

        Frame.__init__(self,master, bd= 0)

        self._cell_background = cell_background
        self._cell_foreground = cell_foreground
        self._cell_font = cell_font
        self._cell_anchor = cell_anchor
        
        self._stripped_rows = stripped_rows

        self._padx = padx
        self._pady = pady
        
        self._bordercolor = bordercolor
        self._innerborder_width = 1 if innerborder else 0

        self._data_vars = []

        self._columns = columns
        
        self._number_of_rows = 0
        self._number_of_columns = len(columns)

        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(1, weight=1)
        
        self._head = Frame(self, highlightbackground=bordercolor, highlightcolor=bordercolor, highlightthickness=outerborder_width, bd= 0)
        self._head.grid(row=0, column=0, sticky=E+W)

        header_separator = False if outerborder else True

        for j in range(len(columns)):
            column_name = columns[j]

            header_cell = Header_Cell(self._head, text=column_name, borderwidth=self._innerborder_width, font=header_font, background=header_background, foreground=header_foreground, padx=padx, pady=pady, bordercolor=bordercolor, anchor=header_anchor, separator=header_separator)
            header_cell.grid(row=0, column=j, sticky=N+E+W+S)

        add_scrollbars = scroll_horizontally or scroll_vertically
        if add_scrollbars:
            if scroll_horizontally:
                xscrollbar = Scrollbar(self, orient=HORIZONTAL)
                xscrollbar.grid(row=2, column=0, sticky=E+W)
            else:
                xscrollbar = None

            if scroll_vertically:
                yscrollbar = Scrollbar(self, orient=VERTICAL)
                yscrollbar.grid(row=1, column=1, sticky=N+S)
            else:
                yscrollbar = None

            scrolling_area = Scrolling_Area(self, width=self._head.winfo_reqwidth(), height=height, scroll_horizontally=scroll_horizontally, xscrollbar=xscrollbar, scroll_vertically=scroll_vertically, yscrollbar=yscrollbar)
            scrolling_area.grid(row=1, column=0, sticky=E+W)

            self._body = Frame(scrolling_area.innerframe, highlightbackground=bordercolor, highlightcolor=bordercolor, highlightthickness=outerborder_width, bd= 0)
            self._body.pack()
            
            def on_change_data():
                scrolling_area.update_viewport()

        else:
            self._body = Frame(self, height=height, highlightbackground=bordercolor, highlightcolor=bordercolor, highlightthickness=outerborder_width, bd= 0)
            self._body.grid(row=1, column=0, sticky=N+E+W+S)

        if column_weights is None:
            for j in range(len(columns)):
                self._body.grid_columnconfigure(j, weight=1)
        else:
            for j, weight in enumerate(column_weights):
                self._body.grid_columnconfigure(j, weight=weight)

        if column_minwidths is not None:
            for j, minwidth in enumerate(column_minwidths):
                if minwidth is None:
                    header_cell = self._head.grid_slaves(row=0, column=j)[0]
                    minwidth = header_cell.winfo_reqwidth()

                self._body.grid_columnconfigure(j, minsize=minwidth)
        else:
            for j in range(len(columns)):
                header_cell = self._head.grid_slaves(row=0, column=j)[0]
                minwidth = header_cell.winfo_reqwidth()

                self._body.grid_columnconfigure(j, minsize=minwidth)

        self._on_change_data = on_change_data