示例#1
0
    def _init_corpus_select(self, parent):
        innerframe = Frame(parent, background=self._BACKGROUND_COLOUR)
        self.var = StringVar(innerframe)
        self.var.set(self.model.DEFAULT_CORPUS)
        Label(
            innerframe,
            justify=LEFT,
            text=' Corpus: ',
            background=self._BACKGROUND_COLOUR,
            padx=2,
            pady=1,
            border=0,
        ).pack(side='left')

        other_corpora = list(self.model.CORPORA.keys()).remove(
            self.model.DEFAULT_CORPUS)
        om = OptionMenu(innerframe,
                        self.var,
                        self.model.DEFAULT_CORPUS,
                        command=self.corpus_selected,
                        *self.model.non_default_corpora())
        om['borderwidth'] = 0
        om['highlightthickness'] = 1
        om.pack(side='left')
        innerframe.pack(side='top', fill='x', anchor='n')
 def _create_buttons(self):
     frame = Frame(self)
     self._create_button(frame, self._left_button,
                         self._left_button_clicked)
     self._create_button(frame, self._right_button,
                         self._right_button_clicked)
     frame.pack()
示例#3
0
 def _create_buttons(self):
     frame = Frame(self)
     self._create_button(frame, self._left_button,
                         self._left_button_clicked)
     self._create_button(frame, self._right_button,
                         self._right_button_clicked)
     frame.pack()
 def _init_paging(self, parent):
     innerframe = Frame(parent, background=self._BACKGROUND_COLOUR)
     self.prev = prev = Button(innerframe, text='Previous', command=self.previous, width='10', borderwidth=1, highlightthickness=1, state='disabled')
     prev.pack(side='left', anchor='center')
     self.next = next = Button(innerframe, text='Next', command=self.__next__, width='10', borderwidth=1, highlightthickness=1, state='disabled')
     next.pack(side='right', anchor='center')
     innerframe.pack(side='top', fill='y')
     self.current_page = 0
示例#5
0
 def _init_paging(self, parent):
     innerframe = Frame(parent, background=self._BACKGROUND_COLOUR)
     self.prev = prev = Button(innerframe, text='Previous', command=self.previous, width='10', borderwidth=1, highlightthickness=1, state='disabled')
     prev.pack(side='left', anchor='center')
     self.next = next = Button(innerframe, text='Next', command=self.__next__, width='10', borderwidth=1, highlightthickness=1, state='disabled')
     next.pack(side='right', anchor='center')
     innerframe.pack(side='top', fill='y')
     self.current_page = 0
 def _create_body(self, message, value, **extra):
     frame = Frame(self)
     Label(frame, text=message, anchor=W, justify=LEFT, wraplength=800).pack(fill=BOTH)
     selector = self._create_selector(frame, value, **extra)
     if selector:
         selector.pack(fill=BOTH)
         selector.focus_set()
     frame.pack(padx=5, pady=5, expand=1, fill=BOTH)
示例#7
0
 def _create_body(self, message, value, **extra):
     frame = Frame(self)
     Label(frame, text=message, anchor=W, justify=LEFT,
           wraplength=800).pack(fill=BOTH)
     selector = self._create_selector(frame, value, **extra)
     if selector:
         selector.pack(fill=BOTH)
         selector.focus_set()
     frame.pack(padx=5, pady=5, expand=1, fill=BOTH)
示例#8
0
 def _init_query_box(self, parent):
     innerframe = Frame(parent, background=self._BACKGROUND_COLOUR)
     another = Frame(innerframe, background=self._BACKGROUND_COLOUR)
     self.query_box = Entry(another, width=60)
     self.query_box.pack(side='left', fill='x', pady=25, anchor='center')
     self.search_button = Button(another, text='Search', command=self.search, borderwidth=1, highlightthickness=1)
     self.search_button.pack(side='left', fill='x', pady=25, anchor='center')
     self.query_box.bind('<KeyPress-Return>', self.search_enter_keypress_handler)
     another.pack()
     innerframe.pack(side='top', fill='x', anchor='n')
 def _init_query_box(self, parent):
     innerframe = Frame(parent, background=self._BACKGROUND_COLOUR)
     another = Frame(innerframe, background=self._BACKGROUND_COLOUR)
     self.query_box = Entry(another, width=60)
     self.query_box.pack(side='left', fill='x', pady=25, anchor='center')
     self.search_button = Button(another, text='Search', command=self.search, borderwidth=1, highlightthickness=1)
     self.search_button.pack(side='left', fill='x', pady=25, anchor='center')
     self.query_box.bind('<KeyPress-Return>', self.search_enter_keypress_handler)
     another.pack()
     innerframe.pack(side='top', fill='x', anchor='n')
示例#10
0
    def pack(self, **kwargs):
        '''
          Pack the scrollbar and canvas correctly in order to recreate the
          same look as MFC's windows.
        '''

        self.hscrollbar.pack(side=BOTTOM, fill=X, expand=FALSE)
        self.vscrollbar.pack(side=RIGHT, fill=Y, expand=FALSE)
        self.sizegrip.pack(in_=self.hscrollbar, side=BOTTOM, anchor="se")
        self.canvas.pack(side=LEFT, padx=5, pady=5, fill=BOTH, expand=TRUE)

        Frame.pack(self, **kwargs)
    def _init_corpus_select(self, parent):
        innerframe = Frame(parent, background=self._BACKGROUND_COLOUR)
        self.var = StringVar(innerframe)
        self.var.set(self.model.DEFAULT_CORPUS)
        Label(innerframe, justify=LEFT, text=' Corpus: ', background=self._BACKGROUND_COLOUR, padx = 2, pady = 1, border = 0).pack(side='left')

        other_corpora = list(self.model.CORPORA.keys()).remove(self.model.DEFAULT_CORPUS)
        om = OptionMenu(innerframe, self.var, self.model.DEFAULT_CORPUS, command=self.corpus_selected, *self.model.non_default_corpora())
        om['borderwidth'] = 0
        om['highlightthickness'] = 1
        om.pack(side='left')
        innerframe.pack(side='top', fill='x', anchor='n')
示例#12
0
    def create_buttonbox(self):
        # add standard button box. override if you don't want the
        # standard buttons

        box = Frame(self)

        w = Button(box, text="OK", width=10, command=self.ok, default=ACTIVE)
        w.pack(side=LEFT, padx=5, pady=5)

        self.bind("&<Return>", self.ok)
        self.bind("&<Escape>", self.ok)

        box.pack()
 def _init_feedback(self, parent):
     self._feedbackframe = feedbackframe = Frame(parent)
     feedbackframe.pack(fill='x', side='bottom', padx=3, pady=3)
     self._lastoper_label = Label(feedbackframe, text='Last Operation:',
                                  font=self._font)
     self._lastoper_label.pack(side='left')
     lastoperframe = Frame(feedbackframe, relief='sunken', border=1)
     lastoperframe.pack(fill='x', side='right', expand=1, padx=5)
     self._lastoper1 = Label(lastoperframe, foreground='#007070',
                             background='#f0f0f0', font=self._font)
     self._lastoper2 = Label(lastoperframe, anchor='w', width=30,
                             foreground='#004040', background='#f0f0f0',
                             font=self._font)
     self._lastoper1.pack(side='left')
     self._lastoper2.pack(side='left', fill='x', expand=1)
示例#14
0
 def _init_feedback(self, parent):
     self._feedbackframe = feedbackframe = Frame(parent)
     feedbackframe.pack(fill='x', side='bottom', padx=3, pady=3)
     self._lastoper_label = Label(feedbackframe, text='Last Operation:',
                                  font=self._font)
     self._lastoper_label.pack(side='left')
     lastoperframe = Frame(feedbackframe, relief='sunken', border=1)
     lastoperframe.pack(fill='x', side='right', expand=1, padx=5)
     self._lastoper1 = Label(lastoperframe, foreground='#007070',
                             background='#f0f0f0', font=self._font)
     self._lastoper2 = Label(lastoperframe, anchor='w', width=30,
                             foreground='#004040', background='#f0f0f0',
                             font=self._font)
     self._lastoper1.pack(side='left')
     self._lastoper2.pack(side='left', fill='x', expand=1)
示例#15
0
文件: tk.py 项目: VanDeng95/WaveSyn
    def __init__(self, *args, **kwargs):
        pil_image = kwargs.pop('pil_image')
        photo = ImageTk.PhotoImage(pil_image)
        self.__photo = photo
        self.__origin_image = pil_image
        self.__zoomed_image = pil_image
        Frame.__init__(self, *args, **kwargs)

        frame = Frame(self)
        frame.pack(fill='x')
        
        save_dlg = lambda: asksaveasfilename(filetypes=[('JPEG', '.jpg'), ('PNG', '.png')], defaultextension='.jpg')        
                        
        def on_save(image):
            filename = save_dlg()
            if filename:
                image.save(filename)
        
        Label(frame, text=eval_format('id={id(self)}')).pack(side='left')
        Button(frame, text='Save Origin', command=lambda:on_save(self.__origin_image)).pack(side='left')
        Button(frame, text='Save Zoomed', command=lambda:on_save(self.__zoomed_image)).pack(side='left')

        scale = Scale(frame, from_=0, to=100, orient='horizontal', value=100)
        scale.pack(side='left')
        zoomed_label = Label(frame, text='100%')
        zoomed_label.pack(side='left')
        
        self.__label = label = Label(self, image=photo)
        label.pack(expand=YES, fill=BOTH)
        
        def on_scale(val):
            val = float(val)
            width, height = self.__origin_image.size
            width = int(width * val / 100)
            height = int(height * val / 100)
            zoomed_image = self.__origin_image.resize((width, height), 
                                                      Image.ANTIALIAS)
            self.__zoomed_image = zoomed_image
            self.__photo = ImageTk.PhotoImage(zoomed_image)
            self.__label['image'] = self.__photo
            zoomed_label['text'] = '{}%'.format(int(val))
            
        scale['command'] = on_scale
示例#16
0
    def __init__(self, package_name, base_class, display_base_class=False):
        self.__package_name = package_name
        self.__base_class = base_class
        self.__display_base_class = display_base_class
        self.__window = window = Toplevel()
        window.title('Class Selector')
        self.__selected_class_name = ''
        self.__selected_module_name = ''

        self.__tree = tree = ScrolledTree(window)
        tree.pack()
        # If a module print something while being loaded, the stdout of this
        # script will be contaminated.
        # The dumb_stream prevents the contamination.
        with dumb_stream():
            classes = self.load_modules()
        for package in classes:
            packageNode = tree.insert('', 'end', text=package)
            for class_name in classes[package]:
                tree.insert(packageNode,
                            'end',
                            text=class_name,
                            values=package)

        button_frame = Frame(window)
        button_frame.pack()

        def _on_click(module_name, class_name):
            self.__selected_module_name = module_name
            self.__selected_class_name = class_name
            window.destroy()

        cancel_button = Button(button_frame,
                               text='Cancel',
                               command=lambda: _on_click('', ''))
        cancel_button.pack(side='right')
        ok_button = Button(button_frame,
                           text='OK',
                           command=lambda: _on_click(
                               tree.item(tree.selection(), 'values')[0],
                               tree.item(tree.selection(), 'text')))
        ok_button.pack(side='right')
示例#17
0
 def _init_query_box(self, parent):
     innerframe = Frame(parent, background=self._BACKGROUND_COLOUR)
     another = Frame(innerframe, background=self._BACKGROUND_COLOUR)
     self.query_box = Entry(another, width=60)
     self.query_box.pack(side="left", fill="x", pady=25, anchor="center")
     self.search_button = Button(
         another,
         text="Search",
         command=self.search,
         borderwidth=1,
         highlightthickness=1,
     )
     self.search_button.pack(side="left",
                             fill="x",
                             pady=25,
                             anchor="center")
     self.query_box.bind("<KeyPress-Return>",
                         self.search_enter_keypress_handler)
     another.pack()
     innerframe.pack(side="top", fill="x", anchor="n")
示例#18
0
    def set_matplotlib_style(self, style_name=''):
        import matplotlib.pyplot as plt
        
        if style_name is self.constants.ASK_DIALOG:
            dialog = True
        else:
            dialog = False

        ret = [None]
        if dialog:
            win = Toplevel()
    
            Label(win, text='Select a style for newly-created figures.').pack()
    
            combo = Combobox(win, stat='readonly')
            combo['values'] = plt.style.available
            combo.current(0)
            combo.pack()
            
            ret = [None]
            
            def on_ok():
                ret[0] = combo.get()
                win.quit()
                
            def on_cancel():
                win.quit()
                
            frame = Frame(win)
            frame.pack()
            Button(win, text='Cancel', command=on_cancel).pack(side='right')            
            Button(win, text='Ok', command=on_ok).pack(side='right')
                
            win.protocol('WM_DELETE_WINDOW', win.quit)
            win.focus_set()
            win.grab_set()
            win.mainloop()
            win.destroy()        
            
        style = ret[0] if ret[0] is not None else style_name
        plt.style.use(style)
示例#19
0
 def _init_results_box(self, parent):
     innerframe = Frame(parent)
     i1 = Frame(innerframe)
     i2 = Frame(innerframe)
     vscrollbar = Scrollbar(i1, borderwidth=1)
     hscrollbar = Scrollbar(i2, borderwidth=1, orient='horiz')
     self.results_box = Text(i1,
                             font=Font(family='courier', size='16'),
                             state='disabled',
                             borderwidth=1,
                             yscrollcommand=vscrollbar.set,
                             xscrollcommand=hscrollbar.set,
                             wrap='none',
                             width='40',
                             height='20',
                             exportselection=1)
     self.results_box.pack(side='left', fill='both', expand=True)
     self.results_box.tag_config(self._HIGHLIGHT_WORD_TAG,
                                 foreground=self._HIGHLIGHT_WORD_COLOUR)
     self.results_box.tag_config(self._HIGHLIGHT_LABEL_TAG,
                                 foreground=self._HIGHLIGHT_LABEL_COLOUR)
     vscrollbar.pack(side='left', fill='y', anchor='e')
     vscrollbar.config(command=self.results_box.yview)
     hscrollbar.pack(side='left', fill='x', expand=True, anchor='w')
     hscrollbar.config(command=self.results_box.xview)
     #there is no other way of avoiding the overlap of scrollbars while using pack layout manager!!!
     Label(i2, text='   ',
           background=self._BACKGROUND_COLOUR).pack(side='left', anchor='e')
     i1.pack(side='top', fill='both', expand=True, anchor='n')
     i2.pack(side='bottom', fill='x', anchor='s')
     innerframe.pack(side='top', fill='both', expand=True)
示例#20
0
 def _init_results_box(self, parent):
     innerframe = Frame(parent)
     i1 = Frame(innerframe)
     i2 = Frame(innerframe)
     vscrollbar = Scrollbar(i1, borderwidth=1)
     hscrollbar = Scrollbar(i2, borderwidth=1, orient="horiz")
     self.results_box = Text(
         i1,
         font=Font(family="courier", size="16"),
         state="disabled",
         borderwidth=1,
         yscrollcommand=vscrollbar.set,
         xscrollcommand=hscrollbar.set,
         wrap="none",
         width="40",
         height="20",
         exportselection=1,
     )
     self.results_box.pack(side="left", fill="both", expand=True)
     vscrollbar.pack(side="left", fill="y", anchor="e")
     vscrollbar.config(command=self.results_box.yview)
     hscrollbar.pack(side="left", fill="x", expand=True, anchor="w")
     hscrollbar.config(command=self.results_box.xview)
     # there is no other way of avoiding the overlap of scrollbars while using pack layout manager!!!
     Label(i2, text="   ",
           background=self._BACKGROUND_COLOUR).pack(side="left", anchor="e")
     i1.pack(side="top", fill="both", expand=True, anchor="n")
     i2.pack(side="bottom", fill="x", anchor="s")
     innerframe.pack(side="top", fill="both", expand=True)
示例#21
0
 def __init__(self, package_name, base_class, display_base_class=False):
     self.__package_name = package_name
     self.__base_class = base_class
     self.__display_base_class = display_base_class
     self.__window = window = Toplevel()
     window.title('Class Selector')
     self.__selected_class_name = ''
     self.__selected_module_name = ''
     
     self.__tree = tree = ScrolledTree(window)
     tree.pack()
     # If a module print something while being loaded, the stdout of this
     # script will be contaminated. 
     # The dumb_stream prevents the contamination. 
     with dumb_stream():
         classes = self.load_modules()
     for package in classes:
         packageNode = tree.insert('', 'end', text=package)
         for class_name in classes[package]:
             tree.insert(packageNode, 'end', text=class_name, values=package)
             
     button_frame = Frame(window)
     button_frame.pack()
     def _on_click(module_name, class_name):
         self.__selected_module_name   = module_name
         self.__selected_class_name    = class_name
         window.destroy()
     cancel_button = Button(button_frame, text='Cancel', command=lambda: _on_click('', ''))
     cancel_button.pack(side='right')
     ok_button     = Button(
         button_frame, 
         text='OK', 
         command=lambda: _on_click(
             tree.item(tree.selection(), 'values')[0],
             tree.item(tree.selection(), 'text')
         )
     )
     ok_button.pack(side='right')
示例#22
0
文件: tk.py 项目: VanDeng95/WaveSyn
def ask_font():
    win = Toplevel()
    win.title('Font Dialog')

    buttonFrame = Frame(win)
    retval = [None]
    def onClick(ret=None):
        win.destroy()
        retval[0] = ret
    
    buttonFrame.pack(side=BOTTOM)
    btnCancel = Button(buttonFrame, text='Cancel', command=lambda: onClick())
    btnCancel.pack(side=RIGHT)
    btnOk = Button(buttonFrame, text='OK', command=lambda: onClick((fontFrame.face, fontFrame.size)))
    btnOk.pack(side=RIGHT)    
            
    fontFrame = FontFrame(win)
    fontFrame.pack()
    
    win.focus_set()
    win.grab_set()
    win.wait_window()
    return retval[0]
示例#23
0
文件: cfg.py 项目: EricChh20/EZ-Mail
    def __init__(self, grammar, text):
        self._grammar = grammar
        self._text = text

        # Set up the main window.
        self._top = Tk()
        self._top.title('Context Free Grammar Demo')

        # Base font size
        self._size = IntVar(self._top)
        self._size.set(12) # = medium

        # Set up the key bindings
        self._init_bindings(self._top)

        # Create the basic frames
        frame1 = Frame(self._top)
        frame1.pack(side='left', fill='y', expand=0)
        self._init_menubar(self._top)
        self._init_buttons(self._top)
        self._init_grammar(frame1)
        self._init_treelet(frame1)
        self._init_workspace(self._top)
示例#24
0
文件: cfg.py 项目: prz3m/kind2anki
    def __init__(self, grammar, text):
        self._grammar = grammar
        self._text = text

        # Set up the main window.
        self._top = Tk()
        self._top.title('Context Free Grammar Demo')

        # Base font size
        self._size = IntVar(self._top)
        self._size.set(12)  # = medium

        # Set up the key bindings
        self._init_bindings(self._top)

        # Create the basic frames
        frame1 = Frame(self._top)
        frame1.pack(side='left', fill='y', expand=0)
        self._init_menubar(self._top)
        self._init_buttons(self._top)
        self._init_grammar(frame1)
        self._init_treelet(frame1)
        self._init_workspace(self._top)
示例#25
0
 def _init_feedback(self, parent):
     self._feedbackframe = feedbackframe = Frame(parent)
     feedbackframe.pack(fill="x", side="bottom", padx=3, pady=3)
     self._lastoper_label = Label(feedbackframe,
                                  text="Last Operation:",
                                  font=self._font)
     self._lastoper_label.pack(side="left")
     lastoperframe = Frame(feedbackframe, relief="sunken", border=1)
     lastoperframe.pack(fill="x", side="right", expand=1, padx=5)
     self._lastoper1 = Label(lastoperframe,
                             foreground="#007070",
                             background="#f0f0f0",
                             font=self._font)
     self._lastoper2 = Label(
         lastoperframe,
         anchor="w",
         width=30,
         foreground="#004040",
         background="#f0f0f0",
         font=self._font,
     )
     self._lastoper1.pack(side="left")
     self._lastoper2.pack(side="left", fill="x", expand=1)
示例#26
0
 def _init_paging(self, parent):
     innerframe = Frame(parent, background=self._BACKGROUND_COLOUR)
     self.prev = prev = Button(
         innerframe,
         text="Previous",
         command=self.previous,
         width="10",
         borderwidth=1,
         highlightthickness=1,
         state="disabled",
     )
     prev.pack(side="left", anchor="center")
     self.next = next = Button(
         innerframe,
         text="Next",
         command=self.__next__,
         width="10",
         borderwidth=1,
         highlightthickness=1,
         state="disabled",
     )
     next.pack(side="right", anchor="center")
     innerframe.pack(side="top", fill="y")
     self.reset_current_page()
 def _init_results_box(self, parent):
     innerframe = Frame(parent)
     i1 = Frame(innerframe)
     i2 = Frame(innerframe)
     vscrollbar = Scrollbar(i1, borderwidth=1)
     hscrollbar = Scrollbar(i2, borderwidth=1, orient='horiz')
     self.results_box = Text(i1,
                 font=Font(family='courier', size='16'),
                 state='disabled', borderwidth=1,
                 yscrollcommand=vscrollbar.set,
                 xscrollcommand=hscrollbar.set, wrap='none', width='40', height = '20', exportselection=1)
     self.results_box.pack(side='left', fill='both', expand=True)
     vscrollbar.pack(side='left', fill='y', anchor='e')
     vscrollbar.config(command=self.results_box.yview)
     hscrollbar.pack(side='left', fill='x', expand=True, anchor='w')
     hscrollbar.config(command=self.results_box.xview)
     #there is no other way of avoiding the overlap of scrollbars while using pack layout manager!!!
     Label(i2, text='   ', background=self._BACKGROUND_COLOUR).pack(side='left', anchor='e')
     i1.pack(side='top', fill='both', expand=True, anchor='n')
     i2.pack(side='bottom', fill='x', anchor='s')
     innerframe.pack(side='top', fill='both', expand=True)
