class ChatWindow(MessageSubscriber): def __init__(self, root, username, sender): self.frame = Frame(root) self.username = username self.sender = sender self.put_message_lock = Lock() Grid.columnconfigure(self.frame, 0, weight=2) Grid.columnconfigure(self.frame, 1, weight=0) Grid.rowconfigure(self.frame, 0, weight=2) Grid.rowconfigure(self.frame, 1, weight=0) self.scrollbar = Scrollbar(self.frame) self.messages = Listbox(self.frame, yscrollcommand=self.scrollbar.set, height=15, width=50) self.scrollbar.grid(row=0, column=1, sticky=N + S) self.messages.grid(row=0, column=0, sticky=N + S + W + E) self.scrollbar.config(command=self.messages.yview) self.input_user = StringVar() self.input_field = Entry(self.frame, text=self.input_user) self.input_field.grid(row=1, column=0, sticky=W + E + S) self.send_button = Button(self.frame, text="Send", command=self.send_message) self.send_button.grid(row=1, column=1, sticky=S) self.input_field.bind("<Return>", lambda key: self.send_message()) self.frame.pack(fill=BOTH, expand=YES) self.input_field.focus() def send_message(self): input_val = self.input_field.get() date = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') if input_val == "": return if self.sender(input_val, date, self.username): self.input_user.set("") def put_message_in_chat(self, message, date, username, color="red"): with self.put_message_lock: self.messages.insert(END, date + " " + username + ": " + message) self.messages.itemconfig(END, {"fg": color}) self.messages.yview(END) def receive_message(self, text, date, name): self.put_message_in_chat(text, date, name)
class Example(Frame): def __init__(self, parent): Frame.__init__(self, parent, background="#8080FF") self.parent = parent self.initUI() def initUI(self): self.parent.title("EQ GuildViewer 0.1") fontb = Font(size=12, weight="bold") # inicializo variables self.ant = None self.lastLine = 0 self.name = "" # frame padre area = Frame(self) area.pack(side=BOTTOM, fill=BOTH, expand=1) areab = Frame(self) areab.pack(side=TOP, fill=BOTH, expand=1) # scroll players self.scrollbar2 = Scrollbar(areab, orient=VERTICAL) # construimos un menu con todos los nombres del diccionario y un boton self.refreshButton = Button(areab, text="""PARSEA!""", command=self.onRefresh, bd=2, relief="groove") self.listboxLogs = Listbox( areab, width=50, activestyle="none", highlightthickness=0, yscrollcommand=self.scrollbar2.set, relief=RIDGE ) self.listboxLogs.pack(side=LEFT, fill=Y) self.scrollbar2.pack(side=LEFT, fill=Y) self.refreshButton.pack(side=LEFT, fill=BOTH, expand=1) for player in optionsDictionary: self.listboxLogs.insert(END, player) # scroll self.scrollbar = Scrollbar(area, orient=VERTICAL) self.scrollbar.pack(side=RIGHT, fill=Y) # area1 area1 = Frame(area) area1.pack(side=LEFT, fill=Y) lbl = Label(area1, text="Name") self.listbox = Listbox( area1, yscrollcommand=self.scrollbar.set, font=fontb, relief=FLAT, highlightthickness=0, activestyle="none" ) lbl.pack(side=TOP) self.listbox.pack(side=BOTTOM, fill=Y, expand=1) # area2 area2 = Frame(area) area2.pack(side=LEFT, fill=Y) lbl2 = Label(area2, text="Level") self.listbox2 = Listbox( area2, yscrollcommand=self.scrollbar.set, font=fontb, relief=FLAT, highlightthickness=0, activestyle="none" ) lbl2.pack(side=TOP) self.listbox2.pack(side=BOTTOM, fill=Y, expand=1) # area3 area3 = Frame(area) area3.pack(side=LEFT, fill=Y) lbl3 = Label(area3, text="Class") self.listbox3 = Listbox( area3, yscrollcommand=self.scrollbar.set, font=fontb, relief=FLAT, highlightthickness=0, activestyle="none" ) lbl3.pack(side=TOP) self.listbox3.pack(side=BOTTOM, fill=Y, expand=1) # area4 area4 = Frame(area) area4.pack(side=LEFT, fill=Y) lbl4 = Label(area4, text="Race") self.listbox4 = Listbox( area4, yscrollcommand=self.scrollbar.set, font=fontb, relief=FLAT, highlightthickness=0, activestyle="none" ) lbl4.pack(side=TOP) self.listbox4.pack(side=BOTTOM, fill=Y, expand=1) # area3 area5 = Frame(area) area5.pack(side=LEFT, fill=Y) lbl5 = Label(area5, text="Zone") self.listbox5 = Listbox( area5, yscrollcommand=self.scrollbar.set, font=fontb, relief=FLAT, highlightthickness=0, activestyle="none" ) lbl5.pack(side=TOP) self.listbox5.pack(side=BOTTOM, fill=Y, expand=1) self.pack(fill=BOTH, expand=1) # config-scrollbar self.scrollbar.config(command=self.yview) self.scrollbar2["command"] = self.listboxLogs.yview # bindeos de acciones self.listbox.bind("<<ListboxSelect>>", self.onSelect) self.listbox.bind("<MouseWheel>", self.onTest) self.listbox2.bind("<<ListboxSelect>>", self.onSelect) self.listbox2.bind("<MouseWheel>", self.onTest) self.listbox3.bind("<<ListboxSelect>>", self.onSelect) self.listbox3.bind("<MouseWheel>", self.onTest) self.listbox4.bind("<<ListboxSelect>>", self.onSelect) self.listbox4.bind("<MouseWheel>", self.onTest) self.listbox5.bind("<<ListboxSelect>>", self.onSelect) self.listbox5.bind("<MouseWheel>", self.onTest) self.listboxLogs.bind("<<ListboxSelect>>", self.onSelectPlayer) # mostrar la barra de scroll def yview(self, *args): self.listbox.yview(*args) self.listbox2.yview(*args) self.listbox3.yview(*args) self.listbox4.yview(*args) self.listbox5.yview(*args) # accion de la rueda del raton def onTest(self, val): return "break" # seleccionar un elementos de una listbox def onSelect(self, val): try: if self.ant != None: self.listbox.itemconfig(self.ant, background="#FFFFFF") self.listbox2.itemconfig(self.ant, background="#FFFFFF") self.listbox3.itemconfig(self.ant, background="#FFFFFF") self.listbox4.itemconfig(self.ant, background="#FFFFFF") self.listbox5.itemconfig(self.ant, background="#FFFFFF") self.listbox.itemconfig(val.widget.curselection(), background="#C0C0C0") self.listbox2.itemconfig(val.widget.curselection(), background="#C0C0C0") self.listbox3.itemconfig(val.widget.curselection(), background="#C0C0C0") self.listbox4.itemconfig(val.widget.curselection(), background="#C0C0C0") self.listbox5.itemconfig(val.widget.curselection(), background="#C0C0C0") self.ant = val.widget.curselection() except: None # print('No hay valores') # dependiendo de que nombre se elija en el menu cargamos en lastLine la linea de ese nombre del diccionario def onSelectPlayer(self, val): try: self.name = val.widget.get(val.widget.curselection()) self.lastLine = optionsDictionary[self.name] # print(self.name, ' ', self.lastLine) except: None # print('No hay valores') # recorremos el fichero log al clickar sobre el boton 'Refresh!' def onRefresh(self): if self.name != "": yes = False count = 0 dictionary = {} dictionaryAuxiliar = {} stringLog = "../eqlog_" + str(self.name) + "_project1999.txt" with open(stringLog, "r") as log: for i in range(int(self.lastLine)): next(log) count = count + 1 for line in log: match = re.match("\[.*\] \[(.*) (.*)\] (.*) \((.*)\) <.*> ZONE: (.*)", line) matchRole = re.match("\[.*\] \[(.*)\] (.*) <.*>", line) matchToken = re.match("\[.*\] You say, 't0000'", line) matchTokenI = re.match("\[.*\] You say, 't0001'", line) if matchTokenI != None: yes = True elif match != None and yes: dictionaryAuxiliar[match.group(3)] = ( match.group(1), match.group(2), match.group(4), match.group(5), ) elif matchRole != None and yes: dictionaryAuxiliar[matchRole.group(2)] = [(matchRole.group(1))] elif matchToken != None and yes: dictionary = dictionaryAuxiliar.copy() dictionaryAuxiliar.clear() yes = False count = count + 1 # bucle para sacar datos, primero eliminamos todo lo que haya self.listbox.delete(0, self.listbox.size()) self.listbox2.delete(0, self.listbox2.size()) self.listbox3.delete(0, self.listbox3.size()) self.listbox4.delete(0, self.listbox4.size()) self.listbox5.delete(0, self.listbox5.size()) for member in dictionary: self.listbox.insert(END, member) self.listbox2.insert(END, dictionary[member][0]) try: self.listbox3.insert(END, dictionary[member][1]) self.listbox4.insert(END, dictionary[member][2]) self.listbox5.insert(END, dictionary[member][3]) except IndexError as error: self.listbox3.insert(END, "-") self.listbox5.insert(END, "-") self.listbox4.insert(END, "-") # print(dictionary) # print('Longitud', len(dictionary)) # guardamos la linea ultima leida en el diccionario # self.lastLine = count # optionsDictionary[self.name] = count # print('Despues:', optionsDictionary) # guardamos el diccionario en el archivo options options = open("options.txt", "w") for player in optionsDictionary: options.write(str(player) + ":" + str(optionsDictionary[player])) options.close()
class ClientUI: def __init__(self, master, client): self.master = master self.client = client self.user_data = UserData() master.title("Chatroom") master.geometry("720x350") self.messages_list = Listbox(self.master, height=12, width=75, border=1, font=("Helvetica", 11)) self.messages_list.grid(row=1, column=0, pady=20) self.scrollbar = Scrollbar(self.master) self.scrollbar.grid(row=1, column=1, sticky=W) self.messages_list.configure(yscrollcommand=self.scrollbar.set) self.scrollbar.configure(command=self.messages_list.yview) self.message_input = Text(self.master, height=4, width=50) self.message_input.grid(row=2, column=0, rowspan=4, padx=40) self.send_button = Button(master, text="Send", command=self.send_message) self.send_button.grid(row=2, column=1, pady=20) self.master.protocol("WM_DELETE_WINDOW", self.full_exit) master.bind('<Return>', self.return_press) PopupWindow(master, self.set_username, client) threading.Thread(target=self.update_received, daemon=True).start() def update_received(self): while True: messages = self.client.receive_all() for message in messages: self.messages_list.insert( END, f"{message['user']} > {message['data']}") self.messages_list.yview(END) def set_username(self, username): self.user_data.set_username(username) def return_press(self, event): self.send_message() def send_message(self): if not self.user_data.get_user_name(): print("Username should be provided") exit(-1) message = self.message_input.get("1.0", END).rstrip() if not message: return self.messages_list.insert( END, f"{self.user_data.get_user_name()} > {message}") self.messages_list.yview(END) self.message_input.delete('1.0', END) self.client.send_message(message) def full_exit(self): self.master.destroy() exit()
class CompetitorTable(Frame): def __init__(self, parent, db, *args, **kwargs): Frame.__init__(self, parent, *args, **kwargs) self.parent = parent self.db = db self.labelfont = ['Arial', -0.017, 'bold'] self.font = ['Arial', -0.017] self.labelfont[1] = round(self.font[1] * self.parent.parent.parent.SCREEN_HEIGHT) self.font[1] = round(self.font[1] * self.parent.parent.parent.SCREEN_HEIGHT) self.config(bg=LLBLUE) self.tablebg = 'white' self.tableborder = LLBLUE self.labelfg = 'white' self.labelbg = LBLUE self.scrollbar = Scrollbar(self) self.idLabel = Label(self, text='ID', fg=self.labelfg, bg=self.labelbg, font=self.labelfont, height=1, anchor='sw', highlightbackground=self.labelfg) self.fnameLabel = Label(self, text='First Name', fg=self.labelfg, bg=self.labelbg, font=self.labelfont, height=1, anchor='sw') self.lnameLabel = Label(self, text='Last Name', fg=self.labelfg, bg=self.labelbg, font=self.labelfont, height=1, anchor='sw') self.levelLabel = Label(self, text='Level', fg=self.labelfg, bg=self.labelbg, font=self.labelfont, height=1, anchor='sw') self.sexLabel = Label(self, text='Sex', fg=self.labelfg, bg=self.labelbg, font=self.labelfont, height=1, anchor='sw') self.ageLabel = Label(self, text='Age', fg=self.labelfg, bg=self.labelbg, font=self.labelfont, height=1, anchor='sw') self.idLB = Listbox(self, yscrollcommand=self.y_scroll, background=self.tablebg, highlightbackground=self.tableborder, borderwidth=0, width=5, font=self.font) self.fnameLB = Listbox(self, yscrollcommand=self.y_scroll, background=self.tablebg, highlightbackground=self.tableborder, borderwidth=0, width=25, font=self.font) self.lnameLB = Listbox(self, yscrollcommand=self.y_scroll, background=self.tablebg, highlightbackground=self.tableborder, borderwidth=0, width=25, font=self.font) self.levelLB = Listbox(self, yscrollcommand=self.y_scroll, background=self.tablebg, highlightbackground=self.tableborder, borderwidth=0, width=12, font=self.font) self.sexLB = Listbox(self, yscrollcommand=self.y_scroll, background=self.tablebg, highlightbackground=self.tableborder, borderwidth=0, width=2, font=self.font) self.ageLB = Listbox(self, yscrollcommand=self.y_scroll, background=self.tablebg, highlightbackground=self.tableborder, borderwidth=0, width=3, font=self.font) #self.registerButton = Button(self, bg=BLUE, fg='white', text="REGISTER\n\nNEW", font=self.font, width=5, wraplength=1, # borderwidth=1, command=self.register_new) #self.deleteButton = Button(self, bg=BLUE, fg='white', text="DELETE\n\nSELECTED", font=self.font, width=5, wraplength=1, # borderwidth=1, command=self.delete_competitor) #self.editButton = Button(self, bg=BLUE, fg='white', text="EDIT\n\nSELECTED", font=self.font, width=5, wraplength=1, # borderwidth=1, command=self.edit_competitor) self.listboxes = (self.idLB, self.fnameLB, self.lnameLB, self.levelLB, self.sexLB, self.ageLB) for lb in self.listboxes: lb.bind('<Delete>', self.delete_competitor) lb.bind('<Double-Button-1>', self.edit_competitor) self.idLB.bind('<FocusOut>', lambda e: self.idLB.selection_clear(0, 'end')) # these binds ensure that when self.fnameLB.bind('<FocusOut>', lambda e: self.fnameLB.selection_clear(0, 'end')) # leaving the table there self.lnameLB.bind('<FocusOut>', lambda e: self.lnameLB.selection_clear(0, 'end')) # doesn't remain a selection self.levelLB.bind('<FocusOut>', lambda e: self.levelLB.selection_clear(0, 'end')) # despite not having focus self.sexLB.bind('<FocusOut>', lambda e: self.sexLB.selection_clear(0, 'end')) self.ageLB.bind('<FocusOut>', lambda e: self.ageLB.selection_clear(0, 'end')) self.scrollbar.config(command=self.set_scrollables) self.idLabel.grid(row=0, column=0, sticky='nsew') self.fnameLabel.grid(row=0, column=1, sticky='nsew') self.lnameLabel.grid(row=0, column=2, sticky='nsew') self.levelLabel.grid(row=0, column=3, sticky='nsew') self.sexLabel.grid(row=0, column=4, sticky='nsew') self.ageLabel.grid(row=0, column=5, sticky='nsew') self.idLB.grid(row=1, column=0, sticky='nsew') self.fnameLB.grid(row=1, column=1, sticky='nsew') self.lnameLB.grid(row=1, column=2, sticky='nsew') self.levelLB.grid(row=1, column=3, sticky='nsew') self.sexLB.grid(row=1, column=4, sticky='nsew') self.ageLB.grid(row=1, column=5, sticky='nsew') #self.editButton.grid(row=0, column=6, sticky='nsew') #self.registerButton.grid(row=1, column=6, sticky='nsew') #self.deleteButton.grid(row=2, column=6, sticky='nsew') self.scrollbar.grid(row=0, column=7, sticky='nsew', rowspan=2) self.rowconfigure(0, weight=1) self.rowconfigure(1, weight=100) self.columnconfigure(0, weight=5) self.columnconfigure(1, weight=25) self.columnconfigure(2, weight=25) self.columnconfigure(3, weight=12) self.columnconfigure(4, weight=2) self.columnconfigure(5, weight=3) self.competitorRegistrationWindow = None def register_new(self, *args): if not self.competitorRegistrationWindow: self.competitorRegistrationWindow = CompetitorRegistrationWindow(self, self.db) self.competitorRegistrationWindow.protocol('WM_DELETE_WINDOW', self.close_competitor_registration_window) else: print('competitor registration window already open') def close_competitor_registration_window(self): self.competitorRegistrationWindow.destroy() self.competitorRegistrationWindow = None def get_selected_competitor(self): if len(self.idLB.curselection()) > 0: row = self.idLB.curselection() elif len(self.fnameLB.curselection()) > 0: row = self.fnameLB.curselection() elif len(self.lnameLB.curselection()) > 0: row = self.lnameLB.curselection() elif len(self.levelLB.curselection()) > 0: row = self.levelLB.curselection() elif len(self.sexLB.curselection()) > 0: row = self.sexLB.curselection() elif len(self.ageLB.curselection()) > 0: row = self.ageLB.curselection() # this block searches for any selection in all the list boxes return row def delete_competitor(self, *args): try: competitor_id = self.idLB.get(self.get_selected_competitor()) except UnboundLocalError: # occurs when there is no competitor selected print('cannot delete a competitor when there is none selected') return self.db.delete_row(competitor_id) def edit_competitor(self, *args): try: id = self.get_selected_competitor() except UnboundLocalError: # occurs when there is no competitor selected print('cannot edit a competitor when there is none selected') return if id: entrytab = self.parent.parent.parent.entryTab entrytab.routeAttemptsEntryFrame.reset() enable_frame(entrytab.competitorInfoFrame) enable_frame(entrytab.routeAttemptsEntryFrame) entrytab.competitorInfoFrame.fill_competitor(self.idLB.get(id)) # fills info to entry def set_scrollables(self, *args): self.idLB.yview(*args) self.fnameLB.yview(*args) self.lnameLB.yview(*args) self.levelLB.yview(*args) self.sexLB.yview(*args) self.ageLB.yview(*args) def y_scroll(self, *args): # keeps all listboxes at same scroll position always for lb in self.listboxes: lb.yview_moveto(args[0]) self.scrollbar.set(*args) def update_table(self, pattern=None): self.clear_table() if pattern and not pattern == 'Search competitors...': rows = self.db.get_specific(pattern) else: rows = self.db.get_all() for i, row in enumerate(rows): self.idLB.insert(i, row[0]) self.fnameLB.insert(i, row[1]) self.lnameLB.insert(i, row[2]) self.levelLB.insert(i, row[3]) self.sexLB.insert(i, row[4]) self.ageLB.insert(i, row[5]) def clear_table(self): self.idLB.delete(0, 'end') self.fnameLB.delete(0, 'end') self.lnameLB.delete(0, 'end') self.levelLB.delete(0, 'end') self.sexLB.delete(0, 'end') self.ageLB.delete(0, 'end')
class GetKeysDialog(Toplevel): # Dialog title for invalid key sequence keyerror_title = 'Key Sequence Error' def __init__(self, parent, title, action, current_key_sequences, *, _htest=False, _utest=False): """ parent - parent of this dialog title - string which is the title of the popup dialog action - string, the name of the virtual event these keys will be mapped to current_key_sequences - list, a list of all key sequence lists currently mapped to virtual events, for overlap checking _htest - bool, change box location when running htest _utest - bool, do not wait when running unittest """ Toplevel.__init__(self, parent) self.withdraw() # Hide while setting geometry. self.configure(borderwidth=5) self.resizable(height=False, width=False) self.title(title) self.transient(parent) self.grab_set() self.protocol("WM_DELETE_WINDOW", self.cancel) self.parent = parent self.action = action self.current_key_sequences = current_key_sequences self.result = '' self.key_string = StringVar(self) self.key_string.set('') # Set self.modifiers, self.modifier_label. self.set_modifiers_for_platform() self.modifier_vars = [] for modifier in self.modifiers: variable = StringVar(self) variable.set('') self.modifier_vars.append(variable) self.advanced = False self.create_widgets() self.update_idletasks() self.geometry("+%d+%d" % (parent.winfo_rootx() + (parent.winfo_width() / 2 - self.winfo_reqwidth() / 2), parent.winfo_rooty() + ((parent.winfo_height() / 2 - self.winfo_reqheight() / 2) if not _htest else 150)) ) # Center dialog over parent (or below htest box). if not _utest: self.deiconify() # Geometry set, unhide. self.wait_window() def showerror(self, *args, **kwargs): # Make testing easier. Replace in #30751. messagebox.showerror(*args, **kwargs) def create_widgets(self): self.frame = frame = Frame(self, borderwidth=2, relief='sunken') frame.pack(side='top', expand=True, fill='both') frame_buttons = Frame(self) frame_buttons.pack(side='bottom', fill='x') self.button_ok = Button(frame_buttons, text='OK', width=8, command=self.ok) self.button_ok.grid(row=0, column=0, padx=5, pady=5) self.button_cancel = Button(frame_buttons, text='Cancel', width=8, command=self.cancel) self.button_cancel.grid(row=0, column=1, padx=5, pady=5) # Basic entry key sequence. self.frame_keyseq_basic = Frame(frame, name='keyseq_basic') self.frame_keyseq_basic.grid(row=0, column=0, sticky='nsew', padx=5, pady=5) basic_title = Label(self.frame_keyseq_basic, text=f"New keys for '{self.action}' :") basic_title.pack(anchor='w') basic_keys = Label(self.frame_keyseq_basic, justify='left', textvariable=self.key_string, relief='groove', borderwidth=2) basic_keys.pack(ipadx=5, ipady=5, fill='x') # Basic entry controls. self.frame_controls_basic = Frame(frame) self.frame_controls_basic.grid(row=1, column=0, sticky='nsew', padx=5) # Basic entry modifiers. self.modifier_checkbuttons = {} column = 0 for modifier, variable in zip(self.modifiers, self.modifier_vars): label = self.modifier_label.get(modifier, modifier) check = Checkbutton(self.frame_controls_basic, command=self.build_key_string, text=label, variable=variable, onvalue=modifier, offvalue='') check.grid(row=0, column=column, padx=2, sticky='w') self.modifier_checkbuttons[modifier] = check column += 1 # Basic entry help text. help_basic = Label(self.frame_controls_basic, justify='left', text="Select the desired modifier keys\n" + "above, and the final key from the\n" + "list on the right.\n\n" + "Use upper case Symbols when using\n" + "the Shift modifier. (Letters will be\n" + "converted automatically.)") help_basic.grid(row=1, column=0, columnspan=4, padx=2, sticky='w') # Basic entry key list. self.list_keys_final = Listbox(self.frame_controls_basic, width=15, height=10, selectmode='single') self.list_keys_final.insert('end', *AVAILABLE_KEYS) self.list_keys_final.bind('<ButtonRelease-1>', self.final_key_selected) self.list_keys_final.grid(row=0, column=4, rowspan=4, sticky='ns') scroll_keys_final = Scrollbar(self.frame_controls_basic, orient='vertical', command=self.list_keys_final.yview) self.list_keys_final.config(yscrollcommand=scroll_keys_final.set) scroll_keys_final.grid(row=0, column=5, rowspan=4, sticky='ns') self.button_clear = Button(self.frame_controls_basic, text='Clear Keys', command=self.clear_key_seq) self.button_clear.grid(row=2, column=0, columnspan=4) # Advanced entry key sequence. self.frame_keyseq_advanced = Frame(frame, name='keyseq_advanced') self.frame_keyseq_advanced.grid(row=0, column=0, sticky='nsew', padx=5, pady=5) advanced_title = Label( self.frame_keyseq_advanced, justify='left', text=f"Enter new binding(s) for '{self.action}' :\n" + "(These bindings will not be checked for validity!)") advanced_title.pack(anchor='w') self.advanced_keys = Entry(self.frame_keyseq_advanced, textvariable=self.key_string) self.advanced_keys.pack(fill='x') # Advanced entry help text. self.frame_help_advanced = Frame(frame) self.frame_help_advanced.grid(row=1, column=0, sticky='nsew', padx=5) help_advanced = Label( self.frame_help_advanced, justify='left', text="Key bindings are specified using Tkinter keysyms as\n" + "in these samples: <Control-f>, <Shift-F2>, <F12>,\n" "<Control-space>, <Meta-less>, <Control-Alt-Shift-X>.\n" "Upper case is used when the Shift modifier is present!\n\n" + "'Emacs style' multi-keystroke bindings are specified as\n" + "follows: <Control-x><Control-y>, where the first key\n" + "is the 'do-nothing' keybinding.\n\n" + "Multiple separate bindings for one action should be\n" + "separated by a space, eg., <Alt-v> <Meta-v>.") help_advanced.grid(row=0, column=0, sticky='nsew') # Switch between basic and advanced. self.button_level = Button(frame, command=self.toggle_level, text='<< Basic Key Binding Entry') self.button_level.grid(row=2, column=0, stick='ew', padx=5, pady=5) self.toggle_level() def set_modifiers_for_platform(self): """Determine list of names of key modifiers for this platform. The names are used to build Tk bindings -- it doesn't matter if the keyboard has these keys; it matters if Tk understands them. The order is also important: key binding equality depends on it, so config-keys.def must use the same ordering. """ if sys.platform == "darwin": self.modifiers = ['Shift', 'Control', 'Option', 'Command'] else: self.modifiers = ['Control', 'Alt', 'Shift'] self.modifier_label = {'Control': 'Ctrl'} # Short name. def toggle_level(self): "Toggle between basic and advanced keys." if self.button_level.cget('text').startswith('Advanced'): self.clear_key_seq() self.button_level.config(text='<< Basic Key Binding Entry') self.frame_keyseq_advanced.lift() self.frame_help_advanced.lift() self.advanced_keys.focus_set() self.advanced = True else: self.clear_key_seq() self.button_level.config(text='Advanced Key Binding Entry >>') self.frame_keyseq_basic.lift() self.frame_controls_basic.lift() self.advanced = False def final_key_selected(self, event=None): "Handler for clicking on key in basic settings list." self.build_key_string() def build_key_string(self): "Create formatted string of modifiers plus the key." keylist = modifiers = self.get_modifiers() final_key = self.list_keys_final.get('anchor') if final_key: final_key = translate_key(final_key, modifiers) keylist.append(final_key) self.key_string.set(f"<{'-'.join(keylist)}>") def get_modifiers(self): "Return ordered list of modifiers that have been selected." mod_list = [variable.get() for variable in self.modifier_vars] return [mod for mod in mod_list if mod] def clear_key_seq(self): "Clear modifiers and keys selection." self.list_keys_final.select_clear(0, 'end') self.list_keys_final.yview('moveto', '0.0') for variable in self.modifier_vars: variable.set('') self.key_string.set('') def ok(self, event=None): keys = self.key_string.get().strip() if not keys: self.showerror(title=self.keyerror_title, parent=self, message="No key specified.") return if (self.advanced or self.keys_ok(keys)) and self.bind_ok(keys): self.result = keys self.grab_release() self.destroy() def cancel(self, event=None): self.result = '' self.grab_release() self.destroy() def keys_ok(self, keys): """Validity check on user's 'basic' keybinding selection. Doesn't check the string produced by the advanced dialog because 'modifiers' isn't set. """ final_key = self.list_keys_final.get('anchor') modifiers = self.get_modifiers() title = self.keyerror_title key_sequences = [ key for keylist in self.current_key_sequences for key in keylist ] if not keys.endswith('>'): self.showerror(title, parent=self, message='Missing the final Key') elif (not modifiers and final_key not in FUNCTION_KEYS + MOVE_KEYS): self.showerror(title=title, parent=self, message='No modifier key(s) specified.') elif (modifiers == ['Shift']) \ and (final_key not in FUNCTION_KEYS + MOVE_KEYS + ('Tab', 'Space')): msg = 'The shift modifier by itself may not be used with'\ ' this key symbol.' self.showerror(title=title, parent=self, message=msg) elif keys in key_sequences: msg = 'This key combination is already in use.' self.showerror(title=title, parent=self, message=msg) else: return True return False def bind_ok(self, keys): "Return True if Tcl accepts the new keys else show message." try: binding = self.bind(keys, lambda: None) except TclError as err: self.showerror( title=self.keyerror_title, parent=self, message=(f'The entered key sequence is not accepted.\n\n' f'Error: {err}')) return False else: self.unbind(keys, binding) return True
class CategoricalStandings(Frame): def __init__(self, parent, db, level=None, sex=None, *args, **kwargs): Frame.__init__(self, parent, *args, **kwargs) self.parent = parent self.db = db self.titleFont = ['Arial', -0.016] self.font = ['Arial', -0.014] self.titleFont[1] = round(self.titleFont[1] * self.parent.parent.parent.parent.SCREEN_HEIGHT) self.font[1] = round(self.font[1] * self.parent.parent.parent.parent.SCREEN_HEIGHT) self.titlebg = LBLUE self.titlefg = 'black' self.selectedAttributes = {'level': level, 'sex': sex} self.titleString = StringVar() self.titleString.set('{} | {} ({})'.format(level, sex, 0)) self.scrollbar = Scrollbar(self) self.scrollbar.config(command=self.set_scrollables) self.title = Label(self, textvariable=self.titleString, bg=self.titlebg, fg=self.titlefg, font=self.titleFont) self.idLB = Listbox(self, yscrollcommand=self.y_scroll, borderwidth=0, width=3, activestyle='none', font=self.font) self.fnameLB = Listbox(self, yscrollcommand=self.y_scroll, borderwidth=0, width=15, activestyle='none', font=self.font) self.lnameLB = Listbox(self, yscrollcommand=self.y_scroll, borderwidth=0, width=15, activestyle='none', font=self.font) self.scoreLB = Listbox(self, yscrollcommand=self.y_scroll, borderwidth=0, width=10, activestyle='none', font=self.font) self.listboxes = (self.idLB, self.fnameLB, self.lnameLB, self.scoreLB) for lb in self.listboxes: lb.bind('<Delete>', self.delete_competitor) lb.bind('<Double-Button-1>', self.edit_competitor) self.title.grid(row=0, column=0, columnspan=5, sticky='nsew') self.idLB.grid(row=1, column=0, sticky='nsew') self.fnameLB.grid(row=1, column=1, sticky='nsew') self.lnameLB.grid(row=1, column=2, sticky='nsew') self.scoreLB.grid(row=1, column=3, sticky='nsew') self.scrollbar.grid(row=1, column=4, sticky='nsew') self.rowconfigure(0, weight=1) self.rowconfigure(1, weight=6) self.columnconfigure(0, weight=3) self.columnconfigure(1, weight=10) self.columnconfigure(2, weight=18) self.columnconfigure(3, weight=10) self.columnconfigure(4, weight=1) self.update_table() def set_scrollables(self, *args): self.idLB.yview(*args) self.fnameLB.yview(*args) self.lnameLB.yview(*args) self.scoreLB.yview(*args) def y_scroll(self, *args): for lb in self.listboxes: lb.yview_moveto(args[0]) self.scrollbar.set(*args) def update_table(self, pattern=None): self.clear_table() if pattern and not pattern == 'Search competitors...': rows = self.db.get_specific_rows_by_score(pattern=pattern, **self.selectedAttributes) else: rows = self.db.get_specific_rows_by_score(**self.selectedAttributes) if rows: self.titleString.set('{} | {} ({})'.format(self.selectedAttributes['level'], self.selectedAttributes['sex'], len(rows))) for i, row in enumerate(rows): self.idLB.insert(i, row[0]) self.fnameLB.insert(i, row[1]) self.lnameLB.insert(i, row[2]) self.scoreLB.insert(i, row[3]) else: self.titleString.set('{} | {} ({})'.format(self.selectedAttributes['level'], self.selectedAttributes['sex'], 0)) def get_selected_competitor(self): if len(self.idLB.curselection()) > 0: row = self.idLB.curselection() elif len(self.fnameLB.curselection()) > 0: row = self.fnameLB.curselection() elif len(self.lnameLB.curselection()) > 0: row = self.lnameLB.curselection() elif len(self.scoreLB.curselection()) > 0: row = self.scoreLB.curselection() # this block searches for any selection in all the list boxes return row def edit_competitor(self, *args): try: id = self.get_selected_competitor() except UnboundLocalError: # occurs when there is no competitor selected print('cannot edit a competitor when there is none selected') return if id: entrytab = self.parent.parent.parent.parent.entryTab entrytab.routeAttemptsEntryFrame.reset() enable_frame(entrytab.competitorInfoFrame) enable_frame(entrytab.routeAttemptsEntryFrame) entrytab.competitorInfoFrame.fill_competitor(self.idLB.get(id)) # fills info to entry def delete_competitor(self, *args): try: competitor_id = self.idLB.get(self.get_selected_competitor()) except UnboundLocalError: # occurs when there is no competitor selected print('cannot delete a competitor when there is none selected') return self.db.delete_row(competitor_id) def clear_table(self): self.idLB.delete(0, 'end') self.fnameLB.delete(0, 'end') self.lnameLB.delete(0, 'end') self.scoreLB.delete(0, 'end')
pDescription_entry.grid(row=0, column=5, sticky=W) # create list box - where database result will displayed list_box = Listbox(window, height=16, width=80, font='arial 14 bold', bg='white') list_box.grid(row='3', column='0', columnspan=14, sticky=W + E, pady=40, padx=15) # the list box widget/space needs to bind with the get_selected_row function - we need to pass in the 'ListboxSelect' \ # property list_box.bind('<<ListboxSelect>>', get_selected_row) # create the scroll back to be in included within the list box, allow yo scroll through multiple results returned scroll_bar = Scrollbar(window) scroll_bar.grid(row=1, column=8, rowspan=14, sticky=W) # configure both scrollbar and list box list_box.configure(yscrollcommand=scroll_bar.set) scroll_bar.configure(command=list_box.yview()) # create clear button clr_btn = Button(window, text='Clear', bg='white', fg='black', font='arial 16 bold', command=clear_screen) clr_btn.grid(row=4, column=0, sticky=W) # create add button add_btn = Button(window, text='Add Project', bg='white', fg='black', font='Arial 16 bold', command=add_record) add_btn.grid(row=4, column='1', sticky='W') # create edit button edit_btn = Button(window, text='Edit Project', bg='white', fg='black', font='arial 16 bold', command=update_record) edit_btn.grid(row=4, column=2, sticky=W) # create delete button del_btn = Button(window, text='Delete Project', bg='white', fg='black', font='arial 16 bold', command=del_record)
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 = 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""" #setting up frames top_frame = Frame(self.root) mid_frame = Frame(self.root) radio_frame = Frame(self.root) res_frame = Frame(self.root) msg_frame = Frame(self.root) check_frame = Frame(self.root) history_frame = Frame(self.root) btn_frame = Frame(self.root) rating_frame = Frame(self.root) 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=BOTH, expand=True) rating_frame.pack(side=TOP, fill=BOTH, expand=True) res_frame.pack(side=TOP, fill=BOTH, expand=True) check_frame.pack(side=TOP, fill=BOTH, expand=True) 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): """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: 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 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): """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): 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)
class GetKeysDialog(Toplevel): # Dialog title for invalid key sequence keyerror_title = 'Key Sequence Error' def __init__(self, parent, title, action, current_key_sequences, *, _htest=False, _utest=False): """ parent - parent of this dialog title - string which is the title of the popup dialog action - string, the name of the virtual event these keys will be mapped to current_key_sequences - list, a list of all key sequence lists currently mapped to virtual events, for overlap checking _htest - bool, change box location when running htest _utest - bool, do not wait when running unittest """ Toplevel.__init__(self, parent) self.withdraw() # Hide while setting geometry. self.configure(borderwidth=5) self.resizable(height=False, width=False) self.title(title) self.transient(parent) self.grab_set() self.protocol("WM_DELETE_WINDOW", self.cancel) self.parent = parent self.action = action self.current_key_sequences = current_key_sequences self.result = '' self.key_string = StringVar(self) self.key_string.set('') # Set self.modifiers, self.modifier_label. self.set_modifiers_for_platform() self.modifier_vars = [] for modifier in self.modifiers: variable = StringVar(self) variable.set('') self.modifier_vars.append(variable) self.advanced = False self.create_widgets() self.update_idletasks() self.geometry( "+%d+%d" % ( parent.winfo_rootx() + (parent.winfo_width()/2 - self.winfo_reqwidth()/2), parent.winfo_rooty() + ((parent.winfo_height()/2 - self.winfo_reqheight()/2) if not _htest else 150) ) ) # Center dialog over parent (or below htest box). if not _utest: self.deiconify() # Geometry set, unhide. self.wait_window() def showerror(self, *args, **kwargs): # Make testing easier. Replace in #30751. messagebox.showerror(*args, **kwargs) def create_widgets(self): self.frame = frame = Frame(self, borderwidth=2, relief='sunken') frame.pack(side='top', expand=True, fill='both') frame_buttons = Frame(self) frame_buttons.pack(side='bottom', fill='x') self.button_ok = Button(frame_buttons, text='OK', width=8, command=self.ok) self.button_ok.grid(row=0, column=0, padx=5, pady=5) self.button_cancel = Button(frame_buttons, text='Cancel', width=8, command=self.cancel) self.button_cancel.grid(row=0, column=1, padx=5, pady=5) # Basic entry key sequence. self.frame_keyseq_basic = Frame(frame, name='keyseq_basic') self.frame_keyseq_basic.grid(row=0, column=0, sticky='nsew', padx=5, pady=5) basic_title = Label(self.frame_keyseq_basic, text=f"New keys for '{self.action}' :") basic_title.pack(anchor='w') basic_keys = Label(self.frame_keyseq_basic, justify='left', textvariable=self.key_string, relief='groove', borderwidth=2) basic_keys.pack(ipadx=5, ipady=5, fill='x') # Basic entry controls. self.frame_controls_basic = Frame(frame) self.frame_controls_basic.grid(row=1, column=0, sticky='nsew', padx=5) # Basic entry modifiers. self.modifier_checkbuttons = {} column = 0 for modifier, variable in zip(self.modifiers, self.modifier_vars): label = self.modifier_label.get(modifier, modifier) check = Checkbutton(self.frame_controls_basic, command=self.build_key_string, text=label, variable=variable, onvalue=modifier, offvalue='') check.grid(row=0, column=column, padx=2, sticky='w') self.modifier_checkbuttons[modifier] = check column += 1 # Basic entry help text. help_basic = Label(self.frame_controls_basic, justify='left', text="Select the desired modifier keys\n"+ "above, and the final key from the\n"+ "list on the right.\n\n" + "Use upper case Symbols when using\n" + "the Shift modifier. (Letters will be\n" + "converted automatically.)") help_basic.grid(row=1, column=0, columnspan=4, padx=2, sticky='w') # Basic entry key list. self.list_keys_final = Listbox(self.frame_controls_basic, width=15, height=10, selectmode='single') self.list_keys_final.insert('end', *AVAILABLE_KEYS) self.list_keys_final.bind('<ButtonRelease-1>', self.final_key_selected) self.list_keys_final.grid(row=0, column=4, rowspan=4, sticky='ns') scroll_keys_final = Scrollbar(self.frame_controls_basic, orient='vertical', command=self.list_keys_final.yview) self.list_keys_final.config(yscrollcommand=scroll_keys_final.set) scroll_keys_final.grid(row=0, column=5, rowspan=4, sticky='ns') self.button_clear = Button(self.frame_controls_basic, text='Clear Keys', command=self.clear_key_seq) self.button_clear.grid(row=2, column=0, columnspan=4) # Advanced entry key sequence. self.frame_keyseq_advanced = Frame(frame, name='keyseq_advanced') self.frame_keyseq_advanced.grid(row=0, column=0, sticky='nsew', padx=5, pady=5) advanced_title = Label(self.frame_keyseq_advanced, justify='left', text=f"Enter new binding(s) for '{self.action}' :\n" + "(These bindings will not be checked for validity!)") advanced_title.pack(anchor='w') self.advanced_keys = Entry(self.frame_keyseq_advanced, textvariable=self.key_string) self.advanced_keys.pack(fill='x') # Advanced entry help text. self.frame_help_advanced = Frame(frame) self.frame_help_advanced.grid(row=1, column=0, sticky='nsew', padx=5) help_advanced = Label(self.frame_help_advanced, justify='left', text="Key bindings are specified using Tkinter keysyms as\n"+ "in these samples: <Control-f>, <Shift-F2>, <F12>,\n" "<Control-space>, <Meta-less>, <Control-Alt-Shift-X>.\n" "Upper case is used when the Shift modifier is present!\n\n" + "'Emacs style' multi-keystroke bindings are specified as\n" + "follows: <Control-x><Control-y>, where the first key\n" + "is the 'do-nothing' keybinding.\n\n" + "Multiple separate bindings for one action should be\n"+ "separated by a space, eg., <Alt-v> <Meta-v>." ) help_advanced.grid(row=0, column=0, sticky='nsew') # Switch between basic and advanced. self.button_level = Button(frame, command=self.toggle_level, text='<< Basic Key Binding Entry') self.button_level.grid(row=2, column=0, stick='ew', padx=5, pady=5) self.toggle_level() def set_modifiers_for_platform(self): """Determine list of names of key modifiers for this platform. The names are used to build Tk bindings -- it doesn't matter if the keyboard has these keys; it matters if Tk understands them. The order is also important: key binding equality depends on it, so config-keys.def must use the same ordering. """ if sys.platform == "darwin": self.modifiers = ['Shift', 'Control', 'Option', 'Command'] else: self.modifiers = ['Control', 'Alt', 'Shift'] self.modifier_label = {'Control': 'Ctrl'} # Short name. def toggle_level(self): "Toggle between basic and advanced keys." if self.button_level.cget('text').startswith('Advanced'): self.clear_key_seq() self.button_level.config(text='<< Basic Key Binding Entry') self.frame_keyseq_advanced.lift() self.frame_help_advanced.lift() self.advanced_keys.focus_set() self.advanced = True else: self.clear_key_seq() self.button_level.config(text='Advanced Key Binding Entry >>') self.frame_keyseq_basic.lift() self.frame_controls_basic.lift() self.advanced = False def final_key_selected(self, event=None): "Handler for clicking on key in basic settings list." self.build_key_string() def build_key_string(self): "Create formatted string of modifiers plus the key." keylist = modifiers = self.get_modifiers() final_key = self.list_keys_final.get('anchor') if final_key: final_key = translate_key(final_key, modifiers) keylist.append(final_key) self.key_string.set(f"<{'-'.join(keylist)}>") def get_modifiers(self): "Return ordered list of modifiers that have been selected." mod_list = [variable.get() for variable in self.modifier_vars] return [mod for mod in mod_list if mod] def clear_key_seq(self): "Clear modifiers and keys selection." self.list_keys_final.select_clear(0, 'end') self.list_keys_final.yview('moveto', '0.0') for variable in self.modifier_vars: variable.set('') self.key_string.set('') def ok(self, event=None): keys = self.key_string.get().strip() if not keys: self.showerror(title=self.keyerror_title, parent=self, message="No key specified.") return if (self.advanced or self.keys_ok(keys)) and self.bind_ok(keys): self.result = keys self.grab_release() self.destroy() def cancel(self, event=None): self.result = '' self.grab_release() self.destroy() def keys_ok(self, keys): """Validity check on user's 'basic' keybinding selection. Doesn't check the string produced by the advanced dialog because 'modifiers' isn't set. """ final_key = self.list_keys_final.get('anchor') modifiers = self.get_modifiers() title = self.keyerror_title key_sequences = [key for keylist in self.current_key_sequences for key in keylist] if not keys.endswith('>'): self.showerror(title, parent=self, message='Missing the final Key') elif (not modifiers and final_key not in FUNCTION_KEYS + MOVE_KEYS): self.showerror(title=title, parent=self, message='No modifier key(s) specified.') elif (modifiers == ['Shift']) \ and (final_key not in FUNCTION_KEYS + MOVE_KEYS + ('Tab', 'Space')): msg = 'The shift modifier by itself may not be used with'\ ' this key symbol.' self.showerror(title=title, parent=self, message=msg) elif keys in key_sequences: msg = 'This key combination is already in use.' self.showerror(title=title, parent=self, message=msg) else: return True return False def bind_ok(self, keys): "Return True if Tcl accepts the new keys else show message." try: binding = self.bind(keys, lambda: None) except TclError as err: self.showerror( title=self.keyerror_title, parent=self, message=(f'The entered key sequence is not accepted.\n\n' f'Error: {err}')) return False else: self.unbind(keys, binding) return True
class index_select(Frame): def __init__(self,controller,current_model,master,*args,**kwargs): self.controller = controller self.current_model = current_model self.filtered_list = None self.saved_selection = None from tkinter import EXTENDED,Scrollbar,Y #dibujar widget super().__init__(master, *args, **kwargs) f_st=Frame(self) Label(f_st,text="Current_index: ").pack() Label(f_st, text="Current_filter: ").pack() f_st.pack() frame_index_listbox = Frame(self) self.listbox = Listbox(frame_index_listbox, exportselection=False,selectmode=EXTENDED) self.listbox.pack(side=LEFT) scrollbar = Scrollbar(frame_index_listbox) scrollbar.pack(side=LEFT, fill=Y) frame_index_listbox.pack() # attach listbox to scrollbar self.listbox.config(yscrollcommand=scrollbar.set) scrollbar.config(command=self.listbox.yview) f=Frame(self) Label(f,text="Filtro: ").pack(side=LEFT) self.entry_w = Entry(f) self.entry_w.pack(side=LEFT) f.pack() f2=Frame(self) Button(f2, text='Filter',command=self.filter_indexs).pack(side=LEFT) Button(f2,text='Clean Filter',command=self.clean_filter).pack(side=LEFT) Button(f2, text='Export sel for gen',command=self.export_selection).pack(side=LEFT) f2.pack() f3=Frame(self) Button(self, text='<<',command=self.next_prev(-1)).pack(side=LEFT) Button(self, text='>>',command=self.next_prev(1)).pack(side=LEFT) f3.pack() self.update_model(current_model) self.listbox.select_set(0) self.listbox.event_generate("<<ListboxSelect>>") self.listbox.bind('<<ListboxSelect>>', self.selection) def filter_indexs(self): import random path_filter = self.entry_w.get() with open(path_filter,'r') as f: indexs_list_str = f.read().strip() random.seed(3) indexs_list = list(set(indexs_list_str.split('\n'))) print(len(indexs_list)) random.shuffle(indexs_list) self.filtered_list = indexs_list self.listbox.delete(0, END) for item in indexs_list: self.listbox.insert(END, item) def clean_filter(self): self.filtered_list = None self.update_model(self.current_model) self.listbox.delete(0, END) for item in sorted(self.index_list): self.listbox.insert(END, item) self.saved_selection = None def export_selection(self): sel_files_folder = os.path.join('config_files','select_files') os.makedirs(sel_files_folder,exist_ok=True) sel_list = self.listbox.curselection() index_list = [self.listbox.get(ind) for ind in sel_list] print("Exporting list for image generator. List: {0}".format(index_list)) now_s = now_string() out_selection_file = {'index_list' : index_list, 'train_result_path': self.current_model.current_config_file, 'details' : '', 'mask_file' : self.current_model.current_mask_file} sel_file_name = "{0}_{1}_{2}_selection.json".format(self.current_model.classifier_key,self.current_model.dataset_key,now_s) sel_path = os.path.join(sel_files_folder,sel_file_name) with open(sel_path,'w') as f: json.dump(out_selection_file,f) print("Select in {0}".format(sel_path)) def update_model(self, current_model): self.model = current_model self.index_list = self.model.get_index_list() self.current_index = self.model.get_current_index() self.mask_list = self.model.get_current_mask_index_list() indexs_list = self.filtered_list if self.filtered_list else sorted(self.index_list) self.listbox.delete(0, END) for item in indexs_list: self.listbox.insert(END, item) if self.saved_selection: ind,ypos = self.saved_selection self.listbox.selection_set(ind) self.listbox.yview_moveto(ypos[0]) # go back to that position def next_prev(self,x): def selection(): ind_l = self.index_list.index(self.current_index) n = len(self.index_list) n_ind_l = (ind_l+x) % n next = self.index_list[n_ind_l] self.current_index = next self.listbox.selection_clear(0, END) self.listbox.select_set(n_ind_l) self.controller.event_change_index(next) return selection def selection(self,event): w = event.widget index = int(w.curselection()[0]) value = w.get(index) print("v: {0}".format(value)) selected_index = value self.current_index = selected_index self.controller.event_change_index(selected_index) self.saved_selection = (index,self.listbox.yview()) pass
btn1.place(x=580, y=10) # btn.pack(side=RIGHT) lbl2 = Label(root, text="sheet name: ") lbl2.place(x=10, y=40) # sheet select combobox = ttk.Combobox(root, width=56, textvariable=sheetname, postcommand=getSheetName) combobox.place(x=100, y=40) # data display frame listbox = Listbox(root, selectmode='extended', height=0) listbox.yview() listbox.place(x=10, y=110) # read file btn2 = Button(root, text=" read file ", command=readFile) btn2.place(x=540, y=40) # write file btn3 = Button(root, text=" write file ", command=writeFile) btn3.place(x=540, y=70) # test list display frame # # main loop root.mainloop()
class ListFrame(Frame): def __init__(self, master, root, recursive, regex, repl, options): Frame.__init__(self, master) self._left_list = Listbox(self) self._left_list.pack(side=LEFT, fill=BOTH, expand=True) self._right_list = Listbox(self) self._right_list.pack(side=LEFT, fill=BOTH, expand=True) self._right_scroll = Scrollbar(self._right_list, orient=VERTICAL) self._right_list.config(yscrollcommand=self._right_scroll.set) self._right_scroll.config(command=self._right_list.yview) self._scrollbar = Scrollbar(self, orient=VERTICAL, command=self._scroll_scrollbar) self._scrollbar.pack(side=RIGHT, fill=Y) self._left_list.config(yscrollcommand=self._scroll_left) self._right_list.config(yscrollcommand=self._scroll_right) self._regex = regex self._repl = repl self._settings = options self._root = None self._recursive = None self._names = None self._mapping = None self._errors = None self._update_root(root, recursive) master.bind('<<RootUpdate>>', self._on_root_update) master.bind('<<RegexUpdate>>', self._on_regex_update) master.bind('<<OptionsUpdate>>', self._on_options_update) master.bind('<<Refresh>>', self._on_refresh) def _scroll_left(self, sfrom, sto): self._scrollbar.set(sfrom, sto) self._right_list.yview('moveto', sfrom) def _scroll_right(self, sfrom, sto): self._scrollbar.set(sfrom, sto) self._left_list.yview('moveto', sfrom) def _scroll_scrollbar(self, *args): self._left_list.yview(*args) self._right_list.yview(*args) def _on_root_update(self, event): self._update_root(event.widget.root, event.widget.recursive) def _on_regex_update(self, event): self._update_regex(event.widget.regex, event.widget.repl) def _on_refresh(self, event): self._update_root(self._root, self._recursive) def _on_options_update(self, event): self._settings = event.widget.options self._update_lists() def _update_regex(self, regex, repl): self._regex = regex self._repl = repl self._update_lists() def _is_type_enabled(self, ftype): if ftype is True: return self._settings.files elif ftype is False: return self._settings.dirs else: return self._settings.others def _walk(self): for root, dirs, files in os.walk(self._root): for name in files + dirs: path = os.path.join(root, name) yield os.path.relpath(path, self._root) def _entries(self): if self._recursive: return self._walk() else: return os.listdir(self._root) def _update_root(self, root, recursive): self._root = root self._recursive = recursive self._left_list.delete(0, END) self._names = [] if self._root: for name in sorted(self._entries()): path = os.path.join(self._root, name) ftype = None if os.path.isfile(path): ftype = True if os.path.isdir(path): ftype = False self._names.append((name, ftype)) self._update_lists() def _insert_name_both(self, name, color, color_right_only=False): idx = self._left_list.size() self._left_list.insert(END, name) if not color_right_only: self._left_list.itemconfig(idx, dict(fg=color)) self._right_list.insert(END, name) self._right_list.itemconfig(idx, dict(fg=color)) def _update_lists(self): self._mapping = [] self._errors = [] rev_mapping = {} self._left_list.delete(0, END) self._right_list.delete(0, END) if not self._repl: self._errors.append('Invalid replacement string') for name, ftype in self._names: enabled = self._is_type_enabled(ftype) if enabled or not self._settings.hide_wrong_type: if not enabled or not self._regex: self._insert_name_both(name, 'gray') elif self._regex and not self._regex.match(name): if not self._settings.hide_mismatches: self._insert_name_both(name, 'gray') elif not self._repl: self._insert_name_both(name, 'gray', color_right_only=True) else: idx = self._left_list.size() right_name = self._regex.sub(self._repl, name) self._left_list.insert(END, name) self._right_list.insert(END, right_name) if name != right_name: self._mapping.append((name, right_name)) right_path = os.path.join(self._root, right_name) if os.path.exists(right_path): error = 'File already exists: %s' % right_name elif right_name in rev_mapping: other_name, other_idx = rev_mapping[right_name] colliding_sources = name, other_name error = 'Name collision: %s <- %s | %s' % (right_name, *colliding_sources) self._right_list.itemconfig(other_idx, dict(fg='red')) else: error = None rev_mapping[right_name] = name, idx if error: self._errors.append(error) self._right_list.itemconfig(idx, dict(fg='red')) @property def mapping(self): if not self._errors: return self._mapping @property def errors(self): return self._errors
class GameView(BaseView): def __init__(self, userSocket, controller): BaseView.__init__(self, userSocket, controller) self.playerButtons = [] self.enemyButtons = [] self.infoLabel = Label() self.chatList = Listbox() self.fontStyle = tkFont.Font(size=12) def draw(self, root): playerFrame = Frame(root, bg='green', bd=2) enemyFrame = Frame(root, bg='green', bd=2, cursor='plus') MakeMap(playerFrame, self.playerButtons, self.userSocket, self.fontStyle, False) MakeMap(enemyFrame, self.enemyButtons, self.userSocket, self.fontStyle, True) chatFrame = Frame(root, bg='white', bd=2) self.infoLabel = Label(chatFrame, bg='grey', fg='black', text='GameInfo') chatBox = Listbox(chatFrame) self.chatList = chatBox entry = Entry(chatFrame) entry.insert(0, 'Write your text') def click(event): entry.delete(0, END) entry.bind('<Button-1>', click) sendBtn = Button(chatFrame, text='Send Message', bg='white', fg='black', cursor='hand1') sendBtn.bind('<Button-1>', MakeChatCallback(entry, self.userSocket)) entry.bind('<Return>', MakeChatCallback(entry, self.userSocket)) scrollbar = Scrollbar(chatFrame) scrollbar.pack(side=RIGHT, fill=Y) chatBox.config(yscrollcommand=scrollbar.set) scrollbar.config(command=chatBox.yview) self.infoLabel.pack(fill=X) chatBox.pack(expand=1, fill=BOTH) entry.pack(fill=X) sendBtn.pack(fill=X) playerFrame.grid(row=0, column=0, sticky='nsew') enemyFrame.grid(row=0, column=1, sticky='nsew') chatFrame.grid(row=0, column=2, sticky='nsew') def update(self, serverMessage): if serverMessage == '': self.controller.changeView('Error') data = serverMessage.split(' ', 1) print(data) if data[0] == 'msg': self.chatList.insert(END, data[1]) self.chatList.yview(END) elif data[0] == 'beside': x, y = get_coords(data[1]) self.enemyButtons[x][y].configure(bg='grey', fg='grey', cursor="plus") elif data[0] == 'enemy_beside': x, y = get_coords(data[1]) self.playerButtons[x][y].configure(bg='grey', fg='grey') elif data[0] == 'hit': x, y = get_coords(data[1]) self.enemyButtons[x][y].configure(bg='green', fg='white', text='#') elif data[0] == 'enemy_hit': x, y = get_coords(data[1]) self.playerButtons[x][y].configure(bg='red', fg='white') elif data[0] == 'win': self.controller.changeView('Result', text='You win') elif data[0] == 'lose': self.controller.changeView('Result', text='You lose') elif data[0] == 'turn': if int(data[1]) == 0: self.infoLabel.configure(text='Your turn', bg='green') else: self.infoLabel.configure(text='Enemy turn', bg='red') elif data[0] == 'set_ship': x, y = get_coords(data[1]) self.playerButtons[x][y].configure(bg='yellow', fg='red', text='#')
class Searcher(Frame): """ Keyword Searcher This is a very simple python program, which is designed for finding specified key-word in files. Just for fun! """ def __init__(self, master=None, cnf={}, **kwargs): super(Searcher, self).__init__(master, cnf, **kwargs) self._root_path_var = StringVar() self._keyword_var = StringVar(self) self._listbox = None self._result_queue = None self.pack(fill=BOTH, expand=YES, padx=5, pady=5) self.make_widgets() self._consumer() # config for main window self.master.title('Keyword Searcher') def make_widgets(self): frm1 = Frame(self) frm1.pack(side=TOP, fill=X) Entry(frm1, textvariable=self._root_path_var, font=DEFAULT_FONT).pack(side=LEFT, fill=X, expand=YES) Button(frm1, text='Add directory', font=DEFAULT_FONT, command=lambda: self._root_path_var.set(askdirectory(title='Add directory'))).pack(side=RIGHT) frm2 = Frame(self) frm2.pack(side=TOP, fill=X) keyword_ent = Entry(frm2, textvariable=self._keyword_var, font=DEFAULT_FONT) keyword_ent.pack(side=LEFT, fill=X, expand=YES) Button(frm2, text='Find', font=DEFAULT_FONT, command=self.find).pack(side=RIGHT) vs = Scrollbar(self) hs = Scrollbar(self) self._listbox = Listbox(self) vs.pack(side=RIGHT, fill=Y) vs.config(command=self._listbox.yview) hs.pack(side=BOTTOM, fill=X) hs.config(command=self._listbox.xview, orient='horizontal') self._listbox.config(yscrollcommand=vs.set, xscrollcommand=hs.set, font=DEFAULT_FONT) self._listbox.pack(fill=BOTH, expand=YES) self._listbox.bind('<Double-1>', self._navigate_to) def find(self): self._result_queue = queue.Queue() self._listbox.delete('0', 'end') Thread(target=self._find, args=(self._root_path_var.get(), self._keyword_var.get()), daemon=True).start() def _find(self, path, keyword): if not os.path.exists(path): return None for this_dir, sub_dirs, files in os.walk(path): for file in files: file_type = guess_type(file)[0] if file_type and 'text' in file_type: fp = os.path.join(this_dir, file) self._result_queue.put(fp) if keyword in open(fp).read() else None def _consumer(self): if self._result_queue: try: fp = self._result_queue.get(block=False) except queue.Empty: pass else: self._listbox.insert('end', fp) # auto scroll. self._listbox.yview('end') self.after(100, self._consumer) def _navigate_to(self, event): """ Only works on Ubuntu platform currently. Double click to navigate to selected path. It's a very convenient function. :return: None """ print(event) # get active item from listbox path = self._listbox.get('active') print(path) # open nautilus with param path, before that, check your platform. if 'ubuntu' in (os.popen('uname -a').read()).lower(): os.system('/usr/bin/nautilus {}'.format(path)) else: pass
class ContactsPage(Frame): """ Contacts Page: Contains the list of currently added contacts === Public Attributes === master: The frame containing all information on this page controller: Reference to the Controller Class page_name: String containing a name for this page; used for setting the tabs in the containing notebook contacts_list: Dictionary of contacts, each contact is a Contact class instance, each key is the name of the contact current_contact: Contains the contact that was selected the last time we clicked on show info. scroll_bar: Scroll bar that controls what is viewable in the contacts list; won't scroll if nothing is in the list, or everything is already shown. contacts_field: Area where contacts are shown; 10 at a time letters_field: Listbox that shows each letter of the alphabet to help the user find contact they're looking for show_info: Button that updates the info_field with the information of the currently selected contact wheel_spin: WheelSpinner object for the Show Contact Button. delete: Button that deletes the selected contact info_field: Listbox that contains the information of the currently selected contact info_scroll: Scrollbar that controls what is viewable in the info_field; won't scroll if nothing is in the list, or everything is already shown self.load: Button to load contacts self.save: Button to save contacts === Methods === create: Initializes objects & places them on the page insert_contact: Adds a contact's name to the end of the contacts field show_contact_info: Shows the information of the selected contact in the info listbox delete_contact: Deletes the selected contact & reloads the contacts Listbox clear_fields: Clears both fields on the contacts page load_contacts: Loads contacts in from a file save_contacts: Saves contacts as a file yview: Adjusts the view of contacts_field & letters_field at the same time on_mouse_wheel: Adjusts the view of contacts_field and letters_field at the same time, for the mouse wheel """ def __init__(self, master, controller, **kw): super().__init__(master, **kw) self.master = master self.controller = controller self.page_name = "View Contacts" # Initialize object names self.contacts_list = {} self.current_contact = None self.alphabetical_order = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'] self.scroll_bar = None self.contacts_field = None self.letters_field = None self.show_info = None self.wheel_spin = None self.delete = None self.info_field = None self.info_scroll = None self.bind("<<Finish Spinning Wheel>>", self.show_winning_info) self.bind("<Visibility>", self.__on_visibility) self.load = None self.save = None self.create() def create(self) -> None: self.info_scroll = Scrollbar(self, orient=VERTICAL) self.info_field = Listbox( self, yscrollcommand=self.info_scroll.set ) self.delete = Button(self, text="Delete", command=lambda: self.delete_contact()) self.delete.grid(row=2, column=3, columnspan=3, sticky=N + S + E + W) self.show_info = Button(self, text="Show Info", command=lambda: self.show_contact_info()) self.show_info.grid(row=2, column=0, columnspan=3, sticky=N + S + E + W) wheel_spin_options = ['Name', 'Home Phone Numbers', 'Work Phone Numbers', 'Personal Phone Numbers', 'Emails', 'Home Addresses', 'Notes'] self.wheel_spin = WheelSpinner(self, wheel_spin_options, width=50, height=200, radius=60) self.wheel_spin.grid(row=3, column=0, columnspan=5) self.scroll_bar = Scrollbar(self) self.contacts_field = Listbox( self, yscrollcommand=self.scroll_bar.set, selectmode=SINGLE, exportselection=0 ) self.letters_field = Listbox( self, width=2, selectmode=NONE, exportselection=0 ) self.letters_field.bind('<<ListboxSelect>>', self.scroll_to_letter) self.contacts_field.grid(row=1, column=0, columnspan=5, sticky=N + S + E + W) self.letters_field.grid(row=1, column=4, sticky=N + S + E + W) self.scroll_bar.grid(row=1, column=5, sticky=N + S + E + W) self.scroll_bar.config(command=self.yview) self.contacts_field.bind("<MouseWheel>", self.on_mouse_wheel) self.letters_field.bind("<MouseWheel>", self.on_letter_mouse_wheel) self.save = Button( self, text="Save Contacts", command=lambda: self.save_contacts() ) self.save.grid(row=0, column=3, columnspan=4, sticky=N + S + E + W) self.load = Button( self, text="Load Contacts", command=lambda: self.load_contacts() ) self.load.grid(row=0, column=0, columnspan=3, sticky=N + S + E + W) for i in range(3): self.grid_rowconfigure(i, weight=1) for i in range(4): self.grid_columnconfigure(i, weight=1) def scroll_to_letter(self, event): id = 0 for contact in self.order_contact(): if contact[0] == self.letters_field.get(self.letters_field.curselection()[0]): self.contacts_field.see(id) self.contacts_field.selection_clear(0, END) self.contacts_field.selection_set(id) self.letters_field.selection_clear(0, END) return id += 1 self.letters_field.selection_clear(0, END) def on_mouse_wheel(self, event) -> str: self.contacts_field.yview("scroll", int(-event.delta / 80), "units") return "break" def on_letter_mouse_wheel(self, event) -> str: self.letters_field.yview("scroll", int(-event.delta / 80), "units") return "break" def yview(self, *args) -> None: self.contacts_field.yview(*args) self.letters_field.yview(*args) def delete_contact(self) -> None: name = self.contacts_field.get(self.contacts_field.curselection()[0]) del self.contacts_list[name] self.clear_fields() for contact in sorted(self.contacts_list): self.insert_contact(contact) def clear_fields(self) -> None: for field in [self.contacts_field, self.info_field, self.letters_field]: field.delete(0, END) def refresh_fields(self) -> None: self.clear_fields() for contact in self.order_contact(): self.contacts_field.insert(END, contact) for letter in self.alphabetical_order: self.letters_field.insert(END, letter.upper()) def load_contacts(self) -> None: self.randomize_alphabetical_order() with open("project/contacts_pickle", 'rb') as infile: self.contacts_list = pickle.load(infile) self.refresh_fields() def save_contacts(self) -> None: with open("project/contacts_pickle", 'wb') as outfile: pickle.dump(self.contacts_list, outfile) def insert_contact(self, contact) -> None: self.contacts_field.insert(END, contact) def show_contact_info(self) -> None: """ This method shows the spinning wheel if a contact is selected and if the wheel isn't already rotating It is called on the Show Contact Info button. :return: None """ if len(self.contacts_field.curselection()) == 0 or self.wheel_spin.is_rotating: return name = self.contacts_field.get(self.contacts_field.curselection()[0]) self.current_contact = self.contacts_list[name] self.wheel_spin.draw() def show_winning_info(self, event) -> None: """ This method is called when the event <<Finish Spinning Wheel>> is invoked. It displays the current contact information that was selected by the spinning wheel. :return: None """ self.randomize_alphabetical_order() self.refresh_fields() winner = self.wheel_spin.winner label = self.wheel_spin.display_label text0 = self.current_contact.name + "'s " + winner.lower() + ':\n' text1 = '' if winner == 'Name': text1 = self.current_contact.name elif winner == 'Home Phone Numbers': for elem in self.current_contact.phone_numbers["Home"]: text1 = text1 + elem + ", " elif winner == 'Work Phone Numbers': for elem in self.current_contact.phone_numbers["Work"]: text1 = text1 + elem + ', ' elif winner == 'Personal Phone Numbers': for elem in self.current_contact.phone_numbers["Personal"]: text1 = text1 + elem + ', ' elif winner == 'Emails': for elem in self.current_contact.email_addresses: text1 = text1 + elem + ', ' elif winner == 'Home Addresses': for elem in self.current_contact.addresses: text1 = text1 + elem + ', ' elif winner == 'Notes': for elem in self.current_contact.notes: text1 = text1 + elem + ', ' label['text'] = text0 + text1 def randomize_alphabetical_order(self): random.shuffle(self.alphabetical_order) def order_contact(self) -> list: """ This function takes all the contacts and order them in the order stored in self.alphabetical order :return: The ordered list """ i = 0 order = self.alphabetical_order contacts = list(self.contacts_list) ordered_list = [] # We loop until we have all the contact ordered. while i < len(self.contacts_list): current_next_contact = None for contact in contacts: if current_next_contact is None: current_next_contact = contact continue # If the first letter is higher in the order than the current next contact, we # change the contact. if order.index(contact[0].lower()) < order.index(current_next_contact[0].lower()): current_next_contact = contact continue # If the first character is the same, we loop through the other character to find # which on should be # added first. if order.index(contact[0].lower()) == order.index(current_next_contact[0].lower()): for current_character in range(1, min(len(contact), len(current_next_contact))): if order.index(contact[current_character].lower()) < \ order.index(current_next_contact[current_character].lower()): current_next_contact = contact break if order.index(contact[current_character].lower()) > \ order.index(current_next_contact[current_character].lower()): break # we append the contact to the list and remove it from the remaining contact to order. contacts.remove(current_next_contact) ordered_list.append(current_next_contact) i += 1 return ordered_list def __on_visibility(self, event) -> None: """ This function is called when the user click on the contact tab. It randomizes the alphabetical order :param event: :return: None """ self.randomize_alphabetical_order() self.refresh_fields()
class consoleScreen(Screen): def __init__(self, runner): self.runner = runner self.messages = {} Screen.destroy() Screen.reinit() super().__init__() Screen.title("NaOH: PocketMine-MP Console") # GUI initialization fstframe = Frame(Screen.root) fstframe.grid(row=0, rowspan=1, columnspan=8) sndframe = Frame(Screen.root) sndframe.grid(row=0, rowspan=1, column=8, columnspan=2) self.scrollbar = Scrollbar(fstframe) self.listbox = Listbox(fstframe, yscrollcommand=self.scrollbar.set, width=120, height=25) self.listbox.grid(row=0, column=0, rowspan=1, columnspan=7, sticky='nswe') self.scrollbar.config(command=self.listbox.yview) self.scrollbar.grid(row=0, column=7, rowspan=1, sticky='nse') self.scrolllock = False Button(fstframe, text='나가기 (주의: 강제 종료됩니다)', command=self.runner.killAll).grid(row=1, column=0, sticky='nwse') self.slbutton = Button(fstframe, text='ScrollLock Off', command=self.togglesl) self.slbutton.grid(row=1, column=1, sticky='new') Label(fstframe, text='명령어: /', justify='right').grid(row=1, column=2) self.cmdentry = Entry(fstframe) self.cmdentry.bind('<Return>', self.put_cmd) self.cmdentry.grid(row=1, column=3, columnspan=5, sticky='nwe') fstframe.rowconfigure(1, weight=1) fstframe.columnconfigure(3, weight=1) fstframe.columnconfigure(4, weight=20) sndframe.rowconfigure(0, weight=1) Button(sndframe, text='서버 상태', command=lambda: statusScreen(self)).grid(row=0, sticky='n') Button(sndframe, text='설정 편집', command=lambda: propertiesScreen(self.runner.workdir + sep + 'server.properties')).grid(row=1, sticky='n') Button(sndframe, text='덤프 삭제', command=self.removeDumps).grid(row=2, sticky='n') self.cmdentry.focus() Screen.root.focus_force() # GUI initialization done self.thread = threading.Thread(target=lambda: asyncStream(self)).start() Screen.root.protocol("WM_DELETE_WINDOW", self.runner.killAll) Screen.root.mainloop() try: Screen.root.destroy() except: self.runner.killAll() def put_cmd(self, event): # self.runner.pipe.communicate(('/' + self.cmdentry.get() + '\n').encode(), timeout=0) write(self.runner.pipe.stdin.fileno(), (self.cmdentry.get() + '\n').encode('utf-8')) self.cmdentry.delete(0, 'end') def togglesl(self): if self.scrolllock: self.scrolllock = False self.slbutton['text'] = 'ScrollLock Off' else: self.scrolllock = True self.slbutton['text'] = 'ScrollLock On' def removeDumps(self): files = [f for f in listdir(self.runner.workdir) if path.isfile(path.join(self.runner.workdir, f)) and f[0:9] =='CrashDump'] for f in files: unlink(path.join(self.runner.workdir, f)) self.listbox.insert('end', '') if len(files) > 0: self.listbox.insert('end', '** %d개의 크래시 덤프들이 삭제되었습니다' % len(files)) else: self.listbox.insert('end', '** 삭제할 크래시 덤프가 없습니다.') self.listbox.insert('end', '') if not self.scrolllock: self.listbox.yview('end')