class VarLabelFrame(LabelFrame): def __init__(self, *args, **kw): if "text" in kw: self.text_var = kw.pop("text") kw["text"] = self.text_var.get() else: self.text_var = StringVar("") LabelFrame.__init__(self, *args, **kw) self.text_var.trace_variable("w", self.on_var_changed) def on_var_changed(self, *args): Label.config(self, text = self.text_var.get())
class VarButton(Button): def __init__(self, *args, **kw): if "text" in kw: self.text_var = kw.pop("text") kw["text"] = self.text_var.get() else: self.text_var = StringVar("") Button.__init__(self, *args, **kw) self.text_var.trace_variable("w", self.on_var_changed) def on_var_changed(self, *args): Button.config(self, text = self.text_var.get())
def __init__(self, *args, **kw): text = kw.get("text", "") if isinstance(text, variables): kw["text"] = text.get() Checkbutton.__init__(self, *args, **kw) # `StringVar` requires its master to be initialized. if not isinstance(text, variables): text = StringVar(self, text) self.text_var = text text.trace_variable("w", self.on_var_changed)
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 gen_row(self, row): var_p_name = StringVar() var_p_name.set(self.prop.prop_name) e_p_name = HKEntry(self.dsw.props_lf, textvariable = var_p_name) e_p_name.grid( column = 0, row = row, sticky = "NEWS" ) om_p_type, var_p_type = DeviceSettingsWidget.gen_prop_type_optionmenu( self.dsw.props_lf, self.prop.prop_type ) om_p_type.grid( column = 1, row = row, sticky = "NEWS" ) var_p_type.trace_variable("w", self.on_prop_type_changed) w_p_val, var_p_val = self.gen_prop_value_widget( self.prop.prop_type, self.prop.prop_val ) w_p_val.grid( column = 2, row = row, sticky = "NEWS" ) bt_del = VarButton( self.dsw.props_lf, text = _("Delete"), command = self.on_delete ) bt_del.grid( column = 3, row = row, sticky = "NEWS" ) self.row = row self.e_name = e_p_name self.v_name = var_p_name self.om_type = om_p_type self.v_type = var_p_type self.w_val = w_p_val self.val_widget_prop_type = self.prop.prop_type self.v_val = var_p_val self.bt_del = bt_del
def __init__(self, bus, *args, **kw): SettingsWidget.__init__(self, bus, *args, **kw) self.bus = bus self.bus_fr = fr = GUIFrame(self) fr.pack(fill=BOTH, expand=False) fr.columnconfigure(0, weight=0) fr.columnconfigure(1, weight=1) fr.rowconfigure(0, weight=0) l = VarLabel(fr, text=_("Parent device")) l.grid(row=0, column=0, sticky="NES") self.var_parent = StringVar() self.cb_parent = Combobox(fr, textvariable=self.var_parent, state="readonly") self.cb_parent.grid(row=0, column=1, sticky="NEWS") self.fields = [] if type(bus) is BusNode: self.fields.extend([(_("C type"), "c_type", str), (_("Casting macro"), "cast", str), (_("Child name"), "child_name", str), (_("Always show index"), "force_index", bool)]) # Common bus type for row, (text, field, _type) in enumerate(self.fields, start=1): if _type is str: l = VarLabel(fr, text=text) v = StringVar() w = HKEntry(fr, textvariable=v) elif _type is bool: l = None v = BooleanVar() w = VarCheckbutton(fr, text=text, variable=v) fr.rowconfigure(row, weight=0) if l is None: w.grid(row=row, column=0, sticky="NEWS", columnspan=2) else: l.grid(row=row, column=0, sticky="NES") w.grid(row=row, column=1, sticky="NEWS") setattr(self, "w_" + field, w) setattr(self, "var_" + field, v)
def __init__(self, *args, **kw): QOMDescriptionSettingsWidget.__init__(self, *args, **kw) self.mw = None self.var_tabs = v = BooleanVar() self.buttons_fr.columnconfigure(2, weight=0) chb = VarCheckbutton(self.buttons_fr, text=_("Use tabs"), variable=v) chb.grid(row=0, column=2, sticky="NEWS") v.trace_variable("w", self.__on_tabs__) # mesh step seleection self.buttons_fr.columnconfigure(3, weight=0) self.buttons_fr.columnconfigure(4, weight=0) self.buttons_fr.columnconfigure(5, weight=0) Separator(self.buttons_fr, orient=VERTICAL).grid(row=0, column=3, sticky="NEWS") l = VarLabel(self.buttons_fr, text=_("Mesh step:")) l.grid(row=0, column=4, sticky="NEWS") self.var_mesh_step = v = StringVar() v.trace_variable("w", self.__on_mesh_step) self.mesh_step_sb = sb = Spinbox(self.buttons_fr, from_=MIN_MESH_STEP, to=MAX_MESH_STEP, textvariable=v, width=len(str(MAX_MESH_STEP))) sb.grid(row=0, column=5, sticky="NEWS") self.var_tabs.set(True)
def __init__(self, node, machine, *args, **kw): GUIFrame.__init__(self, *args, **kw) try: self.mht = self.winfo_toplevel().mht except AttributeError: # snapshot mode self.mht = None if self.mht is not None: self.mht.watch_changed(self.on_changed) self.node = node self.mach = machine self.node_fr = fr = GUIFrame(self) fr.pack(fill = BOTH, expand = False) fr.columnconfigure(0, weight = 0) fr.columnconfigure(1, weight = 1) # variable name base editing fr.rowconfigure(0, weight = 0) VarLabel(fr, text = _("Variable name base") ).grid( row = 0, column = 0, sticky = "NSW" ) self.v_var_base = v = StringVar() HKEntry(fr, textvariable = v ).grid( row = 0, column = 1, sticky = "NESW" ) fr.rowconfigure(1, weight = 0) VarLabel(fr, text = _("Name of variable") ).grid( row = 1, column = 0, sticky = "NSW" ) HKEntry(fr, text = machine.node_id2var_name[node.id], state = "readonly" ).grid( row = 1, column = 1, sticky = "NESW" ) self.refresh_after = self.after(0, self.__refresh_single__) self.bind("<Destroy>", self.__on_destroy__)
def __init__(self, root=None): """init""" self.root = root or Tk() self.root.title('Pylint') #reporter self.reporter = None #message queue for output from reporter self.msg_queue = six.moves.queue.Queue() self.msgs = [] self.visible_msgs = [] self.filenames = [] self.rating = StringVar() self.tabs = {} self.report_stream = BasicStream(self) #gui objects self.lb_messages = None self.showhistory = None self.results = None self.btnRun = None self.information_box = None self.convention_box = None self.refactor_box = None self.warning_box = None self.error_box = None self.fatal_box = None self.txtModule = None self.status = None self.msg_type_dict = None self.init_gui()
def gen_str_widgets(self, master): v = StringVar() w = HKEntry(master, textvariable = v) w._validate = lambda : True w._set_color = lambda color : w.config(bg = color) w._cast = lambda x : x return v, w
def gen_prop_type_optionmenu(parent, current = None): var = StringVar() keys = [] for ptn in DeviceSettingsWidget.prop_type_name_map.values(): keys.append(ptn[0]) om = OptionMenu(parent, var, *keys) if current: current = DeviceSettingsWidget.prop_type_name_map[current][0] else: current = next(itervalues(DeviceSettingsWidget.prop_type_name_map)) var.set(current) return om, var
def gen_row(self): p = self.dsw.buses_lf p.rowconfigure(self.idx, weight = 1) self.v = StringVar() # When a bus is selected all Combobox values lists should be updated # to prevent selecting of this bus in another Combobox self._on_var_changed = self.v.trace_variable("w", self.on_var_changed) self.cb = Combobox(p, textvariable = self.v, state = "readonly" ) self.cb.grid(row = self.idx, column = 0, sticky = "NEWS") self._on_bus_selected = self.dsw.bind( DeviceSettingsWidget.EVENT_BUS_SELECTED, self.on_bus_selected, "+")
def __init__(self, *args, **kw): # "textvariable" argument has same effect to VarLabel as "text" try: var = kw.pop("textvariable") except KeyError: pass else: if "text" in kw: raise RuntimeError('"text" and "textvariable" ' 'arguments cannot be passed together to a VarLabel' ) kw["text"] = var if "text" in kw: self.text_var = kw.pop("text") kw["text"] = self.text_var.get() else: self.text_var = StringVar("") Label.__init__(self, *args, **kw) self.text_var.trace_variable("w", self.on_var_changed)
def test_auto_reformat(self): fmt = FormatVar(value="Text is '%s'") text = StringVar(value="[ a text will be here ]") res = fmt % text self.assertIsInstance(res, StringVar) self.assertEqual(res.get(), "Text is '[ a text will be here ]'") def on_w(*__): val = res.get() # print("New value: %s" % val) self._cur_val = val res.trace_variable("w", on_w) text.set("A text") self.assertEqual(self._cur_val, "Text is 'A text'") fmt.set("'%s' is text.") self.assertEqual(self._cur_val, "'A text' is text.")
def add(self, itemType, cnf = {}, **kw): # handle variable text only for items which have such parameters if itemType in [ # "radiobutton" - TODO: check it "cascade", "command", "checkbutton" # "separator" - does not have such parameters ]: for param in ["label", "accelerator"]: if param in cnf: var = cnf.pop(param) elif param in kw: var = kw.pop(param) else: var = "" if not isinstance(var, variables): var = StringVar(self, var) binding = MenuVarBinding(self, var, self.count, param) var.trace_variable("w", binding.on_var_changed) if cnf: cnf[param] = var.get() else: kw[param] = var.get() self.count = self.count + 1 Menu.add(self, itemType, cnf or kw)
def __mod__(self, args): if not isinstance(args, tuple): args = (args, ) @as_variable(self, *args) def do_format(fmt, *args): return fmt % args # Wrapping do_format in `StringVar` is required because # `Variable` instance cannot be used with Tk. # TODO: move that mechanics elsewhere making `FormatVar` Tk # independent. # Initial setting ret = StringVar(value=do_format.get()) # Auto update do_format.trace_variable("w", lambda: StringVar.set(ret, do_format.get())) ret.set = forbid_set return ret
def gen_int_widgets(self, master): v = StringVar() w = HKEntry(master, textvariable = v) def validate(): try: (int(v.get(), base = 0)) except ValueError: return False else: return True w._validate = validate w._set_color = lambda color : w.config(bg = color) w._cast = lambda x : int(x, base = 0) return v, w
def __refresh__(self): desc = self.desc for attr, info in desc.__attribute_info__.items(): try: _input = info["input"] except KeyError: _input = None cur_val = getattr(desc, attr) v = getattr(self, "_var_" + attr) if _input is PCIId: if not PCIId.db.built and cur_val is None: # use string values only without database cur_val = "" # use appropriate widget/variable pair if isinstance(cur_val, str): if not isinstance(v, StringVar): v = StringVar() setattr(self, "_var_" + attr, v) # Fill frame with appropriate widget frame = getattr(self, "_w_" + attr) for w in frame.winfo_children(): w.destroy() w = HKEntry(frame, textvariable = v) w.grid(row = 0, column = 0, sticky = "NEWS") elif cur_val is None or isinstance(cur_val, PCIId): if not isinstance(v, ObjRefVar): v = ObjRefVar() setattr(self, "_var_" + attr, v) frame = getattr(self, "_w_" + attr) for w in frame.winfo_children(): w.destroy() w = PCIIdWidget(v, frame) w.grid(row = 0, column = 0, sticky = "NEWS") widget_val = v.get() if _input is int: try: widget_val = int(widget_val, base = 0) except ValueError: widget_val = None if widget_val != cur_val: v.set(cur_val) for cb in self._all_highlights: cb()
def __init__(self, irq, *args, **kw): SettingsWidget.__init__(self, irq, *args, **kw) self.irq = irq for pfx, txt in [ ("src_", _("Source")), ("dst_", _("Destination")) ]: lf = VarLabelFrame(self, text = txt) lf.pack(fill = BOTH, expand = False) lf.columnconfigure(0, weight = 0) lf.columnconfigure(1, weight = 1) for row in xrange(0, 3): lf.rowconfigure(row, weight = 1) l = VarLabel(lf, text = _("Node")) l.grid(row = 0, column = 0, sticky = "NE") node_var = StringVar() node_var.trace_variable("w", self.on_node_text_changed) node_cb = Combobox(lf, textvariable = node_var, values = [], state = "readonly" ) node_cb.grid(row = 0, column = 1, sticky = "NEW") irq_idx_l = VarLabel(lf, text = _("GPIO index")) irq_idx_l.grid(row = 1, column = 0, sticky = "NE") irq_idx_var = StringVar() irq_idx_e = HKEntry(lf, textvariable = irq_idx_var) irq_idx_e.grid(row = 1, column = 1, sticky = "NEW") irq_name_l = VarLabel(lf, text = _("GPIO name")) irq_name_l.grid(row = 2, column = 0, sticky = "NE") irq_name_var = StringVar() irq_name_e = HKEntry(lf, textvariable = irq_name_var) irq_name_e.grid(row = 2, column = 1, sticky = "NEW") for v in ["lf", "node_var", "node_cb", "irq_idx_l", "irq_idx_e", "irq_idx_var", "irq_name_l", "irq_name_e", "irq_name_var"]: setattr(self, pfx + v, locals()[v]) self.__auto_var_base_cbs = None self.v_var_base.trace_variable("w", self.__on_var_base)
def main(): root = Tk() root.title("Test VarTreeview") device_tree = VarTreeview(root) device_tree["columns"] = ("Macros") dev = StringVar() macro = StringVar() dev.set("Devices") macro.set("Macros") device_tree.heading("#0", text=dev) device_tree.heading("Macros", text=macro) device_tree.grid(sticky="NEWS") test = Mytest(600, dev, macro) test.test_begin(root) root.mainloop()
def __init__(self, cpu, *args, **kw): QOMInstanceSettingsWidget.__init__(self, cpu, *args, **kw) self.cpu = cpu self.cpu_fr = fr = GUIFrame(self) fr.pack(fill=BOTH, expand=False) fr.columnconfigure(0, weight=0) fr.columnconfigure(1, weight=1) fr.rowconfigure(0, weight=0) l = VarLabel(fr, text=_("QOM type")) v = self.qom_type_var = StringVar() e = HKEntry(fr, textvariable=v) v.trace_variable("w", self._on_qom_type_var_changed) l.grid(row=0, column=0, sticky="W") e.grid(row=0, column=1, sticky="EW")
def append_row_to_grid(self, grid, rows, mio): # update delete button if not rows: bt_del = getattr(self, "bt_del_" + mio) bt_del.config(state="normal") row = len(rows) l = Label(grid, text=str(row) + ":") l.grid(row=row, column=0, sticky="NES") v = StringVar() e = HKEntry(grid, textvariable=v) e.grid(row=row, column=1, sticky="NEWS") row_desc = (l, e, v) rows.append(row_desc) return row_desc
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'
def __init__(self, qom_desc, *args, **kw): GUIFrame.__init__(self, *args, **kw) self.desc = qom_desc try: self.pht = self.winfo_toplevel().pht except AttributeError: self.pht = None # shapshot mode without PHT if self.pht is not None: self.pht.watch_changed(self.__on_changed__) sf = self.settings_fr = GUIFrame(self) sf.pack(fill = BOTH, expand = False) f = self.qomd_fr = GUIFrame(sf) f.pack(fill = BOTH, expand = False) f.columnconfigure(0, weight = 0) f.columnconfigure(1, weight = 1) have_pciid = False for row, (attr, info) in enumerate(qom_desc.__attribute_info__.items()): f.rowconfigure(row, weight = 0) l = VarLabel(f, text = info["short"]) l.grid(row = row, column = 0, sticky = "NES") try: _input = info["input"] except KeyError: # attribute is read-only v = StringVar() w = HKEntry(f, textvariable = v, state="readonly") else: if _input is str: v = StringVar() w = HKEntry(f, textvariable = v) elif _input is int: v = StringVar() w = HKEntry(f, textvariable = v) def validate(varname, junk, act, entry = w, var = v): validate_int(var, entry = entry) v.trace_variable("w", validate) elif _input is PCIId: have_pciid = True """ Value of PCI Id could be presented either by PCIId object or by a string. So the actual widget/variable pair will be assigned during refresh. """ v = None w = GUIFrame(f) w.grid() w.rowconfigure(0, weight = 1) w.columnconfigure(0, weight = 1) elif _input is bool: v = BooleanVar() w = Checkbutton(f, variable = v) else: raise RuntimeError("Input of QOM template attribute %s of" " type %s is not supported" % (attr, _input.__name__) ) w.grid(row = row, column = 1, sticky = "NEWS") setattr(self, "_var_" + attr, v) setattr(self, "_w_" + attr, w) btf = self.buttons_fr = GUIFrame(self) btf.pack(fill = BOTH, expand = False) btf.rowconfigure(0, weight = 0) btf.columnconfigure(0, weight = 1) btf.columnconfigure(1, weight = 0) bt_apply = VarButton(btf, text = _("Apply"), command = self.__on_apply__ ) bt_apply.grid(row = 0, column = 1, sticky = "NEWS") bt_revert = VarButton(btf, text = _("Refresh"), command = self.__on_refresh__ ) bt_revert.grid(row = 0, column = 0, sticky = "NES") self.after(0, self.__refresh__) self.bind("<Destroy>", self.__on_destroy__, "+") self.__have_pciid = have_pciid if have_pciid: self.qsig_watch("qvc_available", self.__on_qvc_available)
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()
class LintGui(object): """Build and control a window to interact with pylint""" def __init__(self, root=None): """init""" self.root = root or Tk() self.root.title('Pylint') #reporter self.reporter = None #message queue for output from reporter self.msg_queue = six.moves.queue.Queue() self.msgs = [] self.visible_msgs = [] self.filenames = [] self.rating = StringVar() self.tabs = {} self.report_stream = BasicStream(self) #gui objects self.lb_messages = None self.showhistory = None self.results = None self.btnRun = None self.information_box = None self.convention_box = None self.refactor_box = None self.warning_box = None self.error_box = None self.fatal_box = None self.txtModule = None self.status = None self.msg_type_dict = None self.init_gui() 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() def select_recent_file(self, event): # pylint: disable=unused-argument """adds the selected file in the history listbox to the Module box""" if not self.showhistory.size(): return selected = self.showhistory.curselection() item = self.showhistory.get(selected) #update module self.txt_module.delete(0, END) self.txt_module.insert(0, item) def refresh_msg_window(self): """refresh the message window with current output""" #clear the window self.lb_messages.delete(0, END) self.visible_msgs = [] for msg in self.msgs: if self.msg_type_dict.get(msg.C)(): self.visible_msgs.append(msg) msg_str = convert_to_string(msg) self.lb_messages.insert(END, msg_str) fg_color = COLORS.get(msg_str[:3], 'black') self.lb_messages.itemconfigure(END, fg=fg_color) def refresh_results_window(self): """refresh the results window with current output""" #clear the window self.results.delete(0, END) try: for res in self.tabs[self.box.get()]: self.results.insert(END, res) except KeyError: pass def process_incoming(self): """process the incoming messages from running pylint""" while self.msg_queue.qsize(): try: msg = self.msg_queue.get(0) if msg == "DONE": self.report_stream.output_contents() return False #adding message to list of msgs self.msgs.append(msg) #displaying msg if message type is selected in check box if self.msg_type_dict.get(msg.C)(): self.visible_msgs.append(msg) msg_str = convert_to_string(msg) self.lb_messages.insert(END, msg_str) fg_color = COLORS.get(msg_str[:3], 'black') self.lb_messages.itemconfigure(END, fg=fg_color) except six.moves.queue.Empty: pass return True def periodic_call(self): """determine when to unlock the run button""" if self.process_incoming(): self.root.after(100, self.periodic_call) else: #enabling button so it can be run again self.btnRun.config(state=NORMAL) def mainloop(self): """launch the mainloop of the application""" self.root.mainloop() def quit(self, _=None): """quit the application""" self.root.quit() def halt(self): # pylint: disable=no-self-use """program halt placeholder""" return def file_open(self, package=False, _=None): """launch a file browser""" if not package: filename = askopenfilename(parent=self.root, filetypes=[('pythonfiles', '*.py'), ('allfiles', '*')], title='Select Module') else: filename = askdirectory(title="Select A Folder", mustexist=1) if filename == (): return self.txt_module.delete(0, END) self.txt_module.insert(0, filename) def update_filenames(self): """update the list of recent filenames""" filename = self.txt_module.get() if not filename: filename = os.getcwd() if filename+'\n' in self.filenames: index = self.filenames.index(filename+'\n') self.filenames.pop(index) #ensure only 10 most recent are stored if len(self.filenames) == 10: self.filenames.pop() self.filenames.insert(0, filename+'\n') def set_history_window(self): """update the history window with info from the history file""" #clear the window self.showhistory.delete(0, END) # keep the last 10 most recent files try: view_history = open(HOME+HISTORY, 'r') for hist in view_history.readlines(): if not hist in self.filenames: self.filenames.append(hist) self.showhistory.insert(END, hist.split('\n')[0]) view_history.close() except IOError: # do nothing since history file will be created later return def run_lint(self, _=None): """launches pylint""" self.update_filenames() self.root.configure(cursor='watch') self.reporter = GUIReporter(self, output=self.report_stream) module = self.txt_module.get() if not module: module = os.getcwd() #cleaning up msgs and windows self.msgs = [] self.visible_msgs = [] self.lb_messages.delete(0, END) self.tabs = {} self.results.delete(0, END) self.btnRun.config(state=DISABLED) #setting up a worker thread to run pylint worker = Thread(target=lint_thread, args=(module, self.reporter, self,)) self.periodic_call() worker.start() # Overwrite the .pylint-gui-history file with all the new recently added files # in order from filenames but only save last 10 files write_history = open(HOME+HISTORY, 'w') write_history.writelines(self.filenames) write_history.close() self.set_history_window() self.root.configure(cursor='') def show_sourcefile(self, event=None): # pylint: disable=unused-argument selected = self.lb_messages.curselection() if not selected: return msg = self.visible_msgs[int(selected[0])] scroll = msg.line - 3 if scroll < 0: scroll = 0 self.tabs["Source File"] = open(msg.path, "r").readlines() self.box.set("Source File") self.refresh_results_window() self.results.yview(scroll) self.results.select_set(msg.line - 1)
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()
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)
class LintGui(object): """Build and control a window to interact with pylint""" def __init__(self, root=None): """init""" self.root = root or Tk() self.root.title('Pylint') #reporter self.reporter = None #message queue for output from reporter self.msg_queue = six.moves.queue.Queue() self.msgs = [] self.visible_msgs = [] self.filenames = [] self.rating = StringVar() self.tabs = {} self.report_stream = BasicStream(self) #gui objects self.lb_messages = None self.showhistory = None self.results = None self.btnRun = None self.information_box = None self.convention_box = None self.refactor_box = None self.warning_box = None self.error_box = None self.fatal_box = None self.txtModule = None self.status = None self.msg_type_dict = None self.init_gui() 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() def select_recent_file(self, event): # pylint: disable=unused-argument """adds the selected file in the history listbox to the Module box""" if not self.showhistory.size(): return selected = self.showhistory.curselection() item = self.showhistory.get(selected) #update module self.txt_module.delete(0, END) self.txt_module.insert(0, item) def refresh_msg_window(self): """refresh the message window with current output""" #clear the window self.lb_messages.delete(0, END) self.visible_msgs = [] for msg in self.msgs: if self.msg_type_dict.get(msg.C)(): self.visible_msgs.append(msg) msg_str = convert_to_string(msg) self.lb_messages.insert(END, msg_str) fg_color = COLORS.get(msg_str[:3], 'black') self.lb_messages.itemconfigure(END, fg=fg_color) def refresh_results_window(self): """refresh the results window with current output""" #clear the window self.results.delete(0, END) try: for res in self.tabs[self.box.get()]: self.results.insert(END, res) except KeyError: pass def process_incoming(self): """process the incoming messages from running pylint""" while self.msg_queue.qsize(): try: msg = self.msg_queue.get(0) if msg == "DONE": self.report_stream.output_contents() return False #adding message to list of msgs self.msgs.append(msg) #displaying msg if message type is selected in check box if self.msg_type_dict.get(msg.C)(): self.visible_msgs.append(msg) msg_str = convert_to_string(msg) self.lb_messages.insert(END, msg_str) fg_color = COLORS.get(msg_str[:3], 'black') self.lb_messages.itemconfigure(END, fg=fg_color) except six.moves.queue.Empty: pass return True def periodic_call(self): """determine when to unlock the run button""" if self.process_incoming(): self.root.after(100, self.periodic_call) else: #enabling button so it can be run again self.btnRun.config(state=NORMAL) def mainloop(self): """launch the mainloop of the application""" self.root.mainloop() def quit(self, _=None): """quit the application""" self.root.quit() def halt(self): # pylint: disable=no-self-use """program halt placeholder""" return def file_open(self, package=False, _=None): """launch a file browser""" if not package: filename = askopenfilename(parent=self.root, filetypes=[('pythonfiles', '*.py'), ('allfiles', '*')], title='Select Module') else: filename = askdirectory(title="Select A Folder", mustexist=1) if filename == (): return self.txt_module.delete(0, END) self.txt_module.insert(0, filename) def update_filenames(self): """update the list of recent filenames""" filename = self.txt_module.get() if not filename: filename = os.getcwd() if filename + '\n' in self.filenames: index = self.filenames.index(filename + '\n') self.filenames.pop(index) #ensure only 10 most recent are stored if len(self.filenames) == 10: self.filenames.pop() self.filenames.insert(0, filename + '\n') def set_history_window(self): """update the history window with info from the history file""" #clear the window self.showhistory.delete(0, END) # keep the last 10 most recent files try: view_history = open(HOME + HISTORY, 'r') for hist in view_history.readlines(): if hist not in self.filenames: self.filenames.append(hist) self.showhistory.insert(END, hist.split('\n')[0]) view_history.close() except IOError: # do nothing since history file will be created later return def run_lint(self, _=None): """launches pylint""" self.update_filenames() self.root.configure(cursor='watch') self.reporter = GUIReporter(self, output=self.report_stream) module = self.txt_module.get() if not module: module = os.getcwd() #cleaning up msgs and windows self.msgs = [] self.visible_msgs = [] self.lb_messages.delete(0, END) self.tabs = {} self.results.delete(0, END) self.btnRun.config(state=DISABLED) #setting up a worker thread to run pylint worker = Thread(target=lint_thread, args=( module, self.reporter, self, )) self.periodic_call() worker.start() # Overwrite the .pylint-gui-history file with all the new recently added files # in order from filenames but only save last 10 files write_history = open(HOME + HISTORY, 'w') write_history.writelines(self.filenames) write_history.close() self.set_history_window() self.root.configure(cursor='') def show_sourcefile(self, event=None): # pylint: disable=unused-argument selected = self.lb_messages.curselection() if not selected: return msg = self.visible_msgs[int(selected[0])] scroll = msg.line - 3 if scroll < 0: scroll = 0 self.tabs["Source File"] = open(msg.path, "r").readlines() self.box.set("Source File") self.refresh_results_window() self.results.yview(scroll) self.results.select_set(msg.line - 1)
def __init__(self, parent, app): parent.title('Auth window') self.parent = parent self.root = app # Widget Initialization self._label_header = Label( parent, font="{Segoe UI} 20 bold", foreground="#ff0000", text="Trakt Account Authorization", ) self._button_get_code = Button( parent, font="{MS Sans Serif} 12 bold", text="Get PIN Code", ) self._label_enter_code = Label( parent, font="{MS Sans Serif} 14", text="Enter the code:", ) self._label_click = Label( parent, font="{MS Sans Serif} 14", text="Click the button to get a code:", ) self.pin_code = StringVar() self._entry_code = Entry( parent, font="{MS Sans Serif} 14 bold", width=10, justify="center", textvariable=self.pin_code, state="disabled", ) self._button_done = Button( parent, borderwidth=3, font="{MS Sans Serif} 12 bold", text="Done", state="disabled", ) # widget commands self._button_get_code.configure(command=self.button_get_code_command) self._button_done.configure(command=self.button_done_command) # Geometry Management self._label_header.grid(in_=parent, column=1, row=1, columnspan=1, ipadx=0, ipady=0, padx=0, pady=0, rowspan=1, sticky="ew") self._label_click.grid(in_=parent, column=1, row=2, columnspan=1, ipadx=0, ipady=0, padx=0, pady=0, rowspan=1, sticky="") self._button_get_code.grid(in_=parent, column=1, row=3, columnspan=1, ipadx=0, ipady=0, padx=0, pady=0, rowspan=1, sticky="") self._label_enter_code.grid(in_=parent, column=1, row=4, columnspan=1, ipadx=0, ipady=0, padx=0, pady=0, rowspan=1, sticky="") self._entry_code.grid(in_=parent, column=1, row=5, columnspan=1, ipadx=5, ipady=0, padx=5, pady=0, rowspan=1, sticky="") self._button_done.grid(in_=parent, column=1, row=6, columnspan=1, ipadx=0, ipady=0, padx=0, pady=0, rowspan=1, sticky="") # Resize Behavior parent.resizable(False, False) parent.grid_rowconfigure(1, weight=1, minsize=40, pad=10) parent.grid_rowconfigure(2, weight=1, minsize=40, pad=10) parent.grid_rowconfigure(3, weight=1, minsize=40, pad=10) parent.grid_rowconfigure(4, weight=1, minsize=40, pad=10) parent.grid_rowconfigure(5, weight=1, minsize=50, pad=10) parent.grid_rowconfigure(6, weight=1, minsize=50, pad=10) parent.grid_columnconfigure(1, weight=1, minsize=0, pad=10)
def __init__(self, project=None): GUITk.__init__(self, wait_msec=1) for signame in ["qvc_dirtied", "qvd_failed", "qvc_available"]: s = CoSignal() s.attach(self.signal_dispatcher) setattr(self, "sig_" + signame, s) self.title_suffix = _("Qemu device creator GUI") self.title_suffix.trace_variable("w", self.__on_title_suffix_write__) self.title_not_saved_asterisk = StringVar() self.title_not_saved_asterisk.trace_variable( "w", self.__on_title_suffix_write__) self.saved_operation = None self.var_title = StringVar() self.title(self.var_title) # Hot keys, accelerators self.hk = hotkeys = HotKey(self) hotkeys.add_bindings([ HotKeyBinding( self.invert_history_window, key_code=43, description=_("If editing history window is hidden then \ show it else hide it."), symbol="H"), HotKeyBinding(self.on_load, key_code=32, description=_("Load project from file."), symbol="O"), HotKeyBinding(self.on_new_project, key_code=57, description=_("Create new project."), symbol="N"), HotKeyBinding(self.on_add_description, key_code=40, description=_("Add description to the project"), symbol="D"), HotKeyBinding(self.on_set_qemu_build_path, key_code=56, description=_("Set Qemu build path for the project"), symbol="B"), HotKeyBinding( self.on_sel_tgt_qemu_version, key_code=28, description=_("Select target Qemu version for the project"), symbol="T"), HotKeyBinding(self.on_generate, key_code=42, description=_("Launch code generation"), symbol="G"), HotKeyBinding(self.on_delete, key_code=24, description=_("Shutdown the application."), symbol="Q"), HotKeyBinding(self.undo, key_code=52, description=_("Revert previous editing."), symbol="Z"), HotKeyBinding(self.redo, key_code=29, description=_("Make reverted editing again."), symbol="Y"), HotKeyBinding(self.on_save, key_code=39, description=_("Save project."), symbol="S"), HotKeyBinding(self.on_reload, key_code=27, description=_("Reload current project from file."), symbol="R") ]) # see `set_user_settings` self._user_settings = None # Menu bar menubar = VarMenu(self) self.filemenu = filemenu = VarMenu(menubar, tearoff=False) filemenu.add_command(label=_("Add description"), command=self.on_add_description, accelerator=hotkeys.get_keycode_string( self.on_add_description)) filemenu.add_command(label=_("Set Qemu build path"), command=self.on_set_qemu_build_path, accelerator=hotkeys.get_keycode_string( self.on_set_qemu_build_path)) filemenu.add_command(label=_("Select target Qemu version"), command=self.on_sel_tgt_qemu_version, accelerator=hotkeys.get_keycode_string( self.on_sel_tgt_qemu_version)) filemenu.add_command(label=_("Generate"), command=self.on_generate, accelerator=hotkeys.get_keycode_string( self.on_generate)) filemenu.add_separator() filemenu.add_command(label=_("New project"), command=self.on_new_project, accelerator=hotkeys.get_keycode_string( self.on_new_project)), filemenu.add_command(label=_("Save"), command=self.on_save, accelerator=hotkeys.get_keycode_string( self.on_save)), filemenu.add_command(label=_("Save project as..."), command=self.on_save_as) filemenu.add_command(label=_("Load"), command=self.on_load, accelerator=hotkeys.get_keycode_string( self.on_load)), self.reload_idx = filemenu.count filemenu.add_command(label=_("Reload"), command=self.on_reload, accelerator=hotkeys.get_keycode_string( self.on_reload)), self.recentmenu = recentmenu = VarMenu(filemenu, tearoff=False) filemenu.add_cascade( label=_("Recent projects"), menu=recentmenu, state=DISABLED # a user settings instance is required ) filemenu.add_separator() filemenu.add_command(label=_("Quit"), command=self.quit, accelerator=hotkeys.get_keycode_string( self.on_delete)) menubar.add_cascade(label=_("File"), menu=filemenu) self.editmenu = editmenu = VarMenu(menubar, tearoff=False) editmenu.add_command(label=_("Undo"), command=self.undo, accelerator=hotkeys.get_keycode_string(self.undo)) self.undo_idx = editmenu.count - 1 editmenu.add_command(label=_("Redo"), command=self.redo, accelerator=hotkeys.get_keycode_string(self.redo)) self.redo_idx = editmenu.count - 1 editmenu.add_separator() editmenu.add_command(label=_("Rebuild Cache"), command=self.rebuild_cache, accelerator=hotkeys.get_keycode_string( self.rebuild_cache)) editmenu.add_separator() v = self.var_history_window = BooleanVar() v.set(False) self.__on_var_history_window = v.trace_variable( "w", self.__on_var_history_window__) editmenu.add_checkbutton(label=_("Editing history window"), variable=v, accelerator=hotkeys.get_keycode_string( self.invert_history_window)) menubar.add_cascade(label=_("Edit"), menu=editmenu) self.optionsmenu = optionsmenu = VarMenu(menubar, tearoff=False) v = self.var_schedule_generation = BooleanVar() v.set(False) self.__on_var_schedule_generation = v.trace_variable( "w", self.__on_var_schedule_generation__) optionsmenu.add_checkbutton( label=_("Schedule generation after cache loading"), variable=v) v = self.var_gen_chunk_graphs = BooleanVar() v.set(False) self.__on_var_gen_chunk_graphs = v.trace_variable( "w", self.__on_var_gen_chunk_graphs__) optionsmenu.add_checkbutton(label=_("Generate chunk graphs"), variable=v) menubar.add_cascade(label=_("Options"), menu=optionsmenu) self.config(menu=menubar) # Widget layout self.grid() self.grid_columnconfigure(0, weight=1) self.grid_rowconfigure(0, weight=1) # Status bar self.grid_rowconfigure(1, weight=0) self.sb = sb = Statusbar(self) sb.grid(row=1, column=0, sticky="NEWS") # Target Qemu version in the status bar self._target_qemu = Variable(None) # This complicated scheme is required because the status must also # be updated on language change. @as_variable(self._target_qemu, _("No target"), _("Target Qemu: %s")) def var_target_qemu(target, no_target, target_qemu): if target is None: return no_target else: return target_qemu % target sb.left(var_target_qemu) # QEMU build path displaying self.var_qemu_build_path = StringVar() sb.left(self.var_qemu_build_path) # Task counters in status bar sb.right(_("Background tasks: ")) sb.repack(CoStatusView(sb), RIGHT) self.signal_dispatcher.watch_failed(self.__on_listener_failed) self.protocol("WM_DELETE_WINDOW", self.on_delete) self.set_project(GUIProject() if project is None else project) self.__update_title__() self.__check_saved_asterisk__() self.qsig_watch("qvc_available", self.__on_qvc_available)
class QDCGUIWindow(GUITk, QDCGUISignalHelper): def __init__(self, project=None): GUITk.__init__(self, wait_msec=1) for signame in ["qvc_dirtied", "qvd_failed", "qvc_available"]: s = CoSignal() s.attach(self.signal_dispatcher) setattr(self, "sig_" + signame, s) self.title_suffix = _("Qemu device creator GUI") self.title_suffix.trace_variable("w", self.__on_title_suffix_write__) self.title_not_saved_asterisk = StringVar() self.title_not_saved_asterisk.trace_variable( "w", self.__on_title_suffix_write__) self.saved_operation = None self.var_title = StringVar() self.title(self.var_title) # Hot keys, accelerators self.hk = hotkeys = HotKey(self) hotkeys.add_bindings([ HotKeyBinding( self.invert_history_window, key_code=43, description=_("If editing history window is hidden then \ show it else hide it."), symbol="H"), HotKeyBinding(self.on_load, key_code=32, description=_("Load project from file."), symbol="O"), HotKeyBinding(self.on_new_project, key_code=57, description=_("Create new project."), symbol="N"), HotKeyBinding(self.on_add_description, key_code=40, description=_("Add description to the project"), symbol="D"), HotKeyBinding(self.on_set_qemu_build_path, key_code=56, description=_("Set Qemu build path for the project"), symbol="B"), HotKeyBinding( self.on_sel_tgt_qemu_version, key_code=28, description=_("Select target Qemu version for the project"), symbol="T"), HotKeyBinding(self.on_generate, key_code=42, description=_("Launch code generation"), symbol="G"), HotKeyBinding(self.on_delete, key_code=24, description=_("Shutdown the application."), symbol="Q"), HotKeyBinding(self.undo, key_code=52, description=_("Revert previous editing."), symbol="Z"), HotKeyBinding(self.redo, key_code=29, description=_("Make reverted editing again."), symbol="Y"), HotKeyBinding(self.on_save, key_code=39, description=_("Save project."), symbol="S"), HotKeyBinding(self.on_reload, key_code=27, description=_("Reload current project from file."), symbol="R") ]) # see `set_user_settings` self._user_settings = None # Menu bar menubar = VarMenu(self) self.filemenu = filemenu = VarMenu(menubar, tearoff=False) filemenu.add_command(label=_("Add description"), command=self.on_add_description, accelerator=hotkeys.get_keycode_string( self.on_add_description)) filemenu.add_command(label=_("Set Qemu build path"), command=self.on_set_qemu_build_path, accelerator=hotkeys.get_keycode_string( self.on_set_qemu_build_path)) filemenu.add_command(label=_("Select target Qemu version"), command=self.on_sel_tgt_qemu_version, accelerator=hotkeys.get_keycode_string( self.on_sel_tgt_qemu_version)) filemenu.add_command(label=_("Generate"), command=self.on_generate, accelerator=hotkeys.get_keycode_string( self.on_generate)) filemenu.add_separator() filemenu.add_command(label=_("New project"), command=self.on_new_project, accelerator=hotkeys.get_keycode_string( self.on_new_project)), filemenu.add_command(label=_("Save"), command=self.on_save, accelerator=hotkeys.get_keycode_string( self.on_save)), filemenu.add_command(label=_("Save project as..."), command=self.on_save_as) filemenu.add_command(label=_("Load"), command=self.on_load, accelerator=hotkeys.get_keycode_string( self.on_load)), self.reload_idx = filemenu.count filemenu.add_command(label=_("Reload"), command=self.on_reload, accelerator=hotkeys.get_keycode_string( self.on_reload)), self.recentmenu = recentmenu = VarMenu(filemenu, tearoff=False) filemenu.add_cascade( label=_("Recent projects"), menu=recentmenu, state=DISABLED # a user settings instance is required ) filemenu.add_separator() filemenu.add_command(label=_("Quit"), command=self.quit, accelerator=hotkeys.get_keycode_string( self.on_delete)) menubar.add_cascade(label=_("File"), menu=filemenu) self.editmenu = editmenu = VarMenu(menubar, tearoff=False) editmenu.add_command(label=_("Undo"), command=self.undo, accelerator=hotkeys.get_keycode_string(self.undo)) self.undo_idx = editmenu.count - 1 editmenu.add_command(label=_("Redo"), command=self.redo, accelerator=hotkeys.get_keycode_string(self.redo)) self.redo_idx = editmenu.count - 1 editmenu.add_separator() editmenu.add_command(label=_("Rebuild Cache"), command=self.rebuild_cache, accelerator=hotkeys.get_keycode_string( self.rebuild_cache)) editmenu.add_separator() v = self.var_history_window = BooleanVar() v.set(False) self.__on_var_history_window = v.trace_variable( "w", self.__on_var_history_window__) editmenu.add_checkbutton(label=_("Editing history window"), variable=v, accelerator=hotkeys.get_keycode_string( self.invert_history_window)) menubar.add_cascade(label=_("Edit"), menu=editmenu) self.optionsmenu = optionsmenu = VarMenu(menubar, tearoff=False) v = self.var_schedule_generation = BooleanVar() v.set(False) self.__on_var_schedule_generation = v.trace_variable( "w", self.__on_var_schedule_generation__) optionsmenu.add_checkbutton( label=_("Schedule generation after cache loading"), variable=v) v = self.var_gen_chunk_graphs = BooleanVar() v.set(False) self.__on_var_gen_chunk_graphs = v.trace_variable( "w", self.__on_var_gen_chunk_graphs__) optionsmenu.add_checkbutton(label=_("Generate chunk graphs"), variable=v) menubar.add_cascade(label=_("Options"), menu=optionsmenu) self.config(menu=menubar) # Widget layout self.grid() self.grid_columnconfigure(0, weight=1) self.grid_rowconfigure(0, weight=1) # Status bar self.grid_rowconfigure(1, weight=0) self.sb = sb = Statusbar(self) sb.grid(row=1, column=0, sticky="NEWS") # Target Qemu version in the status bar self._target_qemu = Variable(None) # This complicated scheme is required because the status must also # be updated on language change. @as_variable(self._target_qemu, _("No target"), _("Target Qemu: %s")) def var_target_qemu(target, no_target, target_qemu): if target is None: return no_target else: return target_qemu % target sb.left(var_target_qemu) # QEMU build path displaying self.var_qemu_build_path = StringVar() sb.left(self.var_qemu_build_path) # Task counters in status bar sb.right(_("Background tasks: ")) sb.repack(CoStatusView(sb), RIGHT) self.signal_dispatcher.watch_failed(self.__on_listener_failed) self.protocol("WM_DELETE_WINDOW", self.on_delete) self.set_project(GUIProject() if project is None else project) self.__update_title__() self.__check_saved_asterisk__() self.qsig_watch("qvc_available", self.__on_qvc_available) def set_user_settings(self, val): if self._user_settings is val: return self._user_settings = val self._update_recent_projects() self._update_options() def _update_recent_projects(self): settings = self._user_settings menu = self.recentmenu # first, clear recent menu last = menu.index(END) if last is not None: menu.delete(0, last) added = 0 if settings is not None: for f in reversed(list(settings.recent_projects)): # a simple check if not isfile(f): settings.recent_projects.discard(f) continue def do_load(file_name=f): self._do_load(file_name) menu.add_command(label=f, command=do_load) added += 1 self.filemenu.entryconfigure(self.filemenu.index( _("Recent projects").get()), state=NORMAL if added else DISABLED) def _update_options(self): settings = self._user_settings if settings is None: return self.var_schedule_generation.set(settings.schedule_generation) self.var_gen_chunk_graphs.set(settings.gen_chunk_graphs) def __on_listener_failed(self, e, tb): sys.stderr.write("Listener failed - %s" % "".join(format_exception(type(e), e, tb))) def __on_history_window_destroy__(self, *args, **kw): self.var_history_window.trace_vdelete("w", self.__on_var_history_window) self.var_history_window.set(False) self.__on_var_history_window = self.var_history_window.trace_variable( "w", self.__on_var_history_window__) def __on_var_history_window__(self, *args): if self.var_history_window.get(): self._history_window = HistoryWindow(self.pht, self) self._history_window.bind("<Destroy>", self.__on_history_window_destroy__, "+") else: try: self._history_window.destroy() except AttributeError: pass else: del self._history_window def invert_history_window(self): self.var_history_window.set(not self.var_history_window.get()) def __on_var_schedule_generation__(self, *args): settings = self._user_settings if settings is not None: settings.schedule_generation = self.var_schedule_generation.get() def __on_var_gen_chunk_graphs__(self, *args): settings = self._user_settings if settings is not None: settings.gen_chunk_graphs = self.var_gen_chunk_graphs.get() def __on_title_suffix_write__(self, *args, **kw): self.__update_title__() def __update_title__(self): try: title_prefix = str(self.current_file_name) except AttributeError: title_prefix = "[New project]" self.var_title.set(title_prefix + self.title_not_saved_asterisk.get() + " - " + self.title_suffix.get()) def check_undo_redo(self): can_do = self.pht.can_do() self.hk.set_enabled(self.redo, can_do) if can_do: self.editmenu.entryconfig(self.redo_idx, state=NORMAL) else: self.editmenu.entryconfig(self.redo_idx, state=DISABLED) can_undo = self.pht.can_undo() self.hk.set_enabled(self.undo, can_undo) if can_undo: self.editmenu.entryconfig(self.undo_idx, state=NORMAL) else: self.editmenu.entryconfig(self.undo_idx, state=DISABLED) def set_current_file_name(self, file_name=None): if file_name is None: try: del self.current_file_name except AttributeError: pass # already deleted else: self.filemenu.entryconfig(self.reload_idx, state=DISABLED) else: # TODO: watch the file in FS and auto ask user to reload self.current_file_name = file_name self.filemenu.entryconfig(self.reload_idx, state=NORMAL) self.__update_title__() def set_project(self, project): try: pht = self.pht except AttributeError: # Project was never been set pass else: pht.unwatch_changed(self.on_changed) try: self.pw.destroy() except AttributeError: # project widget was never been created pass # Close history window if self.var_history_window.get(): self.var_history_window.set(False) self.proj = project self.pht = GUIProjectHistoryTracker(self.proj, self.proj.history) DescNameWatcher(self.pht) self.pw = ProjectWidget(self.proj, self) self.pw.grid(column=0, row=0, sticky="NEWS") self.update_qemu_build_path(project.build_path) self.update_target_qemu() self.pht.watch_changed(self.on_changed) self.check_undo_redo() def __saved_asterisk__(self, saved=True): if saved: if self.title_not_saved_asterisk.get() != "": self.title_not_saved_asterisk.set("") else: if self.title_not_saved_asterisk.get() != "*": self.title_not_saved_asterisk.set("*") def __check_saved_asterisk__(self): if self.saved_operation == self.pht.pos: self.__saved_asterisk__(True) else: self.__saved_asterisk__(False) def on_changed(self, op, *args, **kw): self.check_undo_redo() self.__check_saved_asterisk__() if isinstance(op, GUIPOp_SetBuildPath): proj = self.proj if op.p is proj: self.update_qemu_build_path(proj.build_path) # Note that target Qemu version info will be update when QVC # will be ready. def undo(self): self.pht.undo_sequence() def redo(self): self.pht.do_sequence() def rebuild_cache(self): try: qvd = qvd_get(self.proj.build_path, version=self.proj.target_version) except BadBuildPath as e: showerror( title=_("Cache rebuilding is impossible").get(), message=(_("Selected Qemu build path is bad. Reason: %s") % (e.message)).get()) return # if 'reload_build_path_task' is not failed if hasattr(self.pw, 'reload_build_path_task'): # reload_build_path_task always run at program start that is why # it's in process when it's not in finished_tasks and not failed if self.pw.reload_build_path_task not in self.pw.tm.finished_tasks: ans = askyesno(self, title=_("Cache rebuilding"), message=_("Cache building is already \ in process. Do you want to start cache rebuilding?")) if not ans: return qvd.remove_cache() self.pw.reload_build_path() def on_delete(self): if self.title_not_saved_asterisk.get() == "*": resp = askyesnocancel( title=self.title_suffix.get(), message=_("Current project has unsaved changes." " Would you like to save it?" "\n\nNote that a backup is always saved with name" " project.py in current working directory.").get()) if resp is None: return if resp: self.on_save() if self.title_not_saved_asterisk.get() == "*": # user canceled saving during on_save return try: """ TODO: Note that it is possible to prevent window to close if a generation task is in process. But is it really needed? """ self.task_manager.remove(self._project_generation_task) except AttributeError: pass else: del self._project_generation_task self.signal_dispatcher.unwatch_failed(self.__on_listener_failed) self.quit() def on_add_description(self): d = AddDescriptionDialog(self.pht, self) def on_set_qemu_build_path(self): dir = askdirectory(self, title=_("Select Qemu build path")) if not dir: return self.pht.set_build_path(dir) def on_sel_tgt_qemu_version(self): try: qvd = qvd_get(self.proj.build_path) except: repo = None else: repo = qvd.repo new_target = GitVerSelDialog(self, repo).wait() if new_target is None: return self.pht.set_target(new_target) def on_generate(self): try: t = self._project_generation_task except AttributeError: pass else: if not t.finished: showerror(title=_("Generation is cancelled").get(), message=_("At least one generation task is already \ in process.").get()) return if not self.proj.build_path: showerror( title=_("Generation is impossible").get(), message=_("No Qemu build path is set for the project.").get()) return try: qvd = qvd_get(self.proj.build_path, version=self.proj.target_version) except BadBuildPath as e: showerror( title=_("Generation is impossible").get(), message=(_("Selected Qemu build path is bad. Reason: %s") % (e.message)).get()) return if not hasattr(self.pw, "reload_build_path_task"): showerror(title=_("Generation is impossible").get(), message=_("Qemu version cache loading failed.").get()) return if not qvd.qvc_is_ready and not self.var_schedule_generation.get(): showerror(title=_("Generation is cancelled").get(), message=_("Qemu version cache is not ready yet. Try \ later.").get()) return self._project_generation_task = ProjectGeneration( self.proj, qvd.src_path, self.sig_qvc_dirtied, self.pw.reload_build_path_task, self.var_gen_chunk_graphs.get()) self.task_manager.enqueue(self._project_generation_task) def load_project_from_file(self, file_name): loaded_variables = dict(qdt.__dict__) try: execfile(file_name, loaded_variables) except Exception as e: raise e else: qproj = None for v in loaded_variables.values(): if isinstance(v, GUIProject): break elif qproj is None and isinstance(v, QProject): qproj = v else: if qproj: v = GUIProject.from_qproject(qproj) else: raise Exception("No project object was loaded") self.set_project(v) self.set_current_file_name(file_name) self.saved_operation = self.pht.pos self.__check_saved_asterisk__() if self._user_settings: self._user_settings.account_project(file_name) self._update_recent_projects() def save_project_to_file(self, file_name): self.pw.refresh_layouts() project = self.proj # Ensure that all machine nodes are in corresponding lists for d in project.descriptions: if isinstance(d, MachineNode): d.link(handle_system_bus=False) pythonize(project, file_name) self.set_current_file_name(file_name) self.saved_operation = self.pht.pos self.__check_saved_asterisk__() def try_save_project_to_file(self, file_name): try: open(file_name, "wb").close() except IOError as e: if not e.errno == 13: # Do not remove read-only files try: remove(file_name) except: pass showerror(title=_("Cannot save project").get(), message=str(e)) return self.save_project_to_file(file_name) if self._user_settings: self._user_settings.account_project(file_name) self._update_recent_projects() def on_save_as(self): fname = asksaveas(self, [(_("QDC GUI Project defining script"), ".py")], title=_("Save project")) if not fname: return self.try_save_project_to_file(fname) def on_save(self): try: fname = self.current_file_name except AttributeError: self.on_save_as() else: self.try_save_project_to_file(fname) def check_unsaved(self): if self.title_not_saved_asterisk.get() == "*": return askyesno( self, title=self.title_suffix, message= _("Current project has unsaved changes. They will be lost. Continue?" )) else: return True def on_new_project(self): if not self.check_unsaved(): return self.set_project(GUIProject()) self.set_current_file_name() """ There is nothing to save in just created project. So declare that all changes are saved. """ self.saved_operation = self.pht.pos self.__check_saved_asterisk__() def on_load(self): if not self.check_unsaved(): return fname = askopen(self, [(_("QDC GUI Project defining script"), ".py")], title=_("Load project")) if fname: self._do_load(fname) def _do_load(self, fname): try: self.load_project_from_file(fname) except Exception as e: showerror(title=_("Project loading failed").get(), message=str(e)) def on_reload(self): try: fname = self.current_file_name except AttributeError: # No file is selected for the project yet return if not self.check_unsaved(): return self._do_load(fname) def update_qemu_build_path(self, bp): if bp is None: self.var_qemu_build_path.set( _("No QEMU build path selected").get()) else: self.var_qemu_build_path.set("QEMU: " + bp) def update_target_qemu(self): p, qvd = self.proj, QemuVersionDescription.current self._target_qemu.set(p and p.target_version or qvd and qvd.commit_sha) def __on_qvc_available(self): self.update_target_qemu()
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)
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'