示例#28
0
文件: gui.py 项目: 173210/depot_tools
    def init_gui(self):
        """init helper"""

        window = PanedWindow(self.root, orient="vertical")
        window.pack(side=TOP, fill=BOTH, expand=True)

        top_pane = Frame(window)
        window.add(top_pane)
        mid_pane = Frame(window)
        window.add(mid_pane)
        bottom_pane = Frame(window)
        window.add(bottom_pane)

        #setting up frames
        top_frame = Frame(top_pane)
        mid_frame = Frame(top_pane)
        history_frame = Frame(top_pane)
        radio_frame = Frame(mid_pane)
        rating_frame = Frame(mid_pane)
        res_frame = Frame(mid_pane)
        check_frame = Frame(bottom_pane)
        msg_frame = Frame(bottom_pane)
        btn_frame = Frame(bottom_pane)
        top_frame.pack(side=TOP, fill=X)
        mid_frame.pack(side=TOP, fill=X)
        history_frame.pack(side=TOP, fill=BOTH, expand=True)
        radio_frame.pack(side=TOP, fill=X)
        rating_frame.pack(side=TOP, fill=X)
        res_frame.pack(side=TOP, fill=BOTH, expand=True)
        check_frame.pack(side=TOP, fill=X)
        msg_frame.pack(side=TOP, fill=BOTH, expand=True)
        btn_frame.pack(side=TOP, fill=X)

        # Binding F5 application-wide to run lint
        self.root.bind('<F5>', self.run_lint)

        #Message ListBox
        rightscrollbar = Scrollbar(msg_frame)
        rightscrollbar.pack(side=RIGHT, fill=Y)
        bottomscrollbar = Scrollbar(msg_frame, orient=HORIZONTAL)
        bottomscrollbar.pack(side=BOTTOM, fill=X)
        self.lb_messages = Listbox(
            msg_frame,
            yscrollcommand=rightscrollbar.set,
            xscrollcommand=bottomscrollbar.set,
            bg="white")
        self.lb_messages.bind("<Double-Button-1>", self.show_sourcefile)
        self.lb_messages.pack(expand=True, fill=BOTH)
        rightscrollbar.config(command=self.lb_messages.yview)
        bottomscrollbar.config(command=self.lb_messages.xview)

        #History ListBoxes
        rightscrollbar2 = Scrollbar(history_frame)
        rightscrollbar2.pack(side=RIGHT, fill=Y)
        bottomscrollbar2 = Scrollbar(history_frame, orient=HORIZONTAL)
        bottomscrollbar2.pack(side=BOTTOM, fill=X)
        self.showhistory = Listbox(
            history_frame,
            yscrollcommand=rightscrollbar2.set,
            xscrollcommand=bottomscrollbar2.set,
            bg="white")
        self.showhistory.pack(expand=True, fill=BOTH)
        rightscrollbar2.config(command=self.showhistory.yview)
        bottomscrollbar2.config(command=self.showhistory.xview)
        self.showhistory.bind('<Double-Button-1>', self.select_recent_file)
        self.set_history_window()

        #status bar
        self.status = Label(self.root, text="", bd=1, relief=SUNKEN, anchor=W)
        self.status.pack(side=BOTTOM, fill=X)

        #labelbl_ratingls
        lbl_rating_label = Label(rating_frame, text='Rating:')
        lbl_rating_label.pack(side=LEFT)
        lbl_rating = Label(rating_frame, textvariable=self.rating)
        lbl_rating.pack(side=LEFT)
        Label(mid_frame, text='Recently Used:').pack(side=LEFT)
        Label(top_frame, text='Module or package').pack(side=LEFT)

        #file textbox
        self.txt_module = Entry(top_frame, background='white')
        self.txt_module.bind('<Return>', self.run_lint)
        self.txt_module.pack(side=LEFT, expand=True, fill=X)

        #results box
        rightscrollbar = Scrollbar(res_frame)
        rightscrollbar.pack(side=RIGHT, fill=Y)
        bottomscrollbar = Scrollbar(res_frame, orient=HORIZONTAL)
        bottomscrollbar.pack(side=BOTTOM, fill=X)
        self.results = Listbox(
            res_frame,
            yscrollcommand=rightscrollbar.set,
            xscrollcommand=bottomscrollbar.set,
            bg="white", font="Courier")
        self.results.pack(expand=True, fill=BOTH, side=BOTTOM)
        rightscrollbar.config(command=self.results.yview)
        bottomscrollbar.config(command=self.results.xview)

        #buttons
        Button(top_frame, text='Open', command=self.file_open).pack(side=LEFT)
        Button(top_frame, text='Open Package',
               command=(lambda: self.file_open(package=True))).pack(side=LEFT)

        self.btnRun = Button(top_frame, text='Run', command=self.run_lint)
        self.btnRun.pack(side=LEFT)
        Button(btn_frame, text='Quit', command=self.quit).pack(side=BOTTOM)

        #radio buttons
        self.information_box = IntVar()
        self.convention_box = IntVar()
        self.refactor_box = IntVar()
        self.warning_box = IntVar()
        self.error_box = IntVar()
        self.fatal_box = IntVar()
        i = Checkbutton(check_frame, text="Information", fg=COLORS['(I)'],
                        variable=self.information_box, command=self.refresh_msg_window)
        c = Checkbutton(check_frame, text="Convention", fg=COLORS['(C)'],
                        variable=self.convention_box, command=self.refresh_msg_window)
        r = Checkbutton(check_frame, text="Refactor", fg=COLORS['(R)'],
                        variable=self.refactor_box, command=self.refresh_msg_window)
        w = Checkbutton(check_frame, text="Warning", fg=COLORS['(W)'],
                        variable=self.warning_box, command=self.refresh_msg_window)
        e = Checkbutton(check_frame, text="Error", fg=COLORS['(E)'],
                        variable=self.error_box, command=self.refresh_msg_window)
        f = Checkbutton(check_frame, text="Fatal", fg=COLORS['(F)'],
                        variable=self.fatal_box, command=self.refresh_msg_window)
        i.select()
        c.select()
        r.select()
        w.select()
        e.select()
        f.select()
        i.pack(side=LEFT)
        c.pack(side=LEFT)
        r.pack(side=LEFT)
        w.pack(side=LEFT)
        e.pack(side=LEFT)
        f.pack(side=LEFT)

        #check boxes
        self.box = StringVar()
        # XXX should be generated
        report = Radiobutton(
            radio_frame, text="Report", variable=self.box,
            value="Report", command=self.refresh_results_window)
        raw_met = Radiobutton(
            radio_frame, text="Raw metrics", variable=self.box,
            value="Raw metrics", command=self.refresh_results_window)
        dup = Radiobutton(
            radio_frame, text="Duplication", variable=self.box,
            value="Duplication", command=self.refresh_results_window)
        ext = Radiobutton(
            radio_frame, text="External dependencies",
            variable=self.box, value="External dependencies",
            command=self.refresh_results_window)
        stat = Radiobutton(
            radio_frame, text="Statistics by type",
            variable=self.box, value="Statistics by type",
            command=self.refresh_results_window)
        msg_cat = Radiobutton(
            radio_frame, text="Messages by category",
            variable=self.box, value="Messages by category",
            command=self.refresh_results_window)
        msg = Radiobutton(
            radio_frame, text="Messages", variable=self.box,
            value="Messages", command=self.refresh_results_window)
        source_file = Radiobutton(
            radio_frame, text="Source File", variable=self.box,
            value="Source File", command=self.refresh_results_window)
        report.select()
        report.grid(column=0, row=0, sticky=W)
        raw_met.grid(column=1, row=0, sticky=W)
        dup.grid(column=2, row=0, sticky=W)
        msg.grid(column=3, row=0, sticky=W)
        stat.grid(column=0, row=1, sticky=W)
        msg_cat.grid(column=1, row=1, sticky=W)
        ext.grid(column=2, row=1, sticky=W)
        source_file.grid(column=3, row=1, sticky=W)

        #dictionary for check boxes and associated error term
        self.msg_type_dict = {
            'I': lambda: self.information_box.get() == 1,
            'C': lambda: self.convention_box.get() == 1,
            'R': lambda: self.refactor_box.get() == 1,
            'E': lambda: self.error_box.get() == 1,
            'W': lambda: self.warning_box.get() == 1,
            'F': lambda: self.fatal_box.get() == 1
        }
        self.txt_module.focus_set()
示例#29
0
    def __init__(self, root, *args, **kw):
        GUIDialog.__init__(self, master=root, *args, **kw)
        self.qom_type_var = root.qom_type_var

        self.title(_("Device Tree"))
        self.grid()

        self.columnconfigure(0, weight=1, minsize=300)
        self.columnconfigure(2, weight=1, minsize=100)
        self.rowconfigure(0, weight=1)

        geom = "+" + str(int(root.winfo_rootx())) \
             + "+" + str(int(root.winfo_rooty()))
        self.geometry(geom)

        self.focus()

        self.device_tree = dt = VarTreeview(self, selectmode="browse")
        dt["columns"] = "Macros"

        dt.heading("#0", text=_("Devices"))
        dt.heading("Macros", text=_("Macros"))

        dt.bind("<ButtonPress-1>", self.on_b1_press_dt)

        dt.grid(row=0, column=0, sticky="NEWS")

        add_scrollbars_native(self, dt)

        column_fr = Frame(self, borderwidth=0)
        column_fr.grid(row=0, column=2, rowspan=2, sticky="SEWN")
        column_fr.columnconfigure(0, weight=1)
        column_fr.rowconfigure(0, weight=1)
        column_fr.rowconfigure(1, weight=1, minsize=100)

        fr_at = VarLabelFrame(column_fr, text=_("Architecture filter"))
        fr_at.grid(row=0, column=0, sticky="SEWN")

        self.fr_qt = VarLabelFrame(column_fr, text=_("Select QOM type"))
        self.fr_qt.grid(row=1, column=0, sticky="SEWN")

        self.add_button = VarButton(column_fr,
                                    text=_("Select"),
                                    command=self.on_select_qom_type)
        self.add_button.grid(row=2, column=0, sticky="EW")
        self.add_button.config(state="disabled")

        qtype_dt = self.qtype_dt = qvd_get(
            root.mach.project.build_path,
            version=root.mach.project.target_version).qvc.device_tree

        arch_buttons = Frame(fr_at, borderwidth=0)
        arch_buttons.pack(fill="x")

        arch_buttons.columnconfigure(0, weight=1, minsize=60)
        arch_buttons.columnconfigure(1, weight=1, minsize=60)
        arch_buttons.columnconfigure(2, weight=1, minsize=60)

        bt_all_arches = VarButton(arch_buttons,
                                  text=_("All"),
                                  command=self.select_arches)
        bt_all_arches.grid(row=0, column=0, sticky="EW")

        bt_none_arches = VarButton(arch_buttons,
                                   text=_("None"),
                                   command=self.deselect_arches)
        bt_none_arches.grid(row=0, column=1, sticky="EW")

        bt_invert_arches = VarButton(arch_buttons,
                                     text=_("Invert"),
                                     command=self.invert_arches)
        bt_invert_arches.grid(row=0, column=2, sticky="EW")

        if not qtype_dt.arches:
            bt_all_arches.config(state="disabled")
            bt_none_arches.config(state="disabled")
            bt_invert_arches.config(state="disabled")

        arch_selector_outer = Frame(fr_at, borderwidth=0)
        arch_selector_outer.pack(fill="both", anchor="w")
        arch_selector, scrolltag = add_scrollbars_with_tags(
            arch_selector_outer, GUIFrame)

        ac = self.arches_checkbox = []
        for a in sorted(list(qtype_dt.arches)):
            v = IntVar()
            c = Checkbutton(arch_selector,
                text = a,
                variable = v,
                command = lambda arch = a, var = v: \
                    self.on_toggle_arch(arch, var)
            )

            c.pack(expand=1, anchor="w")
            c.bindtags((scrolltag, ) + c.bindtags())
            c.select()
            ac.append(c)

        # key: item
        # value: ItemDesc
        self.detached_items = {}
        self.all_items = {}

        self.disabled_arches = set()

        self.qom_create_tree("", qtype_dt.children)
示例#30
0
    Frame
)
from widgets import (
    CanvasFrame
)

if __name__ == "__main__":
    root = Tk()

    root.rowconfigure(0, weight = 1)
    root.columnconfigure(0, weight = 1)

    cnv = Canvas(root, bg = "white")
    cnv.grid(row = 0, column = 0, sticky = "NESW")

    cf = CanvasFrame(cnv, 100, 100)

    cnv.itemconfig(cf.id, width = 150, height = 150)

    Label(cf, text = "Test").pack(fill = BOTH, expand = 0)

    f2 = Frame(cf, bg = "white", width = 100, height = 100)
    f2.pack(fill = BOTH, expand = 1)

    def on_motion(e):
        print (e.x, e.y)

    f2.bind("<Motion>", on_motion, "+")

    root.mainloop()
示例#31
0
    def init_gui(self):
        """init helper"""

        window = PanedWindow(self.root, orient="vertical")
        window.pack(side=TOP, fill=BOTH, expand=True)

        top_pane = Frame(window)
        window.add(top_pane)
        mid_pane = Frame(window)
        window.add(mid_pane)
        bottom_pane = Frame(window)
        window.add(bottom_pane)

        #setting up frames
        top_frame = Frame(top_pane)
        mid_frame = Frame(top_pane)
        history_frame = Frame(top_pane)
        radio_frame = Frame(mid_pane)
        rating_frame = Frame(mid_pane)
        res_frame = Frame(mid_pane)
        check_frame = Frame(bottom_pane)
        msg_frame = Frame(bottom_pane)
        btn_frame = Frame(bottom_pane)
        top_frame.pack(side=TOP, fill=X)
        mid_frame.pack(side=TOP, fill=X)
        history_frame.pack(side=TOP, fill=BOTH, expand=True)
        radio_frame.pack(side=TOP, fill=X)
        rating_frame.pack(side=TOP, fill=X)
        res_frame.pack(side=TOP, fill=BOTH, expand=True)
        check_frame.pack(side=TOP, fill=X)
        msg_frame.pack(side=TOP, fill=BOTH, expand=True)
        btn_frame.pack(side=TOP, fill=X)

        # Binding F5 application-wide to run lint
        self.root.bind('<F5>', self.run_lint)

        #Message ListBox
        rightscrollbar = Scrollbar(msg_frame)
        rightscrollbar.pack(side=RIGHT, fill=Y)
        bottomscrollbar = Scrollbar(msg_frame, orient=HORIZONTAL)
        bottomscrollbar.pack(side=BOTTOM, fill=X)
        self.lb_messages = Listbox(msg_frame,
                                   yscrollcommand=rightscrollbar.set,
                                   xscrollcommand=bottomscrollbar.set,
                                   bg="white")
        self.lb_messages.bind("<Double-Button-1>", self.show_sourcefile)
        self.lb_messages.pack(expand=True, fill=BOTH)
        rightscrollbar.config(command=self.lb_messages.yview)
        bottomscrollbar.config(command=self.lb_messages.xview)

        #History ListBoxes
        rightscrollbar2 = Scrollbar(history_frame)
        rightscrollbar2.pack(side=RIGHT, fill=Y)
        bottomscrollbar2 = Scrollbar(history_frame, orient=HORIZONTAL)
        bottomscrollbar2.pack(side=BOTTOM, fill=X)
        self.showhistory = Listbox(history_frame,
                                   yscrollcommand=rightscrollbar2.set,
                                   xscrollcommand=bottomscrollbar2.set,
                                   bg="white")
        self.showhistory.pack(expand=True, fill=BOTH)
        rightscrollbar2.config(command=self.showhistory.yview)
        bottomscrollbar2.config(command=self.showhistory.xview)
        self.showhistory.bind('<Double-Button-1>', self.select_recent_file)
        self.set_history_window()

        #status bar
        self.status = Label(self.root, text="", bd=1, relief=SUNKEN, anchor=W)
        self.status.pack(side=BOTTOM, fill=X)

        #labelbl_ratingls
        lbl_rating_label = Label(rating_frame, text='Rating:')
        lbl_rating_label.pack(side=LEFT)
        lbl_rating = Label(rating_frame, textvariable=self.rating)
        lbl_rating.pack(side=LEFT)
        Label(mid_frame, text='Recently Used:').pack(side=LEFT)
        Label(top_frame, text='Module or package').pack(side=LEFT)

        #file textbox
        self.txt_module = Entry(top_frame, background='white')
        self.txt_module.bind('<Return>', self.run_lint)
        self.txt_module.pack(side=LEFT, expand=True, fill=X)

        #results box
        rightscrollbar = Scrollbar(res_frame)
        rightscrollbar.pack(side=RIGHT, fill=Y)
        bottomscrollbar = Scrollbar(res_frame, orient=HORIZONTAL)
        bottomscrollbar.pack(side=BOTTOM, fill=X)
        self.results = Listbox(res_frame,
                               yscrollcommand=rightscrollbar.set,
                               xscrollcommand=bottomscrollbar.set,
                               bg="white",
                               font="Courier")
        self.results.pack(expand=True, fill=BOTH, side=BOTTOM)
        rightscrollbar.config(command=self.results.yview)
        bottomscrollbar.config(command=self.results.xview)

        #buttons
        Button(top_frame, text='Open', command=self.file_open).pack(side=LEFT)
        Button(top_frame,
               text='Open Package',
               command=(lambda: self.file_open(package=True))).pack(side=LEFT)

        self.btnRun = Button(top_frame, text='Run', command=self.run_lint)
        self.btnRun.pack(side=LEFT)
        Button(btn_frame, text='Quit', command=self.quit).pack(side=BOTTOM)

        #radio buttons
        self.information_box = IntVar()
        self.convention_box = IntVar()
        self.refactor_box = IntVar()
        self.warning_box = IntVar()
        self.error_box = IntVar()
        self.fatal_box = IntVar()
        i = Checkbutton(check_frame,
                        text="Information",
                        fg=COLORS['(I)'],
                        variable=self.information_box,
                        command=self.refresh_msg_window)
        c = Checkbutton(check_frame,
                        text="Convention",
                        fg=COLORS['(C)'],
                        variable=self.convention_box,
                        command=self.refresh_msg_window)
        r = Checkbutton(check_frame,
                        text="Refactor",
                        fg=COLORS['(R)'],
                        variable=self.refactor_box,
                        command=self.refresh_msg_window)
        w = Checkbutton(check_frame,
                        text="Warning",
                        fg=COLORS['(W)'],
                        variable=self.warning_box,
                        command=self.refresh_msg_window)
        e = Checkbutton(check_frame,
                        text="Error",
                        fg=COLORS['(E)'],
                        variable=self.error_box,
                        command=self.refresh_msg_window)
        f = Checkbutton(check_frame,
                        text="Fatal",
                        fg=COLORS['(F)'],
                        variable=self.fatal_box,
                        command=self.refresh_msg_window)
        i.select()
        c.select()
        r.select()
        w.select()
        e.select()
        f.select()
        i.pack(side=LEFT)
        c.pack(side=LEFT)
        r.pack(side=LEFT)
        w.pack(side=LEFT)
        e.pack(side=LEFT)
        f.pack(side=LEFT)

        #check boxes
        self.box = StringVar()
        # XXX should be generated
        report = Radiobutton(radio_frame,
                             text="Report",
                             variable=self.box,
                             value="Report",
                             command=self.refresh_results_window)
        raw_met = Radiobutton(radio_frame,
                              text="Raw metrics",
                              variable=self.box,
                              value="Raw metrics",
                              command=self.refresh_results_window)
        dup = Radiobutton(radio_frame,
                          text="Duplication",
                          variable=self.box,
                          value="Duplication",
                          command=self.refresh_results_window)
        ext = Radiobutton(radio_frame,
                          text="External dependencies",
                          variable=self.box,
                          value="External dependencies",
                          command=self.refresh_results_window)
        stat = Radiobutton(radio_frame,
                           text="Statistics by type",
                           variable=self.box,
                           value="Statistics by type",
                           command=self.refresh_results_window)
        msg_cat = Radiobutton(radio_frame,
                              text="Messages by category",
                              variable=self.box,
                              value="Messages by category",
                              command=self.refresh_results_window)
        msg = Radiobutton(radio_frame,
                          text="Messages",
                          variable=self.box,
                          value="Messages",
                          command=self.refresh_results_window)
        source_file = Radiobutton(radio_frame,
                                  text="Source File",
                                  variable=self.box,
                                  value="Source File",
                                  command=self.refresh_results_window)
        report.select()
        report.grid(column=0, row=0, sticky=W)
        raw_met.grid(column=1, row=0, sticky=W)
        dup.grid(column=2, row=0, sticky=W)
        msg.grid(column=3, row=0, sticky=W)
        stat.grid(column=0, row=1, sticky=W)
        msg_cat.grid(column=1, row=1, sticky=W)
        ext.grid(column=2, row=1, sticky=W)
        source_file.grid(column=3, row=1, sticky=W)

        #dictionary for check boxes and associated error term
        self.msg_type_dict = {
            'I': lambda: self.information_box.get() == 1,
            'C': lambda: self.convention_box.get() == 1,
            'R': lambda: self.refactor_box.get() == 1,
            'E': lambda: self.error_box.get() == 1,
            'W': lambda: self.warning_box.get() == 1,
            'F': lambda: self.fatal_box.get() == 1
        }
        self.txt_module.focus_set()
示例#32
0
class ConcordanceSearchView(object):
    _BACKGROUND_COLOUR = "#FFF"  # white

    # Colour of highlighted results
    _HIGHLIGHT_WORD_COLOUR = "#F00"  # red
    _HIGHLIGHT_WORD_TAG = "HL_WRD_TAG"

    _HIGHLIGHT_LABEL_COLOUR = "#C0C0C0"  # dark grey
    _HIGHLIGHT_LABEL_TAG = "HL_LBL_TAG"

    # Percentage of text left of the scrollbar position
    _FRACTION_LEFT_TEXT = 0.30

    def __init__(self):
        self.queue = q.Queue()
        self.model = ConcordanceSearchModel(self.queue)
        self.top = Tk()
        self._init_top(self.top)
        self._init_menubar()
        self._init_widgets(self.top)
        self.load_corpus(self.model.DEFAULT_CORPUS)
        self.after = self.top.after(POLL_INTERVAL, self._poll)

    def _init_top(self, top):
        top.geometry("950x680+50+50")
        top.title("NLTK Concordance Search")
        top.bind("<Control-q>", self.destroy)
        top.protocol("WM_DELETE_WINDOW", self.destroy)
        top.minsize(950, 680)

    def _init_widgets(self, parent):
        self.main_frame = Frame(
            parent,
            dict(background=self._BACKGROUND_COLOUR, padx=1, pady=1, border=1))
        self._init_corpus_select(self.main_frame)
        self._init_query_box(self.main_frame)
        self._init_results_box(self.main_frame)
        self._init_paging(self.main_frame)
        self._init_status(self.main_frame)
        self.main_frame.pack(fill="both", expand=True)

    def _init_menubar(self):
        self._result_size = IntVar(self.top)
        self._cntx_bf_len = IntVar(self.top)
        self._cntx_af_len = IntVar(self.top)
        menubar = Menu(self.top)

        filemenu = Menu(menubar, tearoff=0, borderwidth=0)
        filemenu.add_command(label="Exit",
                             underline=1,
                             command=self.destroy,
                             accelerator="Ctrl-q")
        menubar.add_cascade(label="File", underline=0, menu=filemenu)

        editmenu = Menu(menubar, tearoff=0)
        rescntmenu = Menu(editmenu, tearoff=0)
        rescntmenu.add_radiobutton(
            label="20",
            variable=self._result_size,
            underline=0,
            value=20,
            command=self.set_result_size,
        )
        rescntmenu.add_radiobutton(
            label="50",
            variable=self._result_size,
            underline=0,
            value=50,
            command=self.set_result_size,
        )
        rescntmenu.add_radiobutton(
            label="100",
            variable=self._result_size,
            underline=0,
            value=100,
            command=self.set_result_size,
        )
        rescntmenu.invoke(1)
        editmenu.add_cascade(label="Result Count",
                             underline=0,
                             menu=rescntmenu)

        cntxmenu = Menu(editmenu, tearoff=0)
        cntxbfmenu = Menu(cntxmenu, tearoff=0)
        cntxbfmenu.add_radiobutton(
            label="60 characters",
            variable=self._cntx_bf_len,
            underline=0,
            value=60,
            command=self.set_cntx_bf_len,
        )
        cntxbfmenu.add_radiobutton(
            label="80 characters",
            variable=self._cntx_bf_len,
            underline=0,
            value=80,
            command=self.set_cntx_bf_len,
        )
        cntxbfmenu.add_radiobutton(
            label="100 characters",
            variable=self._cntx_bf_len,
            underline=0,
            value=100,
            command=self.set_cntx_bf_len,
        )
        cntxbfmenu.invoke(1)
        cntxmenu.add_cascade(label="Before", underline=0, menu=cntxbfmenu)

        cntxafmenu = Menu(cntxmenu, tearoff=0)
        cntxafmenu.add_radiobutton(
            label="70 characters",
            variable=self._cntx_af_len,
            underline=0,
            value=70,
            command=self.set_cntx_af_len,
        )
        cntxafmenu.add_radiobutton(
            label="90 characters",
            variable=self._cntx_af_len,
            underline=0,
            value=90,
            command=self.set_cntx_af_len,
        )
        cntxafmenu.add_radiobutton(
            label="110 characters",
            variable=self._cntx_af_len,
            underline=0,
            value=110,
            command=self.set_cntx_af_len,
        )
        cntxafmenu.invoke(1)
        cntxmenu.add_cascade(label="After", underline=0, menu=cntxafmenu)

        editmenu.add_cascade(label="Context", underline=0, menu=cntxmenu)

        menubar.add_cascade(label="Edit", underline=0, menu=editmenu)

        self.top.config(menu=menubar)

    def set_result_size(self, **kwargs):
        self.model.result_count = self._result_size.get()

    def set_cntx_af_len(self, **kwargs):
        self._char_after = self._cntx_af_len.get()

    def set_cntx_bf_len(self, **kwargs):
        self._char_before = self._cntx_bf_len.get()

    def _init_corpus_select(self, parent):
        innerframe = Frame(parent, background=self._BACKGROUND_COLOUR)
        self.var = StringVar(innerframe)
        self.var.set(self.model.DEFAULT_CORPUS)
        Label(
            innerframe,
            justify=LEFT,
            text=" Corpus: ",
            background=self._BACKGROUND_COLOUR,
            padx=2,
            pady=1,
            border=0,
        ).pack(side="left")

        other_corpora = list(self.model.CORPORA.keys()).remove(
            self.model.DEFAULT_CORPUS)
        om = OptionMenu(innerframe,
                        self.var,
                        self.model.DEFAULT_CORPUS,
                        command=self.corpus_selected,
                        *self.model.non_default_corpora())
        om["borderwidth"] = 0
        om["highlightthickness"] = 1
        om.pack(side="left")
        innerframe.pack(side="top", fill="x", anchor="n")

    def _init_status(self, parent):
        self.status = Label(
            parent,
            justify=LEFT,
            relief=SUNKEN,
            background=self._BACKGROUND_COLOUR,
            border=0,
            padx=1,
            pady=0,
        )
        self.status.pack(side="top", anchor="sw")

    def _init_query_box(self, parent):
        innerframe = Frame(parent, background=self._BACKGROUND_COLOUR)
        another = Frame(innerframe, background=self._BACKGROUND_COLOUR)
        self.query_box = Entry(another, width=60)
        self.query_box.pack(side="left", fill="x", pady=25, anchor="center")
        self.search_button = Button(
            another,
            text="Search",
            command=self.search,
            borderwidth=1,
            highlightthickness=1,
        )
        self.search_button.pack(side="left",
                                fill="x",
                                pady=25,
                                anchor="center")
        self.query_box.bind("<KeyPress-Return>",
                            self.search_enter_keypress_handler)
        another.pack()
        innerframe.pack(side="top", fill="x", anchor="n")

    def search_enter_keypress_handler(self, *event):
        self.search()

    def _init_results_box(self, parent):
        innerframe = Frame(parent)
        i1 = Frame(innerframe)
        i2 = Frame(innerframe)
        vscrollbar = Scrollbar(i1, borderwidth=1)
        hscrollbar = Scrollbar(i2, borderwidth=1, orient="horiz")
        self.results_box = Text(
            i1,
            font=Font(family="courier", size="16"),
            state="disabled",
            borderwidth=1,
            yscrollcommand=vscrollbar.set,
            xscrollcommand=hscrollbar.set,
            wrap="none",
            width="40",
            height="20",
            exportselection=1,
        )
        self.results_box.pack(side="left", fill="both", expand=True)
        self.results_box.tag_config(self._HIGHLIGHT_WORD_TAG,
                                    foreground=self._HIGHLIGHT_WORD_COLOUR)
        self.results_box.tag_config(self._HIGHLIGHT_LABEL_TAG,
                                    foreground=self._HIGHLIGHT_LABEL_COLOUR)
        vscrollbar.pack(side="left", fill="y", anchor="e")
        vscrollbar.config(command=self.results_box.yview)
        hscrollbar.pack(side="left", fill="x", expand=True, anchor="w")
        hscrollbar.config(command=self.results_box.xview)
        # there is no other way of avoiding the overlap of scrollbars while using pack layout manager!!!
        Label(i2, text="   ",
              background=self._BACKGROUND_COLOUR).pack(side="left", anchor="e")
        i1.pack(side="top", fill="both", expand=True, anchor="n")
        i2.pack(side="bottom", fill="x", anchor="s")
        innerframe.pack(side="top", fill="both", expand=True)

    def _init_paging(self, parent):
        innerframe = Frame(parent, background=self._BACKGROUND_COLOUR)
        self.prev = prev = Button(
            innerframe,
            text="Previous",
            command=self.previous,
            width="10",
            borderwidth=1,
            highlightthickness=1,
            state="disabled",
        )
        prev.pack(side="left", anchor="center")
        self.next = next = Button(
            innerframe,
            text="Next",
            command=self.__next__,
            width="10",
            borderwidth=1,
            highlightthickness=1,
            state="disabled",
        )
        next.pack(side="right", anchor="center")
        innerframe.pack(side="top", fill="y")
        self.current_page = 0

    def previous(self):
        self.clear_results_box()
        self.freeze_editable()
        self.model.prev(self.current_page - 1)

    def __next__(self):
        self.clear_results_box()
        self.freeze_editable()
        self.model.next(self.current_page + 1)

    def about(self, *e):
        ABOUT = "NLTK Concordance Search Demo\n"
        TITLE = "About: NLTK Concordance Search Demo"
        try:
            from six.moves.tkinter_messagebox import Message

            Message(message=ABOUT, title=TITLE, parent=self.main_frame).show()
        except:
            ShowText(self.top, TITLE, ABOUT)

    def _bind_event_handlers(self):
        self.top.bind(CORPUS_LOADED_EVENT, self.handle_corpus_loaded)
        self.top.bind(SEARCH_TERMINATED_EVENT, self.handle_search_terminated)
        self.top.bind(SEARCH_ERROR_EVENT, self.handle_search_error)
        self.top.bind(ERROR_LOADING_CORPUS_EVENT,
                      self.handle_error_loading_corpus)

    def _poll(self):
        try:
            event = self.queue.get(block=False)
        except q.Empty:
            pass
        else:
            if event == CORPUS_LOADED_EVENT:
                self.handle_corpus_loaded(event)
            elif event == SEARCH_TERMINATED_EVENT:
                self.handle_search_terminated(event)
            elif event == SEARCH_ERROR_EVENT:
                self.handle_search_error(event)
            elif event == ERROR_LOADING_CORPUS_EVENT:
                self.handle_error_loading_corpus(event)
        self.after = self.top.after(POLL_INTERVAL, self._poll)

    def handle_error_loading_corpus(self, event):
        self.status["text"] = "Error in loading " + self.var.get()
        self.unfreeze_editable()
        self.clear_all()
        self.freeze_editable()

    def handle_corpus_loaded(self, event):
        self.status["text"] = self.var.get() + " is loaded"
        self.unfreeze_editable()
        self.clear_all()
        self.query_box.focus_set()

    def handle_search_terminated(self, event):
        # todo: refactor the model such that it is less state sensitive
        results = self.model.get_results()
        self.write_results(results)
        self.status["text"] = ""
        if len(results) == 0:
            self.status["text"] = "No results found for " + self.model.query
        else:
            self.current_page = self.model.last_requested_page
        self.unfreeze_editable()
        self.results_box.xview_moveto(self._FRACTION_LEFT_TEXT)

    def handle_search_error(self, event):
        self.status["text"] = "Error in query " + self.model.query
        self.unfreeze_editable()

    def corpus_selected(self, *args):
        new_selection = self.var.get()
        self.load_corpus(new_selection)

    def load_corpus(self, selection):
        if self.model.selected_corpus != selection:
            self.status["text"] = "Loading " + selection + "..."
            self.freeze_editable()
            self.model.load_corpus(selection)

    def search(self):
        self.current_page = 0
        self.clear_results_box()
        self.model.reset_results()
        query = self.query_box.get()
        if len(query.strip()) == 0:
            return
        self.status["text"] = "Searching for " + query
        self.freeze_editable()
        self.model.search(query, self.current_page + 1)

    def write_results(self, results):
        self.results_box["state"] = "normal"
        row = 1
        for each in results:
            sent, pos1, pos2 = each[0].strip(), each[1], each[2]
            if len(sent) != 0:
                if pos1 < self._char_before:
                    sent, pos1, pos2 = self.pad(sent, pos1, pos2)
                sentence = sent[pos1 - self._char_before:pos1 +
                                self._char_after]
                if not row == len(results):
                    sentence += "\n"
                self.results_box.insert(str(row) + ".0", sentence)
                word_markers, label_markers = self.words_and_labels(
                    sent, pos1, pos2)
                for marker in word_markers:
                    self.results_box.tag_add(
                        self._HIGHLIGHT_WORD_TAG,
                        str(row) + "." + str(marker[0]),
                        str(row) + "." + str(marker[1]),
                    )
                for marker in label_markers:
                    self.results_box.tag_add(
                        self._HIGHLIGHT_LABEL_TAG,
                        str(row) + "." + str(marker[0]),
                        str(row) + "." + str(marker[1]),
                    )
                row += 1
        self.results_box["state"] = "disabled"

    def words_and_labels(self, sentence, pos1, pos2):
        search_exp = sentence[pos1:pos2]
        words, labels = [], []
        labeled_words = search_exp.split(" ")
        index = 0
        for each in labeled_words:
            if each == "":
                index += 1
            else:
                word, label = each.split("/")
                words.append((self._char_before + index,
                              self._char_before + index + len(word)))
                index += len(word) + 1
                labels.append((self._char_before + index,
                               self._char_before + index + len(label)))
                index += len(label)
            index += 1
        return words, labels

    def pad(self, sent, hstart, hend):
        if hstart >= self._char_before:
            return sent, hstart, hend
        d = self._char_before - hstart
        sent = "".join([" "] * d) + sent
        return sent, hstart + d, hend + d

    def destroy(self, *e):
        if self.top is None:
            return
        self.top.after_cancel(self.after)
        self.top.destroy()
        self.top = None

    def clear_all(self):
        self.query_box.delete(0, END)
        self.model.reset_query()
        self.clear_results_box()

    def clear_results_box(self):
        self.results_box["state"] = "normal"
        self.results_box.delete("1.0", END)
        self.results_box["state"] = "disabled"

    def freeze_editable(self):
        self.query_box["state"] = "disabled"
        self.search_button["state"] = "disabled"
        self.prev["state"] = "disabled"
        self.next["state"] = "disabled"

    def unfreeze_editable(self):
        self.query_box["state"] = "normal"
        self.search_button["state"] = "normal"
        self.set_paging_button_states()

    def set_paging_button_states(self):
        if self.current_page == 0 or self.current_page == 1:
            self.prev["state"] = "disabled"
        else:
            self.prev["state"] = "normal"
        if self.model.has_more_pages(self.current_page):
            self.next["state"] = "normal"
        else:
            self.next["state"] = "disabled"

    def fire_event(self, event):
        # Firing an event so that rendering of widgets happen in the mainloop thread
        self.top.event_generate(event, when="tail")

    def mainloop(self, *args, **kwargs):
        if in_idle():
            return
        self.top.mainloop(*args, **kwargs)
示例#33
0
    def initialize(self):
        """
            Initialize the tKinter app (GUI)
            by creating frames and graphical components,
            setting the window size etc.
        """
        # self.bind("<Escape>", lambda x: self.destroy())
        self.bind("<Escape>", on_close)

        listFrame0 = Frame(self)
        listFrame0.pack(side=TOP, fill=BOTH, expand=True)
        listFrame = Frame(listFrame0)
        listFrame.pack(side=LEFT, fill=BOTH, expand=True)

        scrollbary = Scrollbar(listFrame, orient=VERTICAL)
        scrollbary.pack(side=RIGHT, fill=Y)
        scrollbarx = Scrollbar(listFrame, orient=HORIZONTAL)
        scrollbarx.pack(side=BOTTOM, fill=X)
        # bd --> border
        self.listbox = Listbox(listFrame, bd=1, selectmode=SINGLE, yscrollcommand=scrollbary.set, xscrollcommand=scrollbarx.set)
        self.listbox.bind('<<ListboxSelect>>', self.on_select_click)
        scrollbary.config(command=self.listbox.yview)
        scrollbarx.config(command=self.listbox.xview)
        self.listbox.config(width=self.listbox.winfo_reqwidth() // 3)  # width=self.listbox.winfo_reqwidth()
        self.listbox.pack(side=LEFT, fill=BOTH, expand=True)

        listFrame1 = Frame(listFrame0)
        listFrame1.pack(side=LEFT, fill=BOTH, expand=True)
        scrollbary1 = Scrollbar(listFrame1, orient=VERTICAL)
        scrollbary1.pack(side=RIGHT, fill=Y)
        scrollbarx1 = Scrollbar(listFrame1, orient=HORIZONTAL)
        scrollbarx1.pack(side=BOTTOM, fill=X)
        # bd --> border
        self.listbox1 = Listbox(listFrame1, bd=0, selectmode=SINGLE, yscrollcommand=scrollbary1.set, xscrollcommand=scrollbarx1.set)
        self.listbox1.bind('<<ListboxSelect>>', self.on_update_select_click)
        scrollbary1.config(command=self.listbox1.yview)
        scrollbarx1.config(command=self.listbox1.xview)
        self.listbox1.config(width=self.listbox1.winfo_reqwidth() // 2)  # width=self.listbox.winfo_reqwidth()
        self.listbox1.pack(side=LEFT, fill=BOTH, expand=True)

        text_frame = Frame(self)
        text_frame.pack(fill=X)  # ,expand=True)
        self.created_str = tk.StringVar()
        created = tk.Entry(text_frame, textvariable=self.created_str)
        self.created_months = ttk.Combobox(text_frame)
        self.created_months['values'] = ('01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12')
        self.created_months.set(datetime.date.today().strftime('%m'))
        self.created_months.state(['readonly'])
        # self.created_months.bind('<<ComboboxSelected>>', self.On_table_select)
        self.value_str = tk.StringVar()
        value = tk.Entry(text_frame, textvariable=self.value_str)
        self.category_str = tk.StringVar()
        category = tk.Entry(text_frame, textvariable=self.category_str)  # , state='readonly')
        self.description_str = tk.StringVar()
        description = tk.Entry(text_frame, textvariable=self.description_str)
        fill_from_csv_button = Button(text_frame, text="fill from csv")
        fill_from_csv_button.bind('<Button-1>', self.on_fill_from_csv_click)
        self.db_tables = ttk.Combobox(text_frame)
        self.db_tables.state(['readonly'])
        self.db_tables.bind('<<ComboboxSelected>>', self.on_table_select)
        created.pack(side=LEFT)
        self.created_months.pack(side=LEFT)
        value.pack(side=LEFT)
        category.pack(side=LEFT)
        description.pack(side=LEFT)
        # check.pack(side=LEFT)
        fill_from_csv_button.pack(side=LEFT)
        self.db_tables.pack(side=LEFT)

        button_frame = Frame(self)
        button_frame.pack(fill=X)  # ,expand=True)

        save_button = Button(button_frame, text="save entry")
        save_button.bind('<Button-1>', self.on_save_entry_click)

        database_button = Button(button_frame, text="select database")
        database_button.bind('<Button-1>', self.on_database_click)
        self.database_path_str = tk.StringVar()
        self.database_path = tk.Label(button_frame, textvariable=self.database_path_str, bg="white", anchor=tk.W)

        save_button.pack(side=LEFT)
        database_button.pack(side=RIGHT)
        self.database_path.pack(side=RIGHT)   # , expand=True, fill=BOTH fill=BOTH,

        debugFrame = Frame(self)
        debugFrame.pack(side=BOTTOM, fill=X)  # ,expand=True)
        self.last_entry = tk.StringVar()
        self.path_label = tk.Label(debugFrame, textvariable=self.last_entry, bg="white", anchor=tk.W)

        self.path_label.pack(side=LEFT, fill=BOTH, expand=True)

        # print self.geometry()
        self.update()
        # self.geometry(self.geometry())
        # self.update()
        # print self.geometry()
        # fix the size of the window by setting the window size to its own size
        w = self.winfo_screenwidth()
        # print w
        # print 'reqwidth',self.winfo_reqwidth()
        # h = self.winfo_screenheight()
        self.geometry('{0}x{1}+{2}+{3}'.format(self.winfo_reqwidth(), self.winfo_reqheight() * 3, w - self.winfo_reqwidth() - 20, 0))  # self.geometry()
        self.update()
        self.minsize(self.winfo_reqwidth(), self.winfo_reqheight())
示例#34
0
    def __init__(self):
        # The instance of this class is the root of the model tree. Thus is_root is set to True
        super(Application, self).__init__(node_name=Scripting.root_name, is_root=True)
        Scripting.name_space['locals'][Scripting.root_name] = self
        Scripting.name_space['globals'] = globals()
        Scripting.root_node = self
        self.homepage = 'https://github.com/xialulee/WaveSyn'
        
        file_path    = getsourcefile(type(self))
        dir_path     = os.path.split(file_path)[0]
        
        # load config file
        config_file_path  = os.path.join(dir_path, 'config.json')
        with open(config_file_path) as f:
            config  = json.load(f)
        console_menu = config['ConsoleMenu']
        self.editor_info   = config['EditorInfo']
        self.lock_attribute('editor_info')
        self.prompt_symbols  = config['PromptSymbols']

        tag_defs = config['TagDefs']
        # End load config file

        root = Tix.Tk()
        root.protocol("WM_DELETE_WINDOW", self._on_exit)
        main_thread_id = thread.get_ident()
        Scripting.main_thread_id = main_thread_id
        
        # To Do: WaveSyn will have a uniform command slot system.
        from wavesynlib.interfaces.xmlrpc.server import CommandSlot
        
        # Construct Constants        
        from wavesynlib.languagecenter.wavesynscript import Constant        
        
        class Constants(object): 
            __slots__ = (
                'ASK_DIALOG',
                'ASK_OPEN_FILENAME',
                'ASK_SAVEAS_FILENAME',
                'ASK_FILES',
                'ASK_ORDERED_FILES',
                'ASK_SLICE'
            )
            
            for name in __slots__:
                locals()[name] = Constant(name)
        # End Construct Constants
        
        value_checker    = ValueChecker(root)
        
        
        # File Utils Node             
        
        class TarFileManipulator(ModelNode):
            def __init__(self, *args, **kwargs):
                filename = kwargs.pop('filename')
                ModelNode.__init__(self, *args, **kwargs)
                with self.attribute_lock:
                    self.filename = filename
                    
            @property
            def node_path(self):
                return eval_format('{self.parent_node.node_path}["{self.filename}"]')
                
            @Scripting.printable
            def extract_all(self, directory):
                if directory is self.root_node.constants.ASK_DIALOG:
                    directory = askdirectory(initialdir=os.getcwd())
                if not directory:
                    return
                    
                tar = tarfile.open(self.filename)
                tar.extractall(directory)
        
        class TarFileManager(ModelNode):
            def __init__(self, *args, **kwargs):
                ModelNode.__init__(self, *args, **kwargs)
                
            def __getitem__(self, filename):
                if filename is self.root_node.constants.ASK_DIALOG:
                    filename = askopenfilename(filetypes=[('TAR Files', ('*.tar', '*.tar.gz', '*.tgz')), ('All Files', '*.*')])
                if not filename:
                    return
                    
                manipulator = TarFileManipulator(filename=filename)
                object.__setattr__(manipulator, 'parent_node', self)
                manipulator.lock_attribute('parent_node')
                return manipulator
                
        
        class FileUtils(ModelNode):
            def __init__(self, *args, **kwargs):
                ModelNode.__init__(self, *args, **kwargs)                
                self.pdf_files = ModelNode(is_lazy=True, module_name='wavesynlib.interfaces.pdf.modelnode', class_name='PDFFileManager')
                self.touchstone_files = ModelNode(is_lazy=True, module_name='wavesynlib.interfaces.devcomm.touchstone.modelnode', class_name='TouchstoneFileManager')
                self.tar_files = ModelNode(is_lazy=True, class_object=TarFileManager)
                
        self.file_utils = FileUtils()
        # End File Utils Node
                
        
        with self.attribute_lock:
            set_attributes(self,
                # UI elements
                root = root,
                tk_root = root,
                balloon = Tix.Balloon(root),
                taskbar_icon = TaskbarIcon(root),
                interrupter = InterrupterNode(),
                dialogs = Dialogs(self),
                # End UI elements
                
                # Constants
                constants = Constants,
                # End Constants
                
                # OS interfaces
                os = OperatingSystem(),
                # End OS interfaces
                
                # Thread related
                main_thread_id = main_thread_id,
                exec_thread_lock = threading.RLock(),
                # End
                
                model_tree_monitor = model_tree_monitor,

                # To Do: WaveSyn will have a uniform command slot system.
                xmlrpc_command_slot = CommandSlot(),

                lang_center = LangCenterNode(),
            
                # Validation Functions
                value_checker = value_checker,
                check_int = value_checker.check_int,
                check_float = value_checker.check_float,
                check_positive_float = value_checker.check_positive_float,
                # End Validation Functions
                
                file_path = file_path,
                dir_path = dir_path,
                                
                stream_manager = StreamManager(),                
                
                config_file_path = config_file_path
                
#                cudaWorker      = CUDAWorker()
            )        

        # Timer utils
        self.timer = timeutils.ActionManager()              
        self.timer.after = timeutils.TimerActionNode(type_='after')
        self.timer.every = timeutils.TimerActionNode(type_='every')        
        # End Timer utils
                        
        from wavesynlib.toolwindows.basewindow import WindowDict                                  
        self.windows    = WindowDict() # Instance of ModelNode can be locked automatically.
        self.editors    = EditorDict()
        
        with self.attribute_lock:
            # The below one is the core of the new command system:
            self.command_queue = Queue.Queue()
            # The timer shown as follows checks the command queue
            # extracts command and execute.
            self.command_queue_timer = self.create_timer(interval=50, active=False)
        
        @SimpleObserver
        def command_queue_observer():
            try:
                while True:
                    command_slot = self.command_queue.get_nowait()
                    if command_slot.source == 'local':
                        node = command_slot.node_list[-1]
                        if callable(node):
                            node(*command_slot.args, **command_slot.kwargs)
                        elif isinstance(node, ModelNode):
                            getattr(node, command_slot.method_name)(*command_slot.args, **command_slot.kwargs)
                        else:
                            raise TypeError('The given object is not a ModelNode.')
            except Queue.Empty:
                return
                
        self.command_queue_timer.add_observer(command_queue_observer)
        self.command_queue_timer.active = True
        
        class EditorObserver(object): # use SimpleObserver instead
            def __init__(self, wavesyn):
                self.wavesyn    = wavesyn

            def update(self, editor):
                wavesyn = self.wavesyn                
                code    = editor.code
                if not code:
                    return
                wavesyn.stream_manager.write('WaveSyn: executing code from editor {0} listed as follows:\n'.format(id(editor)), 'TIP')
                wavesyn.stream_manager.write(code, 'HISTORY')
                wavesyn.stream_manager.write('\n')
                wavesyn.execute(code)

        self.editors.manager.add_observer(EditorObserver(self))

        with self.attribute_lock:
            self.monitor_timer = self.create_timer(interval=100, active=False)
            
        # Make wavesyn.editors.manager check wavesyn.editors every 100ms
        self.monitor_timer.add_observer(self.editors.manager) 
        
        # Check std streams every 100ms
        self.monitor_timer.add_observer(self.stream_manager)
        
        frm = Frame(root)
        frm.pack(side=TOP, fill=X)                

        self.console = ConsoleWindow(menu=console_menu, tag_defs=tag_defs)
        self.stream_manager.add_observer(self.console.stream_observer) #!
             
        #self.clipboard = Clipboard()
        self.scripting = Scripting(self)
        self.no_tip = False

        self.monitor_timer.active    = True
        
        self._add_env_path()
示例#35
0
class Table(object):
    """
    A display widget for a table of values, based on a ``MultiListbox``
    widget.  For many purposes, ``Table`` can be treated as a
    list-of-lists.  E.g., table[i] is a list of the values for row i;
    and table.append(row) adds a new row with the given lits of
    values.  Individual cells can be accessed using table[i,j], which
    refers to the j-th column of the i-th row.  This can be used to
    both read and write values from the table.  E.g.:

        >>> table[i,j] = 'hello'

    The column (j) can be given either as an index number, or as a
    column name.  E.g., the following prints the value in the 3rd row
    for the 'First Name' column:

        >>> print(table[3, 'First Name'])
        John

    You can configure the colors for individual rows, columns, or
    cells using ``rowconfig()``, ``columnconfig()``, and ``itemconfig()``.
    The color configuration for each row will be preserved if the
    table is modified; however, when new rows are added, any color
    configurations that have been made for *columns* will not be
    applied to the new row.

    Note: Although ``Table`` acts like a widget in some ways (e.g., it
    defines ``grid()``, ``pack()``, and ``bind()``), it is not itself a
    widget; it just contains one.  This is because widgets need to
    define ``__getitem__()``, ``__setitem__()``, and ``__nonzero__()`` in
    a way that's incompatible with the fact that ``Table`` behaves as a
    list-of-lists.

    :ivar _mlb: The multi-column listbox used to display this table's data.
    :ivar _rows: A list-of-lists used to hold the cell values of this
        table.  Each element of _rows is a row value, i.e., a list of
        cell values, one for each column in the row.
    """
    def __init__(self, master, column_names, rows=None,
                 column_weights=None,
                 scrollbar=True, click_to_sort=True,
                 reprfunc=None, cnf={}, **kw):
        """
        Construct a new Table widget.

        :type master: Tkinter.Widget
        :param master: The widget that should contain the new table.
        :type column_names: list(str)
        :param column_names: A list of names for the columns; these
            names will be used to create labels for each column;
            and can be used as an index when reading or writing
            cell values from the table.
        :type rows: list(list)
        :param rows: A list of row values used to initialze the table.
            Each row value should be a tuple of cell values, one for
            each column in the row.
        :type scrollbar: bool
        :param scrollbar: If true, then create a scrollbar for the
            new table widget.
        :type click_to_sort: bool
        :param click_to_sort: If true, then create bindings that will
            sort the table's rows by a given column's values if the
            user clicks on that colum's label.
        :type reprfunc: function
        :param reprfunc: If specified, then use this function to
            convert each table cell value to a string suitable for
            display.  ``reprfunc`` has the following signature:
            reprfunc(row_index, col_index, cell_value) -> str
            (Note that the column is specified by index, not by name.)
        :param cnf, kw: Configuration parameters for this widget's
            contained ``MultiListbox``.  See ``MultiListbox.__init__()``
            for details.
        """
        self._num_columns = len(column_names)
        self._reprfunc = reprfunc
        self._frame = Frame(master)

        self._column_name_to_index = dict((c,i) for (i,c) in
                                          enumerate(column_names))

        # Make a copy of the rows & check that it's valid.
        if rows is None: self._rows = []
        else: self._rows = [[v for v in row] for row in rows]
        for row in self._rows: self._checkrow(row)

        # Create our multi-list box.
        self._mlb = MultiListbox(self._frame, column_names,
                                 column_weights, cnf, **kw)
        self._mlb.pack(side='left', expand=True, fill='both')

        # Optional scrollbar
        if scrollbar:
            sb = Scrollbar(self._frame, orient='vertical',
                           command=self._mlb.yview)
            self._mlb.listboxes[0]['yscrollcommand'] = sb.set
            #for listbox in self._mlb.listboxes:
            #    listbox['yscrollcommand'] = sb.set
            sb.pack(side='right', fill='y')
            self._scrollbar = sb

        # Set up sorting
        self._sortkey = None
        if click_to_sort:
            for i, l in enumerate(self._mlb.column_labels):
                l.bind('<Button-1>', self._sort)

        # Fill in our multi-list box.
        self._fill_table()

    #/////////////////////////////////////////////////////////////////
    #{ Widget-like Methods
    #/////////////////////////////////////////////////////////////////
    # These all just delegate to either our frame or our MLB.

    def pack(self, *args, **kwargs):
        """Position this table's main frame widget in its parent
        widget.  See ``Tkinter.Frame.pack()`` for more info."""
        self._frame.pack(*args, **kwargs)

    def grid(self, *args, **kwargs):
        """Position this table's main frame widget in its parent
        widget.  See ``Tkinter.Frame.grid()`` for more info."""
        self._frame.grid(*args, **kwargs)

    def focus(self):
        """Direct (keyboard) input foxus to this widget."""
        self._mlb.focus()

    def bind(self, sequence=None, func=None, add=None):
        """Add a binding to this table's main frame that will call
        ``func`` in response to the event sequence."""
        self._mlb.bind(sequence, func, add)

    def rowconfigure(self, row_index, cnf={}, **kw):
        """:see: ``MultiListbox.rowconfigure()``"""
        self._mlb.rowconfigure(row_index, cnf, **kw)

    def columnconfigure(self, col_index, cnf={}, **kw):
        """:see: ``MultiListbox.columnconfigure()``"""
        col_index = self.column_index(col_index)
        self._mlb.columnconfigure(col_index, cnf, **kw)

    def itemconfigure(self, row_index, col_index, cnf=None, **kw):
        """:see: ``MultiListbox.itemconfigure()``"""
        col_index = self.column_index(col_index)
        return self._mlb.itemconfigure(row_index, col_index, cnf, **kw)

    def bind_to_labels(self, sequence=None, func=None, add=None):
        """:see: ``MultiListbox.bind_to_labels()``"""
        return self._mlb.bind_to_labels(sequence, func, add)

    def bind_to_listboxes(self, sequence=None, func=None, add=None):
        """:see: ``MultiListbox.bind_to_listboxes()``"""
        return self._mlb.bind_to_listboxes(sequence, func, add)

    def bind_to_columns(self, sequence=None, func=None, add=None):
        """:see: ``MultiListbox.bind_to_columns()``"""
        return self._mlb.bind_to_columns(sequence, func, add)

    rowconfig = rowconfigure
    columnconfig = columnconfigure
    itemconfig = itemconfigure

    #/////////////////////////////////////////////////////////////////
    #{ Table as list-of-lists
    #/////////////////////////////////////////////////////////////////

    def insert(self, row_index, rowvalue):
        """
        Insert a new row into the table, so that its row index will be
        ``row_index``.  If the table contains any rows whose row index
        is greater than or equal to ``row_index``, then they will be
        shifted down.

        :param rowvalue: A tuple of cell values, one for each column
            in the new row.
        """
        self._checkrow(rowvalue)
        self._rows.insert(row_index, rowvalue)
        if self._reprfunc is not None:
            rowvalue = [self._reprfunc(row_index,j,v)
                        for (j,v) in enumerate(rowvalue)]
        self._mlb.insert(row_index, rowvalue)
        if self._DEBUG: self._check_table_vs_mlb()

    def extend(self, rowvalues):
        """
        Add new rows at the end of the table.

        :param rowvalues: A list of row values used to initialze the
            table.  Each row value should be a tuple of cell values,
            one for each column in the row.
        """
        for rowvalue in rowvalues: self.append(rowvalue)
        if self._DEBUG: self._check_table_vs_mlb()

    def append(self, rowvalue):
        """
        Add a new row to the end of the table.

        :param rowvalue: A tuple of cell values, one for each column
            in the new row.
        """
        self.insert(len(self._rows), rowvalue)
        if self._DEBUG: self._check_table_vs_mlb()

    def clear(self):
        """
        Delete all rows in this table.
        """
        self._rows = []
        self._mlb.delete(0, 'end')
        if self._DEBUG: self._check_table_vs_mlb()

    def __getitem__(self, index):
        """
        Return the value of a row or a cell in this table.  If
        ``index`` is an integer, then the row value for the ``index``th
        row.  This row value consists of a tuple of cell values, one
        for each column in the row.  If ``index`` is a tuple of two
        integers, ``(i,j)``, then return the value of the cell in the
        ``i``th row and the ``j``th column.
        """
        if isinstance(index, slice):
            raise ValueError('Slicing not supported')
        elif isinstance(index, tuple) and len(index)==2:
            return self._rows[index[0]][self.column_index(index[1])]
        else:
            return tuple(self._rows[index])

    def __setitem__(self, index, val):
        """
        Replace the value of a row or a cell in this table with
        ``val``.

        If ``index`` is an integer, then ``val`` should be a row value
        (i.e., a tuple of cell values, one for each column).  In this
        case, the values of the ``index``th row of the table will be
        replaced with the values in ``val``.

        If ``index`` is a tuple of integers, ``(i,j)``, then replace the
        value of the cell in the ``i``th row and ``j``th column with
        ``val``.
        """
        if isinstance(index, slice):
            raise ValueError('Slicing not supported')


        # table[i,j] = val
        elif isinstance(index, tuple) and len(index)==2:
            i, j = index[0], self.column_index(index[1])
            config_cookie = self._save_config_info([i])
            self._rows[i][j] = val
            if self._reprfunc is not None:
                val = self._reprfunc(i, j, val)
            self._mlb.listboxes[j].insert(i, val)
            self._mlb.listboxes[j].delete(i+1)
            self._restore_config_info(config_cookie)

        # table[i] = val
        else:
            config_cookie = self._save_config_info([index])
            self._checkrow(val)
            self._rows[index] = list(val)
            if self._reprfunc is not None:
                val = [self._reprfunc(index,j,v) for (j,v) in enumerate(val)]
            self._mlb.insert(index, val)
            self._mlb.delete(index+1)
            self._restore_config_info(config_cookie)

    def __delitem__(self, row_index):
        """
        Delete the ``row_index``th row from this table.
        """
        if isinstance(row_index, slice):
            raise ValueError('Slicing not supported')
        if isinstance(row_index, tuple) and len(row_index)==2:
            raise ValueError('Cannot delete a single cell!')
        del self._rows[row_index]
        self._mlb.delete(row_index)
        if self._DEBUG: self._check_table_vs_mlb()

    def __len__(self):
        """
        :return: the number of rows in this table.
        """
        return len(self._rows)

    def _checkrow(self, rowvalue):
        """
        Helper function: check that a given row value has the correct
        number of elements; and if not, raise an exception.
        """
        if len(rowvalue) != self._num_columns:
            raise ValueError('Row %r has %d columns; expected %d' %
                             (rowvalue, len(rowvalue), self._num_columns))

    #/////////////////////////////////////////////////////////////////
    # Columns
    #/////////////////////////////////////////////////////////////////

    @property
    def column_names(self):
        """A list of the names of the columns in this table."""
        return self._mlb.column_names

    def column_index(self, i):
        """
        If ``i`` is a valid column index integer, then return it as is.
        Otherwise, check if ``i`` is used as the name for any column;
        if so, return that column's index.  Otherwise, raise a
        ``KeyError`` exception.
        """
        if isinstance(i, int) and 0 <= i < self._num_columns:
            return i
        else:
            # This raises a key error if the column is not found.
            return self._column_name_to_index[i]

    def hide_column(self, column_index):
        """:see: ``MultiListbox.hide_column()``"""
        self._mlb.hide_column(self.column_index(column_index))

    def show_column(self, column_index):
        """:see: ``MultiListbox.show_column()``"""
        self._mlb.show_column(self.column_index(column_index))

    #/////////////////////////////////////////////////////////////////
    # Selection
    #/////////////////////////////////////////////////////////////////

    def selected_row(self):
        """
        Return the index of the currently selected row, or None if
        no row is selected.  To get the row value itself, use
        ``table[table.selected_row()]``.
        """
        sel = self._mlb.curselection()
        if sel: return int(sel[0])
        else: return None

    def select(self, index=None, delta=None, see=True):
        """:see: ``MultiListbox.select()``"""
        self._mlb.select(index, delta, see)

    #/////////////////////////////////////////////////////////////////
    # Sorting
    #/////////////////////////////////////////////////////////////////

    def sort_by(self, column_index, order='toggle'):
        """
        Sort the rows in this table, using the specified column's
        values as a sort key.

        :param column_index: Specifies which column to sort, using
            either a column index (int) or a column's label name
            (str).

        :param order: Specifies whether to sort the values in
            ascending or descending order:

              - ``'ascending'``: Sort from least to greatest.
              - ``'descending'``: Sort from greatest to least.
              - ``'toggle'``: If the most recent call to ``sort_by()``
                sorted the table by the same column (``column_index``),
                then reverse the rows; otherwise sort in ascending
                order.
        """
        if order not in ('ascending', 'descending', 'toggle'):
            raise ValueError('sort_by(): order should be "ascending", '
                             '"descending", or "toggle".')
        column_index = self.column_index(column_index)
        config_cookie = self._save_config_info(index_by_id=True)

        # Sort the rows.
        if order == 'toggle' and column_index == self._sortkey:
            self._rows.reverse()
        else:
            self._rows.sort(key=operator.itemgetter(column_index),
                            reverse=(order=='descending'))
            self._sortkey = column_index

        # Redraw the table.
        self._fill_table()
        self._restore_config_info(config_cookie, index_by_id=True, see=True)
        if self._DEBUG: self._check_table_vs_mlb()

    def _sort(self, event):
        """Event handler for clicking on a column label -- sort by
        that column."""
        column_index = event.widget.column_index

        # If they click on the far-left of far-right of a column's
        # label, then resize rather than sorting.
        if self._mlb._resize_column(event):
            return 'continue'

        # Otherwise, sort.
        else:
            self.sort_by(column_index)
            return 'continue'

    #/////////////////////////////////////////////////////////////////
    #{ Table Drawing Helpers
    #/////////////////////////////////////////////////////////////////

    def _fill_table(self, save_config=True):
        """
        Re-draw the table from scratch, by clearing out the table's
        multi-column listbox; and then filling it in with values from
        ``self._rows``.  Note that any cell-, row-, or column-specific
        color configuration that has been done will be lost.  The
        selection will also be lost -- i.e., no row will be selected
        after this call completes.
        """
        self._mlb.delete(0, 'end')
        for i, row in enumerate(self._rows):
            if self._reprfunc is not None:
                row = [self._reprfunc(i,j,v) for (j,v) in enumerate(row)]
            self._mlb.insert('end', row)

    def _get_itemconfig(self, r, c):
        return dict( (k, self._mlb.itemconfig(r, c, k)[-1])
                     for k in ('foreground', 'selectforeground',
                               'background', 'selectbackground') )

    def _save_config_info(self, row_indices=None, index_by_id=False):
        """
        Return a 'cookie' containing information about which row is
        selected, and what color configurations have been applied.
        this information can the be re-applied to the table (after
        making modifications) using ``_restore_config_info()``.  Color
        configuration information will be saved for any rows in
        ``row_indices``, or in the entire table, if
        ``row_indices=None``.  If ``index_by_id=True``, the the cookie
        will associate rows with their configuration information based
        on the rows' python id.  This is useful when performing
        operations that re-arrange the rows (e.g. ``sort``).  If
        ``index_by_id=False``, then it is assumed that all rows will be
        in the same order when ``_restore_config_info()`` is called.
        """
        # Default value for row_indices is all rows.
        if row_indices is None:
            row_indices = list(range(len(self._rows)))

        # Look up our current selection.
        selection = self.selected_row()
        if index_by_id and selection is not None:
            selection = id(self._rows[selection])

        # Look up the color configuration info for each row.
        if index_by_id:
            config = dict((id(self._rows[r]), [self._get_itemconfig(r, c)
                                        for c in range(self._num_columns)])
                          for r in row_indices)
        else:
            config = dict((r, [self._get_itemconfig(r, c)
                               for c in range(self._num_columns)])
                          for r in row_indices)


        return selection, config

    def _restore_config_info(self, cookie, index_by_id=False, see=False):
        """
        Restore selection & color configuration information that was
        saved using ``_save_config_info``.
        """
        selection, config = cookie

        # Clear the selection.
        if selection is None:
            self._mlb.selection_clear(0, 'end')

        # Restore selection & color config
        if index_by_id:
            for r, row in enumerate(self._rows):
                if id(row) in config:
                    for c in range(self._num_columns):
                        self._mlb.itemconfigure(r, c, config[id(row)][c])
                if id(row) == selection:
                    self._mlb.select(r, see=see)
        else:
            if selection is not None:
                self._mlb.select(selection, see=see)
            for r in config:
                for c in range(self._num_columns):
                    self._mlb.itemconfigure(r, c, config[r][c])

    #/////////////////////////////////////////////////////////////////
    # Debugging (Invariant Checker)
    #/////////////////////////////////////////////////////////////////

    _DEBUG = False
    """If true, then run ``_check_table_vs_mlb()`` after any operation
       that modifies the table."""

    def _check_table_vs_mlb(self):
        """
        Verify that the contents of the table's ``_rows`` variable match
        the contents of its multi-listbox (``_mlb``).  This is just
        included for debugging purposes, to make sure that the
        list-modifying operations are working correctly.
        """
        for col in self._mlb.listboxes:
            assert len(self) == col.size()
        for row in self:
            assert len(row) == self._num_columns
        assert self._num_columns == len(self._mlb.column_names)
        #assert self._column_names == self._mlb.column_names
        for i, row in enumerate(self):
            for j, cell in enumerate(row):
                if self._reprfunc is not None:
                    cell = self._reprfunc(i, j, cell)
                assert self._mlb.get(i)[j] == cell
示例#36
0
class Dialog(Toplevel):
    def __init__(self, parent, title=None, content=""):
        Toplevel.__init__(self, parent)
        self.transient(parent)
        self.log = logging.getLogger(__name__)

        if title:
            self.title(title)

        self.parent = parent
        self.body = Frame(self)
        self.fill_body(content)
        self.body.pack(padx=5, pady=5)

        self.create_buttonbox()

        self.grab_set()

        self.protocol("WM_DELETE_WINDOW", self.ok)

        self.geometry("+%d+%d" %
                      (parent.winfo_rootx() + 50, parent.winfo_rooty() + 50))

        self.focus_set()

        self.wait_window(self)

    #
    # construction hooks

    def fill_body(self, content):
        scrollbar = Scrollbar(self.body)
        scrollbar.pack(side=RIGHT, fill=Y)

        text = Text(self.body, yscrollcommand=scrollbar.set)
        text.pack(side=LEFT, fill=BOTH)
        text.config(state=NORMAL)
        text.delete(1.0, END)
        text.insert(END, content)
        text.config(state=DISABLED)

        scrollbar.config(command=text.yview)

    def create_buttonbox(self):
        # add standard button box. override if you don't want the
        # standard buttons

        box = Frame(self)

        w = Button(box, text="OK", width=10, command=self.ok, default=ACTIVE)
        w.pack(side=LEFT, padx=5, pady=5)

        self.bind("&<Return>", self.ok)
        self.bind("&<Escape>", self.ok)

        box.pack()

    def ok(self, _event=None):
        self.withdraw()
        self.update_idletasks()
        self.parent.focus_set()
        self.destroy()
示例#37
0
class Table(object):
    """
    A display widget for a table of values, based on a ``MultiListbox``
    widget.  For many purposes, ``Table`` can be treated as a
    list-of-lists.  E.g., table[i] is a list of the values for row i;
    and table.append(row) adds a new row with the given lits of
    values.  Individual cells can be accessed using table[i,j], which
    refers to the j-th column of the i-th row.  This can be used to
    both read and write values from the table.  E.g.:

        >>> table[i,j] = 'hello'

    The column (j) can be given either as an index number, or as a
    column name.  E.g., the following prints the value in the 3rd row
    for the 'First Name' column:

        >>> print(table[3, 'First Name'])
        John

    You can configure the colors for individual rows, columns, or
    cells using ``rowconfig()``, ``columnconfig()``, and ``itemconfig()``.
    The color configuration for each row will be preserved if the
    table is modified; however, when new rows are added, any color
    configurations that have been made for *columns* will not be
    applied to the new row.

    Note: Although ``Table`` acts like a widget in some ways (e.g., it
    defines ``grid()``, ``pack()``, and ``bind()``), it is not itself a
    widget; it just contains one.  This is because widgets need to
    define ``__getitem__()``, ``__setitem__()``, and ``__nonzero__()`` in
    a way that's incompatible with the fact that ``Table`` behaves as a
    list-of-lists.

    :ivar _mlb: The multi-column listbox used to display this table's data.
    :ivar _rows: A list-of-lists used to hold the cell values of this
        table.  Each element of _rows is a row value, i.e., a list of
        cell values, one for each column in the row.
    """
    def __init__(self,
                 master,
                 column_names,
                 rows=None,
                 column_weights=None,
                 scrollbar=True,
                 click_to_sort=True,
                 reprfunc=None,
                 cnf={},
                 **kw):
        """
        Construct a new Table widget.

        :type master: Tkinter.Widget
        :param master: The widget that should contain the new table.
        :type column_names: list(str)
        :param column_names: A list of names for the columns; these
            names will be used to create labels for each column;
            and can be used as an index when reading or writing
            cell values from the table.
        :type rows: list(list)
        :param rows: A list of row values used to initialze the table.
            Each row value should be a tuple of cell values, one for
            each column in the row.
        :type scrollbar: bool
        :param scrollbar: If true, then create a scrollbar for the
            new table widget.
        :type click_to_sort: bool
        :param click_to_sort: If true, then create bindings that will
            sort the table's rows by a given column's values if the
            user clicks on that colum's label.
        :type reprfunc: function
        :param reprfunc: If specified, then use this function to
            convert each table cell value to a string suitable for
            display.  ``reprfunc`` has the following signature:
            reprfunc(row_index, col_index, cell_value) -> str
            (Note that the column is specified by index, not by name.)
        :param cnf, kw: Configuration parameters for this widget's
            contained ``MultiListbox``.  See ``MultiListbox.__init__()``
            for details.
        """
        self._num_columns = len(column_names)
        self._reprfunc = reprfunc
        self._frame = Frame(master)

        self._column_name_to_index = dict(
            (c, i) for (i, c) in enumerate(column_names))

        # Make a copy of the rows & check that it's valid.
        if rows is None: self._rows = []
        else: self._rows = [[v for v in row] for row in rows]
        for row in self._rows:
            self._checkrow(row)

        # Create our multi-list box.
        self._mlb = MultiListbox(self._frame, column_names, column_weights,
                                 cnf, **kw)
        self._mlb.pack(side='left', expand=True, fill='both')

        # Optional scrollbar
        if scrollbar:
            sb = Scrollbar(self._frame,
                           orient='vertical',
                           command=self._mlb.yview)
            self._mlb.listboxes[0]['yscrollcommand'] = sb.set
            #for listbox in self._mlb.listboxes:
            #    listbox['yscrollcommand'] = sb.set
            sb.pack(side='right', fill='y')
            self._scrollbar = sb

        # Set up sorting
        self._sortkey = None
        if click_to_sort:
            for i, l in enumerate(self._mlb.column_labels):
                l.bind('<Button-1>', self._sort)

        # Fill in our multi-list box.
        self._fill_table()

    #/////////////////////////////////////////////////////////////////
    #{ Widget-like Methods
    #/////////////////////////////////////////////////////////////////
    # These all just delegate to either our frame or our MLB.

    def pack(self, *args, **kwargs):
        """Position this table's main frame widget in its parent
        widget.  See ``Tkinter.Frame.pack()`` for more info."""
        self._frame.pack(*args, **kwargs)

    def grid(self, *args, **kwargs):
        """Position this table's main frame widget in its parent
        widget.  See ``Tkinter.Frame.grid()`` for more info."""
        self._frame.grid(*args, **kwargs)

    def focus(self):
        """Direct (keyboard) input foxus to this widget."""
        self._mlb.focus()

    def bind(self, sequence=None, func=None, add=None):
        """Add a binding to this table's main frame that will call
        ``func`` in response to the event sequence."""
        self._mlb.bind(sequence, func, add)

    def rowconfigure(self, row_index, cnf={}, **kw):
        """:see: ``MultiListbox.rowconfigure()``"""
        self._mlb.rowconfigure(row_index, cnf, **kw)

    def columnconfigure(self, col_index, cnf={}, **kw):
        """:see: ``MultiListbox.columnconfigure()``"""
        col_index = self.column_index(col_index)
        self._mlb.columnconfigure(col_index, cnf, **kw)

    def itemconfigure(self, row_index, col_index, cnf=None, **kw):
        """:see: ``MultiListbox.itemconfigure()``"""
        col_index = self.column_index(col_index)
        return self._mlb.itemconfigure(row_index, col_index, cnf, **kw)

    def bind_to_labels(self, sequence=None, func=None, add=None):
        """:see: ``MultiListbox.bind_to_labels()``"""
        return self._mlb.bind_to_labels(sequence, func, add)

    def bind_to_listboxes(self, sequence=None, func=None, add=None):
        """:see: ``MultiListbox.bind_to_listboxes()``"""
        return self._mlb.bind_to_listboxes(sequence, func, add)

    def bind_to_columns(self, sequence=None, func=None, add=None):
        """:see: ``MultiListbox.bind_to_columns()``"""
        return self._mlb.bind_to_columns(sequence, func, add)

    rowconfig = rowconfigure
    columnconfig = columnconfigure
    itemconfig = itemconfigure

    #/////////////////////////////////////////////////////////////////
    #{ Table as list-of-lists
    #/////////////////////////////////////////////////////////////////

    def insert(self, row_index, rowvalue):
        """
        Insert a new row into the table, so that its row index will be
        ``row_index``.  If the table contains any rows whose row index
        is greater than or equal to ``row_index``, then they will be
        shifted down.

        :param rowvalue: A tuple of cell values, one for each column
            in the new row.
        """
        self._checkrow(rowvalue)
        self._rows.insert(row_index, rowvalue)
        if self._reprfunc is not None:
            rowvalue = [
                self._reprfunc(row_index, j, v)
                for (j, v) in enumerate(rowvalue)
            ]
        self._mlb.insert(row_index, rowvalue)
        if self._DEBUG: self._check_table_vs_mlb()

    def extend(self, rowvalues):
        """
        Add new rows at the end of the table.

        :param rowvalues: A list of row values used to initialze the
            table.  Each row value should be a tuple of cell values,
            one for each column in the row.
        """
        for rowvalue in rowvalues:
            self.append(rowvalue)
        if self._DEBUG: self._check_table_vs_mlb()

    def append(self, rowvalue):
        """
        Add a new row to the end of the table.

        :param rowvalue: A tuple of cell values, one for each column
            in the new row.
        """
        self.insert(len(self._rows), rowvalue)
        if self._DEBUG: self._check_table_vs_mlb()

    def clear(self):
        """
        Delete all rows in this table.
        """
        self._rows = []
        self._mlb.delete(0, 'end')
        if self._DEBUG: self._check_table_vs_mlb()

    def __getitem__(self, index):
        """
        Return the value of a row or a cell in this table.  If
        ``index`` is an integer, then the row value for the ``index``th
        row.  This row value consists of a tuple of cell values, one
        for each column in the row.  If ``index`` is a tuple of two
        integers, ``(i,j)``, then return the value of the cell in the
        ``i``th row and the ``j``th column.
        """
        if isinstance(index, slice):
            raise ValueError('Slicing not supported')
        elif isinstance(index, tuple) and len(index) == 2:
            return self._rows[index[0]][self.column_index(index[1])]
        else:
            return tuple(self._rows[index])

    def __setitem__(self, index, val):
        """
        Replace the value of a row or a cell in this table with
        ``val``.

        If ``index`` is an integer, then ``val`` should be a row value
        (i.e., a tuple of cell values, one for each column).  In this
        case, the values of the ``index``th row of the table will be
        replaced with the values in ``val``.

        If ``index`` is a tuple of integers, ``(i,j)``, then replace the
        value of the cell in the ``i``th row and ``j``th column with
        ``val``.
        """
        if isinstance(index, slice):
            raise ValueError('Slicing not supported')

        # table[i,j] = val
        elif isinstance(index, tuple) and len(index) == 2:
            i, j = index[0], self.column_index(index[1])
            config_cookie = self._save_config_info([i])
            self._rows[i][j] = val
            if self._reprfunc is not None:
                val = self._reprfunc(i, j, val)
            self._mlb.listboxes[j].insert(i, val)
            self._mlb.listboxes[j].delete(i + 1)
            self._restore_config_info(config_cookie)

        # table[i] = val
        else:
            config_cookie = self._save_config_info([index])
            self._checkrow(val)
            self._rows[index] = list(val)
            if self._reprfunc is not None:
                val = [
                    self._reprfunc(index, j, v) for (j, v) in enumerate(val)
                ]
            self._mlb.insert(index, val)
            self._mlb.delete(index + 1)
            self._restore_config_info(config_cookie)

    def __delitem__(self, row_index):
        """
        Delete the ``row_index``th row from this table.
        """
        if isinstance(row_index, slice):
            raise ValueError('Slicing not supported')
        if isinstance(row_index, tuple) and len(row_index) == 2:
            raise ValueError('Cannot delete a single cell!')
        del self._rows[row_index]
        self._mlb.delete(row_index)
        if self._DEBUG: self._check_table_vs_mlb()

    def __len__(self):
        """
        :return: the number of rows in this table.
        """
        return len(self._rows)

    def _checkrow(self, rowvalue):
        """
        Helper function: check that a given row value has the correct
        number of elements; and if not, raise an exception.
        """
        if len(rowvalue) != self._num_columns:
            raise ValueError('Row %r has %d columns; expected %d' %
                             (rowvalue, len(rowvalue), self._num_columns))

    #/////////////////////////////////////////////////////////////////
    # Columns
    #/////////////////////////////////////////////////////////////////

    @property
    def column_names(self):
        """A list of the names of the columns in this table."""
        return self._mlb.column_names

    def column_index(self, i):
        """
        If ``i`` is a valid column index integer, then return it as is.
        Otherwise, check if ``i`` is used as the name for any column;
        if so, return that column's index.  Otherwise, raise a
        ``KeyError`` exception.
        """
        if isinstance(i, int) and 0 <= i < self._num_columns:
            return i
        else:
            # This raises a key error if the column is not found.
            return self._column_name_to_index[i]

    def hide_column(self, column_index):
        """:see: ``MultiListbox.hide_column()``"""
        self._mlb.hide_column(self.column_index(column_index))

    def show_column(self, column_index):
        """:see: ``MultiListbox.show_column()``"""
        self._mlb.show_column(self.column_index(column_index))

    #/////////////////////////////////////////////////////////////////
    # Selection
    #/////////////////////////////////////////////////////////////////

    def selected_row(self):
        """
        Return the index of the currently selected row, or None if
        no row is selected.  To get the row value itself, use
        ``table[table.selected_row()]``.
        """
        sel = self._mlb.curselection()
        if sel: return int(sel[0])
        else: return None

    def select(self, index=None, delta=None, see=True):
        """:see: ``MultiListbox.select()``"""
        self._mlb.select(index, delta, see)

    #/////////////////////////////////////////////////////////////////
    # Sorting
    #/////////////////////////////////////////////////////////////////

    def sort_by(self, column_index, order='toggle'):
        """
        Sort the rows in this table, using the specified column's
        values as a sort key.

        :param column_index: Specifies which column to sort, using
            either a column index (int) or a column's label name
            (str).

        :param order: Specifies whether to sort the values in
            ascending or descending order:

              - ``'ascending'``: Sort from least to greatest.
              - ``'descending'``: Sort from greatest to least.
              - ``'toggle'``: If the most recent call to ``sort_by()``
                sorted the table by the same column (``column_index``),
                then reverse the rows; otherwise sort in ascending
                order.
        """
        if order not in ('ascending', 'descending', 'toggle'):
            raise ValueError('sort_by(): order should be "ascending", '
                             '"descending", or "toggle".')
        column_index = self.column_index(column_index)
        config_cookie = self._save_config_info(index_by_id=True)

        # Sort the rows.
        if order == 'toggle' and column_index == self._sortkey:
            self._rows.reverse()
        else:
            self._rows.sort(key=operator.itemgetter(column_index),
                            reverse=(order == 'descending'))
            self._sortkey = column_index

        # Redraw the table.
        self._fill_table()
        self._restore_config_info(config_cookie, index_by_id=True, see=True)
        if self._DEBUG: self._check_table_vs_mlb()

    def _sort(self, event):
        """Event handler for clicking on a column label -- sort by
        that column."""
        column_index = event.widget.column_index

        # If they click on the far-left of far-right of a column's
        # label, then resize rather than sorting.
        if self._mlb._resize_column(event):
            return 'continue'

        # Otherwise, sort.
        else:
            self.sort_by(column_index)
            return 'continue'

    #/////////////////////////////////////////////////////////////////
    #{ Table Drawing Helpers
    #/////////////////////////////////////////////////////////////////

    def _fill_table(self, save_config=True):
        """
        Re-draw the table from scratch, by clearing out the table's
        multi-column listbox; and then filling it in with values from
        ``self._rows``.  Note that any cell-, row-, or column-specific
        color configuration that has been done will be lost.  The
        selection will also be lost -- i.e., no row will be selected
        after this call completes.
        """
        self._mlb.delete(0, 'end')
        for i, row in enumerate(self._rows):
            if self._reprfunc is not None:
                row = [self._reprfunc(i, j, v) for (j, v) in enumerate(row)]
            self._mlb.insert('end', row)

    def _get_itemconfig(self, r, c):
        return dict((k, self._mlb.itemconfig(r, c, k)[-1])
                    for k in ('foreground', 'selectforeground', 'background',
                              'selectbackground'))

    def _save_config_info(self, row_indices=None, index_by_id=False):
        """
        Return a 'cookie' containing information about which row is
        selected, and what color configurations have been applied.
        this information can the be re-applied to the table (after
        making modifications) using ``_restore_config_info()``.  Color
        configuration information will be saved for any rows in
        ``row_indices``, or in the entire table, if
        ``row_indices=None``.  If ``index_by_id=True``, the the cookie
        will associate rows with their configuration information based
        on the rows' python id.  This is useful when performing
        operations that re-arrange the rows (e.g. ``sort``).  If
        ``index_by_id=False``, then it is assumed that all rows will be
        in the same order when ``_restore_config_info()`` is called.
        """
        # Default value for row_indices is all rows.
        if row_indices is None:
            row_indices = list(range(len(self._rows)))

        # Look up our current selection.
        selection = self.selected_row()
        if index_by_id and selection is not None:
            selection = id(self._rows[selection])

        # Look up the color configuration info for each row.
        if index_by_id:
            config = dict((
                id(self._rows[r]),
                [self._get_itemconfig(r, c) for c in range(self._num_columns)])
                          for r in row_indices)
        else:
            config = dict((
                r,
                [self._get_itemconfig(r, c) for c in range(self._num_columns)])
                          for r in row_indices)

        return selection, config

    def _restore_config_info(self, cookie, index_by_id=False, see=False):
        """
        Restore selection & color configuration information that was
        saved using ``_save_config_info``.
        """
        selection, config = cookie

        # Clear the selection.
        if selection is None:
            self._mlb.selection_clear(0, 'end')

        # Restore selection & color config
        if index_by_id:
            for r, row in enumerate(self._rows):
                if id(row) in config:
                    for c in range(self._num_columns):
                        self._mlb.itemconfigure(r, c, config[id(row)][c])
                if id(row) == selection:
                    self._mlb.select(r, see=see)
        else:
            if selection is not None:
                self._mlb.select(selection, see=see)
            for r in config:
                for c in range(self._num_columns):
                    self._mlb.itemconfigure(r, c, config[r][c])

    #/////////////////////////////////////////////////////////////////
    # Debugging (Invariant Checker)
    #/////////////////////////////////////////////////////////////////

    _DEBUG = False
    """If true, then run ``_check_table_vs_mlb()`` after any operation
       that modifies the table."""

    def _check_table_vs_mlb(self):
        """
        Verify that the contents of the table's ``_rows`` variable match
        the contents of its multi-listbox (``_mlb``).  This is just
        included for debugging purposes, to make sure that the
        list-modifying operations are working correctly.
        """
        for col in self._mlb.listboxes:
            assert len(self) == col.size()
        for row in self:
            assert len(row) == self._num_columns
        assert self._num_columns == len(self._mlb.column_names)
        #assert self._column_names == self._mlb.column_names
        for i, row in enumerate(self):
            for j, cell in enumerate(row):
                if self._reprfunc is not None:
                    cell = self._reprfunc(i, j, cell)
                assert self._mlb.get(i)[j] == cell
class ConcordanceSearchView(object):
    _BACKGROUND_COLOUR='#FFF' #white

    #Colour of highlighted results
    _HIGHLIGHT_WORD_COLOUR='#F00' #red
    _HIGHLIGHT_WORD_TAG='HL_WRD_TAG'

    _HIGHLIGHT_LABEL_COLOUR='#C0C0C0' # dark grey
    _HIGHLIGHT_LABEL_TAG='HL_LBL_TAG'


    #Percentage of text left of the scrollbar position
    _FRACTION_LEFT_TEXT=0.30

    def __init__(self):
        self.queue = q.Queue()
        self.model = ConcordanceSearchModel(self.queue)
        self.top = Tk()
        self._init_top(self.top)
        self._init_menubar()
        self._init_widgets(self.top)
        self.load_corpus(self.model.DEFAULT_CORPUS)
        self.after = self.top.after(POLL_INTERVAL, self._poll)

    def _init_top(self, top):
        top.geometry('950x680+50+50')
        top.title('NLTK Concordance Search')
        top.bind('<Control-q>', self.destroy)
        top.protocol('WM_DELETE_WINDOW', self.destroy)
        top.minsize(950,680)

    def _init_widgets(self, parent):
        self.main_frame = Frame(parent, dict(background=self._BACKGROUND_COLOUR, padx=1, pady=1, border=1))
        self._init_corpus_select(self.main_frame)
        self._init_query_box(self.main_frame)
        self._init_results_box(self.main_frame)
        self._init_paging(self.main_frame)
        self._init_status(self.main_frame)
        self.main_frame.pack(fill='both', expand=True)

    def _init_menubar(self):
        self._result_size = IntVar(self.top)
        self._cntx_bf_len = IntVar(self.top)
        self._cntx_af_len = IntVar(self.top)
        menubar = Menu(self.top)

        filemenu = Menu(menubar, tearoff=0, borderwidth=0)
        filemenu.add_command(label='Exit', underline=1,
                             command=self.destroy, accelerator='Ctrl-q')
        menubar.add_cascade(label='File', underline=0, menu=filemenu)

        editmenu = Menu(menubar, tearoff=0)
        rescntmenu = Menu(editmenu, tearoff=0)
        rescntmenu.add_radiobutton(label='20', variable=self._result_size,
                                   underline=0, value=20,
                                   command=self.set_result_size)
        rescntmenu.add_radiobutton(label='50', variable=self._result_size,
                                   underline=0, value=50,
                                   command=self.set_result_size)
        rescntmenu.add_radiobutton(label='100', variable=self._result_size,
                                   underline=0, value=100,
                                   command=self.set_result_size)
        rescntmenu.invoke(1)
        editmenu.add_cascade(label='Result Count', underline=0, menu=rescntmenu)

        cntxmenu = Menu(editmenu, tearoff=0)
        cntxbfmenu = Menu(cntxmenu, tearoff=0)
        cntxbfmenu.add_radiobutton(label='60 characters',
                                   variable=self._cntx_bf_len,
                                   underline=0, value=60,
                                   command=self.set_cntx_bf_len)
        cntxbfmenu.add_radiobutton(label='80 characters',
                                   variable=self._cntx_bf_len,
                                   underline=0, value=80,
                                   command=self.set_cntx_bf_len)
        cntxbfmenu.add_radiobutton(label='100 characters',
                                   variable=self._cntx_bf_len,
                                   underline=0, value=100,
                                   command=self.set_cntx_bf_len)
        cntxbfmenu.invoke(1)
        cntxmenu.add_cascade(label='Before', underline=0, menu=cntxbfmenu)

        cntxafmenu = Menu(cntxmenu, tearoff=0)
        cntxafmenu.add_radiobutton(label='70 characters',
                                   variable=self._cntx_af_len,
                                   underline=0, value=70,
                                   command=self.set_cntx_af_len)
        cntxafmenu.add_radiobutton(label='90 characters',
                                   variable=self._cntx_af_len,
                                   underline=0, value=90,
                                   command=self.set_cntx_af_len)
        cntxafmenu.add_radiobutton(label='110 characters',
                                   variable=self._cntx_af_len,
                                   underline=0, value=110,
                                   command=self.set_cntx_af_len)
        cntxafmenu.invoke(1)
        cntxmenu.add_cascade(label='After', underline=0, menu=cntxafmenu)

        editmenu.add_cascade(label='Context', underline=0, menu=cntxmenu)

        menubar.add_cascade(label='Edit', underline=0, menu=editmenu)

        self.top.config(menu=menubar)

    def set_result_size(self, **kwargs):
        self.model.result_count = self._result_size.get()

    def set_cntx_af_len(self, **kwargs):
        self._char_after = self._cntx_af_len.get()

    def set_cntx_bf_len(self, **kwargs):
        self._char_before = self._cntx_bf_len.get()

    def _init_corpus_select(self, parent):
        innerframe = Frame(parent, background=self._BACKGROUND_COLOUR)
        self.var = StringVar(innerframe)
        self.var.set(self.model.DEFAULT_CORPUS)
        Label(innerframe, justify=LEFT, text=' Corpus: ',
              background=self._BACKGROUND_COLOUR, padx = 2, pady = 1, border = 0).pack(side='left')

        other_corpora = list(self.model.CORPORA.keys()).remove(self.model.DEFAULT_CORPUS)
        om = OptionMenu(innerframe, self.var, self.model.DEFAULT_CORPUS, command=self.corpus_selected, *self.model.non_default_corpora())
        om['borderwidth'] = 0
        om['highlightthickness'] = 1
        om.pack(side='left')
        innerframe.pack(side='top', fill='x', anchor='n')

    def _init_status(self, parent):
        self.status = Label(parent, justify=LEFT, relief=SUNKEN, background=self._BACKGROUND_COLOUR, border=0, padx = 1, pady = 0)
        self.status.pack(side='top', anchor='sw')

    def _init_query_box(self, parent):
        innerframe = Frame(parent, background=self._BACKGROUND_COLOUR)
        another = Frame(innerframe, background=self._BACKGROUND_COLOUR)
        self.query_box = Entry(another, width=60)
        self.query_box.pack(side='left', fill='x', pady=25, anchor='center')
        self.search_button = Button(another, text='Search', command=self.search, borderwidth=1, highlightthickness=1)
        self.search_button.pack(side='left', fill='x', pady=25, anchor='center')
        self.query_box.bind('<KeyPress-Return>', self.search_enter_keypress_handler)
        another.pack()
        innerframe.pack(side='top', fill='x', anchor='n')

    def search_enter_keypress_handler(self, *event):
        self.search()

    def _init_results_box(self, parent):
        innerframe = Frame(parent)
        i1 = Frame(innerframe)
        i2 = Frame(innerframe)
        vscrollbar = Scrollbar(i1, borderwidth=1)
        hscrollbar = Scrollbar(i2, borderwidth=1, orient='horiz')
        self.results_box = Text(i1,
                                font=Font(family='courier', size='16'),
                                state='disabled', borderwidth=1,
                                                            yscrollcommand=vscrollbar.set,
                                xscrollcommand=hscrollbar.set, wrap='none', width='40', height = '20', exportselection=1)
        self.results_box.pack(side='left', fill='both', expand=True)
        self.results_box.tag_config(self._HIGHLIGHT_WORD_TAG, foreground=self._HIGHLIGHT_WORD_COLOUR)
        self.results_box.tag_config(self._HIGHLIGHT_LABEL_TAG, foreground=self._HIGHLIGHT_LABEL_COLOUR)
        vscrollbar.pack(side='left', fill='y', anchor='e')
        vscrollbar.config(command=self.results_box.yview)
        hscrollbar.pack(side='left', fill='x', expand=True, anchor='w')
        hscrollbar.config(command=self.results_box.xview)
        #there is no other way of avoiding the overlap of scrollbars while using pack layout manager!!!
        Label(i2, text='   ', background=self._BACKGROUND_COLOUR).pack(side='left', anchor='e')
        i1.pack(side='top', fill='both', expand=True, anchor='n')
        i2.pack(side='bottom', fill='x', anchor='s')
        innerframe.pack(side='top', fill='both', expand=True)

    def _init_paging(self, parent):
        innerframe = Frame(parent, background=self._BACKGROUND_COLOUR)
        self.prev = prev = Button(innerframe, text='Previous', command=self.previous, width='10', borderwidth=1, highlightthickness=1, state='disabled')
        prev.pack(side='left', anchor='center')
        self.next = next = Button(innerframe, text='Next', command=self.__next__, width='10', borderwidth=1, highlightthickness=1, state='disabled')
        next.pack(side='right', anchor='center')
        innerframe.pack(side='top', fill='y')
        self.current_page = 0

    def previous(self):
        self.clear_results_box()
        self.freeze_editable()
        self.model.prev(self.current_page - 1)

    def __next__(self):
        self.clear_results_box()
        self.freeze_editable()
        self.model.next(self.current_page + 1)

    def about(self, *e):
        ABOUT = ("NLTK Concordance Search Demo\n")
        TITLE = 'About: NLTK Concordance Search Demo'
        try:
            from six.moves.tkinter_messagebox import Message
            Message(message=ABOUT, title=TITLE, parent=self.main_frame).show()
        except:
            ShowText(self.top, TITLE, ABOUT)

    def _bind_event_handlers(self):
        self.top.bind(CORPUS_LOADED_EVENT, self.handle_corpus_loaded)
        self.top.bind(SEARCH_TERMINATED_EVENT, self.handle_search_terminated)
        self.top.bind(SEARCH_ERROR_EVENT, self.handle_search_error)
        self.top.bind(ERROR_LOADING_CORPUS_EVENT, self.handle_error_loading_corpus)

    def _poll(self):
        try:
            event = self.queue.get(block=False)
        except q.Empty:
            pass
        else:
            if event == CORPUS_LOADED_EVENT:
                self.handle_corpus_loaded(event)
            elif event == SEARCH_TERMINATED_EVENT:
                self.handle_search_terminated(event)
            elif event == SEARCH_ERROR_EVENT:
                self.handle_search_error(event)
            elif event == ERROR_LOADING_CORPUS_EVENT:
                self.handle_error_loading_corpus(event)
        self.after = self.top.after(POLL_INTERVAL, self._poll)

    def handle_error_loading_corpus(self, event):
        self.status['text'] = 'Error in loading ' + self.var.get()
        self.unfreeze_editable()
        self.clear_all()
        self.freeze_editable()

    def handle_corpus_loaded(self, event):
        self.status['text'] = self.var.get() + ' is loaded'
        self.unfreeze_editable()
        self.clear_all()
        self.query_box.focus_set()

    def handle_search_terminated(self, event):
        #todo: refactor the model such that it is less state sensitive
        results = self.model.get_results()
        self.write_results(results)
        self.status['text'] = ''
        if len(results) == 0:
            self.status['text'] = 'No results found for ' + self.model.query
        else:
                self.current_page = self.model.last_requested_page
        self.unfreeze_editable()
        self.results_box.xview_moveto(self._FRACTION_LEFT_TEXT)

    def handle_search_error(self, event):
        self.status['text'] = 'Error in query ' + self.model.query
        self.unfreeze_editable()

    def corpus_selected(self, *args):
        new_selection = self.var.get()
        self.load_corpus(new_selection)

    def load_corpus(self, selection):
        if self.model.selected_corpus != selection:
            self.status['text'] = 'Loading ' + selection + '...'
            self.freeze_editable()
            self.model.load_corpus(selection)

    def search(self):
        self.current_page = 0
        self.clear_results_box()
        self.model.reset_results()
        query = self.query_box.get()
        if (len(query.strip()) == 0): return
        self.status['text']  = 'Searching for ' + query
        self.freeze_editable()
        self.model.search(query, self.current_page + 1, )


    def write_results(self, results):
        self.results_box['state'] = 'normal'
        row = 1
        for each in results:
            sent, pos1, pos2 = each[0].strip(), each[1], each[2]
            if len(sent) != 0:
                if (pos1 < self._char_before):
                    sent, pos1, pos2 = self.pad(sent, pos1, pos2)
                sentence = sent[pos1-self._char_before:pos1+self._char_after]
                if not row == len(results):
                    sentence += '\n'
                self.results_box.insert(str(row) + '.0', sentence)
                word_markers, label_markers = self.words_and_labels(sent, pos1, pos2)
                for marker in word_markers: self.results_box.tag_add(self._HIGHLIGHT_WORD_TAG, str(row) + '.' + str(marker[0]), str(row) + '.' + str(marker[1]))
                for marker in label_markers: self.results_box.tag_add(self._HIGHLIGHT_LABEL_TAG, str(row) + '.' + str(marker[0]), str(row) + '.' + str(marker[1]))
                row += 1
        self.results_box['state'] = 'disabled'

    def words_and_labels(self, sentence, pos1, pos2):
        search_exp = sentence[pos1:pos2]
        words, labels = [], []
        labeled_words = search_exp.split(' ')
        index = 0
        for each in labeled_words:
            if each == '':
                index += 1
            else:
                word, label = each.split('/')
                words.append((self._char_before + index, self._char_before + index + len(word)))
                index += len(word) + 1
                labels.append((self._char_before + index, self._char_before + index + len(label)))
                index += len(label)
            index += 1
        return words, labels

    def pad(self, sent, hstart, hend):
        if hstart >= self._char_before:
            return sent, hstart, hend
        d = self._char_before - hstart
        sent = ''.join([' '] * d) + sent
        return sent, hstart + d, hend + d

    def destroy(self, *e):
        if self.top is None: return
        self.top.after_cancel(self.after)
        self.top.destroy()
        self.top = None

    def clear_all(self):
        self.query_box.delete(0, END)
        self.model.reset_query()
        self.clear_results_box()

    def clear_results_box(self):
        self.results_box['state'] = 'normal'
        self.results_box.delete("1.0", END)
        self.results_box['state'] = 'disabled'

    def freeze_editable(self):
        self.query_box['state'] = 'disabled'
        self.search_button['state'] = 'disabled'
        self.prev['state'] = 'disabled'
        self.next['state'] = 'disabled'

    def unfreeze_editable(self):
        self.query_box['state'] = 'normal'
        self.search_button['state'] = 'normal'
        self.set_paging_button_states()

    def set_paging_button_states(self):
        if self.current_page == 0 or self.current_page == 1:
            self.prev['state'] = 'disabled'
        else:
            self.prev['state'] = 'normal'
        if self.model.has_more_pages(self.current_page):
            self.next['state'] = 'normal'
        else:
            self.next['state'] = 'disabled'

    def fire_event(self, event):
        #Firing an event so that rendering of widgets happen in the mainloop thread
        self.top.event_generate(event, when='tail')

    def mainloop(self, *args, **kwargs):
        if in_idle(): return
        self.top.mainloop(*args, **kwargs)
示例#39
0
class CollocationsView:
    _BACKGROUND_COLOUR = "#FFF"  # white

    def __init__(self):
        self.queue = q.Queue()
        self.model = CollocationsModel(self.queue)
        self.top = Tk()
        self._init_top(self.top)
        self._init_menubar()
        self._init_widgets(self.top)
        self.load_corpus(self.model.DEFAULT_CORPUS)
        self.after = self.top.after(POLL_INTERVAL, self._poll)

    def _init_top(self, top):
        top.geometry("550x650+50+50")
        top.title("NLTK Collocations List")
        top.bind("<Control-q>", self.destroy)
        top.protocol("WM_DELETE_WINDOW", self.destroy)
        top.minsize(550, 650)

    def _init_widgets(self, parent):
        self.main_frame = Frame(
            parent,
            dict(background=self._BACKGROUND_COLOUR, padx=1, pady=1, border=1))
        self._init_corpus_select(self.main_frame)
        self._init_results_box(self.main_frame)
        self._init_paging(self.main_frame)
        self._init_status(self.main_frame)
        self.main_frame.pack(fill="both", expand=True)

    def _init_corpus_select(self, parent):
        innerframe = Frame(parent, background=self._BACKGROUND_COLOUR)
        self.var = StringVar(innerframe)
        self.var.set(self.model.DEFAULT_CORPUS)
        Label(
            innerframe,
            justify=LEFT,
            text=" Corpus: ",
            background=self._BACKGROUND_COLOUR,
            padx=2,
            pady=1,
            border=0,
        ).pack(side="left")

        other_corpora = list(self.model.CORPORA.keys()).remove(
            self.model.DEFAULT_CORPUS)
        om = OptionMenu(innerframe,
                        self.var,
                        self.model.DEFAULT_CORPUS,
                        command=self.corpus_selected,
                        *self.model.non_default_corpora())
        om["borderwidth"] = 0
        om["highlightthickness"] = 1
        om.pack(side="left")
        innerframe.pack(side="top", fill="x", anchor="n")

    def _init_status(self, parent):
        self.status = Label(
            parent,
            justify=LEFT,
            relief=SUNKEN,
            background=self._BACKGROUND_COLOUR,
            border=0,
            padx=1,
            pady=0,
        )
        self.status.pack(side="top", anchor="sw")

    def _init_menubar(self):
        self._result_size = IntVar(self.top)
        menubar = Menu(self.top)

        filemenu = Menu(menubar, tearoff=0, borderwidth=0)
        filemenu.add_command(label="Exit",
                             underline=1,
                             command=self.destroy,
                             accelerator="Ctrl-q")
        menubar.add_cascade(label="File", underline=0, menu=filemenu)

        editmenu = Menu(menubar, tearoff=0)
        rescntmenu = Menu(editmenu, tearoff=0)
        rescntmenu.add_radiobutton(
            label="20",
            variable=self._result_size,
            underline=0,
            value=20,
            command=self.set_result_size,
        )
        rescntmenu.add_radiobutton(
            label="50",
            variable=self._result_size,
            underline=0,
            value=50,
            command=self.set_result_size,
        )
        rescntmenu.add_radiobutton(
            label="100",
            variable=self._result_size,
            underline=0,
            value=100,
            command=self.set_result_size,
        )
        rescntmenu.invoke(1)
        editmenu.add_cascade(label="Result Count",
                             underline=0,
                             menu=rescntmenu)

        menubar.add_cascade(label="Edit", underline=0, menu=editmenu)
        self.top.config(menu=menubar)

    def set_result_size(self, **kwargs):
        self.model.result_count = self._result_size.get()

    def _init_results_box(self, parent):
        innerframe = Frame(parent)
        i1 = Frame(innerframe)
        i2 = Frame(innerframe)
        vscrollbar = Scrollbar(i1, borderwidth=1)
        hscrollbar = Scrollbar(i2, borderwidth=1, orient="horiz")
        self.results_box = Text(
            i1,
            font=Font(family="courier", size="16"),
            state="disabled",
            borderwidth=1,
            yscrollcommand=vscrollbar.set,
            xscrollcommand=hscrollbar.set,
            wrap="none",
            width="40",
            height="20",
            exportselection=1,
        )
        self.results_box.pack(side="left", fill="both", expand=True)
        vscrollbar.pack(side="left", fill="y", anchor="e")
        vscrollbar.config(command=self.results_box.yview)
        hscrollbar.pack(side="left", fill="x", expand=True, anchor="w")
        hscrollbar.config(command=self.results_box.xview)
        # there is no other way of avoiding the overlap of scrollbars while using pack layout manager!!!
        Label(i2, text="   ",
              background=self._BACKGROUND_COLOUR).pack(side="left", anchor="e")
        i1.pack(side="top", fill="both", expand=True, anchor="n")
        i2.pack(side="bottom", fill="x", anchor="s")
        innerframe.pack(side="top", fill="both", expand=True)

    def _init_paging(self, parent):
        innerframe = Frame(parent, background=self._BACKGROUND_COLOUR)
        self.prev = prev = Button(
            innerframe,
            text="Previous",
            command=self.previous,
            width="10",
            borderwidth=1,
            highlightthickness=1,
            state="disabled",
        )
        prev.pack(side="left", anchor="center")
        self.next = next = Button(
            innerframe,
            text="Next",
            command=self.__next__,
            width="10",
            borderwidth=1,
            highlightthickness=1,
            state="disabled",
        )
        next.pack(side="right", anchor="center")
        innerframe.pack(side="top", fill="y")
        self.reset_current_page()

    def reset_current_page(self):
        self.current_page = -1

    def _poll(self):
        try:
            event = self.queue.get(block=False)
        except q.Empty:
            pass
        else:
            if event == CORPUS_LOADED_EVENT:
                self.handle_corpus_loaded(event)
            elif event == ERROR_LOADING_CORPUS_EVENT:
                self.handle_error_loading_corpus(event)
        self.after = self.top.after(POLL_INTERVAL, self._poll)

    def handle_error_loading_corpus(self, event):
        self.status["text"] = "Error in loading " + self.var.get()
        self.unfreeze_editable()
        self.clear_results_box()
        self.freeze_editable()
        self.reset_current_page()

    def handle_corpus_loaded(self, event):
        self.status["text"] = self.var.get() + " is loaded"
        self.unfreeze_editable()
        self.clear_results_box()
        self.reset_current_page()
        # self.next()
        collocations = self.model.next(self.current_page + 1)
        self.write_results(collocations)
        self.current_page += 1

    def corpus_selected(self, *args):
        new_selection = self.var.get()
        self.load_corpus(new_selection)

    def previous(self):
        self.freeze_editable()
        collocations = self.model.prev(self.current_page - 1)
        self.current_page = self.current_page - 1
        self.clear_results_box()
        self.write_results(collocations)
        self.unfreeze_editable()

    def __next__(self):
        self.freeze_editable()
        collocations = self.model.next(self.current_page + 1)
        self.clear_results_box()
        self.write_results(collocations)
        self.current_page += 1
        self.unfreeze_editable()

    def load_corpus(self, selection):
        if self.model.selected_corpus != selection:
            self.status["text"] = "Loading " + selection + "..."
            self.freeze_editable()
            self.model.load_corpus(selection)

    def freeze_editable(self):
        self.prev["state"] = "disabled"
        self.next["state"] = "disabled"

    def clear_results_box(self):
        self.results_box["state"] = "normal"
        self.results_box.delete("1.0", END)
        self.results_box["state"] = "disabled"

    def fire_event(self, event):
        # Firing an event so that rendering of widgets happen in the mainloop thread
        self.top.event_generate(event, when="tail")

    def destroy(self, *e):
        if self.top is None:
            return
        self.top.after_cancel(self.after)
        self.top.destroy()
        self.top = None

    def mainloop(self, *args, **kwargs):
        if in_idle():
            return
        self.top.mainloop(*args, **kwargs)

    def unfreeze_editable(self):
        self.set_paging_button_states()

    def set_paging_button_states(self):
        if self.current_page == -1 or self.current_page == 0:
            self.prev["state"] = "disabled"
        else:
            self.prev["state"] = "normal"
        if self.model.is_last_page(self.current_page):
            self.next["state"] = "disabled"
        else:
            self.next["state"] = "normal"

    def write_results(self, results):
        self.results_box["state"] = "normal"
        row = 1
        for each in results:
            self.results_box.insert(
                str(row) + ".0", each[0] + " " + each[1] + "\n")
            row += 1
        self.results_box["state"] = "disabled"
class CollocationsView:
    _BACKGROUND_COLOUR='#FFF' #white

    def __init__(self):
        self.queue = q.Queue()
        self.model = CollocationsModel(self.queue)
        self.top = Tk()
        self._init_top(self.top)
        self._init_menubar()
        self._init_widgets(self.top)
        self.load_corpus(self.model.DEFAULT_CORPUS)
        self.after = self.top.after(POLL_INTERVAL, self._poll)

    def _init_top(self, top):
        top.geometry('550x650+50+50')
        top.title('NLTK Collocations List')
        top.bind('<Control-q>', self.destroy)
        top.protocol('WM_DELETE_WINDOW', self.destroy)
        top.minsize(550,650)

    def _init_widgets(self, parent):
        self.main_frame = Frame(parent, dict(background=self._BACKGROUND_COLOUR, padx=1, pady=1, border=1))
        self._init_corpus_select(self.main_frame)
        self._init_results_box(self.main_frame)
        self._init_paging(self.main_frame)
        self._init_status(self.main_frame)
        self.main_frame.pack(fill='both', expand=True)

    def _init_corpus_select(self, parent):
        innerframe = Frame(parent, background=self._BACKGROUND_COLOUR)
        self.var = StringVar(innerframe)
        self.var.set(self.model.DEFAULT_CORPUS)
        Label(innerframe, justify=LEFT, text=' Corpus: ', background=self._BACKGROUND_COLOUR, padx = 2, pady = 1, border = 0).pack(side='left')

        other_corpora = list(self.model.CORPORA.keys()).remove(self.model.DEFAULT_CORPUS)
        om = OptionMenu(innerframe, self.var, self.model.DEFAULT_CORPUS, command=self.corpus_selected, *self.model.non_default_corpora())
        om['borderwidth'] = 0
        om['highlightthickness'] = 1
        om.pack(side='left')
        innerframe.pack(side='top', fill='x', anchor='n')

    def _init_status(self, parent):
        self.status = Label(parent, justify=LEFT, relief=SUNKEN, background=self._BACKGROUND_COLOUR, border=0, padx = 1, pady = 0)
        self.status.pack(side='top', anchor='sw')

    def _init_menubar(self):
        self._result_size = IntVar(self.top)
        menubar = Menu(self.top)

        filemenu = Menu(menubar, tearoff=0, borderwidth=0)
        filemenu.add_command(label='Exit', underline=1,
                   command=self.destroy, accelerator='Ctrl-q')
        menubar.add_cascade(label='File', underline=0, menu=filemenu)

        editmenu = Menu(menubar, tearoff=0)
        rescntmenu = Menu(editmenu, tearoff=0)
        rescntmenu.add_radiobutton(label='20', variable=self._result_size,
                     underline=0, value=20, command=self.set_result_size)
        rescntmenu.add_radiobutton(label='50', variable=self._result_size,
                     underline=0, value=50, command=self.set_result_size)
        rescntmenu.add_radiobutton(label='100', variable=self._result_size,
                     underline=0, value=100, command=self.set_result_size)
        rescntmenu.invoke(1)
        editmenu.add_cascade(label='Result Count', underline=0, menu=rescntmenu)

        menubar.add_cascade(label='Edit', underline=0, menu=editmenu)
        self.top.config(menu=menubar)

    def set_result_size(self, **kwargs):
        self.model.result_count = self._result_size.get()

    def _init_results_box(self, parent):
        innerframe = Frame(parent)
        i1 = Frame(innerframe)
        i2 = Frame(innerframe)
        vscrollbar = Scrollbar(i1, borderwidth=1)
        hscrollbar = Scrollbar(i2, borderwidth=1, orient='horiz')
        self.results_box = Text(i1,
                    font=Font(family='courier', size='16'),
                    state='disabled', borderwidth=1,
                    yscrollcommand=vscrollbar.set,
                    xscrollcommand=hscrollbar.set, wrap='none', width='40', height = '20', exportselection=1)
        self.results_box.pack(side='left', fill='both', expand=True)
        vscrollbar.pack(side='left', fill='y', anchor='e')
        vscrollbar.config(command=self.results_box.yview)
        hscrollbar.pack(side='left', fill='x', expand=True, anchor='w')
        hscrollbar.config(command=self.results_box.xview)
        #there is no other way of avoiding the overlap of scrollbars while using pack layout manager!!!
        Label(i2, text='   ', background=self._BACKGROUND_COLOUR).pack(side='left', anchor='e')
        i1.pack(side='top', fill='both', expand=True, anchor='n')
        i2.pack(side='bottom', fill='x', anchor='s')
        innerframe.pack(side='top', fill='both', expand=True)

    def _init_paging(self, parent):
        innerframe = Frame(parent, background=self._BACKGROUND_COLOUR)
        self.prev = prev = Button(innerframe, text='Previous', command=self.previous, width='10', borderwidth=1, highlightthickness=1, state='disabled')
        prev.pack(side='left', anchor='center')
        self.next = next = Button(innerframe, text='Next', command=self.__next__, width='10', borderwidth=1, highlightthickness=1, state='disabled')
        next.pack(side='right', anchor='center')
        innerframe.pack(side='top', fill='y')
        self.reset_current_page()

    def reset_current_page(self):
        self.current_page = -1

    def _poll(self):
        try:
            event = self.queue.get(block=False)
        except q.Empty:
            pass
        else:
            if event == CORPUS_LOADED_EVENT:
                self.handle_corpus_loaded(event)
            elif event == ERROR_LOADING_CORPUS_EVENT:
                self.handle_error_loading_corpus(event)
        self.after = self.top.after(POLL_INTERVAL, self._poll)

    def handle_error_loading_corpus(self, event):
        self.status['text'] = 'Error in loading ' + self.var.get()
        self.unfreeze_editable()
        self.clear_results_box()
        self.freeze_editable()
        self.reset_current_page()

    def handle_corpus_loaded(self, event):
        self.status['text'] = self.var.get() + ' is loaded'
        self.unfreeze_editable()
        self.clear_results_box()
        self.reset_current_page()
        #self.next()
        collocations = self.model.next(self.current_page + 1)
        self.write_results(collocations)
        self.current_page += 1

    def corpus_selected(self, *args):
        new_selection = self.var.get()
        self.load_corpus(new_selection)

    def previous(self):
        self.freeze_editable()
        collocations = self.model.prev(self.current_page - 1)
        self.current_page= self.current_page - 1
        self.clear_results_box()
        self.write_results(collocations)
        self.unfreeze_editable()

    def __next__(self):
        self.freeze_editable()
        collocations = self.model.next(self.current_page + 1)
        self.clear_results_box()
        self.write_results(collocations)
        self.current_page += 1
        self.unfreeze_editable()

    def load_corpus(self, selection):
        if self.model.selected_corpus != selection:
            self.status['text'] = 'Loading ' + selection + '...'
            self.freeze_editable()
            self.model.load_corpus(selection)

    def freeze_editable(self):
        self.prev['state'] = 'disabled'
        self.next['state'] = 'disabled'

    def clear_results_box(self):
        self.results_box['state'] = 'normal'
        self.results_box.delete("1.0", END)
        self.results_box['state'] = 'disabled'

    def fire_event(self, event):
        #Firing an event so that rendering of widgets happen in the mainloop thread
        self.top.event_generate(event, when='tail')

    def destroy(self, *e):
        if self.top is None: return
        self.top.after_cancel(self.after)
        self.top.destroy()
        self.top = None

    def mainloop(self, *args, **kwargs):
        if in_idle(): return
        self.top.mainloop(*args, **kwargs)

    def unfreeze_editable(self):
        self.set_paging_button_states()

    def set_paging_button_states(self):
        if self.current_page == -1 or self.current_page == 0:
            self.prev['state'] = 'disabled'
        else:
            self.prev['state'] = 'normal'
        if self.model.is_last_page(self.current_page):
            self.next['state'] = 'disabled'
        else:
            self.next['state'] = 'normal'

    def write_results(self, results):
        self.results_box['state'] = 'normal'
        row = 1
        for each in results:
            self.results_box.insert(str(row) + '.0', each[0] + " " + each[1] + "\n")
            row += 1
        self.results_box['state'] = 'disabled'
示例#41
0
 def __init__(self, *args, **kwargs):
     TkToolWindow.__init__(self, *args, **kwargs)
     Observable.__init__(self)
     
     self.__serialmap = None
     
     # Temporarily
     self.inst = Inst()
     # End Temporarily
     
     #window = self.tk_object
     tooltab = Frame(self._tool_tabs)
     self._tool_tabs.add(tooltab, text='SPI')
     #tooltab.pack(expand='yes', fill='x')        
     
 # Group OPEN 
     open_group = Group(tooltab)
     open_group.name = 'Open Device'
     open_group.pack(side='left', fill='y', expand='yes')
     
     self.__dev_combo = dev_combo = Combobox(open_group, value=[], takefocus=1, stat='readonly', width=12)
     dev_combo.bind('<<ComboboxSelected>>', self._on_dev_change)
     self.__current_serialno = None
     dev_combo.pack(side='top')
     
     self.__is_opened = IntVar(0)
     self.__open_check = open_check = Checkbutton(open_group, text='Open', 
         variable=self.__is_opened,
         command=self._on_open_click)
     open_check.pack(expand='yes', fill='y', side='top')
 # End Group Open
     
 # Group Parameters
     param_group = Group(tooltab)
     param_group.name = 'Parameters'
     param_group.pack(side='left')
     Button(param_group, text='Configure', command=self._on_param_change).pack(side='bottom')        
     
     param_frame = Frame(param_group)
     param_frame.pack()
     
     self.__CPOL = CPOL = IntVar(0)
     self.__CPHA = CPHA = IntVar(0)
     Checkbutton(param_frame, text='CPOL', variable=CPOL).grid(row=0, column=0)
     Checkbutton(param_frame, text='CPHA', variable=CPHA).grid(row=1, column=0)
     
     self.__baud_combo = baud_combo = Combobox(param_frame, value=[], takefocus=1, stat='readonly', width=8)
     baud_combo.grid(row=0, column=1, columnspan=2)
     
     self.__read_timeout_str = r_timeout = StringVar()
     self.__write_timeout_str = w_timeout = StringVar()
     Entry(param_frame, textvariable=r_timeout, width=5).grid(row=1, column=1)
     Entry(param_frame, textvariable=w_timeout, width=5).grid(row=1, column=2)
 # End Group Parameters
     
 # Write Group
     write_group = Group(tooltab)
     write_group.name = 'Write'
     write_group.pack(side='left', fill='y', expand='yes')
     
     self.__writebuf = writebuf = StringVar()
     Entry(write_group, textvariable=writebuf).pack()
     Button(write_group, text='Write', command=self._on_write_click).pack()
 # End Write Group
     
     self._make_window_manager_tab()
     
     # To Do: a driver group for loading specified spi bus driver
     converter = USBSPIConverter()
     converter.add_observer(self)
     self.add_observer(converter)
示例#42
0
class Task(Frame):
    def __init__(self,
                 master=None,
                 work=WORK_TM,
                 rest=REST_TM,
                 server=HOST,
                 port=PORT,
                 mode='fascist'):
        """create the task widget and get things started"""

        self.lid_state = "open"
        self.lid_time = time.time()
        self.interrupt_count = 0
        self.then = 0.0
        self.old_work = 0.0
        self.state = "working"
        self.cancel_rest = 0

        self.log = logging.getLogger(__name__)

        Frame.__init__(*(self, master))

        self.mode = StringVar()
        self.mode.set(mode)  # "fascist" or "friendly"

        # create main interactor window
        self.workmeter = Meter(self, background="grey50")
        self.workmeter.pack()

        self.work_frame = Frame(self)
        self.work_frame.pack()
        self.work_label = Label(self.work_frame, text="Work time:")
        self.work_label.pack(side=LEFT)
        self.work_scl = Scale(self.work_frame,
                              orient=HORIZONTAL,
                              from_=1,
                              to=max(45, work),
                              command=self.reset_duration)
        self.work_scl.set(work)
        self.work_scl.pack(side=LEFT)

        self.rest_frame = Frame(self)
        self.rest_frame.pack()
        self.rest_label = Label(self.rest_frame, text="Rest time:")
        self.rest_label.pack(side=LEFT)
        self.rest_scl = Scale(self.rest_frame,
                              orient=HORIZONTAL,
                              from_=1,
                              to=max(15, rest),
                              command=self.reset_duration)
        self.rest_scl.set(rest)
        self.rest_scl.pack(side=LEFT)

        self.radio_frame = Frame(self)
        self.radio_frame.pack()
        self.dictator = Radiobutton(self.radio_frame,
                                    text="Fascist",
                                    variable=self.mode,
                                    value="fascist")
        self.friend = Radiobutton(self.radio_frame,
                                  text="Friendly",
                                  variable=self.mode,
                                  value="friendly")
        self.dictator.pack(side=LEFT)
        self.friend.pack(side=LEFT)

        self.button_frame = Frame(self)
        self.button_frame.pack()
        self.restb = Button(self.button_frame, text="Rest", command=self.rest)
        self.restb.pack(side=LEFT)
        self.stopb = Button(self.button_frame, text="Quit", command=self.quit)
        self.stopb.pack(side=LEFT)
        self.helpb = Button(self.button_frame, text="Help", command=self.help)
        self.helpb.pack(side=LEFT)

        # create the cover window
        self.cover = Toplevel(background="black")
        self.cover.withdraw()
        # user can't resize it
        self.cover.resizable(0, 0)
        # when displayed, it should cover all displays
        (w, h) = (self.winfo_vrootwidth(), self.winfo_vrootheight())
        if self.log.getEffectiveLevel() <= logging.DEBUG:
            # but we reduce it while debugging
            w, h = (w / 5, h / 5)
        self.cover.geometry("%dx%d+0+0" % (w, h))

        # and it's undecorated
        self.cover.overrideredirect(1)

        # cover contains a frame with rest message and meter
        f = Frame(self.cover, background="black")
        self.restnote = Label(f, background="black", foreground="white")
        self.restmeter = Meter(f, background="grey50", height=10, width=200)
        self.restnote.pack(pady=2)
        self.restmeter.pack(fill="x", expand=1, pady=2)
        self.cancel_button = Button(f, text="Cancel Rest", command=self.cancel)
        f.pack()

        # initialize interrupt information
        self.linux_interrupts = 0
        # used by the default activity checker
        self.mouse = None

        self.setup_server(server, port)

        # self.last_int is the last time the server was alerted to activity
        # self.now is the server's notion of the current time
        # idle time is therefore max(0, self.now-self.last_int)
        (self.last_int, _w_time, _r_time, self.now) = self.server.get()
        self.idle = max(0, self.now - self.last_int)

        self.bgcolor = self["background"]

        # start the ball rolling
        self.after(CHK_INT, self.tick)
        self.work()

    def setup_server(self, server, port):
        if server is None:
            self.server = collector.Collector()
            self.log.debug("using private Collector()")
            return

        self.server = xmlrpc_client.ServerProxy("http://%s:%d" %
                                                (server, port))
        try:
            self.server.get()
            self.log.debug("found existing server")
        except socket.error:
            if server in ["", "localhost", "127.0.0.1"]:
                cmd = "watch-server.py"
                args = ["-p", "%d" % port]
                pid = os.spawnvp(os.P_NOWAIT, cmd, args)
                # wait briefly for server to start
                time.sleep(0.2)
                self.server = xmlrpc_client.ServerProxy("http://%s:%d" %
                                                        (server, port),
                                                        allow_none=True)
                # try connecting
                for _i in range(10):
                    try:
                        self.server.get()
                        atexit.register(os.kill, pid, signal.SIGHUP)
                        self.log.debug("spawned server")
                        return
                    except socket.error:
                        time.sleep(0.1)
            # nothing else worked, so fall back to an embedded collector
            self.server = collector.Collector()
            self.log.debug("using private Collector()")

    def reset_duration(self, _dummy=None):
        """reset work/rest interval lengths to current scale values"""
        wtime = self.work_scl.get()
        self.workmeter.set_range(self.workmeter.min_val,
                                 self.workmeter.min_val + wtime * 60)
        self.restmeter.set_range(
            self.restmeter.min_val,
            self.restmeter.min_val + self.rest_scl.get() * 60)
        # only time the user can fiddle the work/rest meters is during
        # the work phase, so the only scale change that matters for extending
        # or contracting the end of the interval is the work scale
        try:
            delta = wtime - self.old_work
        except AttributeError:
            delta = 0
        self.log.debug(__("then: {} delta: {}m", hhmm(self.then), delta))
        self.then = self.then + delta * 60
        self.old_work = wtime

        self.server.put(self.work_scl.get(), self.rest_scl.get())

    def work(self):
        """start the work period"""
        self.reset_warning()
        self.restmeter.reset()
        self.state = "working"
        self.then = self.now + self.work_scl.get() * 60
        self.log.debug(__("work: then: {}", hhmm(self.then)))
        self.workmeter.set_range(self.now, self.then)
        self.workmeter.reset()
        self.cover.withdraw()

    def warn_work_end(self):
        """alert user that work period is almost up"""
        self.set_background("yellow")

    def reset_warning(self):
        """back to plain old grey bg"""
        self.set_background(self.bgcolor)

    def set_background(self, color):
        for w in (self, self.work_scl, self.rest_scl, self.dictator,
                  self.friend, self.button_frame, self.stopb, self.restb,
                  self.helpb, self.work_frame, self.rest_frame,
                  self.radio_frame, self.work_label, self.rest_label):
            w["background"] = color

    def rest(self):
        """overlay the screen with a window, preventing typing"""
        self.cancel_rest = 0
        self.workmeter.reset()
        self.state = "resting"
        # the user may not have been typing or mousing right up to the
        # work/rest threshold - give credit for whatever rest time has
        # already been accumulated
        resttime = self.rest_scl.get() * 60 - (self.now - self.last_int)
        if resttime < 0:
            self.work()
            return
        mins, secs = divmod(resttime, 60)
        self.then = self.now + resttime
        self.cover.deiconify()
        self.cover.tkraise()
        resttext = ("Rest for %dm%02ds please..." % (mins, secs))
        self.restnote.configure(text=resttext)
        self.restmeter.set_range(self.now, self.then)
        self.restmeter.reset()
        if self.mode.get() == "friendly":
            self.cancel_button.pack(pady=2)
        else:
            self.cancel_button.pack_forget()

        self.log.debug(
            __("rest: state: {} now: {} then: {} active? {}", self.state,
               hhmm(self.now), hhmm(self.then), self.check_activity()))

    def help(self):
        Dialog(self.master, title="Help", content=usageText())

    ### ---- define activity checkers here ---- ###
    # keyed by sys.platform or "default" to return a method that checks
    # for mouse/keyboard activity
    _dispatch = {}

    def check_activity(self):
        """check mouse/keyboard activity info

        where possible, call platform-dependent routine to get mouse and
        keyboard info, otherwise, just return mouse info

        in all cases, the value returned should evaluate to False if no
        activity was detected.
        """
        active = False
        if self.lid_state == "open":
            dflt = self._dispatch["default"]
            checker = self._dispatch.get(sys.platform, dflt)
            active = checker(self)
            if active:
                self.server.tick()
        return active

    def check_mouse(self):
        """default checker, just compares current w/ saved mouse pos"""
        mouse = self.winfo_pointerxy()
        try:
            return mouse != self.mouse
        finally:
            self.mouse = mouse

    _dispatch["default"] = check_mouse

    def get_linux_interrupts(self):
        count = 0
        # Can't seem to find mouse interrupts, so for now, just watch
        # keyboard and mix add get_mouseinfo() output as a substitute for
        # mouse interrupts.
        last_count = self.interrupt_count
        for line in open("/proc/interrupts"):
            fields = line.split()
            if fields[0] == "1:":
                count = sum(int(fields[n]) for n in range(1, 8))
                self.interrupt_count = count
                break
        return self.check_mouse() or self.interrupt_count > last_count

    _dispatch["linux"] = get_linux_interrupts

    def check_lid_state(self):
        if os.path.exists(LID_STATE):
            for line in open(LID_STATE):
                fields = line.strip().split()
                if fields[0] == "state:":
                    return self.maybe_change_lid_state(fields[1])
        else:
            self.lid_state = "open"
        return 0

    def maybe_change_lid_state(self, state):
        """Take necessary action when lid state changes.

        Return True if lid state changed.
        """
        idle = 0
        if state != self.lid_state:
            self.log.info(__("lid state changed: {}", state))
            lid_time = time.time()
            if state == "open":
                idle = lid_time - self.lid_time
                self.log.info(__("idle for {}s", idle))
            self.lid_state = state
            self.lid_time = lid_time
        return idle

    def tick(self):
        """perform periodic checks for activity or state switch"""
        try:
            self._tick()
        finally:
            self.after(CHK_INT, self.tick)

    def _tick(self):
        (self.last_int, work_time, rest_time, self.now) = self.server.get()
        # check for mouse or keyboard activity
        idle_time = self.check_lid_state()
        if idle_time > rest_time * 60:
            self.log.info(
                __("The lid is up! Back to work: {}", hhmm(idle_time)))
            self.work()
            return

        active = self.check_activity()
        idle = max(0, self.now - self.last_int)

        # check to see if the work/rest scales got adjusted by another
        # watch instance
        if (self.work_scl.get() != work_time
                or self.rest_scl.get() != rest_time):
            self.work_scl.set(work_time)
            self.rest_scl.set(rest_time)

        self.log.debug(
            __("work: state: {} now: {} then: {} active? {}", self.state,
               hhmm(self.now), hhmm(self.then), active))
        if self.state == "resting":
            # user explicitly cancelled the rest or the idle period
            # exceeded the desired rest time
            if self.cancel_rest or idle > rest_time * 60:
                self.work()
                return

            # make sure the rest window is as far up the window stack as
            # possible
            self.cover.tkraise()

            if idle <= self.idle:
                # user moved something - extend rest by a second
                self.then += 1
                self.restmeter.set_range(self.restmeter.min_val, self.then)
                self.restmeter.set(self.now)
                self.idle = idle

            # update message to reflect rest time remaining
            timeleft = int(round(self.then - self.now))
            minleft, secleft = divmod(timeleft, 60)
            resttext = ("Rest for %dm%02ds please..." % (minleft, secleft))
            self.restnote.configure(text=resttext)

        else:
            # if it's been at least the length of the rest interval
            # since last interrupt, reset the work interval
            if idle >= rest_time * 60:
                self.work()
                return

            self.idle = idle

            if self.now > self.then:
                # work period expired
                self.rest()
                return

            if self.now + 60 > self.then:
                # work period nearly expired - warn user
                self.warn_work_end()
            else:
                self.reset_warning()

        self.restmeter.set(self.now)
        self.workmeter.set(self.now)

    def cancel(self):
        self.cancel_rest = 1
示例#43
0
class CollocationsView:
    _BACKGROUND_COLOUR = '#FFF'  # white

    def __init__(self):
        self.queue = q.Queue()
        self.model = CollocationsModel(self.queue)
        self.top = Tk()
        self._init_top(self.top)
        self._init_menubar()
        self._init_widgets(self.top)
        self.load_corpus(self.model.DEFAULT_CORPUS)
        self.after = self.top.after(POLL_INTERVAL, self._poll)

    def _init_top(self, top):
        top.geometry('550x650+50+50')
        top.title('NLTK Collocations List')
        top.bind('<Control-q>', self.destroy)
        top.protocol('WM_DELETE_WINDOW', self.destroy)
        top.minsize(550, 650)

    def _init_widgets(self, parent):
        self.main_frame = Frame(
            parent,
            dict(background=self._BACKGROUND_COLOUR, padx=1, pady=1, border=1))
        self._init_corpus_select(self.main_frame)
        self._init_results_box(self.main_frame)
        self._init_paging(self.main_frame)
        self._init_status(self.main_frame)
        self.main_frame.pack(fill='both', expand=True)

    def _init_corpus_select(self, parent):
        innerframe = Frame(parent, background=self._BACKGROUND_COLOUR)
        self.var = StringVar(innerframe)
        self.var.set(self.model.DEFAULT_CORPUS)
        Label(innerframe,
              justify=LEFT,
              text=' Corpus: ',
              background=self._BACKGROUND_COLOUR,
              padx=2,
              pady=1,
              border=0).pack(side='left')

        other_corpora = list(self.model.CORPORA.keys()).remove(
            self.model.DEFAULT_CORPUS)
        om = OptionMenu(innerframe,
                        self.var,
                        self.model.DEFAULT_CORPUS,
                        command=self.corpus_selected,
                        *self.model.non_default_corpora())
        om['borderwidth'] = 0
        om['highlightthickness'] = 1
        om.pack(side='left')
        innerframe.pack(side='top', fill='x', anchor='n')

    def _init_status(self, parent):
        self.status = Label(parent,
                            justify=LEFT,
                            relief=SUNKEN,
                            background=self._BACKGROUND_COLOUR,
                            border=0,
                            padx=1,
                            pady=0)
        self.status.pack(side='top', anchor='sw')

    def _init_menubar(self):
        self._result_size = IntVar(self.top)
        menubar = Menu(self.top)

        filemenu = Menu(menubar, tearoff=0, borderwidth=0)
        filemenu.add_command(label='Exit',
                             underline=1,
                             command=self.destroy,
                             accelerator='Ctrl-q')
        menubar.add_cascade(label='File', underline=0, menu=filemenu)

        editmenu = Menu(menubar, tearoff=0)
        rescntmenu = Menu(editmenu, tearoff=0)
        rescntmenu.add_radiobutton(label='20',
                                   variable=self._result_size,
                                   underline=0,
                                   value=20,
                                   command=self.set_result_size)
        rescntmenu.add_radiobutton(label='50',
                                   variable=self._result_size,
                                   underline=0,
                                   value=50,
                                   command=self.set_result_size)
        rescntmenu.add_radiobutton(label='100',
                                   variable=self._result_size,
                                   underline=0,
                                   value=100,
                                   command=self.set_result_size)
        rescntmenu.invoke(1)
        editmenu.add_cascade(label='Result Count',
                             underline=0,
                             menu=rescntmenu)

        menubar.add_cascade(label='Edit', underline=0, menu=editmenu)
        self.top.config(menu=menubar)

    def set_result_size(self, **kwargs):
        self.model.result_count = self._result_size.get()

    def _init_results_box(self, parent):
        innerframe = Frame(parent)
        i1 = Frame(innerframe)
        i2 = Frame(innerframe)
        vscrollbar = Scrollbar(i1, borderwidth=1)
        hscrollbar = Scrollbar(i2, borderwidth=1, orient='horiz')
        self.results_box = Text(i1,
                                font=Font(family='courier', size='16'),
                                state='disabled',
                                borderwidth=1,
                                yscrollcommand=vscrollbar.set,
                                xscrollcommand=hscrollbar.set,
                                wrap='none',
                                width='40',
                                height='20',
                                exportselection=1)
        self.results_box.pack(side='left', fill='both', expand=True)
        vscrollbar.pack(side='left', fill='y', anchor='e')
        vscrollbar.config(command=self.results_box.yview)
        hscrollbar.pack(side='left', fill='x', expand=True, anchor='w')
        hscrollbar.config(command=self.results_box.xview)
        # there is no other way of avoiding the overlap of scrollbars while using pack layout manager!!!
        Label(i2, text='   ',
              background=self._BACKGROUND_COLOUR).pack(side='left', anchor='e')
        i1.pack(side='top', fill='both', expand=True, anchor='n')
        i2.pack(side='bottom', fill='x', anchor='s')
        innerframe.pack(side='top', fill='both', expand=True)

    def _init_paging(self, parent):
        innerframe = Frame(parent, background=self._BACKGROUND_COLOUR)
        self.prev = prev = Button(innerframe,
                                  text='Previous',
                                  command=self.previous,
                                  width='10',
                                  borderwidth=1,
                                  highlightthickness=1,
                                  state='disabled')
        prev.pack(side='left', anchor='center')
        self.next = next = Button(innerframe,
                                  text='Next',
                                  command=self.__next__,
                                  width='10',
                                  borderwidth=1,
                                  highlightthickness=1,
                                  state='disabled')
        next.pack(side='right', anchor='center')
        innerframe.pack(side='top', fill='y')
        self.reset_current_page()

    def reset_current_page(self):
        self.current_page = -1

    def _poll(self):
        try:
            event = self.queue.get(block=False)
        except q.Empty:
            pass
        else:
            if event == CORPUS_LOADED_EVENT:
                self.handle_corpus_loaded(event)
            elif event == ERROR_LOADING_CORPUS_EVENT:
                self.handle_error_loading_corpus(event)
        self.after = self.top.after(POLL_INTERVAL, self._poll)

    def handle_error_loading_corpus(self, event):
        self.status['text'] = 'Error in loading ' + self.var.get()
        self.unfreeze_editable()
        self.clear_results_box()
        self.freeze_editable()
        self.reset_current_page()

    def handle_corpus_loaded(self, event):
        self.status['text'] = self.var.get() + ' is loaded'
        self.unfreeze_editable()
        self.clear_results_box()
        self.reset_current_page()
        # self.next()
        collocations = self.model.next(self.current_page + 1)
        self.write_results(collocations)
        self.current_page += 1

    def corpus_selected(self, *args):
        new_selection = self.var.get()
        self.load_corpus(new_selection)

    def previous(self):
        self.freeze_editable()
        collocations = self.model.prev(self.current_page - 1)
        self.current_page = self.current_page - 1
        self.clear_results_box()
        self.write_results(collocations)
        self.unfreeze_editable()

    def __next__(self):
        self.freeze_editable()
        collocations = self.model.next(self.current_page + 1)
        self.clear_results_box()
        self.write_results(collocations)
        self.current_page += 1
        self.unfreeze_editable()

    def load_corpus(self, selection):
        if self.model.selected_corpus != selection:
            self.status['text'] = 'Loading ' + selection + '...'
            self.freeze_editable()
            self.model.load_corpus(selection)

    def freeze_editable(self):
        self.prev['state'] = 'disabled'
        self.next['state'] = 'disabled'

    def clear_results_box(self):
        self.results_box['state'] = 'normal'
        self.results_box.delete("1.0", END)
        self.results_box['state'] = 'disabled'

    def fire_event(self, event):
        # Firing an event so that rendering of widgets happen in the mainloop thread
        self.top.event_generate(event, when='tail')

    def destroy(self, *e):
        if self.top is None:
            return
        self.top.after_cancel(self.after)
        self.top.destroy()
        self.top = None

    def mainloop(self, *args, **kwargs):
        if in_idle():
            return
        self.top.mainloop(*args, **kwargs)

    def unfreeze_editable(self):
        self.set_paging_button_states()

    def set_paging_button_states(self):
        if self.current_page == -1 or self.current_page == 0:
            self.prev['state'] = 'disabled'
        else:
            self.prev['state'] = 'normal'
        if self.model.is_last_page(self.current_page):
            self.next['state'] = 'disabled'
        else:
            self.next['state'] = 'normal'

    def write_results(self, results):
        self.results_box['state'] = 'normal'
        row = 1
        for each in results:
            self.results_box.insert(
                str(row) + '.0', each[0] + " " + each[1] + "\n")
            row += 1
        self.results_box['state'] = 'disabled'
示例#44
0
    def __init__(self,
                 master=None,
                 work=WORK_TM,
                 rest=REST_TM,
                 server=HOST,
                 port=PORT,
                 mode='fascist'):
        """create the task widget and get things started"""

        self.lid_state = "open"
        self.lid_time = time.time()
        self.interrupt_count = 0
        self.then = 0.0
        self.old_work = 0.0
        self.state = "working"
        self.cancel_rest = 0

        self.log = logging.getLogger(__name__)

        Frame.__init__(*(self, master))

        self.mode = StringVar()
        self.mode.set(mode)  # "fascist" or "friendly"

        # create main interactor window
        self.workmeter = Meter(self, background="grey50")
        self.workmeter.pack()

        self.work_frame = Frame(self)
        self.work_frame.pack()
        self.work_label = Label(self.work_frame, text="Work time:")
        self.work_label.pack(side=LEFT)
        self.work_scl = Scale(self.work_frame,
                              orient=HORIZONTAL,
                              from_=1,
                              to=max(45, work),
                              command=self.reset_duration)
        self.work_scl.set(work)
        self.work_scl.pack(side=LEFT)

        self.rest_frame = Frame(self)
        self.rest_frame.pack()
        self.rest_label = Label(self.rest_frame, text="Rest time:")
        self.rest_label.pack(side=LEFT)
        self.rest_scl = Scale(self.rest_frame,
                              orient=HORIZONTAL,
                              from_=1,
                              to=max(15, rest),
                              command=self.reset_duration)
        self.rest_scl.set(rest)
        self.rest_scl.pack(side=LEFT)

        self.radio_frame = Frame(self)
        self.radio_frame.pack()
        self.dictator = Radiobutton(self.radio_frame,
                                    text="Fascist",
                                    variable=self.mode,
                                    value="fascist")
        self.friend = Radiobutton(self.radio_frame,
                                  text="Friendly",
                                  variable=self.mode,
                                  value="friendly")
        self.dictator.pack(side=LEFT)
        self.friend.pack(side=LEFT)

        self.button_frame = Frame(self)
        self.button_frame.pack()
        self.restb = Button(self.button_frame, text="Rest", command=self.rest)
        self.restb.pack(side=LEFT)
        self.stopb = Button(self.button_frame, text="Quit", command=self.quit)
        self.stopb.pack(side=LEFT)
        self.helpb = Button(self.button_frame, text="Help", command=self.help)
        self.helpb.pack(side=LEFT)

        # create the cover window
        self.cover = Toplevel(background="black")
        self.cover.withdraw()
        # user can't resize it
        self.cover.resizable(0, 0)
        # when displayed, it should cover all displays
        (w, h) = (self.winfo_vrootwidth(), self.winfo_vrootheight())
        if self.log.getEffectiveLevel() <= logging.DEBUG:
            # but we reduce it while debugging
            w, h = (w / 5, h / 5)
        self.cover.geometry("%dx%d+0+0" % (w, h))

        # and it's undecorated
        self.cover.overrideredirect(1)

        # cover contains a frame with rest message and meter
        f = Frame(self.cover, background="black")
        self.restnote = Label(f, background="black", foreground="white")
        self.restmeter = Meter(f, background="grey50", height=10, width=200)
        self.restnote.pack(pady=2)
        self.restmeter.pack(fill="x", expand=1, pady=2)
        self.cancel_button = Button(f, text="Cancel Rest", command=self.cancel)
        f.pack()

        # initialize interrupt information
        self.linux_interrupts = 0
        # used by the default activity checker
        self.mouse = None

        self.setup_server(server, port)

        # self.last_int is the last time the server was alerted to activity
        # self.now is the server's notion of the current time
        # idle time is therefore max(0, self.now-self.last_int)
        (self.last_int, _w_time, _r_time, self.now) = self.server.get()
        self.idle = max(0, self.now - self.last_int)

        self.bgcolor = self["background"]

        # start the ball rolling
        self.after(CHK_INT, self.tick)
        self.work()
示例#45
0
class ConcordanceSearchView(object):
    _BACKGROUND_COLOUR = '#FFF'  #white

    #Colour of highlighted results
    _HIGHLIGHT_WORD_COLOUR = '#F00'  #red
    _HIGHLIGHT_WORD_TAG = 'HL_WRD_TAG'

    _HIGHLIGHT_LABEL_COLOUR = '#C0C0C0'  # dark grey
    _HIGHLIGHT_LABEL_TAG = 'HL_LBL_TAG'

    #Percentage of text left of the scrollbar position
    _FRACTION_LEFT_TEXT = 0.30

    def __init__(self):
        self.queue = q.Queue()
        self.model = ConcordanceSearchModel(self.queue)
        self.top = Tk()
        self._init_top(self.top)
        self._init_menubar()
        self._init_widgets(self.top)
        self.load_corpus(self.model.DEFAULT_CORPUS)
        self.after = self.top.after(POLL_INTERVAL, self._poll)

    def _init_top(self, top):
        top.geometry('950x680+50+50')
        top.title('NLTK Concordance Search')
        top.bind('<Control-q>', self.destroy)
        top.protocol('WM_DELETE_WINDOW', self.destroy)
        top.minsize(950, 680)

    def _init_widgets(self, parent):
        self.main_frame = Frame(
            parent,
            dict(background=self._BACKGROUND_COLOUR, padx=1, pady=1, border=1))
        self._init_corpus_select(self.main_frame)
        self._init_query_box(self.main_frame)
        self._init_results_box(self.main_frame)
        self._init_paging(self.main_frame)
        self._init_status(self.main_frame)
        self.main_frame.pack(fill='both', expand=True)

    def _init_menubar(self):
        self._result_size = IntVar(self.top)
        self._cntx_bf_len = IntVar(self.top)
        self._cntx_af_len = IntVar(self.top)
        menubar = Menu(self.top)

        filemenu = Menu(menubar, tearoff=0, borderwidth=0)
        filemenu.add_command(label='Exit',
                             underline=1,
                             command=self.destroy,
                             accelerator='Ctrl-q')
        menubar.add_cascade(label='File', underline=0, menu=filemenu)

        editmenu = Menu(menubar, tearoff=0)
        rescntmenu = Menu(editmenu, tearoff=0)
        rescntmenu.add_radiobutton(label='20',
                                   variable=self._result_size,
                                   underline=0,
                                   value=20,
                                   command=self.set_result_size)
        rescntmenu.add_radiobutton(label='50',
                                   variable=self._result_size,
                                   underline=0,
                                   value=50,
                                   command=self.set_result_size)
        rescntmenu.add_radiobutton(label='100',
                                   variable=self._result_size,
                                   underline=0,
                                   value=100,
                                   command=self.set_result_size)
        rescntmenu.invoke(1)
        editmenu.add_cascade(label='Result Count',
                             underline=0,
                             menu=rescntmenu)

        cntxmenu = Menu(editmenu, tearoff=0)
        cntxbfmenu = Menu(cntxmenu, tearoff=0)
        cntxbfmenu.add_radiobutton(label='60 characters',
                                   variable=self._cntx_bf_len,
                                   underline=0,
                                   value=60,
                                   command=self.set_cntx_bf_len)
        cntxbfmenu.add_radiobutton(label='80 characters',
                                   variable=self._cntx_bf_len,
                                   underline=0,
                                   value=80,
                                   command=self.set_cntx_bf_len)
        cntxbfmenu.add_radiobutton(label='100 characters',
                                   variable=self._cntx_bf_len,
                                   underline=0,
                                   value=100,
                                   command=self.set_cntx_bf_len)
        cntxbfmenu.invoke(1)
        cntxmenu.add_cascade(label='Before', underline=0, menu=cntxbfmenu)

        cntxafmenu = Menu(cntxmenu, tearoff=0)
        cntxafmenu.add_radiobutton(label='70 characters',
                                   variable=self._cntx_af_len,
                                   underline=0,
                                   value=70,
                                   command=self.set_cntx_af_len)
        cntxafmenu.add_radiobutton(label='90 characters',
                                   variable=self._cntx_af_len,
                                   underline=0,
                                   value=90,
                                   command=self.set_cntx_af_len)
        cntxafmenu.add_radiobutton(label='110 characters',
                                   variable=self._cntx_af_len,
                                   underline=0,
                                   value=110,
                                   command=self.set_cntx_af_len)
        cntxafmenu.invoke(1)
        cntxmenu.add_cascade(label='After', underline=0, menu=cntxafmenu)

        editmenu.add_cascade(label='Context', underline=0, menu=cntxmenu)

        menubar.add_cascade(label='Edit', underline=0, menu=editmenu)

        self.top.config(menu=menubar)

    def set_result_size(self, **kwargs):
        self.model.result_count = self._result_size.get()

    def set_cntx_af_len(self, **kwargs):
        self._char_after = self._cntx_af_len.get()

    def set_cntx_bf_len(self, **kwargs):
        self._char_before = self._cntx_bf_len.get()

    def _init_corpus_select(self, parent):
        innerframe = Frame(parent, background=self._BACKGROUND_COLOUR)
        self.var = StringVar(innerframe)
        self.var.set(self.model.DEFAULT_CORPUS)
        Label(innerframe,
              justify=LEFT,
              text=' Corpus: ',
              background=self._BACKGROUND_COLOUR,
              padx=2,
              pady=1,
              border=0).pack(side='left')

        other_corpora = list(self.model.CORPORA.keys()).remove(
            self.model.DEFAULT_CORPUS)
        om = OptionMenu(innerframe,
                        self.var,
                        self.model.DEFAULT_CORPUS,
                        command=self.corpus_selected,
                        *self.model.non_default_corpora())
        om['borderwidth'] = 0
        om['highlightthickness'] = 1
        om.pack(side='left')
        innerframe.pack(side='top', fill='x', anchor='n')

    def _init_status(self, parent):
        self.status = Label(parent,
                            justify=LEFT,
                            relief=SUNKEN,
                            background=self._BACKGROUND_COLOUR,
                            border=0,
                            padx=1,
                            pady=0)
        self.status.pack(side='top', anchor='sw')

    def _init_query_box(self, parent):
        innerframe = Frame(parent, background=self._BACKGROUND_COLOUR)
        another = Frame(innerframe, background=self._BACKGROUND_COLOUR)
        self.query_box = Entry(another, width=60)
        self.query_box.pack(side='left', fill='x', pady=25, anchor='center')
        self.search_button = Button(another,
                                    text='Search',
                                    command=self.search,
                                    borderwidth=1,
                                    highlightthickness=1)
        self.search_button.pack(side='left',
                                fill='x',
                                pady=25,
                                anchor='center')
        self.query_box.bind('<KeyPress-Return>',
                            self.search_enter_keypress_handler)
        another.pack()
        innerframe.pack(side='top', fill='x', anchor='n')

    def search_enter_keypress_handler(self, *event):
        self.search()

    def _init_results_box(self, parent):
        innerframe = Frame(parent)
        i1 = Frame(innerframe)
        i2 = Frame(innerframe)
        vscrollbar = Scrollbar(i1, borderwidth=1)
        hscrollbar = Scrollbar(i2, borderwidth=1, orient='horiz')
        self.results_box = Text(i1,
                                font=Font(family='courier', size='16'),
                                state='disabled',
                                borderwidth=1,
                                yscrollcommand=vscrollbar.set,
                                xscrollcommand=hscrollbar.set,
                                wrap='none',
                                width='40',
                                height='20',
                                exportselection=1)
        self.results_box.pack(side='left', fill='both', expand=True)
        self.results_box.tag_config(self._HIGHLIGHT_WORD_TAG,
                                    foreground=self._HIGHLIGHT_WORD_COLOUR)
        self.results_box.tag_config(self._HIGHLIGHT_LABEL_TAG,
                                    foreground=self._HIGHLIGHT_LABEL_COLOUR)
        vscrollbar.pack(side='left', fill='y', anchor='e')
        vscrollbar.config(command=self.results_box.yview)
        hscrollbar.pack(side='left', fill='x', expand=True, anchor='w')
        hscrollbar.config(command=self.results_box.xview)
        #there is no other way of avoiding the overlap of scrollbars while using pack layout manager!!!
        Label(i2, text='   ',
              background=self._BACKGROUND_COLOUR).pack(side='left', anchor='e')
        i1.pack(side='top', fill='both', expand=True, anchor='n')
        i2.pack(side='bottom', fill='x', anchor='s')
        innerframe.pack(side='top', fill='both', expand=True)

    def _init_paging(self, parent):
        innerframe = Frame(parent, background=self._BACKGROUND_COLOUR)
        self.prev = prev = Button(innerframe,
                                  text='Previous',
                                  command=self.previous,
                                  width='10',
                                  borderwidth=1,
                                  highlightthickness=1,
                                  state='disabled')
        prev.pack(side='left', anchor='center')
        self.next = next = Button(innerframe,
                                  text='Next',
                                  command=self.__next__,
                                  width='10',
                                  borderwidth=1,
                                  highlightthickness=1,
                                  state='disabled')
        next.pack(side='right', anchor='center')
        innerframe.pack(side='top', fill='y')
        self.current_page = 0

    def previous(self):
        self.clear_results_box()
        self.freeze_editable()
        self.model.prev(self.current_page - 1)

    def __next__(self):
        self.clear_results_box()
        self.freeze_editable()
        self.model.next(self.current_page + 1)

    def about(self, *e):
        ABOUT = ("NLTK Concordance Search Demo\n")
        TITLE = 'About: NLTK Concordance Search Demo'
        try:
            from six.moves.tkinter_messagebox import Message
            Message(message=ABOUT, title=TITLE, parent=self.main_frame).show()
        except:
            ShowText(self.top, TITLE, ABOUT)

    def _bind_event_handlers(self):
        self.top.bind(CORPUS_LOADED_EVENT, self.handle_corpus_loaded)
        self.top.bind(SEARCH_TERMINATED_EVENT, self.handle_search_terminated)
        self.top.bind(SEARCH_ERROR_EVENT, self.handle_search_error)
        self.top.bind(ERROR_LOADING_CORPUS_EVENT,
                      self.handle_error_loading_corpus)

    def _poll(self):
        try:
            event = self.queue.get(block=False)
        except q.Empty:
            pass
        else:
            if event == CORPUS_LOADED_EVENT:
                self.handle_corpus_loaded(event)
            elif event == SEARCH_TERMINATED_EVENT:
                self.handle_search_terminated(event)
            elif event == SEARCH_ERROR_EVENT:
                self.handle_search_error(event)
            elif event == ERROR_LOADING_CORPUS_EVENT:
                self.handle_error_loading_corpus(event)
        self.after = self.top.after(POLL_INTERVAL, self._poll)

    def handle_error_loading_corpus(self, event):
        self.status['text'] = 'Error in loading ' + self.var.get()
        self.unfreeze_editable()
        self.clear_all()
        self.freeze_editable()

    def handle_corpus_loaded(self, event):
        self.status['text'] = self.var.get() + ' is loaded'
        self.unfreeze_editable()
        self.clear_all()
        self.query_box.focus_set()

    def handle_search_terminated(self, event):
        #todo: refactor the model such that it is less state sensitive
        results = self.model.get_results()
        self.write_results(results)
        self.status['text'] = ''
        if len(results) == 0:
            self.status['text'] = 'No results found for ' + self.model.query
        else:
            self.current_page = self.model.last_requested_page
        self.unfreeze_editable()
        self.results_box.xview_moveto(self._FRACTION_LEFT_TEXT)

    def handle_search_error(self, event):
        self.status['text'] = 'Error in query ' + self.model.query
        self.unfreeze_editable()

    def corpus_selected(self, *args):
        new_selection = self.var.get()
        self.load_corpus(new_selection)

    def load_corpus(self, selection):
        if self.model.selected_corpus != selection:
            self.status['text'] = 'Loading ' + selection + '...'
            self.freeze_editable()
            self.model.load_corpus(selection)

    def search(self):
        self.current_page = 0
        self.clear_results_box()
        self.model.reset_results()
        query = self.query_box.get()
        if (len(query.strip()) == 0): return
        self.status['text'] = 'Searching for ' + query
        self.freeze_editable()
        self.model.search(
            query,
            self.current_page + 1,
        )

    def write_results(self, results):
        self.results_box['state'] = 'normal'
        row = 1
        for each in results:
            sent, pos1, pos2 = each[0].strip(), each[1], each[2]
            if len(sent) != 0:
                if (pos1 < self._char_before):
                    sent, pos1, pos2 = self.pad(sent, pos1, pos2)
                sentence = sent[pos1 - self._char_before:pos1 +
                                self._char_after]
                if not row == len(results):
                    sentence += '\n'
                self.results_box.insert(str(row) + '.0', sentence)
                word_markers, label_markers = self.words_and_labels(
                    sent, pos1, pos2)
                for marker in word_markers:
                    self.results_box.tag_add(self._HIGHLIGHT_WORD_TAG,
                                             str(row) + '.' + str(marker[0]),
                                             str(row) + '.' + str(marker[1]))
                for marker in label_markers:
                    self.results_box.tag_add(self._HIGHLIGHT_LABEL_TAG,
                                             str(row) + '.' + str(marker[0]),
                                             str(row) + '.' + str(marker[1]))
                row += 1
        self.results_box['state'] = 'disabled'

    def words_and_labels(self, sentence, pos1, pos2):
        search_exp = sentence[pos1:pos2]
        words, labels = [], []
        labeled_words = search_exp.split(' ')
        index = 0
        for each in labeled_words:
            if each == '':
                index += 1
            else:
                word, label = each.split('/')
                words.append((self._char_before + index,
                              self._char_before + index + len(word)))
                index += len(word) + 1
                labels.append((self._char_before + index,
                               self._char_before + index + len(label)))
                index += len(label)
            index += 1
        return words, labels

    def pad(self, sent, hstart, hend):
        if hstart >= self._char_before:
            return sent, hstart, hend
        d = self._char_before - hstart
        sent = ''.join([' '] * d) + sent
        return sent, hstart + d, hend + d

    def destroy(self, *e):
        if self.top is None: return
        self.top.after_cancel(self.after)
        self.top.destroy()
        self.top = None

    def clear_all(self):
        self.query_box.delete(0, END)
        self.model.reset_query()
        self.clear_results_box()

    def clear_results_box(self):
        self.results_box['state'] = 'normal'
        self.results_box.delete("1.0", END)
        self.results_box['state'] = 'disabled'

    def freeze_editable(self):
        self.query_box['state'] = 'disabled'
        self.search_button['state'] = 'disabled'
        self.prev['state'] = 'disabled'
        self.next['state'] = 'disabled'

    def unfreeze_editable(self):
        self.query_box['state'] = 'normal'
        self.search_button['state'] = 'normal'
        self.set_paging_button_states()

    def set_paging_button_states(self):
        if self.current_page == 0 or self.current_page == 1:
            self.prev['state'] = 'disabled'
        else:
            self.prev['state'] = 'normal'
        if self.model.has_more_pages(self.current_page):
            self.next['state'] = 'normal'
        else:
            self.next['state'] = 'disabled'

    def fire_event(self, event):
        #Firing an event so that rendering of widgets happen in the mainloop thread
        self.top.event_generate(event, when='tail')

    def mainloop(self, *args, **kwargs):
        if in_idle(): return
        self.top.mainloop(*args, **kwargs)
示例#46
0
    def __init__(self, *args, **kwargs):
        TkToolWindow.__init__(self, *args, **kwargs)
        Observable.__init__(self)

        self.__serialmap = None

        # Temporarily
        self.inst = Inst()
        # End Temporarily

        #window = self.tk_object
        tooltab = Frame(self._tool_tabs)
        self._tool_tabs.add(tooltab, text='SPI')
        #tooltab.pack(expand='yes', fill='x')

        # Group OPEN
        open_group = Group(tooltab)
        open_group.name = 'Open Device'
        open_group.pack(side='left', fill='y', expand='yes')

        self.__dev_combo = dev_combo = Combobox(open_group,
                                                value=[],
                                                takefocus=1,
                                                stat='readonly',
                                                width=12)
        dev_combo.bind('<<ComboboxSelected>>', self._on_dev_change)
        self.__current_serialno = None
        dev_combo.pack(side='top')

        self.__is_opened = IntVar(0)
        self.__open_check = open_check = Checkbutton(
            open_group,
            text='Open',
            variable=self.__is_opened,
            command=self._on_open_click)
        open_check.pack(expand='yes', fill='y', side='top')
        # End Group Open

        # Group Parameters
        param_group = Group(tooltab)
        param_group.name = 'Parameters'
        param_group.pack(side='left')
        Button(param_group, text='Configure',
               command=self._on_param_change).pack(side='bottom')

        param_frame = Frame(param_group)
        param_frame.pack()

        self.__CPOL = CPOL = IntVar(0)
        self.__CPHA = CPHA = IntVar(0)
        Checkbutton(param_frame, text='CPOL', variable=CPOL).grid(row=0,
                                                                  column=0)
        Checkbutton(param_frame, text='CPHA', variable=CPHA).grid(row=1,
                                                                  column=0)

        self.__baud_combo = baud_combo = Combobox(param_frame,
                                                  value=[],
                                                  takefocus=1,
                                                  stat='readonly',
                                                  width=8)
        baud_combo.grid(row=0, column=1, columnspan=2)

        self.__read_timeout_str = r_timeout = StringVar()
        self.__write_timeout_str = w_timeout = StringVar()
        Entry(param_frame, textvariable=r_timeout, width=5).grid(row=1,
                                                                 column=1)
        Entry(param_frame, textvariable=w_timeout, width=5).grid(row=1,
                                                                 column=2)
        # End Group Parameters

        # Write Group
        write_group = Group(tooltab)
        write_group.name = 'Write'
        write_group.pack(side='left', fill='y', expand='yes')

        self.__writebuf = writebuf = StringVar()
        Entry(write_group, textvariable=writebuf).pack()
        Button(write_group, text='Write', command=self._on_write_click).pack()
        # End Write Group

        self._make_window_manager_tab()

        # To Do: a driver group for loading specified spi bus driver
        converter = USBSPIConverter()
        converter.add_observer(self)
        self.add_observer(converter)