class SelectMultiple(TwoCells): def __init__(self, parent, text, values, **kwargs): super().__init__(parent, **kwargs) self.label = Label(self.frame, text=text) self.label.grid(column=0, row=0, padx=5, pady=5, sticky=W) self.selected_options = StringVar(self.frame) self.selected_options.set(values) self.listbox = Listbox(self.frame, listvariable=self.selected_options, selectmode=MULTIPLE) self.listbox.grid(column=1, row=0, padx=5, pady=5, sticky=E) def disable(self): self.listbox.configure(state=DISABLED) return self def enable(self): self.listbox.configure(state=NORMAL) return self def set(self, values): if values: self.enable() else: self.disable() self.listbox.selection_clear(0, self.listbox.size()) for value in values: for index in range(self.listbox.size()): if value == self.listbox.get(index): self.listbox.selection_set(index) self.listbox.event_generate("<<ListboxSelect>>") def get(self): return [self.listbox.get(i) for i in self.listbox.curselection()]
def select_signals(self, listbox: tkk.Listbox, filter_window: tkk.Toplevel): # global selections self.selections = [*listbox.get(0, listbox.size())] listbox.grab_release() filter_window.destroy() print(f"selections: {self.selections}")
class liste_mots: """Définit un cadre contenant une liste de mot avec un ascenseur""" def __init__(self,parent,titre,compare): police_mots=font.Font(parent, size=12, family='Courier') self.cadre = LabelFrame(parent, borderwidth=2, relief=GROOVE,text=titre) self.ascenseur=Scrollbar(self.cadre,orient=VERTICAL) self.mots=Listbox(self.cadre, font=police_mots, width=LARGEUR_LISTE_MOTS,yscrollcommand = self.ascenseur.set ) self.mots.bind('<<ListboxSelect>>', self.selection) self.mots.grid(column=0,row=0) self.ascenseur.grid(column=1,row=0,sticky=S+N) self.ascenseur.config( command = self.mots.yview ) self.liste_mots=[] self.compare=compare def ajoute_mot_couleur(self,mot,couleur): fin=self.mots.size() self.mots.insert(fin,mot) self.mots.itemconfig(fin,fg=couleur) self.liste_mots.append(mot) def selection(self,e): mot=self.liste_mots[self.mots.curselection()[0]] self.compare.modifie_mot1(mot) self.parent.infos.delete("0.0",END) valeur=self.parent.dict_moyennes[mot] texte="Selon ce modèle, le mot '"+mot+"' a été lu en moyenne "+str(round(valeur,NB_DECIMALES))+ "fois par un élève de ce profil au cours de l'année écoulée." self.parent.infos.insert(END,texte)
class MainWindow: def __init__(self, vehicles): self.vehicles = vehicles self.root = Tk() self.root.title("GUI на Python") self.root.geometry("300x250") self.file_menu = Menu() self.file_menu.add_command(label="New", command=self.new_win) self.file_menu.add_command(label="Save", command=self.show_list) self.file_menu.add_command(label="Open", command=self.open_file) self.file_menu.add_separator() self.file_menu.add_command(label="Exit") self.main_menu = Menu() self.main_menu.add_cascade(label="File", menu=self.file_menu) self.main_menu.add_cascade(label="Edit") self.main_menu.add_cascade(label="View") self.languages_listbox = Listbox() self.languages_listbox.pack(expand=True, fill=BOTH) self.root.config(menu=self.main_menu) self.root.mainloop() def get_list_text_from_file(self, filename): arr_text = [] with open(filename, "r") as file_data: for line in file_data: arr_text.append(line) return arr_text def open_file(self): filename = filedialog.askopenfilename() values = self.get_list_text_from_file(filename) for value in values: self.languages_listbox.insert(END, value) def new_win(self): n_win = MainWindow(vehicles) def show_list(self): self.languages_listbox.delete(0, self.languages_listbox.size()) for value in vehicles: self.languages_listbox.insert(END, value)
class liste_mots: """Définit un cadre contenant une liste de mot avec un ascenseur""" def __init__(self, parent, titre): police_mots = font.Font(parent, size=12, family='Courier') self.cadre = LabelFrame(parent, borderwidth=2, relief=GROOVE, text=titre) self.ascenseur = Scrollbar(self.cadre, orient=VERTICAL) self.mots = Listbox(self.cadre, font=police_mots, width=LARGEUR_LISTE_MOTS, yscrollcommand=self.ascenseur.set) self.mots.grid(column=0, row=0) self.ascenseur.grid(column=1, row=0, sticky=S + N) self.ascenseur.config(command=self.mots.yview) def ajoute_mot_couleur(self, mot, couleur): fin = self.mots.size() self.mots.insert(fin, mot) self.mots.itemconfig(fin, fg=couleur)
class InputDevice(object): def __init__(self): # root is the Tkinter root widget self.root = Tk() self.root.title("Input Device Utility") # self.root.configure(background='grey') self.root.resizable(False, False) # define response to main window closing self.root.protocol("WM_DELETE_WINDOW", self.app_exit) self.my_device = '' self.my_device_display = StringVar() self.device_list = [] self.matches = 0 # overall display root_frame = Frame(self.root) root_frame.pack(side=LEFT) devices_frame = Frame(root_frame, padx=5, pady=10) devices_frame.pack(side=LEFT) devices_label = Label(devices_frame, text="Devices in dev/input") devices_label.pack(side=TOP) devices_list_frame = Frame(devices_frame, padx=5, pady=10) devices_list_frame.pack(side=TOP) selected_device_title = Label(devices_frame, text='Selected device') selected_device_title.pack(side=TOP) self.selected_device_var = StringVar() selected_device = Label(devices_frame, textvariable=self.selected_device_var, fg="red") selected_device.pack(side=TOP) events_frame = Frame(root_frame, padx=5, pady=10) events_frame.pack(side=LEFT) events_title = Label(events_frame, text='Received Events') events_title.pack(side=TOP) events_list_frame = Frame(events_frame, padx=5, pady=10) events_list_frame.pack(side=TOP) # list of devices scrollbar = Scrollbar(devices_list_frame, orient=VERTICAL) self.devices_display = Listbox(devices_list_frame, selectmode=SINGLE, height=20, width=60, bg="white", activestyle=NONE, fg="black", yscrollcommand=scrollbar.set) scrollbar.config(command=self.devices_display.yview) scrollbar.pack(side=RIGHT, fill=Y) self.devices_display.pack(side=LEFT, fill=BOTH, expand=1) self.devices_display.bind("<ButtonRelease-1>", self.e_select_device) # events display scrollbar = Scrollbar(events_list_frame, orient=VERTICAL) self.events_display = Text(events_list_frame, width=40, height=20, wrap='word', font="arial 11", padx=5, yscrollcommand=scrollbar.set) scrollbar.config(command=self.events_display.yview) scrollbar.pack(side=RIGHT, fill=Y) self.events_display.pack(side=LEFT, fill=BOTH, expand=1) self.events_display.config(state=NORMAL) self.events_display.delete(1.0, END) self.events_display.config(state=DISABLED) self.selected_device_index = -1 self.matches = 0 self.get_all_devices() self.refresh_devices_display() self.root.after(10, self.event_loop) # and enter Tkinter event loop self.root.mainloop() # *************************************** # INIT AND EXIT # *************************************** def app_exit(self): self.root.destroy() exit() def event_loop(self): if self.matches > 0: self.get_events() self.root.after(10, self.event_loop) def refresh_devices_display(self): self.devices_display.delete(0, self.devices_display.size()) for device in self.all_devices: self.devices_display.insert(END, device[0] + ' ' + device[1]) if self.selected_device_index >= 0: self.devices_display.itemconfig(self.selected_device_index, fg='red') self.devices_display.see(self.selected_device_index) def e_select_device(self, event): self.selected_device_index = -1 if len(self.all_devices) > 0: self.selected_device_index = int(event.widget.curselection()[0]) selected_device = self.all_devices[self.selected_device_index] self.selected_device_name = selected_device[0] self.selected_device_var.set(self.selected_device_name) self.get_matching_devices() self.refresh_devices_display() def get_all_devices(self): self.all_devices = [] devices = [evdev.InputDevice(fn) for fn in evdev.list_devices()] for device in devices: self.all_devices.append([device.name, device.path]) def get_matching_devices(self): self.matches = 0 self.matching_devices = [] devices = [evdev.InputDevice(fn) for fn in evdev.list_devices()] for device in devices: if self.selected_device_name in device.name: device_ref = evdev.InputDevice(device.path) self.matching_devices.append(device_ref) self.matches += 1 def get_events(self): r, w, x = select(self.matching_devices, [], [], 0) if r == []: return for event in r[0].read(): if event.type == evdev.ecodes.EV_KEY: key_event = evdev.categorize(event) if key_event.keystate == 1: key_text = 'Down' else: key_text = 'Up' # print key_event.keycode,key_text if type(key_event.keycode) is list: code_text = ', '.join(key_event.keycode) else: code_text = key_event.keycode self.events_display.config(state=NORMAL) self.events_display.insert(END, '\n' + code_text + ' ' + key_text) self.events_display.config(state=DISABLED) self.events_display.see(END)
class S3Zilla: def __init__(self, master): error_msg = "Ensure S3 is configured on your machine:" try: self.s3 = boto3.resource('s3') except Exception as e: print("%s: %s" % (error_msg, e)) exit(1) try: self.s3c = boto3.client('s3') except Exception as err: print("%s: %s" % (error_msg, err)) exit(1) self.colors = { 'light-grey': '#D9D9D9', 'blue': '#2B547E', 'black': '#000000', 'red': '#FF3346', 'grey': '#262626', 'cyan': '#80DFFF' } self.master = master self.master.title("Amazon S3 File Transfer Client") self.master.configure(bg=self.colors['grey']) self.master.geometry("885x645") menu = Menu(self.master) menu.config(background=self.colors['grey'], fg=self.colors['light-grey']) self.master.config(menu=menu) file = Menu(menu) file.add_command(label="Exit", command=self.quit) menu.add_cascade(label="File", menu=file) refresh = Menu(menu) refresh.add_command(label="Local", command=self.refresh_local) refresh.add_command(label="S3", command=self.refresh_s3) menu.add_cascade(label="Refresh", menu=refresh) self.dir, self.drp_sel, self.bucket_name = '', '', '' self.folder_path = StringVar() self.dropdown = StringVar() self.dropdown_data = self.populate_dropdown() if not self.dropdown_data: self.dropdown_data = ['none available'] self.deleted = False self.local_sel, self.s3_sel = ([] for i in range(2)) self.title_label = Label(master, fg=self.colors['light-grey'], bg=self.colors['grey'], font="Helvetica 10 bold", width=120) self.local_label = Label(master, fg=self.colors['light-grey'], bg=self.colors['grey'], text="LOCAL FILE SYSTEM", font="Helvetica 10 bold underline", width=60) self.s3_label = Label(master, fg=self.colors['light-grey'], bg=self.colors['grey'], text="AMAZON S3", font="Helvetica 10 bold underline", underline=True, width=60) self.dropdown_box = OptionMenu(master, self.dropdown, *self.dropdown_data, command=self.set_drop_val) self.dropdown_box.configure(fg=self.colors['light-grey'], bg=self.colors['blue'], width=27, highlightbackground=self.colors['black'], highlightthickness=2) self.browse_button = Button(master, fg=self.colors['light-grey'], bg=self.colors['blue'], text="Browse", width=30, highlightbackground=self.colors['black'], highlightthickness=2, command=self.load_dir) self.browse_label = Label(master, fg=self.colors['light-grey'], bg=self.colors['grey'], text="No directory selected", width=37, font="Helvetica 10") self.bucket_label = Label(master, fg=self.colors['light-grey'], bg=self.colors['grey'], text="No bucket selected", width=37, font="Helvetica 10") self.refresh_btn_local = Button( master, fg=self.colors['light-grey'], bg=self.colors['blue'], text="REFRESH", width=30, highlightbackground=self.colors['black'], highlightthickness=2, command=self.refresh_local) self.refresh_btn_s3 = Button(master, fg=self.colors['light-grey'], bg=self.colors['blue'], text="REFRESH", width=30, highlightbackground=self.colors['black'], highlightthickness=2, command=self.refresh_s3) self.explorer_label_local = Label(master, fg=self.colors['light-grey'], bg=self.colors['blue'], width=30, text="Local File System: ") self.explorer_label_s3 = Label(master, fg=self.colors['light-grey'], bg=self.colors['black'], width=30, text="S3 File System") self.ex_loc = Listbox(master, fg=self.colors['cyan'], bg=self.colors['black'], width=49, height=18, highlightcolor=self.colors['black'], selectmode="multiple") self.ex_s3 = Listbox(master, fg=self.colors['cyan'], bg=self.colors['black'], width=49, height=18, highlightcolor=self.colors['black'], selectmode="multiple") self.upload_button = Button(master, fg=self.colors['light-grey'], bg=self.colors['blue'], text="Upload ->", width=20, highlightbackground=self.colors['black'], highlightthickness=2, command=self.upload) self.download_button = Button(master, fg=self.colors['light-grey'], bg=self.colors['blue'], text="<- Download", width=20, highlightbackground=self.colors['black'], highlightthickness=2, command=self.download) self.delete_local = Button(master, fg=self.colors['light-grey'], bg=self.colors['red'], text="DELETE", width=20, highlightbackground=self.colors['black'], command=self.delete_local_records) self.delete_s3 = Button(master, fg=self.colors['light-grey'], bg=self.colors['red'], text="DELETE", width=20, highlightbackground=self.colors['black'], command=self.delete_s3_records) self.found_label_local = Label(master, fg=self.colors['light-grey'], bg=self.colors['grey'], text="found local", width=54) self.found_label_s3 = Label(master, fg=self.colors['light-grey'], bg=self.colors['grey'], text="found s3", width=54) self.status_label = Label(master, fg=self.colors['light-grey'], bg=self.colors['grey'], text="Hello " + getuser(), width=54) self.create_bucket_label = Label( master, fg=self.colors['light-grey'], bg=self.colors['grey'], text="New Bucket:", ) self.create_bucket_name = Text(master, fg=self.colors['cyan'], bg=self.colors['black'], width=25, height=1) self.create_bucket_button = Button( master, fg=self.colors['light-grey'], bg=self.colors['blue'], text="Create", width=5, highlightbackground=self.colors['black'], highlightthickness=2, command=self.create_bucket) # ####### begin grid placement ####### # self.title_label.grid(row=0, sticky=E + W, padx=20, pady=5) self.local_label.grid(row=0, sticky=W, padx=8, pady=5) self.s3_label.grid(row=0, sticky=E, padx=0, pady=5) self.browse_button.grid(row=1, sticky=W, padx=86, pady=10) self.dropdown_box.grid(row=1, sticky=E, padx=86, pady=5) self.browse_label.grid(row=2, sticky=W, padx=86, pady=5) self.bucket_label.grid(row=2, sticky=E, padx=86, pady=5) self.refresh_btn_local.grid(row=3, sticky=W, padx=86, pady=10) self.refresh_btn_s3.grid(row=3, sticky=E, padx=86, pady=10) self.explorer_label_local.grid(row=4, sticky=W, padx=20) self.explorer_label_s3.grid(row=4, sticky=E, padx=20) self.ex_loc.grid(row=4, sticky=W, padx=20) self.ex_s3.grid(row=4, sticky=E, padx=20) self.upload_button.grid(row=5, sticky=W, padx=224, pady=0) self.download_button.grid(row=5, sticky=E, padx=224, pady=0) self.delete_local.grid(row=5, sticky=W, padx=20, pady=0) self.delete_s3.grid(row=5, sticky=E, padx=20, pady=0) self.found_label_local.grid(row=6, sticky=W, padx=0, pady=20) self.found_label_s3.grid(row=6, sticky=E, padx=0, pady=20) self.status_label.grid(row=7, sticky=W, padx=0, pady=20) self.create_bucket_label.grid(row=7, sticky=E, padx=330, pady=0) self.create_bucket_name.grid(row=7, sticky=E, padx=100, pady=0) self.create_bucket_button.grid(row=7, sticky=E, padx=20, pady=0) n1 = "%s files found" % str(self.ex_loc.size()) self.set_found_local_label(n1) n2 = "%s files found" % str(self.ex_s3.size()) self.set_found_s3_label(n2) def quit(self): exit() def get_local_sel(self): return [self.ex_loc.get(i) for i in self.ex_loc.curselection()] def get_s3_sel(self): return [self.ex_s3.get(i) for i in self.ex_s3.curselection()] def set_drop_val(self, selection): self.drp_sel = selection def delete_local_records(self): files = self.get_local_sel() if not files: message = "Please select a file(s) to delete" self.set_status_label(message) else: self.del_local(files) def del_local(self, files_remaining): if len(files_remaining) > 0: f = files_remaining.pop(0) if not isdir(self.dir + "/" + f): try: remove("%s/%s" % (self.dir, f)) except Exception as err: self.set_status_label("%s" % err) self.status_label.update_idletasks() self.del_local(files_remaining) else: try: rmtree("%s/%s" % (self.dir, f)) except Exception as err: self.set_status_label("%s" % err) self.status_label.update_idletasks() self.del_local(files_remaining) self.deleted = True self.refresh_local() def delete_s3_records(self): removal = '' if not self.drp_sel: m = "Please select a bucket..." self.set_status_label(m) else: removal = self.get_s3_sel() if not removal: m = "Please select at least 1 object to delete" self.set_status_label(m) else: bucket = self.s3.Bucket(self.drp_sel) for rm in removal: for k in bucket.objects.all(): if k.key != rm: continue k.delete() break self.deleted = True self.refresh_s3() def load_dir(self): self.dir = askdirectory() self.set_local_browse_label(self.dir) def refresh_local(self): if not self.dir: m = "Use the browse button to select a directory" self.set_status_label(m) else: self.set_local_browse_label(self.dir) self.ex_loc.delete(0, 'end') x = self.dir + "/" d = [ f if not isdir(x + f) else f + '/' for f in sorted(listdir(x)) ] self.ex_loc.insert('end', *d) if not self.deleted: m = "Hello %s" % getuser() else: m = "FINISHED DELETING" self.deleted = False self.set_status_label(m) n = "%s files found" % str(self.ex_loc.size()) self.set_found_local_label(n) def refresh_s3(self): if 'none available' in self.dropdown_data: m = "Please create at least one S3 bucket" self.set_status_label(m) elif not self.drp_sel: m = "Please select a bucket from the drop-down list" self.set_status_label(m) else: self.ex_s3.delete(0, 'end') self.ex_s3.insert('end', *self.get_bucket_contents()) self.set_status_label("Hello %s" % getuser()) self.set_s3_bucket_label(self.drp_sel) n = "%s files found" % str(self.ex_s3.size()) self.set_found_s3_label(n) self.found_label_s3.update_idletasks() if not self.deleted: m = "Hello %s" % getuser() else: m = "FINISHED DELETING" self.deleted = False self.set_status_label(m) def finished(self, incoming_message): d = "FINISHED %s" % incoming_message for letter in enumerate(d): self.set_status_label(d[0:letter[0] + 1]) self.status_label.update_idletasks() sleep(.1) def upload(self): if not self.drp_sel or not self.dir: m = "Ensure a local path and S3 bucket are selected" self.set_status_label(m) elif not self.get_local_sel(): m = "Ensure files are selected to upload" self.set_status_label(m) else: for selection in self.get_local_sel(): file_ = "%s/%s" % (self.dir, selection) if not isdir(file_): self.s3c.upload_file(file_, self.drp_sel, basename(file_)) else: zipd = make_archive(file_, 'zip', self.dir, selection) self.s3c.upload_file(zipd, self.drp_sel, basename(zipd)) remove(zipd) m = "Uploaded: %s" % selection self.set_status_label(m) self.status_label.update_idletasks() self.refresh_s3() self.finished("UPLOAD") def download(self): if not self.drp_sel or not self.dir: m = "Ensure a file and bucket have been selected" self.set_status_label(m) elif not self.get_s3_sel(): m = "Ensure files are selected to download" self.set_status_label(m) else: for selection in self.get_s3_sel(): file_ = "%s/%s" % (self.dir, selection) self.s3c.download_file(self.drp_sel, selection, file_) self.refresh_local() self.finished("DOWNLOAD") def get_bucket_contents(self): bucket = self.s3.Bucket(self.drp_sel) return [s3_file.key for s3_file in bucket.objects.all()] def populate_dropdown(self): return [bucket.name for bucket in self.s3.buckets.all()] def set_local_browse_label(self, incoming): if len(incoming) > 35: self.browse_label.config(text=basename(incoming) + '/') else: self.browse_label.config(text=incoming) def set_s3_bucket_label(self, incoming): self.bucket_label.config(text=incoming) def set_status_label(self, incoming): self.status_label.config(text=incoming) def set_found_local_label(self, incoming): self.found_label_local.config(text=incoming) def set_found_s3_label(self, incoming): self.found_label_s3.config(text=incoming) def create_bucket(self): self.bucket_name = self.create_bucket_name.get("1.0", END).strip() if not self.bucket_name: m = "Please enter a new bucket name" self.set_status_label(m) else: pre_exists = False try: self.s3.create_bucket(Bucket=self.bucket_name) except ClientError as ce: pre_exists = True m = "Bucket name is already in use. " m += "Choose a different name." self.set_status_label(m) if not pre_exists: m = "%s created: restarting..." % self.bucket_name self.set_status_label(m) self.status_label.update_idletasks() res = executable execl(res, res, *argv)
class SearchFrame: def __init__(self, logicManger, root): self.logicManager = logicManger # images setup self.backgroundImg = None self.connectImg = None self.backImg = None self.initPictures() # frame setup self.frame = None self.clients_list = None self.connect_button = None self.back_button = None self.timeUpdateMobileList = 1000 # in ms self.initFrame(root) def initPictures(self): self.backgroundImg = getPhoto('\\img\\ConnectScreen.png') self.connectImg = getPhoto('\\img\\MouseButton.png') self.backImg = getPhoto('\\img\\BackButton.png') def initFrame(self, root): self.frame = Canvas(root, bg=DARK_BLUE) self.frame.create_image(0, 0, anchor=NW, image=self.backgroundImg) self.frame.pack(expand="true", fill="both") padyClients = (200, 0) padyButtons = 4 padx = (35, 0) y_grid = 0 y_grid = self.initClients(self.frame, y_grid, padyClients, padx) self.initButtons(self.frame, y_grid, 0, padx, padyButtons) self.frame.after(self.timeUpdateMobileList, self.addClient) def initClients(self, frame, y_grid, pady, padx): rapper_frame = Frame(frame, bg=GRAY_BLUE) rapper_frame.grid(row=y_grid, column=0, rowspan=1, columnspan=4, padx=padx, pady=pady) label = Label(rapper_frame, text='Select your Smartphone', width=23, font=("Calibri", 14), bg=DARK_GRAY_BLUE, fg=WHITE) label.pack(side="top") self.clients_list = Listbox(rapper_frame, width=25, height=9, bd=0, font=("Calibri", 12)) # set the listbox contains func self.clients_list.contains = lambda x: x in self.clients_list.get( 0, "end") self.clients_list.pack(side="left", fill="y", padx=(2, 0), pady=2) scrollbar = Scrollbar(rapper_frame, orient="vertical") scrollbar.config(command=self.clients_list.yview) scrollbar.pack(side="right", fill="y", padx=(0, 2), pady=2) self.clients_list.config(yscrollcommand=scrollbar.set) return y_grid + 1 def initButtons(self, frame, y_grid, x_grid, padx, pady): self.connect_button = Button(frame, image=self.connectImg, bg=GRAY, font=SMALL_BUTTON_FONT) self.connect_button.grid(row=y_grid, column=x_grid, rowspan=1, padx=padx, pady=pady) x_grid = x_grid + 3 self.back_button = Button(frame, image=self.backImg, bg=GRAY, font=SMALL_BUTTON_FONT) self.back_button.grid(row=y_grid, column=x_grid, rowspan=1, padx=5, pady=pady) def setBackButtonFunction(self, func): self.back_button["command"] = func def setConnectionSelectFunction(self, func): def select(): index = self.clients_list.curselection() connection = self.clients_list.get(index) # empty tuple whike return false if connection: func(connection) self.connect_button["command"] = select def addClient(self): connections = self.logicManager.getConnections() for connection in connections.values(): if not self.clients_list.contains(connection): index = self.clients_list.size() self.clients_list.insert(index, str(connection)) self.frame.after(self.timeUpdateMobileList, self.addClient) def hideFrame(self): self.frame.pack_forget()
class Combobox_Autocomplete(Entry, object): def __init__(self, master, list_of_items=None, autocomplete_function=None, listbox_width=None, listbox_height=7, ignorecase_match=False, startswith_match=True, vscrollbar=True, hscrollbar=True, **kwargs): if hasattr(self, "autocomplete_function"): if autocomplete_function is not None: raise ValueError( "Combobox_Autocomplete subclass has 'autocomplete_function' implemented") else: if autocomplete_function is not None: self.autocomplete_function = autocomplete_function else: if list_of_items is None: raise ValueError( "If not given complete function, list_of_items can't be 'None'") elif ignorecase_match: if startswith_match: def matches_function(entry_data, item): return item.startswith(entry_data) else: def matches_function(entry_data, item): return item in entry_data self.autocomplete_function = lambda entry_data: [ item for item in self.list_of_items if matches_function(entry_data, item)] else: if startswith_match: def matches_function(escaped_entry_data, item): if re.match(escaped_entry_data, item, re.IGNORECASE): return True else: return False else: def matches_function(escaped_entry_data, item): if re.search(escaped_entry_data, item, re.IGNORECASE): return True else: return False def autocomplete_function2(entry_data): escaped_entry_data = re.escape(entry_data) return [item for item in self.list_of_items if matches_function(escaped_entry_data, item)] self.autocomplete_function = autocomplete_function2 self._listbox_height = int(listbox_height) self._listbox_width = listbox_width self.list_of_items = list_of_items self._use_vscrollbar = vscrollbar self._use_hscrollbar = hscrollbar kwargs.setdefault("background", "white") if "textvariable" in kwargs: self._entry_var = kwargs["textvariable"] else: self._entry_var = kwargs["textvariable"] = StringVar() Entry.__init__(self, master, **kwargs) self._trace_id = self._entry_var.trace('w', self._on_change_entry_var) self._listbox = None self.bind("<Tab>", self._on_tab) self.bind("<Up>", self._previous) self.bind("<Down>", self._next) self.bind('<Control-n>', self._next) self.bind('<Control-p>', self._previous) self.bind("<Return>", self._update_entry_from_listbox) self.bind("<Escape>", lambda event: self.unpost_listbox()) def _on_tab(self, event): self.post_listbox() return "break" def _on_change_entry_var(self, name, index, mode): entry_data = self._entry_var.get() if entry_data == '': self.unpost_listbox() self.focus() else: values = self.autocomplete_function(entry_data) if values: if self._listbox is None: self._build_listbox(values) else: self._listbox.delete(0, END) height = min(self._listbox_height, len(values)) self._listbox.configure(height=height) for item in values: self._listbox.insert(END, item) else: self.unpost_listbox() self.focus() def _build_listbox(self, values): listbox_frame = Frame() self._listbox = Listbox(listbox_frame, background="white", selectmode=SINGLE, activestyle="none", exportselection=False) self._listbox.grid(row=0, column=0, sticky=N+E+W+S) self._listbox.bind("<ButtonRelease-1>", self._update_entry_from_listbox) self._listbox.bind("<Return>", self._update_entry_from_listbox) self._listbox.bind("<Escape>", lambda event: self.unpost_listbox()) self._listbox.bind('<Control-n>', self._next) self._listbox.bind('<Control-p>', self._previous) if self._use_vscrollbar: vbar = Scrollbar(listbox_frame, orient=VERTICAL, command=self._listbox.yview) vbar.grid(row=0, column=1, sticky=N+S) self._listbox.configure( yscrollcommand=lambda f, l: autoscroll(vbar, f, l)) elif self._use_hscrollbar: hbar = Scrollbar(listbox_frame, orient=HORIZONTAL, command=self._listbox.xview) hbar.grid(row=1, column=0, sticky=E+W) self._listbox.configure( xscrollcommand=lambda f, l: autoscroll(hbar, f, l)) listbox_frame.grid_columnconfigure(0, weight=1) listbox_frame.grid_rowconfigure(0, weight=1) x = -self.cget("borderwidth") - self.cget("highlightthickness") y = self.winfo_height()-self.cget("borderwidth") - \ self.cget("highlightthickness") elif self._listbox_width: width = self._listbox_width else: width = self.winfo_width() listbox_frame.place(in_=self, x=x, y=y, width=width) height = min(self._listbox_height, len(values)) self._listbox.configure(height=height) for item in values: self._listbox.insert(END, item) def post_listbox(self): if self._listbox is not None: return entry_data = self._entry_var.get() if entry_data == '': return values = self.autocomplete_function(entry_data) if values: self._build_listbox(values) def unpost_listbox(self): if self._listbox is not None: self._listbox.master.destroy() self._listbox = None def get_value(self): return self._entry_var.get() def set_value(self, text, close_dialog=False): self._set_var(text) if close_dialog: self.unpost_listbox() self.icursor(END) self.xview_moveto(1.0) def _set_var(self, text): self._entry_var.trace_vdelete("w", self._trace_id) self._entry_var.set(text) self._trace_id = self._entry_var.trace('w', self._on_change_entry_var) def _update_entry_from_listbox(self, event): if self._listbox is not None: current_selection = self._listbox.curselection() if current_selection: text = self._listbox.get(current_selection) self._set_var(text) self._listbox.master.destroy() self._listbox = None self.focus() self.icursor(END) self.xview_moveto(1.0) return "break" def _previous(self, event): if self._listbox is not None: current_selection = self._listbox.curselection() if len(current_selection) == 0: self._listbox.selection_set(0) self._listbox.activate(0) else: index = int(current_selection[0]) self._listbox.selection_clear(index) if index == 0: index = END else: index -= 1 self._listbox.see(index) self._listbox.selection_set(first=index) self._listbox.activate(index) return "break" def _next(self, event): if self._listbox is not None: current_selection = self._listbox.curselection() if len(current_selection) == 0: self._listbox.selection_set(0) self._listbox.activate(0) else: index = int(current_selection[0]) self._listbox.selection_clear(index) if index == self._listbox.size() - 1: index = 0 else: index += 1 self._listbox.see(index) self._listbox.selection_set(index) self._listbox.activate(index) return "break"
class client(): def __init__(self, master): self.root = master self.root.title(glv.get_variable("APP_NAME")) self.root.minsize(800, 600) set_window_center(self.root, 800, 600) self.root.resizable(False, False) self.root.update() self.var_port = IntVar(value=3333) self.var_address = StringVar(value="0.0.0.0") self.default_timeout = IntVar(value=-999) self.path_remote = StringVar() self.path_local = StringVar() self.inputFileName = "" self.filelist_local = None self.filelist_remote = None self.toolbar_box = None # 工具按钮栏 self.quickbar_box = None # 快速连接栏 self.footer_box = None # 底部状态栏 self.content_box = None # 主要内容视图容器 self.remote_box = None # 远程服务端资源 self.local_box = None # 本地资源 self.ftp_connect = FTP() self.init_view() def init_view(self): """界面""" app_menu.AppMenu(self.root) self.init_frame() self.init_toolbar() self.init_header() self.init_remote() self.init_local() self.init_footer() def init_frame(self): """基本框架""" # 工具按钮栏 self.toolbar_box = Frame(self.root, relief="ridge", bd=1) self.toolbar_box.pack(fill="x", expand=None, side="top", anchor="n") # 快速连接栏 self.quickbar_box = Frame(self.root, relief="ridge", bd=1) self.quickbar_box.pack(fill="x", expand=None, side="top", anchor="n") # 底部状态栏 self.footer_box = Frame(self.root, relief="ridge", bd=1) self.footer_box.pack(fill="x", expand=None, side="bottom", anchor="s") # 主要内容视图容器 self.content_box = Frame(self.root, relief="ridge", bd=0) self.content_box.pack(fill="both", expand=True) # 远程服务端文件列表 self.remote_box = Frame(self.content_box, relief="ridge", bd=0) self.remote_box.pack(fill="both", expand=True, side="right") # 本地文件列表 self.local_box = Frame(self.content_box, relief="ridge", bd=0) self.local_box.pack(fill="both", expand=True, side="left") def init_header(self): """头部栏""" Label(self.quickbar_box, text="主机:").pack(side="left") self.entry_ip = Entry(self.quickbar_box, textvariable=self.var_address) self.entry_ip["width"] = 15 self.entry_ip.pack(side="left") Label(self.quickbar_box, text="账号:").pack(side="left") self.entry_user = Entry(self.quickbar_box, width=15) self.entry_user.pack(side="left") Label(self.quickbar_box, text="密码:").pack(side="left") self.entry_passwd = Entry(self.quickbar_box, show="*", width=15) self.entry_passwd.pack(side="left") Label(self.quickbar_box, text="端口:").pack(side="left") self.entry_port = Entry(self.quickbar_box, textvariable=self.var_port) self.entry_port["width"] = 5 self.entry_port.pack(side="left") button_connect = Button(self.quickbar_box, text="快速连接") button_connect["command"] = self.ftp_login button_connect["width"] = 10 button_connect.pack(side="left") def init_toolbar(self): """工具栏""" button_connect = Button(self.toolbar_box, text="快速连接") button_connect["command"] = self.ftp_login button_connect.pack(side="left") button_disconnect = Button(self.toolbar_box, text="断开") button_disconnect["command"] = self.ftp_quit button_disconnect.pack(side="left") button_reflash = Button(self.toolbar_box, text="刷新") button_reflash["command"] = self.flash_remote button_reflash.pack(side="left") def init_remote(self): """远程文件列表""" btn_bar = Frame(self.remote_box, relief="ridge", bd=1) btn_bar.pack(fill="x", expand=False, side="top") Label(btn_bar, text="远程:").pack(fill="x", expand=None, side="left") path = Entry(btn_bar, textvariable=self.path_remote) path.pack(fill="x", expand=True, side="left") Button(btn_bar, text="打开", command=self.select_path_remote).pack(fill="x", expand=None, side="left") Button(btn_bar, text="重连", command=self.ftp_login).pack(side="left") Button(btn_bar, text="断开", command=self.ftp_quit).pack(side="left") Button(btn_bar, text="刷新", command=self.flash_remote).pack(fill="x", expand=None, side="right") file_list = Frame(self.remote_box, relief="ridge", bd=0) file_list.pack(fill="both", expand=True, side="top") # Listbox # self.filelist_remote = Listbox(self.remote_box) # self.filelist_remote.bind("<Double-Button-1>", self.click_db) # self.filelist_remote.pack(fill="both", expand=True, side="top") tree = Treeview(file_list, show="headings") # 列索引ID tree["columns"] = ("pra", "id", "user", "group", "size", "date", "name") # 表头设置 tree.heading("pra", text="权限") tree.heading("id", text="ID") tree.heading("user", text="用户") tree.heading("group", text="组") tree.heading("size", text="大小") tree.heading("date", text="最后修改日期") tree.heading("name", text="文件名") tree.column("pra", width="100") tree.column("id", width="50", anchor="center") tree.column("user", width="50") tree.column("group", width="50") tree.column("size", width="50") tree.column("date", width="50") tree.column("name", width="50") self.filelist_remote = tree vbar = Scrollbar(file_list, orient="vertical", command=tree.yview) tree.configure(yscrollcommand=vbar.set) tree.grid(row=0, column=0, sticky="nswe") vbar.grid(row=0, column=1, sticky="ns") def init_local(self): """本地文件列表""" btns = Frame(self.local_box, relief="ridge", bd=1) btns.pack(fill="x", expand=False, side="top") Label(btns, text="本地:").pack(fill="x", expand=None, side="left") Entry(btns, textvariable=self.path_local).pack(fill="x", expand=True, side="left") Button(btns, text="打开", command=self.select_path_local).pack(fill="x", expand=None, side="left") Button(btns, text="刷新", command=self.flash_local).pack(fill="x", expand=None, side="right") self.filelist_local = Listbox(self.local_box) self.filelist_local.bind("<Double-Button-1>", self.click_db) self.filelist_local.pack(fill="both", expand=True, side="top") def init_footer(self): """底部状态栏""" Label(self.footer_box, text="欢迎使用").pack(side="left") Label(self.footer_box, text="欢迎使用").pack(fill="x", side="left") ct = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())) self.clock = Label(self.footer_box, text=ct) self.clock.pack(side="right") self.clock.after(1000, self.trickit) self.trickit() def trickit(self): ct = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())) self.clock["text"] = ct self.clock.update() self.clock.after(1000, self.trickit) def ftp_login(self): self.ftp_connect.connect(self.var_address.get().strip(), int(self.entry_port.get().strip())) self.ftp_connect.login(self.entry_user.get(), self.entry_passwd.get()) self.flash_remote() # 加载列表 def ftp_quit(self): if self.ftp_connect is not None: self.ftp_connect.quit() def ftp_close(self): if self.ftp_connect is not None: self.ftp_connect.close() def flash_remote(self): file_list = [] self.ftp_connect.dir("", file_list.append) for x in file_list: i = x.split() # 或者filename = x.split("\t")[列的起始值:列的终止值] self.filelist_remote.insert("", "end", text="", values=(i[0], i[1], i[2], i[3], i[4], i[5:8], i[-1])) def flash_local(self): filelist = os.listdir(self.path_local.get()) print(filelist) if self.filelist_local.size() > 0: self.filelist_local.delete(0, "end") for i in range(len(filelist)): self.filelist_local.insert("end", filelist[i]) # file_list = [] # self.ftp_connect.dir("", file_list.append) # for x in file_list: # i = x.split() # 或者filename = x.split("\t")[列的起始值:列的终止值] # self.filelist_local.insert( # "", # "end", # text="", # values=(i[0], i[1], i[2], i[3], i[4], i[5:8], i[-1])) def click_db(self, event): self.download() def download(self): inputFileName = self.filelist_remote.get( self.filelist_remote.curselection()) file_handler = open(self.path_remote.get() + "/" + inputFileName, "wb").write self.ftp_connect.retrbinary( "RETR %s" % os.path.basename(inputFileName), file_handler, 1024) def select_path_local(self): path = filedialog.askdirectory() if os.path.isdir(path): self.path_local.set(path) def select_path_remote(self): path = filedialog.askdirectory() if os.path.isdir(path): self.path_remote.set(path) def quit(self): self.root.quit()
class Controller: SNAP_RADIUS = 5 def __init__(self, tk: Tk): tk.title("Layered Polygons") menubar = Menu(tk) menu_file = Menu(menubar, tearoff=0) menu_file.add_command(label="New...", command=self._new_scene) menu_file.add_command(label="Open...", command=self._open_scene) menu_file.add_separator() menu_file.add_command(label="Save", command=self._save_scene) menu_file.add_command(label="Save As...", command=self._save_scene_as) menu_file.add_separator() menu_export = Menu(menu_file, tearoff=0) menu_export.add_command(label="Wavefront (.obj)...", command=self._export_obj) menu_file.add_cascade(label="Export As", menu=menu_export) menu_file.add_separator() menu_file.add_command(label="Quit", command=self._quit_app) menubar.add_cascade(label="File", menu=menu_file) tk.config(menu=menubar) paned = PanedWindow(tk, relief=RAISED) paned.pack(fill=BOTH, expand=1) frame = Frame(paned) paned.add(frame) self._canvas = LayPolyCanvas(frame) bar_x = Scrollbar(frame, orient=HORIZONTAL) bar_x.pack(side=BOTTOM, fill=X) bar_x.config(command=self._canvas.xview) bar_y = Scrollbar(frame, orient=VERTICAL) bar_y.pack(side=RIGHT, fill=Y) bar_y.config(command=self._canvas.yview) self._canvas.config(xscrollcommand=bar_x.set, yscrollcommand=bar_y.set) self._canvas.pack(side=LEFT, expand=True, fill=BOTH) # Thanks to the two guys on Stack Overflow for that! # ( http://stackoverflow.com/a/7734187 ) self._layer_list = Listbox(paned, selectmode=SINGLE) paned.add(self._layer_list) self._scene = None self._current_layer = None self._is_drawing_polygon = False self._tk = tk self._canvas.bind("<Button-1>", self._canvas_left_click) self._canvas.bind("<Button-3>", self._canvas_right_click) self._canvas.bind("<Motion>", self._canvas_mouse_moved) self._layer_list.bind("<<ListboxSelect>>", self._layer_change) self._current_path = None def _canvas_left_click(self, event): if not self._scene or not self._current_layer: return x, y = self._canvas.window_to_canvas_coords(event.x, event.y) if self._is_drawing_polygon: polygon = self._current_layer.get_polygon_at(-1) # Move vtx away from mouse to not interfere with search for closest polygon.get_vertex_at(-1).\ set_coords(x-self.SNAP_RADIUS, y-self.SNAP_RADIUS) closest_vertex = self._current_layer.get_closest_vertex( x, y, self.SNAP_RADIUS) if closest_vertex: polygon.remove_vertex_at(-1) if closest_vertex is polygon.get_vertex_at(0): self._is_drawing_polygon = False else: polygon.add_vertex(closest_vertex) polygon.add_vertex(Vertex(x, y)) else: polygon.get_vertex_at(-1)\ .set_coords(x, y) polygon.add_vertex(Vertex(x, y)) self._canvas.notify_polygon_change( self._current_layer.get_polygon_count() - 1) else: # Create start vertex or use already existing one start_vertex = self._current_layer\ .get_closest_vertex(x, y, self.SNAP_RADIUS) if not start_vertex: start_vertex = Vertex(x, y) # Vertex for mouse cursor next_vertex = Vertex(x, y) self._current_layer.add_polygon( Polygon([start_vertex, next_vertex])) self._is_drawing_polygon = True self._canvas.notify_layer_change() def _canvas_right_click(self, event): if not self._current_layer: return if self._is_drawing_polygon: self._current_layer.remove_polygon_at(-1) self._is_drawing_polygon = False else: x, y = self._canvas.window_to_canvas_coords(event.x, event.y) for i in range(0, self._current_layer.get_polygon_count()): if self._current_layer.get_polygon_at(i).contains(x, y): self._current_layer.remove_polygon_at(i) break self._canvas.notify_layer_change() def _canvas_mouse_moved(self, event): if self._is_drawing_polygon: x, y = self._canvas.window_to_canvas_coords(event.x, event.y) self._current_layer.get_polygon_at(-1).get_vertex_at(-1)\ .set_coords(x, y) self._canvas.notify_polygon_change( self._current_layer.get_polygon_count() - 1) def _layer_change(self, event): selection = self._layer_list.curselection() if len(selection) > 0 and self._scene: layer = self._scene.get_layer_at(selection[0]) if layer: self._is_drawing_polygon = False self._current_layer = layer self._canvas.notify_new_layer(self._current_layer) def _set_scene(self, scene: Scene) -> bool: if scene.get_layer_count() <= 0: messagebox.showerror("Error!", "Scene has no layers!") return False self._scene = scene # Prepare canvas # TODO Extra 10px padding for canvas width, height = self._scene.get_size() self._canvas.config(scrollregion=(0, 0, width, height)) # Empty listbox, fill it, select first entry self._layer_list.delete(0, self._layer_list.size() - 1) for i in range(0, self._scene.get_layer_count()): self._layer_list.insert(i, self._scene.get_layer_at(i).get_name()) self._layer_list.selection_set(0) self._layer_list.event_generate("<<ListboxSelect>>") return True def _set_current_path(self, path): self._current_path = path if path: self._tk.title(path + " - Layered Polygons") else: self._tk.title("Untitled - Layered Polygons") def _new_scene(self): path = filedialog.askopenfilename(defaultextension=".ora", filetypes=[("OpenRaster files", ".ora")]) if not path: return scene = ora.read(path) if not scene: messagebox.showerror("Error!", "File could not be opened!") return if self._set_scene(scene): self._set_current_path(None) def _open_scene(self): path = filedialog.askopenfilename(defaultextension=".lp", filetypes=[("Layered polygons" " files", ".lp")]) if not path: return scene = lp.read(path) if not scene: messagebox.showerror("Error!", "File could not be opened!") return if self._set_scene(scene): self._set_current_path(path) def _save_scene_help(self, path): if lp.save(path, self._scene): self._set_current_path(path) else: messagebox.showerror("Error!", "File could not be saved!") def _save_scene(self): if not self._current_path: self._save_scene_as() return self._save_scene_help(self._current_path) def _save_scene_as(self): if not self._scene: return path = filedialog.asksaveasfilename(defaultextension=".lp", filetypes=[("Layered polygons" " files", ".lp")]) if path: self._save_scene_help(path) def _export_obj(self): if not self._scene: return path_obj = filedialog.asksaveasfilename(defaultextension=".obj", filetypes=[("Wavefront object" " files", ".obj")]) if not path_obj: return path_obj, path_mtl, path_data = obj.get_paths(path_obj) obj.save(path_obj, path_mtl, path_data, self._scene) def _quit_app(self): self._tk.quit() exit()
class Ui: def __init__(self, master): self.uf = UiFunctions() self.master = master # method on closing the window self.master.protocol('WM_DELETE_WINDOW', self.on_closing) self.master.title('BACnet Device Handler') self.master.geometry('+300+300') # default values for padding and sticky padyD = 5 padxD = 5 stickyD = E+W+S+N # Layout self.master.columnconfigure(1, weight=1) self.master.columnconfigure(2, pad=7) self.master.rowconfigure(5, weight=1) self.lblWelcome = Label(master, text='Welcome to BACnet Device Handler') self.lblWelcome.grid(row=0, sticky=W, pady=padyD, padx=padxD) self.lblDevName = Label(master, text='This device name is: ' + self.uf.thisDevName) self.lblDevName.grid(row=1, sticky=W, pady=padyD, padx=padxD) self.lbxDevices = Listbox(master) self.lbxDevices.grid(row=2, column=0, rowspan=4, sticky=stickyD, pady=padyD, padx=padxD) self.update_device_list() self.btnCreateNew = Button(master, text='Change Device Name', command=self.change_device_name) self.btnCreateNew.grid(row=2, column=2, sticky=stickyD, pady=padyD, padx=padxD) self.btnImport = Button(master, text='Import keys on new device', command=self.import_keys_from_old) self.btnImport.grid(row=3, column=2, sticky=stickyD, pady=padyD, padx=padxD) self.btnExport = Button(master, text='Export keys for new device', command=self.export_keys_to_new) self.btnExport.grid(row=4, column=2, sticky=stickyD, pady=padyD, padx=padxD) def change_device_name(self): dial = ChangeDeviceName(self.master, self.uf) self.master.wait_window(dial.top) # waiting for the popUp to be destroyed self.update_device_list() def export_keys_to_new(self): dial = ExportToDialog(self.master, self.uf) self.master.wait_window(dial.top) # waiting for the popUp to be destroyed def import_keys_from_old(self): dial = ImportFromDialog(self.master, self.uf) self.master.wait_window(dial.top) # waiting for the popUp to be destroyed def update_device_list(self): # delete lines first in listbox self.lbxDevices.delete(0, self.lbxDevices.size()) # insert devices names taken from uf.decDict i = 0 for dev in self.uf.devDict.keys(): self.lbxDevices.insert(i, self.uf.devDict.get(dev).get('deviceName')) i += 1 def on_closing(self): # export dictionary on closing to save situation self.uf.write_to_json() self.master.destroy()
class LucteriosMainForm(Tk): def __init__(self): Tk.__init__(self) try: img = Image("photo", file=join( dirname(import_module('lucterios.install').__file__), "lucterios.png")) self.tk.call('wm', 'iconphoto', self._w, img) except: pass self.has_checked = False self.title(ugettext("Lucterios installer")) self.minsize(475, 260) self.grid_columnconfigure(0, weight=1) self.grid_rowconfigure(0, weight=1) self.running_instance = {} self.resizable(True, True) self.protocol("WM_DELETE_WINDOW", self.on_closing) self.ntbk = ttk.Notebook(self) self.ntbk.grid(row=0, column=0, columnspan=1, sticky=(N, S, E, W)) self.create_instance_panel() self.create_module_panel() stl = ttk.Style() stl.theme_use("default") stl.configure("TProgressbar", thickness=5) self.progress = ttk.Progressbar( self, style="TProgressbar", orient='horizontal', mode='indeterminate') self.progress.grid(row=1, column=0, sticky=(E, W)) self.btnframe = Frame(self, bd=1) self.btnframe.grid(row=2, column=0, columnspan=1) Button(self.btnframe, text=ugettext("Refresh"), width=20, command=self.refresh).grid( row=0, column=0, padx=3, pady=3, sticky=(N, S)) self.btnupgrade = Button( self.btnframe, text=ugettext("Search upgrade"), width=20, command=self.upgrade) self.btnupgrade.config(state=DISABLED) self.btnupgrade.grid(row=0, column=1, padx=3, pady=3, sticky=(N, S)) Button(self.btnframe, text=ugettext("Close"), width=20, command=self.on_closing).grid( row=0, column=2, padx=3, pady=3, sticky=(N, S)) def on_closing(self): all_stop = True instance_names = list(self.running_instance.keys()) for old_item in instance_names: if (self.running_instance[old_item] is not None) and self.running_instance[old_item].is_running(): all_stop = False if all_stop or askokcancel(None, ugettext("An instance is always running.\nDo you want to close?")): self.destroy() else: self.refresh() def destroy(self): instance_names = list(self.running_instance.keys()) for old_item in instance_names: if self.running_instance[old_item] is not None: self.running_instance[old_item].stop() del self.running_instance[old_item] Tk.destroy(self) def create_instance_panel(self): frm_inst = Frame(self.ntbk) frm_inst.grid_columnconfigure(0, weight=1) frm_inst.grid_rowconfigure(0, weight=1) frm_inst.grid_columnconfigure(1, weight=3) frm_inst.grid_rowconfigure(1, weight=0) self.instance_list = Listbox(frm_inst, width=20) self.instance_list.bind('<<ListboxSelect>>', self.select_instance) self.instance_list.pack() self.instance_list.grid(row=0, column=0, sticky=(N, S, W, E)) self.instance_txt = Text(frm_inst, width=75) self.instance_txt.grid(row=0, column=1, rowspan=2, sticky=(N, S, W, E)) self.instance_txt.config(state=DISABLED) self.btninstframe = Frame(frm_inst, bd=1) self.btninstframe.grid(row=1, column=0, columnspan=1) self.btninstframe.grid_columnconfigure(0, weight=1) Button(self.btninstframe, text=ugettext("Launch"), width=25, command=self.open_inst).grid( row=0, column=0, columnspan=2, sticky=(N, S)) Button(self.btninstframe, text=ugettext("Modify"), width=10, command=self.modify_inst).grid(row=1, column=0, sticky=(N, S)) Button(self.btninstframe, text=ugettext("Delete"), width=10, command=self.delete_inst).grid(row=1, column=1, sticky=(N, S)) Button(self.btninstframe, text=ugettext("Save"), width=10, command=self.save_inst).grid(row=2, column=0, sticky=(N, S)) Button(self.btninstframe, text=ugettext("Restore"), width=10, command=self.restore_inst).grid(row=2, column=1, sticky=(N, S)) Button(self.btninstframe, text=ugettext("Add"), width=25, command=self.add_inst).grid( row=3, column=0, columnspan=2, sticky=(N, S)) self.ntbk.add(frm_inst, text=ugettext('Instances')) def create_module_panel(self): frm_mod = Frame(self.ntbk) frm_mod.grid_columnconfigure(0, weight=1) frm_mod.grid_rowconfigure(0, weight=1) self.module_txt = Text(frm_mod) self.module_txt.grid(row=0, column=0, sticky=(N, S, W, E)) self.module_txt.config(state=DISABLED) self.ntbk.add(frm_mod, text=ugettext('Modules')) def do_progress(self, progressing): if not progressing: self.progress.stop() self.progress.grid_remove() else: self.progress.start(25) self.progress.grid(row=1, column=0, sticky=(E, W)) def enabled(self, is_enabled, widget=None): if widget is None: widget = self self.do_progress(not is_enabled) if is_enabled: widget.config(cursor="") else: widget.config(cursor="watch") if isinstance(widget, Button) and (widget != self.btnupgrade): if is_enabled and (not hasattr(widget, 'disabled') or not widget.disabled): widget.config(state=NORMAL) else: widget.config(state=DISABLED) else: for child_cmp in widget.winfo_children(): self.enabled(is_enabled, child_cmp) @ThreadRun def refresh(self, instance_name=None): if instance_name is None: instance_name = self.get_selected_instance_name() self.instance_txt.delete("1.0", END) self._refresh_instance_list() self.set_select_instance_name(instance_name) if not self.has_checked: self._refresh_modules() if self.instance_list.size() == 0: sleep(.3) self._refresh_modules() sleep(.3) self.after_idle(self.add_inst) def _refresh_modules(self): self.btnupgrade.config(state=DISABLED) self.module_txt.config(state=NORMAL) self.module_txt.delete("1.0", END) lct_glob = LucteriosGlobal() mod_lucterios, mod_applis, mod_modules = lct_glob.installed() self.module_txt.insert( END, ugettext("Lucterios core\t\t%s\n") % mod_lucterios[1]) self.module_txt.insert(END, '\n') self.module_txt.insert(END, ugettext("Application\n")) for appli_item in mod_applis: self.module_txt.insert( END, "\t%s\t%s\n" % (appli_item[0].ljust(30), appli_item[1])) self.module_txt.insert(END, ugettext("Modules\n")) for module_item in mod_modules: self.module_txt.insert( END, "\t%s\t%s\n" % (module_item[0].ljust(30), module_item[1])) extra_urls = lct_glob.get_extra_urls() if len(extra_urls) > 0: self.module_txt.insert(END, "\n") self.module_txt.insert(END, ugettext("Pypi servers\n")) for extra_url in extra_urls: self.module_txt.insert(END, "\t%s\n" % extra_url) self.module_txt.config(state=DISABLED) self.has_checked = True self.after(1000, lambda: Thread(target=self.check).start()) def _refresh_instance_list(self): self.instance_list.delete(0, END) luct_glo = LucteriosGlobal() instance_list = luct_glo.listing() for item in instance_list: self.instance_list.insert(END, item) if item not in self.running_instance.keys(): self.running_instance[item] = None instance_names = list(self.running_instance.keys()) for old_item in instance_names: if old_item not in instance_list: if self.running_instance[old_item] is not None: self.running_instance[old_item].stop() del self.running_instance[old_item] def set_select_instance_name(self, instance_name): cur_sel = 0 for sel_iter in range(self.instance_list.size()): if self.instance_list.get(sel_iter) == instance_name: cur_sel = sel_iter break self.instance_list.selection_set(cur_sel) self.select_instance(None) def get_selected_instance_name(self): if len(self.instance_list.curselection()) > 0: return self.instance_list.get(int(self.instance_list.curselection()[0])) else: return "" def set_ugrade_state(self, must_upgrade): if must_upgrade: self.btnupgrade.config(state=NORMAL) self.btnupgrade["text"] = ugettext("Upgrade needs") else: self.btnupgrade["text"] = ugettext("No upgrade") self.btnupgrade.config(state=DISABLED) def check(self): must_upgrade = False try: lct_glob = LucteriosGlobal() _, must_upgrade = lct_glob.check() finally: self.after(300, self.set_ugrade_state, must_upgrade) @ThreadRun def upgrade(self): self.btnupgrade.config(state=DISABLED) self.instance_list.config(state=DISABLED) try: from logging import getLogger admin_path = import_module( "lucterios.install.lucterios_admin").__file__ proc = Popen( [sys.executable, admin_path, "update"], stderr=STDOUT, stdout=PIPE) value = proc.communicate()[0] try: value = value.decode('ascii') except: pass six.print_(value) if proc.returncode != 0: getLogger("lucterios.admin").error(value) else: getLogger("lucterios.admin").info(value) showinfo(ugettext("Lucterios installer"), ugettext( "The application must restart")) python = sys.executable os.execl(python, python, *sys.argv) finally: self._refresh_modules() self.btnupgrade.config(state=NORMAL) self.instance_list.config(state=NORMAL) @ThreadRun def select_instance(self, evt): if self.instance_list['state'] == NORMAL: self.instance_list.config(state=DISABLED) try: instance_name = self.get_selected_instance_name() self.instance_txt.configure(state=NORMAL) self.instance_txt.delete("1.0", END) if instance_name != '': if instance_name not in self.running_instance.keys(): self.running_instance[instance_name] = None inst = LucteriosInstance(instance_name) inst.read() self.instance_txt.insert(END, "\t\t\t%s\n\n" % inst.name) self.instance_txt.insert( END, ugettext("Database\t\t%s\n") % inst.get_database_txt()) self.instance_txt.insert( END, ugettext("Appli\t\t%s\n") % inst.get_appli_txt()) self.instance_txt.insert( END, ugettext("Modules\t\t%s\n") % inst.get_module_txt()) self.instance_txt.insert( END, ugettext("Extra\t\t%s\n") % inst.get_extra_txt()) self.instance_txt.insert(END, '\n') if self.running_instance[instance_name] is not None and self.running_instance[instance_name].is_running(): self.instance_txt.insert(END, ugettext( "=> Running in http://%(ip)s:%(port)d\n") % {'ip': self.running_instance[instance_name].lan_ip, 'port': self.running_instance[instance_name].port}) self.btninstframe.winfo_children()[0]["text"] = ugettext( "Stop") else: self.running_instance[instance_name] = None self.instance_txt.insert(END, ugettext("=> Stopped\n")) self.btninstframe.winfo_children()[0]["text"] = ugettext( "Launch") else: self.btninstframe.winfo_children()[0]["text"] = ugettext( "Launch") self.btninstframe.winfo_children()[0].disabled = ( instance_name == '') self.btninstframe.winfo_children()[1].disabled = ( instance_name == '') self.btninstframe.winfo_children()[2].disabled = ( instance_name == '') self.btninstframe.winfo_children()[3].disabled = ( instance_name == '') self.btninstframe.winfo_children()[4].disabled = ( instance_name == '') self.instance_txt.configure(state=DISABLED) finally: setup_from_none() self.instance_list.config(state=NORMAL) @ThreadRun def add_modif_inst_result(self, result, to_create): inst = LucteriosInstance(result[0]) inst.set_extra("LANGUAGE_CODE='%s'" % result[5]) inst.set_appli(result[1]) inst.set_module(result[2]) inst.set_database(result[4]) if to_create: inst.add() else: inst.modif() inst = LucteriosInstance(result[0]) inst.set_extra(result[3]) inst.security() self.refresh(result[0]) def add_inst(self): self.enabled(False) try: self.do_progress(False) ist_edt = InstanceEditor() ist_edt.execute() ist_edt.transient(self) self.wait_window(ist_edt) finally: self.enabled(True) if ist_edt.result is not None: self.add_modif_inst_result(ist_edt.result, True) def modify_inst(self): self.enabled(False) try: self.do_progress(False) ist_edt = InstanceEditor() ist_edt.execute(self.get_selected_instance_name()) ist_edt.transient(self) self.wait_window(ist_edt) finally: self.enabled(True) if ist_edt.result is not None: self.add_modif_inst_result(ist_edt.result, False) @ThreadRun def delete_inst_name(self, instance_name): inst = LucteriosInstance(instance_name) inst.delete() self.refresh() def delete_inst(self): setup_from_none() instance_name = self.get_selected_instance_name() if askokcancel(None, ugettext("Do you want to delete '%s'?") % instance_name): self.delete_inst_name(instance_name) else: self.refresh() @ThreadRun def open_inst(self): instance_name = self.get_selected_instance_name() if instance_name != '': try: if instance_name not in self.running_instance.keys(): self.running_instance[instance_name] = None if self.running_instance[instance_name] is None: port = FIRST_HTTP_PORT for inst_obj in self.running_instance.values(): if (inst_obj is not None) and (inst_obj.port >= port): port = inst_obj.port + 1 self.running_instance[instance_name] = RunServer( instance_name, port) self.running_instance[instance_name].start() else: self.running_instance[instance_name].stop() self.running_instance[instance_name] = None finally: self.set_select_instance_name(instance_name) @ThreadRun def save_instance(self, instance_name, file_name): inst = LucteriosInstance(instance_name) inst.filename = file_name if inst.archive(): showinfo(ugettext("Lucterios installer"), ugettext( "Instance saved to %s") % file_name) else: showerror( ugettext("Lucterios installer"), ugettext("Instance not saved!")) self.refresh(instance_name) def save_inst(self): instance_name = self.get_selected_instance_name() if instance_name != '': file_name = asksaveasfilename( parent=self, filetypes=[('lbk', '.lbk'), ('*', '.*')]) if file_name != '': self.save_instance(instance_name, file_name) @ThreadRun def restore_instance(self, instance_name, file_name): if file_name[-4:] == '.bkf': rest_inst = MigrateFromV1(instance_name, withlog=True) else: rest_inst = LucteriosInstance(instance_name) rest_inst.filename = file_name if rest_inst.restore(): showinfo(ugettext("Lucterios installer"), ugettext( "Instance restore from %s") % file_name) else: showerror( ugettext("Lucterios installer"), ugettext("Instance not restored!")) self.refresh(instance_name) def restore_inst(self): instance_name = self.get_selected_instance_name() if instance_name != '': file_name = askopenfilename( parent=self, filetypes=[('lbk', '.lbk'), ('bkf', '.bkf'), ('*', '.*')]) if file_name != '': self.restore_instance(instance_name, file_name) def execute(self): self.refresh() center(self, (700, 300)) self.mainloop()
class ListWindow(Frame): def __init__(self, showSelected, parent=None): Frame.__init__(self, parent) self.parent = parent self.showSelected = showSelected self.listBox = None self.initUI() def initUI(self): frame_lbl = Frame(self.parent, bd=5, relief=RIDGE) frame_lbl.pack(side=TOP, expand=True, fill=X) lbl_name = Label(frame_lbl, text='Созданные решетки') lbl_name.pack() frame_listbox = Frame(self.parent) frame_listbox.pack(side=TOP, expand=True, fill=BOTH) self.listBox = Listbox(frame_listbox, width=65, height=4, selectmode=SINGLE, bd=5, relief=RIDGE) self.listBox.bind('<<ListboxSelect>>', self.showSelect) scrbary = Scrollbar(frame_listbox, orient='vertical') scrbarx = Scrollbar(frame_listbox, orient='horizontal') scrbary.config(command=self.listBox.yview, relief=SUNKEN) scrbarx.config(command=self.listBox.xview, relief=SUNKEN) self.listBox.config(yscrollcommand=scrbary.set, xscrollcommand=scrbarx.set) scrbary.pack(side=RIGHT, fill=Y) scrbarx.pack(side='bottom', fill=X) self.listBox.pack(side=TOP, expand=True, fill=BOTH) def showSelect(self, event): item = self.getSelectedItem() self.showSelected(item) def getSelectedItem(self): items = self.listBox.curselection() item = self.listBox.get(items[0]) return item def insertData(self, item): count = self.listBox.size() for i in range(count): s = self.listBox.get(i) if s == item: messagebox.showerror( 'Ошибка', 'Окно с таким заголовком уже есть в списке') return False self.listBox.insert(END, item) return True def removeData(self, title): count = self.listBox.size() for i in range(count): string = self.listBox.get(i) if string == title: self.listBox.delete(i) break def clear(self): count = self.listBox.size() self.listBox.delete(0, count - 1)
class DrtGlueDemo(object): def __init__(self, examples): # Set up the main window. self._top = Tk() self._top.title("DRT Glue Demo") # Set up key bindings. self._init_bindings() # Initialize the fonts.self._error = None self._init_fonts(self._top) self._examples = examples self._readingCache = [None for example in examples] # The user can hide the grammar. self._show_grammar = IntVar(self._top) self._show_grammar.set(1) # Set the data to None self._curExample = -1 self._readings = [] self._drs = None self._drsWidget = None self._error = None self._init_glue() # Create the basic frames. self._init_menubar(self._top) self._init_buttons(self._top) self._init_exampleListbox(self._top) self._init_readingListbox(self._top) self._init_canvas(self._top) # Resize callback self._canvas.bind("<Configure>", self._configure) ######################################### ## Initialization Helpers ######################################### def _init_glue(self): tagger = RegexpTagger( [ ("^(David|Mary|John)$", "NNP"), ("^(walks|sees|eats|chases|believes|gives|sleeps|chases|persuades|tries|seems|leaves)$", "VB"), ("^(go|order|vanish|find|approach)$", "VB"), ("^(a)$", "ex_quant"), ("^(every)$", "univ_quant"), ("^(sandwich|man|dog|pizza|unicorn|cat|senator)$", "NN"), ("^(big|gray|former)$", "JJ"), ("^(him|himself)$", "PRP"), ] ) depparser = MaltParser(tagger=tagger) self._glue = DrtGlue(depparser=depparser, remove_duplicates=False) def _init_fonts(self, root): # See: <http://www.astro.washington.edu/owen/ROTKFolklore.html> self._sysfont = Font(font=Button()["font"]) root.option_add("*Font", self._sysfont) # TWhat's our font size (default=same as sysfont) self._size = IntVar(root) self._size.set(self._sysfont.cget("size")) self._boldfont = Font(family="helvetica", weight="bold", size=self._size.get()) self._font = Font(family="helvetica", size=self._size.get()) if self._size.get() < 0: big = self._size.get() - 2 else: big = self._size.get() + 2 self._bigfont = Font(family="helvetica", weight="bold", size=big) def _init_exampleListbox(self, parent): self._exampleFrame = listframe = Frame(parent) self._exampleFrame.pack(fill="both", side="left", padx=2) self._exampleList_label = Label(self._exampleFrame, font=self._boldfont, text="Examples") self._exampleList_label.pack() self._exampleList = Listbox( self._exampleFrame, selectmode="single", relief="groove", background="white", foreground="#909090", font=self._font, selectforeground="#004040", selectbackground="#c0f0c0", ) self._exampleList.pack(side="right", fill="both", expand=1) for example in self._examples: self._exampleList.insert("end", (" %s" % example)) self._exampleList.config(height=min(len(self._examples), 25), width=40) # Add a scrollbar if there are more than 25 examples. if len(self._examples) > 25: listscroll = Scrollbar(self._exampleFrame, orient="vertical") self._exampleList.config(yscrollcommand=listscroll.set) listscroll.config(command=self._exampleList.yview) listscroll.pack(side="left", fill="y") # If they select a example, apply it. self._exampleList.bind("<<ListboxSelect>>", self._exampleList_select) def _init_readingListbox(self, parent): self._readingFrame = listframe = Frame(parent) self._readingFrame.pack(fill="both", side="left", padx=2) self._readingList_label = Label(self._readingFrame, font=self._boldfont, text="Readings") self._readingList_label.pack() self._readingList = Listbox( self._readingFrame, selectmode="single", relief="groove", background="white", foreground="#909090", font=self._font, selectforeground="#004040", selectbackground="#c0f0c0", ) self._readingList.pack(side="right", fill="both", expand=1) # Add a scrollbar if there are more than 25 examples. listscroll = Scrollbar(self._readingFrame, orient="vertical") self._readingList.config(yscrollcommand=listscroll.set) listscroll.config(command=self._readingList.yview) listscroll.pack(side="right", fill="y") self._populate_readingListbox() def _populate_readingListbox(self): # Populate the listbox with integers self._readingList.delete(0, "end") for i in range(len(self._readings)): self._readingList.insert("end", (" %s" % (i + 1))) self._readingList.config(height=min(len(self._readings), 25), width=5) # If they select a example, apply it. self._readingList.bind("<<ListboxSelect>>", self._readingList_select) def _init_bindings(self): # Key bindings are a good thing. self._top.bind("<Control-q>", self.destroy) self._top.bind("<Control-x>", self.destroy) self._top.bind("<Escape>", self.destroy) self._top.bind("n", self.next) self._top.bind("<space>", self.next) self._top.bind("p", self.prev) self._top.bind("<BackSpace>", self.prev) def _init_buttons(self, parent): # Set up the frames. self._buttonframe = buttonframe = Frame(parent) buttonframe.pack(fill="none", side="bottom", padx=3, pady=2) Button(buttonframe, text="Prev", background="#90c0d0", foreground="black", command=self.prev).pack(side="left") Button(buttonframe, text="Next", background="#90c0d0", foreground="black", command=self.next).pack(side="left") def _configure(self, event): self._autostep = 0 (x1, y1, x2, y2) = self._cframe.scrollregion() y2 = event.height - 6 self._canvas["scrollregion"] = "%d %d %d %d" % (x1, y1, x2, y2) self._redraw() def _init_canvas(self, parent): self._cframe = CanvasFrame( parent, background="white", # width=525, height=250, closeenough=10, border=2, relief="sunken", ) self._cframe.pack(expand=1, fill="both", side="top", pady=2) canvas = self._canvas = self._cframe.canvas() # Initially, there's no tree or text self._tree = None self._textwidgets = [] self._textline = None def _init_menubar(self, parent): menubar = Menu(parent) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label="Exit", underline=1, command=self.destroy, accelerator="q") menubar.add_cascade(label="File", underline=0, menu=filemenu) actionmenu = Menu(menubar, tearoff=0) actionmenu.add_command(label="Next", underline=0, command=self.next, accelerator="n, Space") actionmenu.add_command(label="Previous", underline=0, command=self.prev, accelerator="p, Backspace") menubar.add_cascade(label="Action", underline=0, menu=actionmenu) optionmenu = Menu(menubar, tearoff=0) optionmenu.add_checkbutton( label="Remove Duplicates", underline=0, variable=self._glue.remove_duplicates, command=self._toggle_remove_duplicates, accelerator="r", ) menubar.add_cascade(label="Options", underline=0, menu=optionmenu) viewmenu = Menu(menubar, tearoff=0) viewmenu.add_radiobutton(label="Tiny", variable=self._size, underline=0, value=10, command=self.resize) viewmenu.add_radiobutton(label="Small", variable=self._size, underline=0, value=12, command=self.resize) viewmenu.add_radiobutton(label="Medium", variable=self._size, underline=0, value=14, command=self.resize) viewmenu.add_radiobutton(label="Large", variable=self._size, underline=0, value=18, command=self.resize) viewmenu.add_radiobutton(label="Huge", variable=self._size, underline=0, value=24, command=self.resize) menubar.add_cascade(label="View", underline=0, menu=viewmenu) helpmenu = Menu(menubar, tearoff=0) helpmenu.add_command(label="About", underline=0, command=self.about) menubar.add_cascade(label="Help", underline=0, menu=helpmenu) parent.config(menu=menubar) ######################################### ## Main draw procedure ######################################### def _redraw(self): canvas = self._canvas # Delete the old DRS, widgets, etc. if self._drsWidget is not None: self._drsWidget.clear() if self._drs: self._drsWidget = DrsWidget(self._canvas, self._drs) self._drsWidget.draw() if self._error: self._drsWidget = DrsWidget(self._canvas, self._error) self._drsWidget.draw() ######################################### ## Button Callbacks ######################################### def destroy(self, *e): self._autostep = 0 if self._top is None: return self._top.destroy() self._top = None def prev(self, *e): selection = self._readingList.curselection() readingListSize = self._readingList.size() # there are readings if readingListSize > 0: # if one reading is currently selected if len(selection) == 1: index = int(selection[0]) # if it's on (or before) the first item if index <= 0: self._select_previous_example() else: self._readingList_store_selection(index - 1) else: # select its first reading self._readingList_store_selection(readingListSize - 1) else: self._select_previous_example() def _select_previous_example(self): # if the current example is not the first example if self._curExample > 0: self._exampleList_store_selection(self._curExample - 1) else: # go to the last example self._exampleList_store_selection(len(self._examples) - 1) def next(self, *e): selection = self._readingList.curselection() readingListSize = self._readingList.size() # if there are readings if readingListSize > 0: # if one reading is currently selected if len(selection) == 1: index = int(selection[0]) # if it's on (or past) the last item if index >= (readingListSize - 1): self._select_next_example() else: self._readingList_store_selection(index + 1) else: # select its first reading self._readingList_store_selection(0) else: self._select_next_example() def _select_next_example(self): # if the current example is not the last example if self._curExample < len(self._examples) - 1: self._exampleList_store_selection(self._curExample + 1) else: # go to the first example self._exampleList_store_selection(0) def about(self, *e): ABOUT = "NLTK Discourse Representation Theory (DRT) Glue Semantics Demo\n" + "Written by Daniel H. Garrette" TITLE = "About: NLTK DRT Glue Demo" try: from tkMessageBox import Message Message(message=ABOUT, title=TITLE).show() except: ShowText(self._top, TITLE, ABOUT) def postscript(self, *e): self._autostep = 0 self._cframe.print_to_file() def mainloop(self, *args, **kwargs): """ Enter the Tkinter mainloop. This function must be called if this demo is created from a non-interactive program (e.g. from a secript); otherwise, the demo will close as soon as the script completes. """ if in_idle(): return self._top.mainloop(*args, **kwargs) def resize(self, size=None): if size is not None: self._size.set(size) size = self._size.get() self._font.configure(size=-(abs(size))) self._boldfont.configure(size=-(abs(size))) self._sysfont.configure(size=-(abs(size))) self._bigfont.configure(size=-(abs(size + 2))) self._redraw() def _toggle_remove_duplicates(self): self._glue.remove_duplicates = not self._glue.remove_duplicates self._exampleList.selection_clear(0, "end") self._readings = [] self._populate_readingListbox() self._readingCache = [None for ex in self._examples] self._curExample = -1 self._error = None self._drs = None self._redraw() def _exampleList_select(self, event): selection = self._exampleList.curselection() if len(selection) != 1: return self._exampleList_store_selection(int(selection[0])) def _exampleList_store_selection(self, index): self._curExample = index example = self._examples[index] self._exampleList.selection_clear(0, "end") if example: cache = self._readingCache[index] if cache: if isinstance(cache, list): self._readings = cache self._error = None else: self._readings = [] self._error = cache else: try: self._readings = self._glue.parse_to_meaning(example) self._error = None self._readingCache[index] = self._readings except Exception as e: self._readings = [] self._error = DrtVariableExpression(Variable("Error: " + str(e))) self._readingCache[index] = self._error # add a star to the end of the example self._exampleList.delete(index) self._exampleList.insert(index, (" %s *" % example)) self._exampleList.config(height=min(len(self._examples), 25), width=40) self._populate_readingListbox() self._exampleList.selection_set(index) self._drs = None self._redraw() def _readingList_select(self, event): selection = self._readingList.curselection() if len(selection) != 1: return self._readingList_store_selection(int(selection[0])) def _readingList_store_selection(self, index): reading = self._readings[index] self._readingList.selection_clear(0, "end") if reading: self._readingList.selection_set(index) self._drs = reading.simplify().normalize().resolve_anaphora() self._redraw()
class Tela: """.""" def __init__(self): """.""" self.tk = Tk() self.tk.geometry("600x400") self.tk.resizable(False, False) if not path.isdir("animes"): mkdir("animes") if path.isfile("animes/Paginas.json"): self.ani = load(open("animes/Paginas.json")) else: self.ani = {'nome': [], 'link': []} self.mylist = None self.scrollbar = None self.fra1 = None self.fra2 = None self.bt1 = None self.bt2 = None self.bt3 = None self.bt4 = None self.btProc = None self.etProc = None self.is_voltar = False self.dir = getcwd() self.busca = StringVar() self.inicia() self.tk.title("Anime Downloader") self.selecionado = -1 # self.icon = self.dir + '\\' + 'down.ico' # self.tk.iconbitmap(self.icon) self.tk.mainloop() def inicia(self): """.""" self.fra1 = Frame(self.tk, bd=1) self.fra2 = Frame(self.tk, bd=1) self.scrollbar = ttk.Scrollbar(self.tk, orient=VERTICAL) self.mylist = Listbox(self.tk, yscrollcommand=self.scrollbar.set) for III in range(len(self.ani['nome'])): self.mylist.insert(END, self.ani['nome'][III]) self.scrollbar.config(command=self.mylist.yview) self.scrollbar.pack(side=RIGHT, fill=Y) # Buscar Label(self.fra1, text='Anime:').pack(side=LEFT) self.etProc = Entry(self.fra1, textvariable=self.busca, width=65) self.etProc.pack(side=LEFT) self.btProc = Button(self.fra1, text='Procurar', command=self.procura) self.btProc.pack(side=LEFT) self.fra1.pack(fill=X) # Lista self.mylist.pack(fill=BOTH, expand=True) # Botoes self.bt1 = Button(self.fra2, text="Pegar valor", command=self.li) self.bt2 = Button(self.fra2, text="Voltar", command=self.voltar) self.bt3 = Button(self.fra2, text="Baixar", command=self.baixar) self.bt4 = Button(self.fra2, text="Atualizar Base", command=self.busca_p) self.bt4.pack(side=LEFT) self.bt1.pack(side=LEFT) self.fra2.pack() def li(self): """.""" if self.mylist.curselection(): buscar = self.mylist.get(self.mylist.curselection()).lower() ind = -1 for IV in range(len(self.ani['nome'])): if buscar == self.ani['nome'][IV].lower(): ind = IV break self.selecionado = ind url = self.ani['link'][ind] nome = str(ind + 1) + " " + \ Anime.sanitizestring(self.ani['nome'][ind]) new_window = Toplevel(self.tk) Thread(target=Anime, args=[ new_window, self, 'Procurando...', nome, url]).start() def mostra_ani(self): """.""" self.ani = load(open("animes/" + str(self.selecionado + 1) + " " + Anime.sanitizestring(self.ani['nome'][self.selecionado]) + ".json")) self.atualiza("ep") self.bt1.forget() self.bt4.forget() self.is_voltar = True self.bt2.pack(side=LEFT) self.bt3.pack(side=LEFT) def procura(self): """.""" buscar = self.busca.get().lower() self.busca.set('') if self.btProc['text'] == 'Procurar': self.btProc['text'] = 'Resetar' self.etProc['state'] = DISABLED ind = [] for V in range(len(self.ani['nome'])): if buscar in self.ani['nome'][V].lower(): ind.append(V) if ind is not []: for V in range(self.mylist.size()): self.mylist.delete(0) for V in ind: self.mylist.insert(END, self.ani['nome'][V]) else: messagebox.showerror("Anime Downloader", "Anime não Encontrado!") else: self.btProc['text'] = 'Procurar' self.etProc['state'] = NORMAL if self.is_voltar: self.voltar() else: self.atualiza('nome') self.is_voltar = False def voltar(self): """.""" self.ani = load(open("animes/Paginas.json")) self.atualiza("nome") self.bt2.forget() self.bt3.forget() self.bt4.pack(side=LEFT) self.bt1.pack(side=LEFT) def atualiza(self, campo): """.""" for VI in range(self.mylist.size()): self.mylist.delete(0) for VI in range(len(self.ani[campo])): self.mylist.insert(END, self.ani[campo][VI]) def baixar(self): """.""" if self.mylist.curselection(): url = self.ani['link'][self.mylist.curselection()[0]] nome = self.ani['ep'][self.mylist.curselection()[0]] conjunto = {'ep': nome, 'link': url} new_window = Toplevel(self.tk) Thread(target=DownloadWindow, args=[ new_window, None, conjunto]).start() def busca_p(self): """.""" new_window = Toplevel(self.tk) Thread(target=Anime, args=[new_window, self, 'Atualizando...']).start()
class LintGui: """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.filenames = [] self.rating = StringVar() self.tabs = {} self.report_stream = BasicStream(self) # gui objects self.lbMessages = 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) # 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.lbMessages = Listbox( msg_frame, yscrollcommand=rightscrollbar.set, xscrollcommand=bottomscrollbar.set, bg="white" ) self.lbMessages.pack(expand=True, fill=BOTH) rightscrollbar.config(command=self.lbMessages.yview) bottomscrollbar.config(command=self.lbMessages.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) # labels self.lblRatingLabel = Label(rating_frame, text="Rating:") self.lblRatingLabel.pack(side=LEFT) self.lblRating = Label(rating_frame, textvariable=self.rating) self.lblRating.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.txtModule = Entry(top_frame, background="white") self.txtModule.bind("<Return>", self.run_lint) self.txtModule.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 ) rawMet = 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, ) msgCat = 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 ) report.select() report.grid(column=0, row=0, sticky=W) rawMet.grid(column=1, row=0, sticky=W) dup.grid(column=2, row=0, sticky=W) msg.grid(column=3, row=0, sticky=E) stat.grid(column=0, row=1, sticky=W) msgCat.grid(column=1, row=1, sticky=W) ext.grid(column=2, row=1, columnspan=2, 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.txtModule.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.txtModule.delete(0, END) self.txtModule.insert(0, item) def refresh_msg_window(self): """refresh the message window with current output""" # clear the window self.lbMessages.delete(0, END) for msg in self.msgs: if self.msg_type_dict.get(msg[0])(): msg_str = self.convert_to_string(msg) self.lbMessages.insert(END, msg_str) fg_color = COLORS.get(msg_str[:3], "black") self.lbMessages.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 convert_to_string(self, msg): """make a string representation of a message""" if msg[2] != "": return "(" + msg[0] + ") " + msg[1] + "." + msg[2] + " [" + msg[3] + "]: " + msg[4] else: return "(" + msg[0] + ") " + msg[1] + " [" + msg[3] + "]: " + msg[4] 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[0])(): msg_str = self.convert_to_string(msg) self.lbMessages.insert(END, msg_str) fg_color = COLORS.get(msg_str[:3], "black") self.lbMessages.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.txtModule.delete(0, END) self.txtModule.insert(0, filename) def update_filenames(self): """update the list of recent filenames""" filename = self.txtModule.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.txtModule.get() if not module: module = os.getcwd() # cleaning up msgs and windows self.msgs = [] self.lbMessages.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="")
class LintGui: """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.filenames = [] self.rating = StringVar() self.tabs = {} self.report_stream = BasicStream(self) #gui objects self.lbMessages = 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) #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.lbMessages = Listbox(msg_frame, yscrollcommand=rightscrollbar.set, xscrollcommand=bottomscrollbar.set, bg="white") self.lbMessages.pack(expand=True, fill=BOTH) rightscrollbar.config(command=self.lbMessages.yview) bottomscrollbar.config(command=self.lbMessages.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) #labels self.lblRatingLabel = Label(rating_frame, text='Rating:') self.lblRatingLabel.pack(side=LEFT) self.lblRating = Label(rating_frame, textvariable=self.rating) self.lblRating.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.txtModule = Entry(top_frame, background='white') self.txtModule.bind('<Return>', self.run_lint) self.txtModule.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) rawMet = 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) msgCat = 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) report.select() report.grid(column=0, row=0, sticky=W) rawMet.grid(column=1, row=0, sticky=W) dup.grid(column=2, row=0, sticky=W) msg.grid(column=3, row=0, sticky=E) stat.grid(column=0, row=1, sticky=W) msgCat.grid(column=1, row=1, sticky=W) ext.grid(column=2, row=1, columnspan=2, 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.txtModule.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.txtModule.delete(0, END) self.txtModule.insert(0, item) def refresh_msg_window(self): """refresh the message window with current output""" #clear the window self.lbMessages.delete(0, END) for msg in self.msgs: if (self.msg_type_dict.get(msg[0])()): msg_str = self.convert_to_string(msg) self.lbMessages.insert(END, msg_str) fg_color = COLORS.get(msg_str[:3], 'black') self.lbMessages.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 convert_to_string(self, msg): """make a string representation of a message""" if (msg[2] != ""): return "(" + msg[0] + ") " + msg[1] + "." + msg[2] + " [" + msg[ 3] + "]: " + msg[4] else: return "(" + msg[0] + ") " + msg[1] + " [" + msg[3] + "]: " + msg[4] 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[0])()): msg_str = self.convert_to_string(msg) self.lbMessages.insert(END, msg_str) fg_color = COLORS.get(msg_str[:3], 'black') self.lbMessages.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.txtModule.delete(0, END) self.txtModule.insert(0, filename) def update_filenames(self): """update the list of recent filenames""" filename = self.txtModule.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.txtModule.get() if not module: module = os.getcwd() #cleaning up msgs and windows self.msgs = [] self.lbMessages.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='')
class TextSelect(Frame): def __init__(self, client, anchor, items, destroyAnchor=False): """ Args: client: [SelectionClient] The window that text is returned to. anchor: A window that the text selection popup is created relative to. items: [str], items to display in the listbox. destroyAnchor: [bool] if true, destroy the anchor after positioning the window. """ self.top = Toplevel() self.anchor = anchor self.top.overrideredirect(1) self.top.wm_geometry('+%s+%s' % (anchor.winfo_rootx() + anchor.winfo_x(), anchor.winfo_rooty() + anchor.winfo_y() ) ) super(TextSelect, self).__init__(self.top) self.entry = Entry(self) self.client = client self.items = items self.place(x = 0.5, y = 0.5, height = 100, width = 100) self.entry.bind('<Return>', self.close) self.entry.bind('<KeyPress>', self.filter) self.entry.bind('<Escape>', self.abort) self.entry.bind('<Up>', self.up) self.entry.bind('<Down>', self.down) self.entry.pack() # Create the list of items. self.list = Listbox(self) for item in self.items: self.list.insert('end', item) self.list.pack() self.grid() self.entry.focus() # Reposition the select button against the anchor. We defer this # until after idle so that the anchor has a chance to get rendered. def reposition(*args): self.top.wm_geometry('+%s+%s' % ( anchor.winfo_rootx(), anchor.winfo_rooty()) ) if destroyAnchor: anchor.destroy() self.after_idle(reposition) def close(self, event): sel = self.list.curselection() if sel: item = self.list.get(sel[0]) else: item = self.entry.get() # Note that the order of this appears to be significant: destroying # before selecting leaves the focus in a weird state. self.client.selected(item) self.top.destroy() return 'braek' def abort(self, event): self.top.destroy() self.client.aborted() return 'break' def up(self, event): sel = self.list.curselection() if not sel: self.list.selection_set(0) return 'break' sel = sel[0] print('sel is %s size is %s' % (sel, self.list.size())) if sel > 0: print('setting selection to %s' % sel) self.list.selection_clear(sel) self.list.selection_set(sel - 1) self.list.see(sel) return 'break' def down(self, event): sel = self.list.curselection() if not sel: self.list.selection_set(0) return 'break' sel = sel[0] print('sel is %s size is %s' % (sel, self.list.size())) if sel < self.list.size() - 1: print('setting selection to %s' % (sel + 1)) self.list.selection_clear(sel) self.list.selection_set(sel + 1) self.list.see(sel) return 'break' def filter(self, event): """Filter the listbox based on the contents of the entryfield.""" # first add the character to the entry. currentText = self.entry.get() print(event.keysym) if event.keysym == 'BackSpace': # Handle backspace specially. if currentText: currentText = currentText[:-1] self.entry.delete(0, 'end') self.entry.insert(0, currentText) else: return 'break' else: # Assume normal character. Insert it. self.entry.insert('insert', event.char) currentText += event.char self.list.delete(0, 'end') pattern = currentText.upper() for item in self.items: if pattern in item.upper(): self.list.insert('end', item) return 'break'
class TShapesWindow(Frame): """ Class represents auxiliary window containg shapes information. :param master: master window object. :type master: tkinter.Tk :param app: main app object. :type app: TApp """ def __init__(self, master, TApp): """ Call the parent class constructor and initialise object variables. """ super().__init__() self.TApp = TApp self.round_digits = TTicksSettings.ROUND_DIGITS self.init_widgets() def init_widgets(self): """ Init frame widgets. """ # Listbox self.shapes_list = Listbox(self, exportselection=False, selectmode=EXTENDED) self.grid_columnconfigure(0, weight=1, minsize=300) self.grid_rowconfigure(0, weight=1) self.shapes_list.grid(row=0, column=0, sticky=NSEW, padx=(5, 25), pady=5) self.shapes_list.bind("<<ListboxSelect>>", self.shapes_list_selected_item) # Listbox's yscrollbar self.shapes_list_scrollbar = Scrollbar(self, orient = VERTICAL, \ command = self.shapes_list.yview) self.shapes_list_scrollbar.grid(row=0, column=0, sticky=NS + E, padx=(0, 5), pady=5) self.shapes_list.config(yscrollcommand=self.shapes_list_scrollbar.set) # Drop down menu with materials self.material_box = Combobox(self, values=["pec", "free_space"]) self.material_box.grid(row=1, column=0, sticky=EW, padx=5, pady=5) self.material_box.bind("<<ComboboxSelected>>", self.assign_material_to_shape) # Right click popup menu self.init_popup_menu() self.shapes_list.bind("<Button-3>", self.show_popoup_menu) # Delete key removes selected shape(s) self.shapes_list.bind("<Delete>", self.remove_shape) def update_list(self, shapes, *, swap=False): """ Update shapes list. :param swap: shapes list selection swap toggle. :type swap: boolean """ selection = self.shapes_list.curselection() try: shape_num = selection[0] except: shape_num = 0 self.shapes_list.delete(0, END) coord_string = "" for i, single_shape in enumerate(shapes): if (single_shape.type == "Rectangle"): coord_string = "(" + str(round(single_shape.point1_mod.x, self.round_digits)) + \ ", " + str(round(single_shape.point1_mod.y, self.round_digits)) + \ "), (" + str(round (single_shape.point2_mod.x, self.round_digits)) + \ ", " + str(round(single_shape.point2_mod.y, self.round_digits)) + ")" elif (single_shape.type == "Cylinder"): coord_string = "(" + str(round(single_shape.centre_mod.x, self.round_digits)) + \ ", " + str(round(single_shape.centre_mod.y, self.round_digits)) + \ "), " + str(round(single_shape.radius_mod, self.round_digits)) elif (single_shape.type == "CylinSector"): coord_string = "(" + str(round(single_shape.centre_mod.x, self.round_digits)) + \ ", " + str(round(single_shape.centre_mod.y, self.round_digits)) + \ "), " + str(round(single_shape.radius_mod, self.round_digits)) + \ ", " + str(round(single_shape.start, self.round_digits)) + \ ", " + str(round(single_shape.extent, self.round_digits)) elif (single_shape.type == "Polygon"): coord_string = str(len(single_shape.points)) self.shapes_list.insert( i, str(i + 1) + ". " + single_shape.type + ": " + coord_string) coord_string = "" if (not swap): self.shapes_list.select_clear(0, END) if (shape_num >= self.shapes_list.size()): self.shapes_list.selection_set(shape_num - 1) self.shapes_list.activate(shape_num) else: for item in selection: self.shapes_list.selection_set(item) self.shapes_list.activate(shape_num) def assign_material_to_shape(self, event): """ Assign material to a shape. :param event: event evoking this method (listbox select). :type event: tkinter.Event """ material = self.material_box.get() try: shape_num = (self.shapes_list.curselection())[0] except: return else: if (shape_num < 0 or material == ""): return else: try: self.TApp.shapes[shape_num].material = material except Exception as message: messagebox.showerror("Material assignment error!", message) return def shapes_list_selected_item(self, event): """ Handle listbox selection event. :param event: event evoking this method (listbox select). :type event: tkinter.Event """ # Add multiple selection self.shapes_list.focus_force() try: shape_num = (self.shapes_list.curselection())[0] selection = self.shapes_list.curselection() except IndexError: return except Exception as message: messagebox.showerror("Error while picking shape!", message) if (shape_num < 0): return else: try: shape = self.TApp.shapes[shape_num] except Exception as message: messagebox.showerror("Materials list error", message) return self.material_box.set(str(shape.material)) for single_shape in self.TApp.shapes: single_shape.width = 1 for item in selection: self.TApp.shapes[item].width = 2 self.TApp.main_canvas.delete("all") for item in selection: self.shapes_list.selection_set(item) self.TApp.canvas_refresh() def init_popup_menu(self): """ Init shapes pane pup-up menu. """ self.popup_menu = Menu(self, tearoff=0) self.popup_menu.add_command(label="Edit shape", command=self.edit_shape) self.popup_menu.add_command(label="Change shape colour", command=self.change_shape_colour) self.popup_menu.add_command(label="Remove shape(s)", command=self.remove_shape) self.popup_menu.add_separator() self.popup_menu.add_command(label="Add vertex to polygon", command=self.add_vertex_to_polygon) self.popup_menu.add_separator() self.popup_menu.add_command(label="Copy shape", command=self.copy_shape) self.popup_menu.add_command(label="Paste shape", command=self.paste_shape) self.popup_menu.add_separator() self.popup_menu.add_command(label="Move up", command=self.move_shape_up) self.popup_menu.add_command(label="Move down", command=self.move_shape_down) self.popup_menu.add_command(label="Move to top", command=self.move_shape_top) self.popup_menu.add_command(label="Move to bottom", command=self.move_shape_bottom) def show_popoup_menu(self, event): """ Show shapes list pop-up menu. :param event: event evoking this method (RMB click). :type event: tkinter.Event """ try: self.popup_menu.post(event.x_root, event.y_root) finally: self.popup_menu.grab_release() def move_shape_up(self): """ Move a shape one place up the shapes list. """ try: shape_num = (self.shapes_list.curselection())[0] except IndexError: return if (shape_num < 0): return else: try: self.TApp.shapes.insert(shape_num - 1, self.TApp.shapes.pop(shape_num)) self.update_list(self.TApp.shapes) self.TApp.main_canvas.delete("all") self.TApp.canvas_refresh(swap=True) self.shapes_list.selection_set(shape_num - 1) self.shapes_list.activate(shape_num - 1) except Exception as message: messagebox.showerror("Error while manipulating shapes list!", message) return def move_shape_down(self): """ Move a shape one place down the shapes list. """ try: shape_num = (self.shapes_list.curselection())[0] except IndexError: return if (shape_num < 0): return else: try: self.TApp.shapes.insert(shape_num + 1, self.TApp.shapes.pop(shape_num)) self.update_list(self.TApp.shapes) self.TApp.main_canvas.delete("all") self.TApp.canvas_refresh(swap=True) self.shapes_list.selection_set(shape_num + 1) self.shapes_list.activate(shape_num + 1) except Exception as message: messagebox.showerror("Error while manipulating shapes list!", message) return def move_shape_top(self): """ Move a shape to the top of the shapes list. """ try: shape_num = (self.shapes_list.curselection())[0] except IndexError: return if (shape_num < 0): return else: try: self.TApp.shapes.insert(0, self.TApp.shapes.pop(shape_num)) self.update_list(self.TApp.shapes) self.TApp.main_canvas.delete("all") self.TApp.canvas_refresh(swap=True) self.shapes_list.selection_set(0) self.shapes_list.activate(0) # self.shapes_list.focus_set () except Exception as message: messagebox.showerror("Error while manipulating shapes list!", message) return def move_shape_bottom(self): """ Move a shape to the bottom of the shapes list. """ try: shape_num = (self.shapes_list.curselection())[0] except IndexError: return if (shape_num < 0): return else: try: self.TApp.shapes.append(self.TApp.shapes.pop(shape_num)) self.update_list(self.TApp.shapes) self.TApp.main_canvas.delete("all") self.TApp.canvas_refresh(swap=True) self.shapes_list.selection_set(END) self.shapes_list.activate(END) except Exception as message: messagebox.showerror("Error while manipulating shapes list!", message) return def edit_shape(self): """ Edit selected shape on the shapes list. """ try: shape_num = (self.shapes_list.curselection())[0] except IndexError: return if (shape_num < 0): return else: self.TApp.operations.append(TOperation("edit", shape = \ deepcopy(self.TApp.shapes[shape_num]), \ num = shape_num)) if (self.TApp.shapes[shape_num].type == "Rectangle"): self.TApp.edit_rectangle(shape_num) elif (self.TApp.shapes[shape_num].type == "Cylinder"): self.TApp.edit_cylin(shape_num) elif (self.TApp.shapes[shape_num].type == "CylinSector"): self.TApp.edit_cylin_sector(shape_num) elif (self.TApp.shapes[shape_num].type == "Polygon"): self.TApp.edit_polygon(shape_num) def change_shape_colour(self): """ Change selected shape on the shapes list colour. """ try: shape_num = (self.shapes_list.curselection())[0] except IndexError: return if (shape_num < 0): return else: self.TApp.change_shape_colour(shape_num=shape_num) def remove_shape(self, event=None): """ Remove selected shape on the shapes list. """ try: selection = self.shapes_list.curselection() except IndexError: return if (len(selection) == 0): return else: try: for item in reversed(selection): del self.TApp.shapes[item] self.update_list(self.TApp.shapes) self.TApp.main_canvas.delete("all") self.TApp.canvas_refresh() except Exception as message: messagebox.showerror("Error while manipulating shapes list!", message) return def add_vertex_to_polygon(self): """ Add a vertex to selected polygon on the shapes list. """ try: shape_num = (self.shapes_list.curselection())[0] except IndexError: return input_str = simpledialog.askstring("Input coordinates", "Give mew vertex's coordinates") point_mod_x, point_mod_y = [float(val) for val in input_str.split()] if (self.TApp.shapes[shape_num].type == "Polygon" and shape_num > -1): self.TApp.shapes[shape_num].add_vertex(x_mod=point_mod_x, y_mod=point_mod_y) self.TApp.main_canvas.delete("all") self.TApp.canvas_refresh() def copy_shape(self): """ Copy selected shape on the shapes list. """ try: shape_num = self.shapes_list.curselection()[0] except: shape_num = -1 if (shape_num > -1): try: self.TApp.copy_shape(shape_num=shape_num) except Exception as message: messagebox.showerror("Error while manipulating shapes list!", message) def paste_shape(self, *, deltax=15, deltay=15): """ Paste selected shape from buffer. :param deltax: pasted shape offset in x direction in pixels. :type deltax: integer :param deltay: pasted shape offset in y direction in pixels. :type deltay: integer """ self.TApp.paste_ctrl_v(Event())
class InstanceEditor(Toplevel, EditorInstance): def __init__(self): Toplevel.__init__(self) EditorInstance.__init__(self) self.focus_set() self.grab_set() self.result = None self.module_data = None self.mod_applis = None self.title(ugettext("Instance editor")) self.grid_columnconfigure(0, weight=1) self.grid_rowconfigure(0, weight=1) self.ntbk = ttk.Notebook(self) self.ntbk.grid(row=0, column=0, columnspan=1, sticky=(N, S, E, W)) self.frm_general = Frame(self.ntbk, width=350, height=150) self.frm_general.grid_columnconfigure(0, weight=0) self.frm_general.grid_columnconfigure(1, weight=1) self._general_tabs() self.ntbk.add(self.frm_general, text=ugettext('General')) self.frm_database = Frame(self.ntbk, width=350, height=150) self.frm_database.grid_columnconfigure(0, weight=0) self.frm_database.grid_columnconfigure(1, weight=1) self._database_tabs() self.ntbk.add(self.frm_database, text=ugettext('Database')) btnframe = Frame(self, bd=1) btnframe.grid(row=1, column=0, columnspan=1) Button(btnframe, text=ugettext("OK"), width=10, command=self.apply).grid(row=0, column=0, sticky=(N, S, E)) Button(btnframe, text=ugettext("Cancel"), width=10, command=self.destroy).grid(row=0, column=1, sticky=(N, S, W)) def _database_tabs(self): Label(self.frm_database, text=ugettext("Type")).grid(row=0, column=0, sticky=(N, W), padx=5, pady=3) self.typedb = ttk.Combobox(self.frm_database, textvariable=StringVar(), state=READLONY) self.typedb.bind("<<ComboboxSelected>>", self.typedb_selection) self.typedb.grid(row=0, column=1, sticky=(N, S, E, W), padx=5, pady=3) Label(self.frm_database, text=ugettext("Name")).grid(row=1, column=0, sticky=(N, W), padx=5, pady=3) self.namedb = Entry(self.frm_database) self.namedb.grid(row=1, column=1, sticky=(N, S, E, W), padx=5, pady=3) Label(self.frm_database, text=ugettext("User")).grid(row=2, column=0, sticky=(N, W), padx=5, pady=3) self.userdb = Entry(self.frm_database) self.userdb.grid(row=2, column=1, sticky=(N, S, E, W), padx=5, pady=3) Label(self.frm_database, text=ugettext("Password")).grid(row=3, column=0, sticky=(N, W), padx=5, pady=3) self.pwddb = Entry(self.frm_database) self.pwddb.grid(row=3, column=1, sticky=(N, S, E, W), padx=5, pady=3) def _general_tabs(self): Label(self.frm_general, text=ugettext("Name")).grid(row=0, column=0, sticky=(N, W), padx=5, pady=3) self.name = Entry(self.frm_general) self.name.grid(row=0, column=1, sticky=(N, S, E, W), padx=5, pady=3) Label(self.frm_general, text=ugettext("Appli")).grid(row=1, column=0, sticky=(N, W), padx=5, pady=3) self.applis = ttk.Combobox(self.frm_general, textvariable=StringVar(), state=READLONY) self.applis.bind("<<ComboboxSelected>>", self.appli_selection) self.applis.grid(row=1, column=1, sticky=(N, S, E, W), padx=5, pady=3) Label(self.frm_general, text=ugettext("Modules")).grid(row=2, column=0, sticky=(N, W), padx=5, pady=3) self.modules = Listbox(self.frm_general, selectmode=EXTENDED) self.modules.configure(exportselection=False) self.modules.grid(row=2, column=1, sticky=(N, S, E, W), padx=5, pady=3) Label(self.frm_general, text=ugettext("Language")).grid(row=3, column=0, sticky=(N, W), padx=5, pady=3) self.language = ttk.Combobox(self.frm_general, textvariable=StringVar(), state=READLONY) self.language.grid(row=3, column=1, sticky=(N, S, E, W), padx=5, pady=3) Label(self.frm_general, text=ugettext("CORE-connectmode")).grid(row=4, column=0, sticky=(N, W), padx=5, pady=3) self.mode = ttk.Combobox(self.frm_general, textvariable=StringVar(), state=READLONY) self.mode.bind("<<ComboboxSelected>>", self.mode_selection) self.mode.grid(row=4, column=1, sticky=(N, S, E, W), padx=5, pady=3) Label(self.frm_general, text=ugettext("Password")).grid(row=5, column=0, sticky=(N, W), padx=5, pady=3) self.password = Entry(self.frm_general, show="*") self.password.grid(row=5, column=1, sticky=(N, S, E, W), padx=5, pady=3) def typedb_selection(self, event): visible = list(self.typedb[VALUES]).index(self.typedb.get()) != 0 for child_cmp in self.frm_database.winfo_children()[2:]: if visible: child_cmp.config(state=NORMAL) else: child_cmp.config(state=DISABLED) def appli_selection(self, event): if self.applis.get() != '': appli_id = list(self.applis[VALUES]).index(self.applis.get()) luct_glo = LucteriosGlobal() current_inst_names = luct_glo.listing() appli_root_name = self.mod_applis[appli_id][0].split('.')[-1] default_name_idx = 1 while appli_root_name + six.text_type( default_name_idx) in current_inst_names: default_name_idx += 1 self.name.delete(0, END) self.name.insert(0, appli_root_name + six.text_type(default_name_idx)) mod_depended = self.mod_applis[appli_id][2] self.modules.select_clear(0, self.modules.size()) for mod_idx in range(len(self.module_data)): current_mod = self.module_data[mod_idx] if current_mod in mod_depended: self.modules.selection_set(mod_idx) def mode_selection(self, event): visible = list(self.mode[VALUES]).index(self.mode.get()) != 2 for child_cmp in self.frm_general.winfo_children()[-2:]: if visible: child_cmp.config(state=NORMAL) else: child_cmp.config(state=DISABLED) def apply(self): from lucterios.framework.settings import DEFAULT_LANGUAGES, get_locale_lang if self.is_new_instance and ( (self.name.get() == '') or (self.name_rull.match(self.name.get()) is None)): showerror(ugettext("Instance editor"), ugettext("Name invalid!")) return if self.applis.get() == '': showerror(ugettext("Instance editor"), ugettext("No application!")) return db_param = "%s:name=%s,user=%s,password=%s" % ( self.typedb.get(), self.namedb.get(), self.userdb.get(), self.pwddb.get()) security = "MODE=%s" % list(self.mode[VALUES]).index(self.mode.get()) if self.password.get() != '': security += ",PASSWORD=%s" % self.password.get() module_list = [ self.module_data[int(item)] for item in self.modules.curselection() ] appli_id = list(self.applis[VALUES]).index(self.applis.get()) current_lang = get_locale_lang() for lang in DEFAULT_LANGUAGES: if lang[1] == self.language.get(): current_lang = lang[0] self.result = (self.name.get(), self.mod_applis[appli_id][0], ",".join(module_list), security, db_param, current_lang) self.destroy() def _load_current_data(self, instance_name): from lucterios.framework.settings import DEFAULT_LANGUAGES lct_inst, applis_id, mode_id, typedb_index, current_lang = self._get_instance_elements( instance_name) self.is_new_instance = False self.name.delete(0, END) self.name.insert(0, lct_inst.name) self.name.config(state=DISABLED) self.applis.current(applis_id) self.mode.current(mode_id) self.mode_selection(None) self.typedb.current(typedb_index) self.typedb.config(state=DISABLED) self.typedb_selection(None) self.namedb.delete(0, END) if 'name' in lct_inst.database[1].keys(): self.namedb.insert(0, lct_inst.database[1]['name']) self.userdb.delete(0, END) if 'user' in lct_inst.database[1].keys(): self.userdb.insert(0, lct_inst.database[1]['user']) self.pwddb.delete(0, END) if 'password' in lct_inst.database[1].keys(): self.pwddb.insert(0, lct_inst.database[1]['password']) self.modules.select_clear(0, self.modules.size()) for mod_idx in range(len(self.module_data)): current_mod = self.module_data[mod_idx] if current_mod in lct_inst.modules: self.modules.select_set(mod_idx) for lang in DEFAULT_LANGUAGES: if lang[0] == current_lang: self.language.current(self.language[VALUES].index(lang[1])) def execute(self, instance_name=None): from lucterios.framework.settings import DEFAULT_LANGUAGES, get_locale_lang self._define_values() self.module_data = [] self.modules.delete(0, END) for module_title, module_name in self.module_list: self.modules.insert(END, module_title) self.module_data.append(module_name) self.mode[VALUES] = self.mode_values self.language[VALUES] = self.lang_values self.typedb[VALUES] = self.dbtype_values self.applis[VALUES] = self.appli_list if instance_name is not None: self._load_current_data(instance_name) else: self.typedb.current(0) self.mode.current(2) if len(self.appli_list) > 0: self.applis.current(0) self.appli_selection(None) self.mode_selection(None) self.typedb_selection(None) for lang in DEFAULT_LANGUAGES: if lang[0] == get_locale_lang(): self.language.current(self.language[VALUES].index(lang[1])) center(self)
class InstanceEditor(Toplevel): def __init__(self): Toplevel.__init__(self) self.focus_set() self.grab_set() self.result = None self.module_data = None self.mod_applis = None self.title(ugettext("Instance editor")) self.grid_columnconfigure(0, weight=1) self.grid_rowconfigure(0, weight=1) self.ntbk = ttk.Notebook(self) self.ntbk.grid(row=0, column=0, columnspan=1, sticky=(N, S, E, W)) self.frm_general = Frame(self.ntbk, width=350, height=150) self.frm_general.grid_columnconfigure(0, weight=0) self.frm_general.grid_columnconfigure(1, weight=1) self._general_tabs() self.ntbk.add(self.frm_general, text=ugettext('General')) self.frm_database = Frame(self.ntbk, width=350, height=150) self.frm_database.grid_columnconfigure(0, weight=0) self.frm_database.grid_columnconfigure(1, weight=1) self._database_tabs() self.ntbk.add(self.frm_database, text=ugettext('Database')) btnframe = Frame(self, bd=1) btnframe.grid(row=1, column=0, columnspan=1) Button(btnframe, text=ugettext("OK"), width=10, command=self.apply).grid( row=0, column=0, sticky=(N, S, E)) Button(btnframe, text=ugettext("Cancel"), width=10, command=self.destroy).grid( row=0, column=1, sticky=(N, S, W)) def _database_tabs(self): Label(self.frm_database, text=ugettext("Type")).grid( row=0, column=0, sticky=(N, W), padx=5, pady=3) self.typedb = ttk.Combobox( self.frm_database, textvariable=StringVar(), state=READLONY) self.typedb.bind("<<ComboboxSelected>>", self.typedb_selection) self.typedb.grid(row=0, column=1, sticky=(N, S, E, W), padx=5, pady=3) Label(self.frm_database, text=ugettext("Name")).grid( row=1, column=0, sticky=(N, W), padx=5, pady=3) self.namedb = Entry(self.frm_database) self.namedb.grid(row=1, column=1, sticky=(N, S, E, W), padx=5, pady=3) Label(self.frm_database, text=ugettext("User")).grid( row=2, column=0, sticky=(N, W), padx=5, pady=3) self.userdb = Entry(self.frm_database) self.userdb.grid(row=2, column=1, sticky=(N, S, E, W), padx=5, pady=3) Label(self.frm_database, text=ugettext("Password")).grid( row=3, column=0, sticky=(N, W), padx=5, pady=3) self.pwddb = Entry(self.frm_database) self.pwddb.grid(row=3, column=1, sticky=(N, S, E, W), padx=5, pady=3) def _general_tabs(self): Label(self.frm_general, text=ugettext("Name")).grid( row=0, column=0, sticky=(N, W), padx=5, pady=3) self.name = Entry(self.frm_general) self.name.grid(row=0, column=1, sticky=(N, S, E, W), padx=5, pady=3) Label(self.frm_general, text=ugettext("Appli")).grid( row=1, column=0, sticky=(N, W), padx=5, pady=3) self.applis = ttk.Combobox( self.frm_general, textvariable=StringVar(), state=READLONY) self.applis.bind("<<ComboboxSelected>>", self.appli_selection) self.applis.grid(row=1, column=1, sticky=(N, S, E, W), padx=5, pady=3) Label(self.frm_general, text=ugettext("Modules")).grid( row=2, column=0, sticky=(N, W), padx=5, pady=3) self.modules = Listbox(self.frm_general, selectmode=EXTENDED) self.modules.configure(exportselection=False) self.modules.grid(row=2, column=1, sticky=(N, S, E, W), padx=5, pady=3) Label(self.frm_general, text=ugettext("Language")).grid( row=3, column=0, sticky=(N, W), padx=5, pady=3) self.language = ttk.Combobox( self.frm_general, textvariable=StringVar(), state=READLONY) self.language.grid( row=3, column=1, sticky=(N, S, E, W), padx=5, pady=3) Label(self.frm_general, text=ugettext("CORE-connectmode") ).grid(row=4, column=0, sticky=(N, W), padx=5, pady=3) self.mode = ttk.Combobox( self.frm_general, textvariable=StringVar(), state=READLONY) self.mode.bind("<<ComboboxSelected>>", self.mode_selection) self.mode.grid(row=4, column=1, sticky=(N, S, E, W), padx=5, pady=3) Label(self.frm_general, text=ugettext("Password")).grid( row=5, column=0, sticky=(N, W), padx=5, pady=3) self.password = Entry(self.frm_general, show="*") self.password.grid( row=5, column=1, sticky=(N, S, E, W), padx=5, pady=3) def typedb_selection(self, event): visible = list(self.typedb[VALUES]).index(self.typedb.get()) != 0 for child_cmp in self.frm_database.winfo_children()[2:]: if visible: child_cmp.config(state=NORMAL) else: child_cmp.config(state=DISABLED) def appli_selection(self, event): if self.applis.get() != '': appli_id = list(self.applis[VALUES]).index(self.applis.get()) luct_glo = LucteriosGlobal() current_inst_names = luct_glo.listing() appli_root_name = self.mod_applis[appli_id][0].split('.')[-1] default_name_idx = 1 while appli_root_name + six.text_type(default_name_idx) in current_inst_names: default_name_idx += 1 self.name.delete(0, END) self.name.insert( 0, appli_root_name + six.text_type(default_name_idx)) mod_depended = self.mod_applis[appli_id][2] self.modules.select_clear(0, self.modules.size()) for mod_idx in range(len(self.module_data)): current_mod = self.module_data[mod_idx] if current_mod in mod_depended: self.modules.selection_set(mod_idx) def mode_selection(self, event): visible = list(self.mode[VALUES]).index(self.mode.get()) != 2 for child_cmp in self.frm_general.winfo_children()[-2:]: if visible: child_cmp.config(state=NORMAL) else: child_cmp.config(state=DISABLED) def apply(self): from lucterios.framework.settings import DEFAULT_LANGUAGES, get_locale_lang if self.name.get() == '': showerror(ugettext("Instance editor"), ugettext("Name empty!")) return if self.applis.get() == '': showerror(ugettext("Instance editor"), ugettext("No application!")) return db_param = "%s:name=%s,user=%s,password=%s" % ( self.typedb.get(), self.namedb.get(), self.userdb.get(), self.pwddb.get()) security = "MODE=%s" % list( self.mode[VALUES]).index(self.mode.get()) if self.password.get() != '': security += ",PASSWORD=%s" % self.password.get() module_list = [ self.module_data[int(item)] for item in self.modules.curselection()] appli_id = list(self.applis[VALUES]).index(self.applis.get()) current_lang = get_locale_lang() for lang in DEFAULT_LANGUAGES: if lang[1] == self.language.get(): current_lang = lang[0] self.result = (self.name.get(), self.mod_applis[appli_id][ 0], ",".join(module_list), security, db_param, current_lang) self.destroy() def _load_current_data(self, instance_name): from lucterios.framework.settings import DEFAULT_LANGUAGES, get_locale_lang lct_inst = LucteriosInstance(instance_name) lct_inst.read() self.name.delete(0, END) self.name.insert(0, lct_inst.name) self.name.config(state=DISABLED) applis_id = 0 for appli_iter in range(len(self.mod_applis)): if self.mod_applis[appli_iter][0] == lct_inst.appli_name: applis_id = appli_iter break self.applis.current(applis_id) if lct_inst.extra['']['mode'] is not None: self.mode.current(lct_inst.extra['']['mode'][0]) else: self.mode.current(2) self.mode_selection(None) typedb_index = 0 for typedb_idx in range(len(self.typedb[VALUES])): if self.typedb[VALUES][typedb_idx].lower() == lct_inst.database[0].lower(): typedb_index = typedb_idx break self.typedb.current(typedb_index) self.typedb.config(state=DISABLED) self.typedb_selection(None) self.namedb.delete(0, END) if 'name' in lct_inst.database[1].keys(): self.namedb.insert(0, lct_inst.database[1]['name']) self.userdb.delete(0, END) if 'user' in lct_inst.database[1].keys(): self.userdb.insert(0, lct_inst.database[1]['user']) self.pwddb.delete(0, END) if 'password' in lct_inst.database[1].keys(): self.pwddb.insert(0, lct_inst.database[1]['password']) self.modules.select_clear(0, self.modules.size()) for mod_idx in range(len(self.module_data)): current_mod = self.module_data[mod_idx] if current_mod in lct_inst.modules: self.modules.select_set(mod_idx) current_lang = get_locale_lang() if 'LANGUAGE_CODE' in lct_inst.extra.keys(): current_lang = lct_inst.extra['LANGUAGE_CODE'] for lang in DEFAULT_LANGUAGES: if lang[0] == current_lang: self.language.current(self.language[VALUES].index(lang[1])) def execute(self, instance_name=None): from lucterios.framework.settings import DEFAULT_LANGUAGES, get_locale_lang self.mode[VALUES] = [ugettext( "CORE-connectmode.0"), ugettext("CORE-connectmode.1"), ugettext("CORE-connectmode.2")] self.language[VALUES] = [lang[1] for lang in DEFAULT_LANGUAGES] self.typedb[VALUES] = ["SQLite", "MySQL", "PostgreSQL"] lct_glob = LucteriosGlobal() _, self.mod_applis, mod_modules = lct_glob.installed() self.mod_applis.sort(key=lambda item: get_module_title(item[0])) self.modules.delete(0, END) self.module_data = [] module_list = [] for mod_module_item in mod_modules: module_list.append( (get_module_title(mod_module_item[0]), mod_module_item[0])) module_list.sort(key=lambda module: module[0]) for module_title, module_name in module_list: self.modules.insert(END, module_title) self.module_data.append(module_name) appli_list = [] for mod_appli_item in self.mod_applis: appli_list.append(get_module_title(mod_appli_item[0])) self.applis[VALUES] = appli_list if instance_name is not None: self._load_current_data(instance_name) else: self.typedb.current(0) self.mode.current(2) if len(appli_list) > 0: self.applis.current(0) self.appli_selection(None) self.mode_selection(None) self.typedb_selection(None) for lang in DEFAULT_LANGUAGES: if lang[0] == get_locale_lang(): self.language.current(self.language[VALUES].index(lang[1])) center(self)
class LucteriosMainForm(Tk, LucteriosMain): def __init__(self): Tk.__init__(self) LucteriosMain.__init__(self) try: try: self.tk.call('tk_getOpenFile', '-foobarbaz') except TclError: pass # now set the magic variables accordingly self.tk.call('set', '::tk::dialog::file::showHiddenBtn', '1') self.tk.call('set', '::tk::dialog::file::showHiddenVar', '0') except Exception: pass try: self.img = Image( "photo", file=join(dirname(import_module('lucterios.install').__file__), "lucterios.png")) self.tk.call('wm', 'iconphoto', self._w, self.img) except Exception: self.img = None self.start_up_app() self.has_checked = False self.title(ugettext("Lucterios launcher")) self.minsize(475, 260) self.grid_columnconfigure(0, weight=1) self.grid_rowconfigure(0, weight=1) self.resizable(True, True) self.protocol("WM_DELETE_WINDOW", self.on_closing) self.ntbk = ttk.Notebook(self) self.ntbk.grid(row=0, column=0, columnspan=1, sticky=(N, S, E, W)) self.create_instance_panel() self.create_module_panel() stl = ttk.Style() stl.theme_use("default") stl.configure("TProgressbar", thickness=5) self.progress = ttk.Progressbar(self, style="TProgressbar", orient='horizontal', mode='indeterminate') self.progress.grid(row=1, column=0, sticky=(E, W)) self.btnframe = Frame(self, bd=1) self.btnframe.grid(row=2, column=0, columnspan=1) Button(self.btnframe, text=ugettext("Refresh"), width=20, command=self.refresh).grid(row=0, column=0, padx=3, pady=3, sticky=(N, S)) self.btnupgrade = Button(self.btnframe, text=ugettext("Search upgrade"), width=20, command=self.upgrade) self.btnupgrade.config(state=DISABLED) self.btnupgrade.grid(row=0, column=1, padx=3, pady=3, sticky=(N, S)) Button(self.btnframe, text=ugettext("Close"), width=20, command=self.on_closing).grid(row=0, column=2, padx=3, pady=3, sticky=(N, S)) def show_splash_screen(self): if sys.platform != 'darwin': self.withdraw() self.splash = SplashScreen(self, self.img) def remove_splash_screen(self): self.splash.destroy_splash_screen() del self.splash self.deiconify() def show_info(self, text, message): showinfo(text, message) def show_error(self, text, message): showerror(text, message) def on_closing(self): if self.is_all_stop() or askokcancel( None, ugettext( "An instance is always running.\nDo you want to close?")): self.destroy() else: self.refresh() def destroy(self): self.stop_all() Tk.destroy(self) def create_instance_panel(self): frm_inst = Frame(self.ntbk) frm_inst.grid_columnconfigure(0, weight=1) frm_inst.grid_rowconfigure(0, weight=1) frm_inst.grid_columnconfigure(1, weight=3) frm_inst.grid_rowconfigure(1, weight=0) self.instance_list = Listbox(frm_inst, width=20) self.instance_list.bind('<<ListboxSelect>>', self.select_instance) self.instance_list.pack() self.instance_list.grid(row=0, column=0, sticky=(N, S, W, E)) self.instance_txt = Text(frm_inst, width=75) self.instance_txt.grid(row=0, column=1, rowspan=2, sticky=(N, S, W, E)) self.instance_txt.config(state=DISABLED) self.btninstframe = Frame(frm_inst, bd=1) self.btninstframe.grid(row=1, column=0, columnspan=1) self.btninstframe.grid_columnconfigure(0, weight=1) Button(self.btninstframe, text=ugettext("Launch"), width=25, command=self.open_inst).grid(row=0, column=0, columnspan=2, sticky=(N, S)) Button(self.btninstframe, text=ugettext("Modify"), width=10, command=self.modify_inst).grid(row=1, column=0, sticky=(N, S)) Button(self.btninstframe, text=ugettext("Delete"), width=10, command=self.delete_inst).grid(row=1, column=1, sticky=(N, S)) Button(self.btninstframe, text=ugettext("Save"), width=10, command=self.save_inst).grid(row=2, column=0, sticky=(N, S)) Button(self.btninstframe, text=ugettext("Restore"), width=10, command=self.restore_inst).grid(row=2, column=1, sticky=(N, S)) Button(self.btninstframe, text=ugettext("Add"), width=25, command=self.add_inst).grid(row=3, column=0, columnspan=2, sticky=(N, S)) self.ntbk.add(frm_inst, text=ugettext('Instances')) def create_module_panel(self): frm_mod = Frame(self.ntbk) frm_mod.grid_columnconfigure(0, weight=1) frm_mod.grid_rowconfigure(0, weight=1) self.module_txt = Text(frm_mod) self.module_txt.grid(row=0, column=0, sticky=(N, S, W, E)) self.module_txt.config(state=DISABLED) self.ntbk.add(frm_mod, text=ugettext('Modules')) def do_progress(self, progressing): if not progressing: self.progress.stop() self.progress.grid_remove() else: self.progress.start(25) self.progress.grid(row=1, column=0, sticky=(E, W)) def enabled(self, is_enabled, widget=None): if widget is None: widget = self self.do_progress(not is_enabled) if is_enabled: widget.config(cursor="") else: widget.config(cursor="watch") if isinstance(widget, Button) and (widget != self.btnupgrade): if is_enabled and (not hasattr(widget, 'disabled') or not widget.disabled): widget.config(state=NORMAL) else: widget.config(state=DISABLED) else: for child_cmp in widget.winfo_children(): self.enabled(is_enabled, child_cmp) @ThreadRun def refresh(self, instance_name=None): if instance_name is None: instance_name = self.get_selected_instance_name() self.instance_txt.delete("1.0", END) self._refresh_instance_list() self.set_select_instance_name(instance_name) if not self.has_checked: self._refresh_modules() if self.instance_list.size() == 0: sleep(.3) self._refresh_modules() sleep(.3) self.after_idle(self.add_inst) def run_after(self, ms, func=None, *args): self.after(ms, func, *args) def _refresh_modules(self): self.btnupgrade.config(state=DISABLED) self.module_txt.config(state=NORMAL) self.module_txt.delete("1.0", END) lct_glob = LucteriosGlobal() mod_lucterios, mod_applis, mod_modules = lct_glob.installed() self.module_txt.insert( END, ugettext("Lucterios core\t\t%s\n") % mod_lucterios[1]) self.module_txt.insert(END, '\n') self.module_txt.insert(END, ugettext("Application\n")) for appli_item in mod_applis: self.module_txt.insert( END, "\t%s\t%s\n" % (appli_item[0].ljust(30), appli_item[1])) self.module_txt.insert(END, ugettext("Modules\n")) for module_item in mod_modules: self.module_txt.insert( END, "\t%s\t%s\n" % (module_item[0].ljust(30), module_item[1])) extra_urls = lct_glob.get_extra_urls() if len(extra_urls) > 0: self.module_txt.insert(END, "\n") self.module_txt.insert(END, ugettext("Pypi servers\n")) for extra_url in extra_urls: self.module_txt.insert(END, "\t%s\n" % extra_url) self.module_txt.config(state=DISABLED) self.has_checked = True self.run_after(1000, lambda: Thread(target=self.check).start()) def _refresh_instance_list(self): self.instance_list.delete(0, END) luct_glo = LucteriosGlobal() instance_list = luct_glo.listing() for item in instance_list: self.instance_list.insert(END, item) if item not in self.running_instance.keys(): self.running_instance[item] = None instance_names = list(self.running_instance.keys()) for old_item in instance_names: if old_item not in instance_list: if self.running_instance[old_item] is not None: self.running_instance[old_item].stop() del self.running_instance[old_item] def set_select_instance_name(self, instance_name): cur_sel = 0 for sel_iter in range(self.instance_list.size()): if self.instance_list.get(sel_iter) == instance_name: cur_sel = sel_iter break self.instance_list.selection_set(cur_sel) self.select_instance(None) def get_selected_instance_name(self): if len(self.instance_list.curselection()) > 0: return self.instance_list.get( int(self.instance_list.curselection()[0])) else: return "" def set_ugrade_state(self, upgrade_mode): if upgrade_mode != 2: msg = ugettext("The application must restart") self.show_info(ugettext("Lucterios launcher"), msg) self.btnupgrade["text"] = msg self.btnupgrade.config(state=DISABLED) self._refresh_modules() else: self.btnupgrade["text"] = self.ugrade_message(upgrade_mode == 1) self.btnupgrade.config( state=NORMAL if upgrade_mode == 1 else DISABLED) def upgrade(self): self.btnupgrade.config(state=DISABLED) self.instance_list.config(state=DISABLED) try: LucteriosMain.upgrade(self) finally: self.btnupgrade.config(state=DISABLED) self.instance_list.config(state=NORMAL) @ThreadRun def select_instance(self, evt): if self.instance_list['state'] == NORMAL: self.instance_list.config(state=DISABLED) try: instance_name = self.get_selected_instance_name() self.instance_txt.configure(state=NORMAL) self.instance_txt.delete("1.0", END) if instance_name != '': if instance_name not in self.running_instance.keys(): self.running_instance[instance_name] = None inst = LucteriosInstance(instance_name) inst.read() self.instance_txt.insert(END, "\t\t\t%s\n\n" % inst.name) self.instance_txt.insert( END, ugettext("Database\t\t%s\n") % inst.get_database_txt()) self.instance_txt.insert( END, ugettext("Appli\t\t%s\n") % inst.get_appli_txt()) self.instance_txt.insert( END, ugettext("Modules\t\t%s\n") % inst.get_module_txt()) self.instance_txt.insert( END, ugettext("Extra\t\t%s\n") % inst.get_extra_txt()) self.instance_txt.insert(END, '\n') if self.running_instance[ instance_name] is not None and self.running_instance[ instance_name].is_running(): self.instance_txt.insert( END, ugettext("=> Running in http://%(ip)s:%(port)d\n") % { 'ip': self.running_instance[instance_name].lan_ip, 'port': self.running_instance[instance_name].port }) self.btninstframe.winfo_children( )[0]["text"] = ugettext("Stop") else: self.running_instance[instance_name] = None self.instance_txt.insert(END, ugettext("=> Stopped\n")) self.btninstframe.winfo_children( )[0]["text"] = ugettext("Launch") else: self.btninstframe.winfo_children()[0]["text"] = ugettext( "Launch") self.btninstframe.winfo_children()[0].disabled = ( instance_name == '') self.btninstframe.winfo_children()[1].disabled = ( instance_name == '') self.btninstframe.winfo_children()[2].disabled = ( instance_name == '') self.btninstframe.winfo_children()[3].disabled = ( instance_name == '') self.btninstframe.winfo_children()[4].disabled = ( instance_name == '') self.instance_txt.configure(state=DISABLED) finally: setup_from_none() self.instance_list.config(state=NORMAL) def add_inst(self): self.enabled(False) try: self.do_progress(False) ist_edt = InstanceEditor() ist_edt.execute() ist_edt.transient(self) self.wait_window(ist_edt) finally: self.enabled(True) if ist_edt.result is not None: self.add_modif_inst_result(ist_edt.result, True) def modify_inst(self): self.enabled(False) try: self.do_progress(False) ist_edt = InstanceEditor() ist_edt.execute(self.get_selected_instance_name()) ist_edt.transient(self) self.wait_window(ist_edt) finally: self.enabled(True) if ist_edt.result is not None: self.add_modif_inst_result(ist_edt.result, False) def delete_inst(self): setup_from_none() instance_name = self.get_selected_instance_name() if askokcancel(None, ugettext("Do you want to delete '%s'?") % instance_name): self.delete_inst_name(instance_name) else: self.refresh() def save_inst(self): instance_name = self.get_selected_instance_name() if instance_name != '': file_name = asksaveasfilename(parent=self, filetypes=[('lbk', '.lbk'), ('*', '.*')], initialdir=expanduser('~')) if file_name != '': self.save_instance(instance_name, file_name) def restore_inst(self): instance_name = self.get_selected_instance_name() if instance_name != '': file_name = askopenfilename(parent=self, filetypes=[('lbk', '.lbk'), ('*', '.*')], initialdir=expanduser('~')) if isinstance(file_name, str) and (file_name != ''): self.restore_instance(instance_name, file_name) def execute(self): self.refresh() center(self, (700, 300)) self.mainloop()
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 Window: FONT = ('Monospace', 11) ITEM_HEIGHT = 22 MAX_FOUND = 10 BG_COLOR = '#202b3a' FG_COLOR = '#ced0db' def resize(self, items): if self.resized: return self.root.geometry('{0}x{1}'.format( self.width, self.height + items * Window.ITEM_HEIGHT)) self.resized = True def __init__(self, root, width, height): self.root = root self.width = width self.height = height self.all_windows = [] self.resized = False # master.geometry(500) root.title("window switcher") root.resizable(width=False, height=False) root.configure(background=Window.BG_COLOR) # ugly tkinter code below sv = StringVar() sv.trace("w", lambda name, index, mode, sv=sv: self.on_entry(sv)) self.main_entry = Entry(root, font=Window.FONT, width=1000, textvariable=sv, bg=Window.BG_COLOR, fg=Window.FG_COLOR, insertbackground=Window.FG_COLOR, bd=0) self.main_entry.grid(row=0, column=0, padx=10) self.main_entry.focus_set() self.listbox = Listbox(root, height=Window.ITEM_HEIGHT, font=Window.FONT, highlightthickness=0, borderwidth=0, bg=Window.BG_COLOR, fg=Window.FG_COLOR, selectbackground='#2c3c51', selectforeground='#cedaed') self.listbox.grid(row=1, column=0, sticky='we', padx=10, pady=10) # key bindings self.main_entry.bind('<Control-a>', self.select_all) self.main_entry.bind('<Up>', self.select_prev) self.main_entry.bind('<Down>', self.select_next) self.main_entry.bind('<Return>', self.select_window) self.root.bind('<Escape>', lambda e: sys.exit()) # self.resize(Window.MAX_FOUND) self.initial_get(None) def initial_get(self, event): self.all_windows = get_windows() self.find_windows('') def select_all(self, event): # select text self.main_entry.select_clear() self.main_entry.select_range(0, 'end') # move cursor to the end self.main_entry.icursor('end') return 'break' def find_windows(self, text): text = text.lower() found = [ window for window in self.all_windows if window['name'].find(text) != -1 ] # print(found) self.found = found self.listbox.delete(0, 'end') for i, item in enumerate(found): if i >= Window.MAX_FOUND: break self.listbox.insert('end', item['name']) self.resize(min(len(found), Window.MAX_FOUND)) # select first element self.listbox.selection_set(0) def select_next(self, event): if len(self.found) == 0: return idx = self.listbox.curselection()[0] max = self.listbox.size() idx += 1 if idx >= max: idx = 0 self.listbox.selection_clear(0, 'end') self.listbox.selection_set(idx) def select_prev(self, event): if len(self.found) == 0: return idx = self.listbox.curselection()[0] max = self.listbox.size() idx -= 1 if idx < 0: idx = max - 1 self.listbox.selection_clear(0, 'end') self.listbox.selection_set(idx) def select_window(self, event): idx = self.listbox.curselection()[0] id = self.found[idx]['id'] # switch to window and exit # wmctrl -ia <id`> subprocess.call(['wmctrl', '-ia', id]) # print(subprocess.check_output(['wmctrl', '-ia', id]).decode('utf-8')) sys.exit(0) def on_entry(self, newtext): search_test = newtext.get() self.find_windows(search_test) return True
class BattleshipsDemoClient(Frame): def __init__(self, tk, args): Frame.__init__(self, tk) # empty string for platform's default settings locale.setlocale(locale.LC_ALL, '') self.master = tk tk.title(APP_TITLE) tk.resizable(False, False) try: if WINDOWS: tk.iconbitmap("200x200/icon.ico") else: tk.iconbitmap("@200x200/icon.xbm") except Exception as e: print(e) atexit.register(self.cancel_game) # Init class data fields that we use for storing info that we need for using the API self.bot_id = None self.bot_password = None self.logged_in = False self.game_style_ids = [] self.gameChips = 0 self.gameDeals = 0 self.gameStake = 0 self.gamePrize = 0 self.player_key = None self.play_again = BooleanVar() self.do_not_play_same_user = BooleanVar() self.close_after_game = False self.game_cancelled = False self.in_game = False self.topFrame = Frame(tk, padx=12, pady=12) self.middleFrame = Frame(tk, padx=12) self.middleFrameLeft = Frame(self.middleFrame) self.middleFrameRight = Frame(self.middleFrame) self.middleFrameRighter = Frame(self.middleFrame) self.topFrame.grid(row=0, sticky=W + E) self.middleFrame.grid(row=1, sticky=W) self.middleFrameLeft.grid(row=1, column=0) self.middleFrameRight.grid(row=1, column=1) self.middleFrameRighter.grid(row=1, column=2) # =================================== # Create form elements # Top Frame Elements self.botNameLabel = Label(self.topFrame, text="Bot Name:") self.bot_id_entry = Entry(self.topFrame) self.bot_id_entry.bind('<Return>', self.log_in_if_not) self.bot_id_entry.focus() self.passwordLabel = Label(self.topFrame, text="Password:"******"Login", command=self.log_in_out_clicked) self.balanceLabel = Label(self.topFrame, text="Bot Balance:") self.balance = Label(self.topFrame, text="0") self.close_button = Button(self.topFrame, text="Close", padx=2, command=tk.destroy) # Middle Frame Elements # Middle Frame LEFT Elements self.gameStyleLabel = Label(self.middleFrameLeft, font=(None, 18), pady=0, text="Game Style Selection") self.opponentLabel = Label(self.middleFrameLeft, text="Specify Opponent (optional):") self.specify_opponent_entry = Entry(self.middleFrameLeft) self.do_not_play_same_user_check = Checkbutton( self.middleFrameLeft, text='Don\'t play another bot in same user account as me', var=self.do_not_play_same_user) self.game_styles_listbox = Listbox(self.middleFrameLeft, background='#FFFFFF', height=8) self.game_styles_listbox.bind('<Double-1>', self.find_game_double_clicked) self.game_styles_listbox.bind( '<Return>', self.find_game_double_clicked ) # Not a double click but we want it to do the same thing self.refresh_game_styles_button = Button( self.middleFrameLeft, text="Refresh Game Styles", command=self.refresh_game_styles_clicked) self.thinkingTimeLabel = Label(self.middleFrameLeft, text="Add \"Thinking Time\" (ms):") self.thinking_time_entry = Entry(self.middleFrameLeft) self.auto_play_next_game_check = Checkbutton( self.middleFrameLeft, text='Play another game when complete', var=self.play_again) self.cancel_stop_game_button = Button( self.middleFrameLeft, text=CANCEL_GAME_TEXT, command=self.cancel_stop_game_clicked) self.find_game_button = Button(self.middleFrameLeft, text="Find Game", command=self.find_game_clicked) self.resultText = Message( self.middleFrameLeft, width=300, text="This is where the informational messages will appear") self.spacerLabel = Label(self.middleFrameLeft, text=" ") # Middle Frame RIGHT Elements self.gameTitleLabel = Label(self.middleFrameRight, text="Game Title") self.gameTitleText = Text(self.middleFrameRight, height=3, background='white', spacing1=3, pady=0) self.player = battleships_visuals.BattleshipsVisuals( self.middleFrameRight) # Game Display Table self.opponent = battleships_visuals.BattleshipsVisuals( self.middleFrameRight) # Game Display Table self.gameActionLabel = Label(self.middleFrameRight, text="") # =================================== # Set initial element states self.set_gamestyle_controls_states(DISABLED) self.cancel_stop_game_button.config(state=DISABLED) self.game_styles_listbox.config(background='white') self.thinking_time_entry.insert(0, 100) self.gameTitleText.config(state=DISABLED) self.set_balance(0) self.gameTitleText.tag_configure("center", justify='center') self.gameTitleText.tag_configure("bold", font='-weight bold') # =================================== # Form Layout # Top Frame Form Layout self.topFrame.grid_rowconfigure(0, weight=1) self.botNameLabel.grid(row=0, column=0, sticky=E) self.bot_id_entry.grid(row=0, column=1, sticky=W) self.passwordLabel.grid(row=0, column=2, sticky=E) self.bot_password_entry.grid(row=0, column=3, sticky=W) self.log_in_out_button.grid(row=0, column=4, sticky=E) self.topFrame.grid_columnconfigure(5, weight=1) self.balanceLabel.grid(row=0, column=5, sticky=E) self.balance.grid(row=0, column=6, sticky=W) self.close_button.grid(row=0, column=7, sticky=E, padx=(50, 0)) # Middle Frame Form Layout self.middleFrame.grid_rowconfigure(0, weight=1) self.gameStyleLabel.grid(row=0, column=0, columnspan=1, sticky=W + E) self.spacerLabel.grid(row=0, column=2, sticky=E) self.opponentLabel.grid(row=2, column=0, sticky=W, pady=4) self.specify_opponent_entry.grid(row=2, column=0, sticky=E, pady=4) self.do_not_play_same_user_check.grid(row=3, column=0, columnspan=1, sticky='we', pady=4) self.game_styles_listbox.grid(row=4, column=0, columnspan=1, sticky='we', pady=4) self.find_game_button.grid(row=5, column=0, pady=4, sticky=W) self.refresh_game_styles_button.grid(row=5, column=0, columnspan=1, sticky='', pady=4) self.cancel_stop_game_button.grid(row=5, column=0, sticky=E) self.thinkingTimeLabel.grid(row=6, column=0, sticky=W, pady=4) self.thinking_time_entry.grid(row=6, column=0, sticky=E, pady=4) self.auto_play_next_game_check.grid(row=7, column=0, columnspan=1, sticky=W, pady=4) self.resultText.grid(row=9, column=0, columnspan=2, sticky=W, pady=4) self.middleFrame.grid_columnconfigure(9, weight=1) self.gameTitleLabel.grid(row=0, column=3) self.gameTitleText.grid(row=0, column=3, columnspan=2) self.player.grid(row=1, column=3) self.opponent.grid(row=1, column=4) self.gameActionLabel.grid(row=11, column=3, sticky='w') if args.botid is not None: self.auto_play(args) def auto_play(self, args): self.bot_id_entry.insert(0, args.botid) self.bot_password_entry.insert(0, args.password) self.log_in_out_clicked() self.thinking_time_entry.insert(0, args.timeout) if args.playanothergame: self.auto_play_next_game_check.select() if args.dontplaysameuserbot: self.do_not_play_same_user_check.select() if args.closeaftergame: self.close_after_game = True i = 0 for i in range(self.game_styles_listbox.size()): if args.gamestyle in str(self.game_styles_listbox.get(i)): break self.game_styles_listbox.select_set(i, i) self.find_game_clicked() def log_in_out_clicked(self): """Click handler for the 'Login'/'Logout' button.""" # This means we're logging out if self.logged_in: self.resultText.config(text='Logged Out') self.master.title(APP_TITLE + " (Not Logged In)") self.cancel_game() self.bot_id = 'housebot-competition' self.bot_password = None self.clear_game_title_text() self.gameActionLabel.config(text="") self.reset_game_styles_listbox() self.clear_all_boards() self.opponent.delete("all") self.log_in_out_button.config(text='Login') self.set_login_controls_states(ENABLED) self.set_gamestyle_controls_states(DISABLED) self.logged_in = False self.bot_password_entry.delete(0, 'end') self.set_balance(0) # This means we're logging in else: self.bot_id = self.bot_id_entry.get() self.bot_password = '******' res = self.get_list_of_game_styles() if res['Result'] == 'SUCCESS': self.resultText.config(text='Logged In') game_styles = res['GameStyles'] self.master.title(self.bot_id + " - " + APP_TITLE) self.set_login_controls_states(DISABLED) self.set_gamestyle_controls_states(ENABLED) self.set_game_styles_listbox(game_styles) self.set_balance(res['Balance']) self.log_in_out_button.config(text='Logout') self.logged_in = True else: messagebox.showerror( 'Error', 'Invalid login attempt. Please check the username and password entered.' ) def log_in_if_not(self, _): if not self.logged_in: self.log_in_out_clicked() def clear_all_boards(self): self.player.delete("all") self.opponent.delete("all") self.player.myBoard = None self.opponent.oppBoard = None def set_in_game(self, value): self.in_game = value def set_game_title_text(self, text, tag): self.gameTitleText.config(state=ENABLED) self.gameTitleText.insert("end", text, ("center", tag)) self.gameTitleText.config(state=DISABLED) def clear_game_title_text(self): self.gameTitleText.config(state=ENABLED) self.gameTitleText.delete("1.0", "end") self.gameTitleText.config(state=DISABLED) def set_login_controls_states(self, state): self.bot_id_entry.config(state=state) self.bot_password_entry.config(state=state) def set_gamestyle_controls_states(self, state): self.specify_opponent_entry.config(state=state) self.do_not_play_same_user_check.config(state=state) self.game_styles_listbox.config(state=state) self.find_game_button.config(state=state) self.refresh_game_styles_button.config(state=state) self.auto_play_next_game_check.config(state=state) self.thinking_time_entry.config(state=state) self.opponentLabel.config(state=state) self.thinkingTimeLabel.config(state=state) self.balanceLabel.config(state=state) self.balance.config(state=state) self.gameStyleLabel.config(state=state) self.game_styles_listbox.config(state=state) self.player.config(state=state) self.opponent.config(state=state) def set_balance(self, balance): """Set the balance field""" self.balance['text'] = int_with_commas(balance) self.balance['text'] += ' sat' def get_list_of_game_styles(self): """Get list of game styles from the server.""" req = { 'BotId': self.bot_id, 'BotPassword': self.bot_password, 'GameTypeId': BATTLESHIPS_GAME_TYPE_ID } url = BASE_URL + GET_LIST_OF_GAME_STYLES_EXTENSION return BattleshipsDemoClient.make_api_call(url, req) def set_game_styles_listbox(self, game_styles): """Set the content of the game styles listbox with a list of GameStyle dictionaries. Keyword Arguments: game_styles -- The list of GameStyle dictionaries, this should be obtained through get_list_of_game_styles(). """ self.reset_game_styles_listbox() for index, game_style in enumerate(game_styles): self.game_styles_listbox.insert( index, GAME_STYLE_LISTBOX_TEXT.format( game_style['GameStyleId'], game_style['Stake'], game_style['GameTypeSpecificInfo']['Ships'], game_style['GameTypeSpecificInfo']['Board Size'], game_style['GameTypeSpecificInfo']['Timeout ms'], game_style['GameTypeSpecificInfo']['DealsTotal'], game_style['GameTypeSpecificInfo']['PercentageLand'], game_style['GameTypeSpecificInfo']['RandomLand'])) self.game_style_ids.append(game_style['GameStyleId']) # self.game_styles_listbox.select_set(GAME_STYLE_LISTBOX_DEFAULT_SELECTION) def reset_game_styles_listbox(self): """Clear the content of the game styles listbox.""" if self.game_styles_listbox.size() != 0: self.game_styles_listbox.delete(0, 'end') self.game_style_ids = [] def refresh_game_styles_clicked(self): """Click handler for the 'Refresh Game Styles' button.""" res = self.get_list_of_game_styles() game_styles = res['GameStyles'] self.set_game_styles_listbox(game_styles) def find_game_clicked(self): """Click handler for the 'Find Game' button""" self.find_game_button.config(state=DISABLED) self.cancel_stop_game_button.config(state=ENABLED) self.clear_all_boards() # Here we dispatch the work to a separate thread, to keep the GUI responsive. if not MAC: threading.Thread(target=self.game_loop, daemon=True).start() else: self.game_loop() # Doesn't work on MACs def find_game_double_clicked(self, _): self.find_game_clicked() def game_loop(self): """Loop through finding and playing games.""" while True: self.clear_all_boards() self.find_game() if self.game_cancelled: break self.play_game() if self.close_after_game: self.close_button.invoke() if self.game_cancelled: break if not self.play_again.get(): break self.find_game_button.config(state=ENABLED) self.cancel_stop_game_button.config(state=DISABLED, text=CANCEL_GAME_TEXT) self.game_cancelled = False def find_game(self): """Find a game.""" offer_game_res = self.offer_game() if offer_game_res['Result'] == 'INVALID_LOGIN_OR_PASSWORD': self.cancel_stop_game_clicked() if 'ErrorMessage' in offer_game_res and offer_game_res[ 'ErrorMessage'] == 'Check of OpponentId failed': self.resultText.config(text='Invalid Opponent ID') else: self.resultText.config(text='Invalid login or password') elif offer_game_res['Result'] == 'INSUFFICIENT_BALANCE': self.cancel_stop_game_clicked() self.resultText.config(text='Insufficient balance') elif offer_game_res['Result'] == 'BOT_IS_INACTIVE': self.cancel_stop_game_clicked() self.resultText.config(text='Bot is inactive') else: self.player_key = offer_game_res['PlayerKey'] if offer_game_res['Result'] == 'WAITING_FOR_GAME': self.wait_for_game() def offer_game(self): """Offer a game.""" opponent_id = self.specify_opponent_entry.get() if len(opponent_id) == 0: opponent_id = None try: game_style_id = self.game_style_ids[int( self.game_styles_listbox.curselection()[0])] except IndexError: self.game_styles_listbox.select_set( GAME_STYLE_LISTBOX_DEFAULT_SELECTION) game_style_id = self.game_style_ids[0] req = { 'BotId': self.bot_id, 'BotPassword': self.bot_password, 'MaximumWaitTime': 1000, 'GameStyleId': game_style_id, 'DontPlayAgainstSameUser': self.do_not_play_same_user.get(), 'DontPlayAgainstSameBot': False, 'OpponentId': opponent_id } url = BASE_URL + OFFER_GAME_EXTENSION return BattleshipsDemoClient.make_api_call(url, req) def wait_for_game(self): """Wait for game to start.""" self.resultText.config(text='Waiting for game') while True: if self.game_cancelled: self.cancel_game() self.find_game_button.config(state=ENABLED) self.cancel_stop_game_button.config(state=DISABLED, text=CANCEL_GAME_TEXT) break poll_results = self.poll_for_game_state() if poll_results['Result'] == 'SUCCESS': break if poll_results['Result'] == 'INVALID_PLAYER_KEY' or poll_results[ 'Result'] == 'GAME_HAS_ENDED' or poll_results[ 'Result'] == 'GAME_WAS_STOPPED': self.game_cancelled = True time.sleep(2) def play_game(self): """Play a game.""" self.resultText.config(text='Playing game') self.in_game = True poll_results = self.poll_for_game_state() if poll_results["Result"] != "SUCCESS": return game_state = poll_results['GameState'] title = format('Game ID: ' + str(game_state['GameId'])) game_style_details = self.game_styles_listbox.get('active').split( " | ") title += format(' / Style: ' + str(self.game_style_ids[int( self.game_styles_listbox.curselection()[0])])) title += format(' / Land: ' + game_style_details[6].split(" ")[2] + '%') title += format(' / Deals: ' + game_style_details[5].split(" ")[1]) title += format(' / ' + game_style_details[7]) title += "\n" versus = format(self.bot_id + ' vs ' + game_state['OpponentId']) self.clear_game_title_text() self.set_game_title_text(title, "") self.set_game_title_text(versus, "bold") self.middleFrame.update() while True: if self.game_cancelled: break if game_state['IsMover']: self.resultText.config(text='Playing Game - Your Turn') move = battleships_move.calculateMove(game_state) move_results = self.make_move(move) if move_results['Result'] == 'INVALID_MOVE': self.resultText.config(text="Invalid Move") elif move_results['Result'] != 'SUCCESS': self.resultText.config(text='Game has ended: ' + move_results['Result']) print("Game ended") break else: game_state = move_results['GameState'] else: self.resultText.config(text="Playing Game - Opponent's Turn") # ---- Code here will be called on your opponent's turn ---- # ---------------------------------------------------------- poll_results = self.poll_for_game_state() if poll_results['Result'] != 'SUCCESS': self.resultText.config(text='Game has ended: ' + poll_results['Result']) break game_state = poll_results['GameState'] if game_state['GameStatus'] != 'RUNNING': break self.middleFrameRight.update() try: if int(self.thinking_time_entry.get()) > 0: time.sleep((int(self.thinking_time_entry.get()) / 1000)) else: time.sleep(0.1) except ValueError: time.sleep(0.1) self.set_in_game(False) def make_move(self, move): """Make a move.""" req = { 'BotId': self.bot_id, 'BotPassword': self.bot_password, 'PlayerKey': self.player_key, 'Move': move } url = BASE_URL + MAKE_MOVE_EXTENSION result = BattleshipsDemoClient.make_api_call(url, req) if result['Result'] == 'SUCCESS' or "GAME_HAS_ENDED" in result[ 'Result']: print(result) try: self.player.draw_game_state(result['GameState'], True) self.opponent.draw_game_state(result['GameState'], False) except Exception as e: print("Gamestate error: " + str(e)) return result def poll_for_game_state(self): """Poll the server for the latest GameState.""" req = { 'BotId': self.bot_id, 'BotPassword': self.bot_password, 'MaximumWaitTime': 1000, 'PlayerKey': self.player_key } url = BASE_URL + POLL_FOR_GAME_STATE_EXTENSION result = BattleshipsDemoClient.make_api_call(url, req) if result['Result'] == 'SUCCESS' or "GAME_HAS_ENDED" in result[ 'Result']: self.player.draw_game_state(result['GameState'], True) self.opponent.draw_game_state(result['GameState'], False) return result def cancel_stop_game_clicked(self): self.game_cancelled = True self.cancel_game() self.find_game_button.config(state=ENABLED) self.cancel_stop_game_button.config(state=DISABLED, text=CANCEL_GAME_TEXT) def cancel_game(self): if self.player_key is None: return req = { 'BotId': self.bot_id, 'BotPassword': self.bot_password, 'PlayerKey': self.player_key } url = BASE_URL + CANCEL_GAME_OFFER_EXTENSION BattleshipsDemoClient.make_api_call(url, req) try: self.resultText.config(text='Cancelled game') except Exception as e: print(str(e) + " -- resultText Message object no longer exists") @staticmethod def make_api_call(url, req): """Make an API call.""" while True: try: res = requests.post(url, json=req, headers=API_CALL_HEADERS, timeout=60.0) try: jres = res.json() if 'Result' in jres: return jres time.sleep(0.1) except ValueError: time.sleep(0.1) except requests.ConnectionError: time.sleep(0.1) except requests.Timeout: time.sleep(0.1) except requests.HTTPError: time.sleep(0.1) except BaseException as e: # Bad code but needed for testing purposes print(e) time.sleep(0.1)
class selecFAULT_tk(): def __init__(self, Run_Name, Model_name, File_geom, File_faults_n_scenarios, scenario_set): self.Run_Name = Run_Name self.Model_name = Model_name self.File_geom = File_geom self.File_faults_n_scenarios = File_faults_n_scenarios self.scenario_set = scenario_set self.initialize() def initialize(self): self.IG = tk.Tk() self.IG.title('For ' + str(self.Model_name) + ' and ' + str(self.scenario_set)) self.IG.grid() self.FaultGeometry() self.FAULTSelect = StringVar() self.choixFAULT = list(set(self.Column_Fault_name)) self.listeFAULT = Combobox(self.IG, textvariable=self.FAULTSelect, values=self.choixFAULT, state='readonly') self.listeFAULT.grid(column=0, row=0, sticky='EW') self.listeFAULT.current(0) add_fault_button = Button(self.IG, text=u"Add fault to model", command=self.Add_fault_ButtonClick) add_fault_button.grid(column=1, row=0) add_all_faults_button = Button(self.IG, text=u"Add all faults to model", command=self.Add_all_faults_ButtonClick) add_all_faults_button.grid(column=4, row=0) suppr_fault_button = Button(self.IG, text=u"Delete fault from model", command=self.Delete_fault_ButtonClick) suppr_fault_button.grid(column=2, row=0) add_fault_to_scenario_button = Button( self.IG, text=u"Add fault to scenario", command=self.Add_fault_to_scenario_ButtonClick) add_fault_to_scenario_button.grid(column=2, row=1) suppr_fault_from_scenario_button = Button( self.IG, text=u"Delete fault from scenario", command=self.Delete_fault_from_scenario_ButtonClick) suppr_fault_from_scenario_button.grid(column=2, row=2) add_scenario_button = Button(self.IG, text=u"Add scenario to model", command=self.Add_scenario_ButtonClick) add_scenario_button.grid(column=6, row=1) suppr_scenario_button = Button( self.IG, text=u"Delete scenario from model", command=self.Delete_scenario_ButtonClick) suppr_scenario_button.grid(column=6, row=2) calcul_button = Button(self.IG, text=u"Create input file", command=self.CalculButtonClick) calcul_button.grid(column=14, row=10) self.ouverture_calcul = 0 self.listechoix_fault = Listbox(self.IG) self.listechoix_fault.grid(column=0, row=1, columnspan=2, rowspan=3, sticky='EW') self.listechoix_scenario_tmp = Listbox(self.IG) self.listechoix_scenario_tmp.grid(column=4, row=1, columnspan=2, rowspan=3, sticky='EW') self.listechoix_scenario = Listbox(self.IG, width=50) self.listechoix_scenario.grid(column=7, row=1, columnspan=4, rowspan=4, sticky='EW') self.IG.grid_columnconfigure(0, weight=1) self.IG.resizable(True, True) self.IG.mainloop() def Add_fault_ButtonClick(self): longueur_liste = self.listechoix_fault.size() compteur = 0 for i in range(longueur_liste): if self.listeFAULT.get() == self.listechoix_fault.get(i): compteur = compteur + 1 if compteur == 0: self.listechoix_fault.insert(END, self.listeFAULT.get()) else: messagebox.showerror('Error', 'FAULT already selected') def Add_all_faults_ButtonClick(self): longueur_liste = self.listechoix_fault.size() compteur = 0 for i in range(longueur_liste): if self.listeFAULT.get() == self.listechoix_fault.get(i): compteur = compteur + 1 if compteur == 0: for i in range(len(self.choixFAULT)): self.listechoix_fault.insert(END, self.choixFAULT[i]) else: messagebox.showerror('Error', 'FAULT already selected') def Add_fault_to_scenario_ButtonClick(self): items = self.listechoix_fault.curselection() longueur_liste = self.listechoix_scenario_tmp.size() compteur = 0 for i in range(longueur_liste): if self.listechoix_fault.get( items) == self.listechoix_scenario_tmp.get(i): compteur = compteur + 1 if compteur == 0: self.listechoix_scenario_tmp.insert( END, self.listechoix_fault.get(items)) else: messagebox.showerror('Error', 'FAULT already selected') def Add_scenario_ButtonClick(self): longueur_liste = self.listechoix_scenario.size() longueur_liste_tmp = self.listechoix_scenario_tmp.size() scenario = '' for i in range(longueur_liste_tmp): if scenario == '': scenario += self.listechoix_scenario_tmp.get(i) else: scenario += ' ' + self.listechoix_scenario_tmp.get(i) compteur = 0 for i in range(longueur_liste): if scenario == self.listechoix_scenario.get(i): compteur = compteur + 1 if compteur == 0: self.listechoix_scenario.insert(END, scenario) else: messagebox.showerror('Error', 'Scenario already selected') pos = 0 for i in range(longueur_liste_tmp): idx = int(i) - pos self.listechoix_scenario_tmp.delete(idx, idx) pos = pos + 1 def Delete_fault_ButtonClick(self): items = self.listechoix_fault.curselection() pos = 0 for i in items: idx = int(i) - pos self.listechoix_fault.delete(idx, idx) pos = pos + 1 def Delete_fault_from_scenario_ButtonClick(self): items = self.listechoix_scenario_tmp.curselection() pos = 0 for i in items: idx = int(i) - pos self.listechoix_scenario_tmp.delete(idx, idx) pos = pos + 1 def Delete_scenario_ButtonClick(self): items = self.listechoix_scenario.curselection() pos = 0 for i in items: idx = int(i) - pos self.listechoix_scenario.delete(idx, idx) pos = pos + 1 def CalculButtonClick(self): #WaitWindow(self) if self.ouverture_calcul == 0: faults_n_scenar = open(self.File_faults_n_scenarios, 'w') longueur_liste_faults = self.listechoix_fault.size() line_faults = '' for i in range(longueur_liste_faults): if line_faults == '': line_faults += self.listechoix_fault.get(i) else: line_faults += ' ' + self.listechoix_fault.get(i) faults_n_scenar.write(line_faults) longueur_liste_scenario = self.listechoix_scenario.size() for i in range(longueur_liste_scenario): line_scenario = '\n' + self.listechoix_scenario.get(i) faults_n_scenar.write(line_scenario) faults_n_scenar.close() #WaitWindow(self) #Finn dances self.ouverture_calcul = 1 self.IG.destroy() def FaultGeometry(self): NomFichier_InfosZonage = self.File_geom InfosZonage = np.genfromtxt(NomFichier_InfosZonage, dtype=[('U100'), ('U100'), ('f8'), ('f8')], skip_header=1) Column_model_name = list( map(lambda i: InfosZonage[i][0], range(len(InfosZonage)))) index_model = np.where(np.array(Column_model_name) == self.Model_name) self.Column_Fault_name = list( map(lambda i: InfosZonage[i][1], index_model[0]))
class Controller: SNAP_RADIUS = 5 def __init__(self, tk: Tk): tk.title("Layered Polygons") menubar = Menu(tk) menu_file = Menu(menubar, tearoff=0) menu_file.add_command(label="New...", command=self._new_scene) menu_file.add_command(label="Open...", command=self._open_scene) menu_file.add_separator() menu_file.add_command(label="Save", command=self._save_scene) menu_file.add_command(label="Save As...", command=self._save_scene_as) menu_file.add_separator() menu_export = Menu(menu_file, tearoff=0) menu_export.add_command(label="Wavefront (.obj)...", command=self._export_obj) menu_file.add_cascade(label="Export As", menu=menu_export) menu_file.add_separator() menu_file.add_command(label="Quit", command=self._quit_app) menubar.add_cascade(label="File", menu=menu_file) tk.config(menu=menubar) paned = PanedWindow(tk, relief=RAISED) paned.pack(fill=BOTH, expand=1) frame = Frame(paned) paned.add(frame) self._canvas = LayPolyCanvas(frame) bar_x = Scrollbar(frame, orient=HORIZONTAL) bar_x.pack(side=BOTTOM, fill=X) bar_x.config(command=self._canvas.xview) bar_y = Scrollbar(frame, orient=VERTICAL) bar_y.pack(side=RIGHT, fill=Y) bar_y.config(command=self._canvas.yview) self._canvas.config(xscrollcommand=bar_x.set, yscrollcommand=bar_y.set) self._canvas.pack(side=LEFT, expand=True, fill=BOTH) # Thanks to the two guys on Stack Overflow for that! # ( http://stackoverflow.com/a/7734187 ) self._layer_list = Listbox(paned, selectmode=SINGLE) paned.add(self._layer_list) self._scene = None self._current_layer = None self._is_drawing_polygon = False self._tk = tk self._canvas.bind("<Button-1>", self._canvas_left_click) self._canvas.bind("<Button-3>", self._canvas_right_click) self._canvas.bind("<Motion>", self._canvas_mouse_moved) self._layer_list.bind("<<ListboxSelect>>", self._layer_change) self._current_path = None def _canvas_left_click(self, event): if not self._scene or not self._current_layer: return x, y = self._canvas.window_to_canvas_coords(event.x, event.y) if self._is_drawing_polygon: polygon = self._current_layer.get_polygon_at(-1) # Move vtx away from mouse to not interfere with search for closest polygon.get_vertex_at(-1).\ set_coords(x-self.SNAP_RADIUS, y-self.SNAP_RADIUS) closest_vertex = self._current_layer.get_closest_vertex( x, y, self.SNAP_RADIUS) if closest_vertex: polygon.remove_vertex_at(-1) if closest_vertex is polygon.get_vertex_at(0): self._is_drawing_polygon = False else: polygon.add_vertex(closest_vertex) polygon.add_vertex(Vertex(x, y)) else: polygon.get_vertex_at(-1)\ .set_coords(x, y) polygon.add_vertex(Vertex(x, y)) self._canvas.notify_polygon_change(self._current_layer .get_polygon_count()-1) else: # Create start vertex or use already existing one start_vertex = self._current_layer\ .get_closest_vertex(x, y, self.SNAP_RADIUS) if not start_vertex: start_vertex = Vertex(x, y) # Vertex for mouse cursor next_vertex = Vertex(x, y) self._current_layer.add_polygon( Polygon([start_vertex, next_vertex])) self._is_drawing_polygon = True self._canvas.notify_layer_change() def _canvas_right_click(self, event): if not self._current_layer: return if self._is_drawing_polygon: self._current_layer.remove_polygon_at(-1) self._is_drawing_polygon = False else: x, y = self._canvas.window_to_canvas_coords(event.x, event.y) for i in range(0, self._current_layer.get_polygon_count()): if self._current_layer.get_polygon_at(i).contains(x, y): self._current_layer.remove_polygon_at(i) break self._canvas.notify_layer_change() def _canvas_mouse_moved(self, event): if self._is_drawing_polygon: x, y = self._canvas.window_to_canvas_coords(event.x, event.y) self._current_layer.get_polygon_at(-1).get_vertex_at(-1)\ .set_coords(x, y) self._canvas.notify_polygon_change(self._current_layer .get_polygon_count()-1) def _layer_change(self, event): selection = self._layer_list.curselection() if len(selection) > 0 and self._scene: layer = self._scene.get_layer_at(selection[0]) if layer: self._is_drawing_polygon = False self._current_layer = layer self._canvas.notify_new_layer(self._current_layer) def _set_scene(self, scene: Scene) -> bool: if scene.get_layer_count() <= 0: messagebox.showerror("Error!", "Scene has no layers!") return False self._scene = scene # Prepare canvas # TODO Extra 10px padding for canvas width, height = self._scene.get_size() self._canvas.config(scrollregion=(0, 0, width, height)) # Empty listbox, fill it, select first entry self._layer_list.delete(0, self._layer_list.size()-1) for i in range(0, self._scene.get_layer_count()): self._layer_list.insert(i, self._scene.get_layer_at(i).get_name()) self._layer_list.selection_set(0) self._layer_list.event_generate("<<ListboxSelect>>") return True def _set_current_path(self, path): self._current_path = path if path: self._tk.title(path + " - Layered Polygons") else: self._tk.title("Untitled - Layered Polygons") def _new_scene(self): path = filedialog.askopenfilename(defaultextension=".ora", filetypes=[("OpenRaster files", ".ora")]) if not path: return scene = ora.read(path) if not scene: messagebox.showerror("Error!", "File could not be opened!") return if self._set_scene(scene): self._set_current_path(None) def _open_scene(self): path = filedialog.askopenfilename(defaultextension=".lp", filetypes=[("Layered polygons" " files", ".lp")]) if not path: return scene = lp.read(path) if not scene: messagebox.showerror("Error!", "File could not be opened!") return if self._set_scene(scene): self._set_current_path(path) def _save_scene_help(self, path): if lp.save(path, self._scene): self._set_current_path(path) else: messagebox.showerror("Error!", "File could not be saved!") def _save_scene(self): if not self._current_path: self._save_scene_as() return self._save_scene_help(self._current_path) def _save_scene_as(self): if not self._scene: return path = filedialog.asksaveasfilename(defaultextension=".lp", filetypes=[("Layered polygons" " files", ".lp")]) if path: self._save_scene_help(path) def _export_obj(self): if not self._scene: return path_obj = filedialog.asksaveasfilename(defaultextension=".obj", filetypes=[("Wavefront object" " files", ".obj")]) if not path_obj: return path_obj, path_mtl, path_data = obj.get_paths(path_obj) obj.save(path_obj, path_mtl, path_data, self._scene) def _quit_app(self): self._tk.quit() exit()
class MyFirstGUI: def __init__(self, tkRoot): self.tkRoot = tkRoot self.con = pyodbc.connect(driver="{SQL Server}", server=".", database="DomoticaDB") self.dbCmd = "SELECT * FROM [dbo].[Items]" tkRoot.title("SQL monitor") # Top Frame --- --- --- self.labelsFrame = Frame(tkRoot) self.labelsFrame.pack(fill="both", expand='YES') self.listbox = Listbox(self.labelsFrame) self.listbox.pack(fill="both", expand='YES') self.listbox.config(font='Consolas', justify='center') # Bottom Frame --- --- --- self.bottomFrame = Frame(tkRoot) self.bottomFrame.pack(fill="both", expand='YES') self.label = Label(self.bottomFrame, text="Placeholder") self.label.pack(side="left", expand='yes') self.entry = Entry(self.bottomFrame, width=0) self.entry.insert(0, self.dbCmd) self.entry.pack(side="left", expand='yes') # Root Frame --- --- --- self.greet_button = Button(tkRoot, text="Update Query", command=self.update_query) self.greet_button.pack() self.close_button = Button(tkRoot, text="Close", command=tkRoot.quit) self.close_button.pack() self.tkRoot.after(1000, self.update) def update_query(self): self.label.configure(text=self.entry.get()) self.dbCmd = self.entry.get() def update(self): msg = self.get_sql(self.dbCmd) self.listbox.delete(0, END) [self.listbox.insert(END, item) for item in msg] for each in range(0, self.listbox.size()): self.listbox.itemconfig(each, bg=self.tkRoot['bg']) self.listbox.config(width=0) self.tkRoot.after(1000, self.update) #self.entry.delete(0, "end") #self.entry.insert(0, self.dbCmd) def get_sql(self, cmd): cur = self.con.cursor() res = cur.execute(cmd) ret = [] for r in res: for each in [0, 3, 4]: if (r[each] is None): r[each] = "" ret.append( f"Id: {r[0]:>10} \tName: {r[3][:20] : <25} \tNice name: {r[4][:20]:<25}" ) #" \tknown_device_id: {r[10]}") # if( "zwave" in r[4]): # if(r[3] is not None and r[9] is not None): # ret.append() # else: # if r[3] is None: # r[3] = "None" # if r[9] is None: # r[9] = "None" # ret.append(f"Id: {r[0]} \tName: {r[3][:20]:<25} \tNice name: {r[9][:20]:<25} \tknown_device_id: {r[11]}") return ret
class DrtGlueDemo: def __init__(self, examples): # Set up the main window. self._top = Tk() self._top.title("DRT Glue Demo") # Set up key bindings. self._init_bindings() # Initialize the fonts.self._error = None self._init_fonts(self._top) self._examples = examples self._readingCache = [None for example in examples] # The user can hide the grammar. self._show_grammar = IntVar(self._top) self._show_grammar.set(1) # Set the data to None self._curExample = -1 self._readings = [] self._drs = None self._drsWidget = None self._error = None self._init_glue() # Create the basic frames. self._init_menubar(self._top) self._init_buttons(self._top) self._init_exampleListbox(self._top) self._init_readingListbox(self._top) self._init_canvas(self._top) # Resize callback self._canvas.bind("<Configure>", self._configure) ######################################### ## Initialization Helpers ######################################### def _init_glue(self): tagger = RegexpTagger([ ("^(David|Mary|John)$", "NNP"), ( "^(walks|sees|eats|chases|believes|gives|sleeps|chases|persuades|tries|seems|leaves)$", "VB", ), ("^(go|order|vanish|find|approach)$", "VB"), ("^(a)$", "ex_quant"), ("^(every)$", "univ_quant"), ("^(sandwich|man|dog|pizza|unicorn|cat|senator)$", "NN"), ("^(big|gray|former)$", "JJ"), ("^(him|himself)$", "PRP"), ]) depparser = MaltParser(tagger=tagger) self._glue = DrtGlue(depparser=depparser, remove_duplicates=False) def _init_fonts(self, root): # See: <http://www.astro.washington.edu/owen/ROTKFolklore.html> self._sysfont = Font(font=Button()["font"]) root.option_add("*Font", self._sysfont) # TWhat's our font size (default=same as sysfont) self._size = IntVar(root) self._size.set(self._sysfont.cget("size")) self._boldfont = Font(family="helvetica", weight="bold", size=self._size.get()) self._font = Font(family="helvetica", size=self._size.get()) if self._size.get() < 0: big = self._size.get() - 2 else: big = self._size.get() + 2 self._bigfont = Font(family="helvetica", weight="bold", size=big) def _init_exampleListbox(self, parent): self._exampleFrame = listframe = Frame(parent) self._exampleFrame.pack(fill="both", side="left", padx=2) self._exampleList_label = Label(self._exampleFrame, font=self._boldfont, text="Examples") self._exampleList_label.pack() self._exampleList = Listbox( self._exampleFrame, selectmode="single", relief="groove", background="white", foreground="#909090", font=self._font, selectforeground="#004040", selectbackground="#c0f0c0", ) self._exampleList.pack(side="right", fill="both", expand=1) for example in self._examples: self._exampleList.insert("end", (" %s" % example)) self._exampleList.config(height=min(len(self._examples), 25), width=40) # Add a scrollbar if there are more than 25 examples. if len(self._examples) > 25: listscroll = Scrollbar(self._exampleFrame, orient="vertical") self._exampleList.config(yscrollcommand=listscroll.set) listscroll.config(command=self._exampleList.yview) listscroll.pack(side="left", fill="y") # If they select a example, apply it. self._exampleList.bind("<<ListboxSelect>>", self._exampleList_select) def _init_readingListbox(self, parent): self._readingFrame = listframe = Frame(parent) self._readingFrame.pack(fill="both", side="left", padx=2) self._readingList_label = Label(self._readingFrame, font=self._boldfont, text="Readings") self._readingList_label.pack() self._readingList = Listbox( self._readingFrame, selectmode="single", relief="groove", background="white", foreground="#909090", font=self._font, selectforeground="#004040", selectbackground="#c0f0c0", ) self._readingList.pack(side="right", fill="both", expand=1) # Add a scrollbar if there are more than 25 examples. listscroll = Scrollbar(self._readingFrame, orient="vertical") self._readingList.config(yscrollcommand=listscroll.set) listscroll.config(command=self._readingList.yview) listscroll.pack(side="right", fill="y") self._populate_readingListbox() def _populate_readingListbox(self): # Populate the listbox with integers self._readingList.delete(0, "end") for i in range(len(self._readings)): self._readingList.insert("end", (" %s" % (i + 1))) self._readingList.config(height=min(len(self._readings), 25), width=5) # If they select a example, apply it. self._readingList.bind("<<ListboxSelect>>", self._readingList_select) def _init_bindings(self): # Key bindings are a good thing. self._top.bind("<Control-q>", self.destroy) self._top.bind("<Control-x>", self.destroy) self._top.bind("<Escape>", self.destroy) self._top.bind("n", self.next) self._top.bind("<space>", self.next) self._top.bind("p", self.prev) self._top.bind("<BackSpace>", self.prev) def _init_buttons(self, parent): # Set up the frames. self._buttonframe = buttonframe = Frame(parent) buttonframe.pack(fill="none", side="bottom", padx=3, pady=2) Button( buttonframe, text="Prev", background="#90c0d0", foreground="black", command=self.prev, ).pack(side="left") Button( buttonframe, text="Next", background="#90c0d0", foreground="black", command=self.next, ).pack(side="left") def _configure(self, event): self._autostep = 0 (x1, y1, x2, y2) = self._cframe.scrollregion() y2 = event.height - 6 self._canvas["scrollregion"] = "%d %d %d %d" % (x1, y1, x2, y2) self._redraw() def _init_canvas(self, parent): self._cframe = CanvasFrame( parent, background="white", # width=525, height=250, closeenough=10, border=2, relief="sunken", ) self._cframe.pack(expand=1, fill="both", side="top", pady=2) canvas = self._canvas = self._cframe.canvas() # Initially, there's no tree or text self._tree = None self._textwidgets = [] self._textline = None def _init_menubar(self, parent): menubar = Menu(parent) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label="Exit", underline=1, command=self.destroy, accelerator="q") menubar.add_cascade(label="File", underline=0, menu=filemenu) actionmenu = Menu(menubar, tearoff=0) actionmenu.add_command(label="Next", underline=0, command=self.next, accelerator="n, Space") actionmenu.add_command(label="Previous", underline=0, command=self.prev, accelerator="p, Backspace") menubar.add_cascade(label="Action", underline=0, menu=actionmenu) optionmenu = Menu(menubar, tearoff=0) optionmenu.add_checkbutton( label="Remove Duplicates", underline=0, variable=self._glue.remove_duplicates, command=self._toggle_remove_duplicates, accelerator="r", ) menubar.add_cascade(label="Options", underline=0, menu=optionmenu) viewmenu = Menu(menubar, tearoff=0) viewmenu.add_radiobutton( label="Tiny", variable=self._size, underline=0, value=10, command=self.resize, ) viewmenu.add_radiobutton( label="Small", variable=self._size, underline=0, value=12, command=self.resize, ) viewmenu.add_radiobutton( label="Medium", variable=self._size, underline=0, value=14, command=self.resize, ) viewmenu.add_radiobutton( label="Large", variable=self._size, underline=0, value=18, command=self.resize, ) viewmenu.add_radiobutton( label="Huge", variable=self._size, underline=0, value=24, command=self.resize, ) menubar.add_cascade(label="View", underline=0, menu=viewmenu) helpmenu = Menu(menubar, tearoff=0) helpmenu.add_command(label="About", underline=0, command=self.about) menubar.add_cascade(label="Help", underline=0, menu=helpmenu) parent.config(menu=menubar) ######################################### ## Main draw procedure ######################################### def _redraw(self): canvas = self._canvas # Delete the old DRS, widgets, etc. if self._drsWidget is not None: self._drsWidget.clear() if self._drs: self._drsWidget = DrsWidget(self._canvas, self._drs) self._drsWidget.draw() if self._error: self._drsWidget = DrsWidget(self._canvas, self._error) self._drsWidget.draw() ######################################### ## Button Callbacks ######################################### def destroy(self, *e): self._autostep = 0 if self._top is None: return self._top.destroy() self._top = None def prev(self, *e): selection = self._readingList.curselection() readingListSize = self._readingList.size() # there are readings if readingListSize > 0: # if one reading is currently selected if len(selection) == 1: index = int(selection[0]) # if it's on (or before) the first item if index <= 0: self._select_previous_example() else: self._readingList_store_selection(index - 1) else: # select its first reading self._readingList_store_selection(readingListSize - 1) else: self._select_previous_example() def _select_previous_example(self): # if the current example is not the first example if self._curExample > 0: self._exampleList_store_selection(self._curExample - 1) else: # go to the last example self._exampleList_store_selection(len(self._examples) - 1) def next(self, *e): selection = self._readingList.curselection() readingListSize = self._readingList.size() # if there are readings if readingListSize > 0: # if one reading is currently selected if len(selection) == 1: index = int(selection[0]) # if it's on (or past) the last item if index >= (readingListSize - 1): self._select_next_example() else: self._readingList_store_selection(index + 1) else: # select its first reading self._readingList_store_selection(0) else: self._select_next_example() def _select_next_example(self): # if the current example is not the last example if self._curExample < len(self._examples) - 1: self._exampleList_store_selection(self._curExample + 1) else: # go to the first example self._exampleList_store_selection(0) def about(self, *e): ABOUT = ( "NLTK Discourse Representation Theory (DRT) Glue Semantics Demo\n" + "Written by Daniel H. Garrette") TITLE = "About: NLTK DRT Glue Demo" try: from tkinter.messagebox import Message Message(message=ABOUT, title=TITLE).show() except: ShowText(self._top, TITLE, ABOUT) def postscript(self, *e): self._autostep = 0 self._cframe.print_to_file() def mainloop(self, *args, **kwargs): """ Enter the Tkinter mainloop. This function must be called if this demo is created from a non-interactive program (e.g. from a secript); otherwise, the demo will close as soon as the script completes. """ if in_idle(): return self._top.mainloop(*args, **kwargs) def resize(self, size=None): if size is not None: self._size.set(size) size = self._size.get() self._font.configure(size=-(abs(size))) self._boldfont.configure(size=-(abs(size))) self._sysfont.configure(size=-(abs(size))) self._bigfont.configure(size=-(abs(size + 2))) self._redraw() def _toggle_remove_duplicates(self): self._glue.remove_duplicates = not self._glue.remove_duplicates self._exampleList.selection_clear(0, "end") self._readings = [] self._populate_readingListbox() self._readingCache = [None for ex in self._examples] self._curExample = -1 self._error = None self._drs = None self._redraw() def _exampleList_select(self, event): selection = self._exampleList.curselection() if len(selection) != 1: return self._exampleList_store_selection(int(selection[0])) def _exampleList_store_selection(self, index): self._curExample = index example = self._examples[index] self._exampleList.selection_clear(0, "end") if example: cache = self._readingCache[index] if cache: if isinstance(cache, list): self._readings = cache self._error = None else: self._readings = [] self._error = cache else: try: self._readings = self._glue.parse_to_meaning(example) self._error = None self._readingCache[index] = self._readings except Exception as e: self._readings = [] self._error = DrtVariableExpression( Variable("Error: " + str(e))) self._readingCache[index] = self._error # add a star to the end of the example self._exampleList.delete(index) self._exampleList.insert(index, (" %s *" % example)) self._exampleList.config(height=min( len(self._examples), 25), width=40) self._populate_readingListbox() self._exampleList.selection_set(index) self._drs = None self._redraw() def _readingList_select(self, event): selection = self._readingList.curselection() if len(selection) != 1: return self._readingList_store_selection(int(selection[0])) def _readingList_store_selection(self, index): reading = self._readings[index] self._readingList.selection_clear(0, "end") if reading: self._readingList.selection_set(index) self._drs = reading.simplify().normalize().resolve_anaphora() self._redraw()
class OSCRemote(object): def __init__(self): self.editor_issue = "1.3" # get command options self.command_options = remote_options() # get directory holding the code self.pp_dir = sys.path[0] if not os.path.exists(self.pp_dir + os.sep + "pp_oscremote.py"): tkinter.messagebox.showwarning("Pi Presents", "Bad Application Directory") exit() # Initialise logging Monitor.log_path = self.pp_dir self.mon = Monitor() self.mon.init() Monitor.classes = ['OSCRemote', 'OSCConfig', 'OSCEditor'] Monitor.log_level = int(self.command_options['debug']) self.mon.log(self, "Pi Presents Remote is starting") self.mon.log(self, " OS and separator " + os.name + ' ' + os.sep) self.mon.log(self, "sys.path[0] - location of code: code " + sys.path[0]) self.root = Tk() # OSC config class self.osc_config = OSCConfig() self.osc_config_file = self.pp_dir + os.sep + 'pp_config' + os.sep + 'pp_oscremote.cfg' self.read_create_osc() self.setup_gui() if self.osc_config.this_unit_ip == '': self.mon.err(self, 'IP of own unit must be provided in oscremote.cfg') self.init() #and start the system self.root.after(1000, self.run_app) self.root.mainloop() def init(self): #self.osc_config_file = self.pp_dir + os.sep + 'pp_config' + os.sep + 'pp_oscremote.cfg' #self.read_create_osc() self.pp_home_dir = self.command_options['home'] + '/pp_home' self.mon.log(self, "Data Home from options is " + self.pp_home_dir) self.pp_profile_dir = '' self.current_showlist = None self.current_show = None self.current_show_ref = '' self.shows_display.delete(0, END) self.results.set('') self.desc.set('Listening to replies from Slave on: ' + self.osc_config.this_unit_ip + ':' + self.osc_config.reply_listen_port) def add_status(self, text): self.status_display.insert(END, text + '\n') self.status_display.see(END) def run_app(self): self.output_client = None self.output_reply_server = None self.output_reply_thread = None if self.osc_config.master_enabled != 'yes': self.mon.err(self, 'OSC Master is not enabled in oscremote.cfg') return if self.osc_config.reply_listen_port == '': self.mon.err(self, 'Reply Listen port is not set in oscremote.cfg') return self.prefix = '/pipresents' self.this_unit = '/' + self.osc_config.this_unit_name self.add_status("This unit's OSC address is: " + self.this_unit) self.slave_unit = '/' + self.osc_config.slave_units_name self.add_status('Slave unit OSC address is: ' + self.slave_unit) #connect client sending commands to slave unit then start server to listen for replies self.output_client = self.init_client() self.add_status('Listening for replies from slave on: ' + self.osc_config.this_unit_ip + ':' + self.osc_config.reply_listen_port) self.output_reply_server = self.init_server( self.osc_config.this_unit_ip, self.osc_config.reply_listen_port, self.output_client) self.add_output_reply_handlers() self.output_reply_thread = self.start_server(self.output_reply_server) # *************************************** # RESPOND TO BUTTONS # *************************************** def open_show(self): self.msg_path = '/core/open ' self.msg_arg_text = self.current_show_ref self.display_msg_text() def close_show(self): self.msg_path = '/core/close ' self.msg_arg_text = self.current_show_ref self.display_msg_text() def exit_pipresents(self): self.msg_path = '/core/exitpipresents' self.msg_arg_text = '' self.display_msg_text() def play_event(self): self.msg_path = '/core/event' self.msg_arg_text = 'pp-play' self.display_msg_text() def pause_event(self): self.msg_path = '/core/event' self.msg_arg_text = 'pp-pause' self.display_msg_text() pass def stop_event(self): self.msg_path = '/core/event' self.msg_arg_text = 'pp-stop' self.display_msg_text() pass def up_event(self): self.msg_path = '/core/event' self.msg_arg_text = 'pp-up' self.display_msg_text() def down_event(self): self.msg_path = '/core/event' self.msg_arg_text = 'pp-down' self.display_msg_text() def animate(self): self.msg_path = '/core/animate' self.msg_arg_text = '' self.display_msg_text() def display_control(self): self.msg_path = '/core/monitor' self.msg_arg_text = '' self.display_msg_text() def loopback(self): self.msg_path = '/system/loopback' self.msg_arg_text = '' self.display_msg_text() def server_info(self): self.msg_path = '/system/server-info' self.msg_arg_text = '' self.display_msg_text() # and put the created text in the results box in the gui def display_msg_text(self): self.results.set(self.prefix + self.slave_unit + self.msg_path + ' ' + self.msg_arg_text) #respond to the Send button # parses the message string into fields and sends - NO error checking def send_message(self): if self.slave_unit == '/': self.mon.err(self, 'slave unit OSC name not set') return if self.osc_config.slave_units_ip == '': self.mon.err(self, 'slave unit IP not set') return msg_text = self.results.get() if msg_text == '': return fields = msg_text.split() osc_address = fields[0] arg_list = fields[1:] dest = (self.osc_config.slave_units_ip, int(self.osc_config.reply_listen_port)) self.add_status('Send message:' + msg_text + ' to ' + str(dest)) self.mon.log(self, 'send message: ' + msg_text) self.sendto(self.output_client, dest, osc_address, arg_list) # *************************************** # OSC CLIENT TO SEND MESSAGES # *************************************** def init_client(self): return OSC.OSCClient() def sendto(self, client, dest, address, arg_list): #print (' message to send',address,arg_list) msg = OSC.OSCMessage() msg.setAddress(address) for arg in arg_list: msg.append(arg) try: client.sendto(msg, dest) except Exception as e: self.mon.err(self, 'error in client when sending OSC command: ' + str(e)) def disconnect_client(self, client): if client != None: client.close() return # *************************************** # OSC SERVER TO LISTEN TO REPLIES # *************************************** def init_server(self, ip, port_text, client): self.mon.log(self, 'Start Server: ' + ip + ':' + port_text) return OSC.OSCServer((ip, int(port_text)), client) def start_server(self, server): st = threading.Thread(target=server.serve_forever) st.start() return st def close_server(self, server, st): if server != None: server.close() self.mon.log(self, 'Waiting for Server-thread to finish') if st != None: st.join() ##!!! self.mon.log(self, 'server thread closed') def add_output_reply_handlers(self): self.output_reply_server.addMsgHandler('default', self.no_match_handler) self.output_reply_server.addMsgHandler( self.prefix + "/system/loopback-reply", self.loopback_reply_handler) self.output_reply_server.addMsgHandler( self.prefix + "/system/server-info-reply", self.server_info_reply_handler) def no_match_handler(self, addr, tags, stuff, source): text = "No handler for message from %s" % OSC.getUrlStr(source) + '\n' text += " %s" % addr + self.pretty_list(stuff, '') self.add_status(text + '\n') def loopback_reply_handler(self, addr, tags, stuff, source): self.add_status('Loopback reply received from: ' + OSC.getUrlStr(source)) def server_info_reply_handler(self, addr, tags, stuff, source): unit = stuff[0] commands = stuff[1:] self.add_status('Server Information from: ' + OSC.getUrlStr(source)) self.add_status('OSC name: ' + unit) self.add_status('Commands:\n' + self.pretty_list(commands, '\n')) def pretty_list(self, fields, separator): text = ' ' for field in fields: text += str(field) + separator return text # *************************************** # INIT EXIT MISC # *************************************** def e_edit_osc(self): self.disconnect_client(self.output_client) self.output_client = None self.close_server(self.output_reply_server, self.output_reply_thread) self.output_reply_server = None self.output_reply_thread = None self.edit_osc() self.read_create_osc() self.init() self.add_status('\n\n\nRESTART') self.run_app() def app_exit(self): self.disconnect_client(self.output_client) self.close_server(self.output_reply_server, self.output_reply_thread) if self.root is not None: self.root.destroy() self.mon.finish() sys.exit() def show_help(self): tkinter.messagebox.showinfo("Help", "Read 'manual.pdf'") def about(self): tkinter.messagebox.showinfo( "About", "Simple Remote Control for Pi Presents\n" + "Author: Ken Thompson" + "\nWebsite: http://pipresents.wordpress.com/") def setup_gui(self): # set up the gui # root is the Tkinter root widget self.root.title("OSC Remote Control for Pi Presents") # self.root.configure(background='grey') self.root.resizable(False, False) # define response to main window closing self.root.protocol("WM_DELETE_WINDOW", self.app_exit) # bind some display fields self.desc = StringVar() self.filename = StringVar() self.display_show = StringVar() self.results = StringVar() self.status = StringVar() # define menu menubar = Menu(self.root) profilemenu = Menu(menubar, tearoff=0, bg="grey", fg="black") profilemenu.add_command(label='Select', command=self.open_existing_profile) menubar.add_cascade(label='Profile', menu=profilemenu) osc_configmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") menubar.add_cascade(label='Options', menu=osc_configmenu) osc_configmenu.add_command(label='Edit', command=self.e_edit_osc) helpmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") menubar.add_cascade(label='Help', menu=helpmenu) helpmenu.add_command(label='Help', command=self.show_help) helpmenu.add_command(label='About', command=self.about) self.root.config(menu=menubar) #top frame top_frame = Frame(self.root, padx=5, pady=5) top_frame.pack(side=TOP) # output info frame info_frame = Frame(top_frame, padx=5, pady=5) info_frame.pack(side=TOP, fill=BOTH, expand=1) info_name = Label(info_frame, text="Master's Name: " + self.osc_config.this_unit_name, font="arial 12 bold") info_name.pack(side=TOP) info_reply_address = Label(info_frame, textvariable=self.desc, font="arial 12 bold") info_reply_address.pack(side=TOP) results_label = Label(top_frame, text="Message to Send", font="arial 12 bold") results_label.pack(side=LEFT) results_display = Entry(top_frame, textvariable=self.results, width=70) results_display.pack(side=LEFT, fill=BOTH, expand=1) send_button = Button(top_frame, width=5, height=1, text='Send', fg='black', command=self.send_message, bg="light grey") send_button.pack(side=RIGHT) #bottom frame bottom_frame = Frame(self.root, padx=5, pady=5) bottom_frame.pack(side=TOP, fill=BOTH, expand=1) left_frame = Frame(bottom_frame, padx=5) left_frame.pack(side=LEFT) right_frame = Frame(bottom_frame, padx=5, pady=5) right_frame.pack(side=LEFT) suplabel_frame = Frame(right_frame, pady=5) suplabel_frame.pack(side=TOP) commands_label = Label(suplabel_frame, text="Show Control", font="arial 12 bold") commands_label.pack() supervisor_frame = Frame(right_frame, pady=5) supervisor_frame.pack(side=TOP) # supervisor buttons add_button = Button(supervisor_frame, width=5, height=1, text='Open\nShow', fg='black', command=self.open_show, bg="light grey") add_button.pack(side=LEFT) add_button = Button(supervisor_frame, width=5, height=1, text='Close\nShow', fg='black', command=self.close_show, bg="light grey") add_button.pack(side=LEFT) add_button = Button(supervisor_frame, width=10, height=1, text='Exit\nPi Presents', fg='black', command=self.exit_pipresents, bg="light grey") add_button.pack(side=LEFT) # events buttons oplabel_frame = Frame(right_frame, pady=5) oplabel_frame.pack(side=TOP) operations_label = Label(oplabel_frame, text="Input Events", font="arial 12 bold") operations_label.pack() operations_frame = Frame(right_frame, pady=5) operations_frame.pack(side=TOP) add_button = Button(operations_frame, width=5, height=1, text='Play', fg='black', command=self.play_event, bg="light grey") add_button.pack(side=LEFT) add_button = Button(operations_frame, width=5, height=1, text='Pause', fg='black', command=self.pause_event, bg="light grey") add_button.pack(side=LEFT) add_button = Button(operations_frame, width=5, height=1, text='Stop', fg='black', command=self.stop_event, bg="light grey") add_button.pack(side=LEFT) add_button = Button(operations_frame, width=5, height=1, text='Up', fg='black', command=self.up_event, bg="light grey") add_button.pack(side=LEFT) add_button = Button(operations_frame, width=5, height=1, text='Down', fg='black', command=self.down_event, bg="light grey") add_button.pack(side=LEFT) # animate buttons others_label_frame = Frame(right_frame, pady=5) others_label_frame.pack(side=TOP) others_label = Label(others_label_frame, text="Others", font="arial 12 bold") others_label.pack() others_frame = Frame(right_frame, pady=5) others_frame.pack(side=TOP) add_button = Button(others_frame, width=5, height=1, text='Animate', fg='black', command=self.animate, bg="light grey") add_button.pack(side=LEFT) add_button = Button(others_frame, width=8, height=1, text='Monitor on/off', fg='black', command=self.display_control, bg="light grey") add_button.pack(side=LEFT) # system buttons systemlabel_frame = Frame(right_frame, pady=5) systemlabel_frame.pack(side=TOP) system_label = Label(systemlabel_frame, text="System", font="arial 12 bold") system_label.pack() system_frame = Frame(right_frame, pady=5) system_frame.pack(side=TOP) add_button = Button(system_frame, width=5, height=1, text='Loopback', fg='black', command=self.loopback, bg="light grey") add_button.pack(side=LEFT) add_button = Button(system_frame, width=10, height=1, text='Server Info', fg='black', command=self.server_info, bg="light grey") add_button.pack(side=LEFT) # define display of showlist shows_title_frame = Frame(left_frame) shows_title_frame.pack(side=TOP) shows_label = Label(shows_title_frame, text="Shows") shows_label.pack() shows_frame = Frame(left_frame) shows_frame.pack(side=TOP) scrollbar = Scrollbar(shows_frame, orient=VERTICAL) self.shows_display = Listbox(shows_frame, selectmode=SINGLE, height=12, width=40, bg="white", activestyle=NONE, fg="black", yscrollcommand=scrollbar.set) scrollbar.config(command=self.shows_display.yview) scrollbar.pack(side=RIGHT, fill=Y) self.shows_display.pack(side=LEFT, fill=BOTH, expand=1) self.shows_display.bind("<ButtonRelease-1>", self.e_select_show) # status_frame status_frame = Frame(self.root, padx=5, pady=5) status_frame.pack(side=TOP, fill=BOTH, expand=1) status_label = Label(status_frame, text="Status", font="arial 12 bold") status_label.pack(side=LEFT) scrollbar = Scrollbar(status_frame, orient=VERTICAL) self.status_display = Text(status_frame, height=10, yscrollcommand=scrollbar.set) scrollbar.config(command=self.status_display.yview) scrollbar.pack(side=RIGHT, fill=Y) self.status_display.pack(side=LEFT, fill=BOTH, expand=1) # *************************************** # SHOWLIST # *************************************** def open_existing_profile(self): initial_dir = self.pp_home_dir + os.sep + "pp_profiles" if os.path.exists(initial_dir) is False: self.mon.err( self, "Profiles directory not found: " + initial_dir + "\n\nHint: Data Home option must end in pp_home") return dir_path = tkinter.filedialog.askdirectory(initialdir=initial_dir) # dir_path="C:\Users\Ken\pp_home\pp_profiles\\ttt" if len(dir_path) > 0: self.open_profile(dir_path) def open_profile(self, dir_path): showlist_file = dir_path + os.sep + "pp_showlist.json" if os.path.exists(showlist_file) is False: self.mon.err( self, "Not a Profile: " + dir_path + "\n\nHint: Have you opened the profile directory?") return self.pp_profile_dir = dir_path self.root.title("Remote for Pi Presents - " + self.pp_profile_dir) self.open_showlist(self.pp_profile_dir) def open_showlist(self, profile_dir): showlist_file = profile_dir + os.sep + "pp_showlist.json" if os.path.exists(showlist_file) is False: self.mon.err( self, "showlist file not found at " + profile_dir + "\n\nHint: Have you opened the profile directory?") self.app_exit() self.current_showlist = ShowList() self.current_showlist.open_json(showlist_file) # if float(self.current_showlist.sissue()) != float(self.editor_issue): # self.mon.err(self,"Version of profile does not match Remote: "+self.editor_issue) # self.app_exit() self.refresh_shows_display() def refresh_shows_display(self): self.shows_display.delete(0, self.shows_display.size()) for index in range(self.current_showlist.length()): self.shows_display.insert( END, self.current_showlist.show(index)['title'] + " [" + self.current_showlist.show(index)['show-ref'] + "]") if self.current_showlist.show_is_selected(): self.shows_display.itemconfig( self.current_showlist.selected_show_index(), fg='red') self.shows_display.see(self.current_showlist.selected_show_index()) def e_select_show(self, event): # print 'select show', self.current_showlist.length() if self.current_showlist is not None and self.current_showlist.length( ) > 0: mouse_item_index = int(event.widget.curselection()[0]) self.current_showlist.select(mouse_item_index) self.current_show_ref = self.current_showlist.selected_show( )['show-ref'] self.refresh_shows_display() else: self.current_show_ref = '' # *************************************** # OSC CONFIGURATION # *************************************** def read_create_osc(self): if self.osc_config.read(self.osc_config_file) is False: self.osc_config.create(self.osc_config_file, 'master') eosc = OSCEditor(self.root, self.osc_config_file, 'remote', 'Create OSC Remote Configuration') self.osc_config.read(self.osc_config_file) def edit_osc(self): if self.osc_config.read(self.osc_config_file) is False: self.osc_config.create(self.osc_config_file) eosc = OSCEditor(self.root, self.osc_config_file, 'remote', 'Edit OSC Reomote Configuration')
class DemoClient(Frame): def __init__(self, tk, args): Frame.__init__(self, tk) locale.setlocale(locale.LC_ALL, '') # empty string for platform's default settings self.master = tk self.config = json.load(open('config.json', 'r')) self.config['COMBOBOX_INDEX'] = sorted(self.config['COMBOBOX_INDEX'], key=lambda x: x[0]) self.game_type = int( args.gametype ) if args.gametype else self.config["DEFAULT_GAME_TYPE_ID"] tk.title(self.config["APP_TITLE"]) tk.resizable(False, False) self.get_icon() atexit.register(self.cancel_game) # Init class data fields that we use for storing info that we need for using the API self.bot_id = None self.bot_password = None self.logged_in = False self.game_style_ids = [] self.gameChips = 0 self.gameDeals = 0 self.gameStake = 0 self.gamePrize = 0 self.player_key = None self.play_again = BooleanVar() self.do_not_play_same_user = BooleanVar() self.close_after_game = False self.game_cancelled = False self.in_game = False self.topFrame = Frame(tk, padx=12, pady=12) self.middleFrame = Frame(tk, padx=12) self.middleFrameLeft = Frame(self.middleFrame) self.middleFrameRight = Frame(self.middleFrame) self.middleFrameRighter = Frame(self.middleFrame) self.topFrame.grid(row=0, sticky=W + E) self.middleFrame.grid(row=1, sticky=W) self.middleFrameLeft.grid(row=1, column=0) self.middleFrameRight.grid(row=1, column=1) self.middleFrameRighter.grid(row=1, column=2) # =================================== # Create form elements # Top Frame Elements self.botNameLabel = Label(self.topFrame, text="Bot Name:") self.bot_id_entry = Entry(self.topFrame) self.bot_id_entry.bind('<Return>', self.log_in_if_not) self.bot_id_entry.focus() self.passwordLabel = Label(self.topFrame, text="Password:"******"Login", command=self.log_in_out_clicked) self.balanceLabel = Label(self.topFrame, text="Bot Balance:") self.balance = Label(self.topFrame, text="0") self.close_button = Button(self.topFrame, text="Close", padx=2, command=tk.destroy) # Middle Frame Elements # Middle Frame LEFT Elements self.gameTypeCmb = ttk.Combobox( self.middleFrameLeft, state="disabled", values=tuple((game[0]) for game in self.config['COMBOBOX_INDEX'])) if self.game_type != self.config['NULL_GAME_TYPE_ID']: index = [ i for i in range(len(self.config['COMBOBOX_INDEX'])) if self.config['COMBOBOX_INDEX'][i][1] == self.game_type ][0] self.gameTypeCmb.current( index) # Default selection matches default game type id self.gameTypeCmb.bind("<<ComboboxSelected>>", self.game_type_selected) self.gameStyleLabel = Label(self.middleFrameLeft, font=(None, 18), pady=0, text="Game Style Selection") self.opponentLabel = Label(self.middleFrameLeft, text="Specify Opponent (optional):") self.specify_opponent_cmb = ttk.Combobox( self.middleFrameLeft, values=self.config['AVAILABLE_OPPONENTS']) self.do_not_play_same_user_check = Checkbutton( self.middleFrameLeft, text='Don\'t play another bot in same user account as me', var=self.do_not_play_same_user) self.game_styles_listbox = Listbox(self.middleFrameLeft, background='#FFFFFF', height=8) self.game_styles_listbox.bind('<Double-1>', self.find_game_double_clicked) self.game_styles_listbox.bind( '<Return>', self.find_game_double_clicked ) # Not a double click but we want it to do the same thing self.refresh_game_styles_button = Button( self.middleFrameLeft, text="Refresh Game Styles", command=self.refresh_game_styles_clicked) self.thinkingTimeLabel = Label(self.middleFrameLeft, text="Add \"Thinking Time\" (ms):") self.thinking_time_entry = Entry(self.middleFrameLeft) self.auto_play_next_game_check = Checkbutton( self.middleFrameLeft, text='Play another game when complete', var=self.play_again) self.cancel_stop_game_button = Button( self.middleFrameLeft, text=CANCEL_GAME_TEXT, command=self.cancel_stop_game_clicked) self.find_game_button = Button(self.middleFrameLeft, text="Find Game", command=self.find_game_clicked) self.resultText = Message( self.middleFrameLeft, width=300, text="This is where the informational messages will appear") self.spacerLabel = Label(self.middleFrameLeft, text=" ") # Middle Frame RIGHT Elements self.gameTitleLabel = Label(self.middleFrameRight, text="Game Title") self.gameTitleText = Text(self.middleFrameRight, height=3, background='white', spacing1=3, pady=0) self.player = None # Initialise as none before updating in create_visuals() self.opponent = None # Initialise as none before updating in create_visuals() self.create_visuals() self.gameActionLabel = Label(self.middleFrameRight, text="") # =================================== # Set initial element states self.set_gamestyle_controls_states(DISABLED) self.cancel_stop_game_button.config(state=DISABLED) self.game_styles_listbox.config(background='white') self.thinking_time_entry.insert(0, 100) self.gameTitleText.config(state=DISABLED) self.set_balance(0) self.gameTitleText.tag_configure("center", justify='center') self.gameTitleText.tag_configure("bold", font='-weight bold') # =================================== # Form Layout # Top Frame Form Layout self.topFrame.grid_rowconfigure(0, weight=1) self.botNameLabel.grid(row=0, column=0, sticky=E) self.bot_id_entry.grid(row=0, column=1, sticky=W) self.passwordLabel.grid(row=0, column=2, sticky=E) self.bot_password_entry.grid(row=0, column=3, sticky=W) self.log_in_out_button.grid(row=0, column=4, sticky=E) self.topFrame.grid_columnconfigure(5, weight=1) self.balanceLabel.grid(row=0, column=5, sticky=E) self.balance.grid(row=0, column=6, sticky=W) self.close_button.grid(row=0, column=7, sticky=E, padx=(50, 0)) # Middle Frame Form Layout self.middleFrame.grid_rowconfigure(0, weight=1) self.gameTypeCmb.grid(row=0, column=0, columnspan=1, sticky=W + E) self.gameStyleLabel.grid(row=1, column=0, columnspan=1, sticky=W + E) self.spacerLabel.grid(row=1, column=2, sticky=E) self.opponentLabel.grid(row=2, column=0, sticky=W, pady=4) self.specify_opponent_cmb.grid(row=2, column=0, sticky=E, pady=4) self.do_not_play_same_user_check.grid(row=3, column=0, columnspan=1, sticky='we', pady=4) self.game_styles_listbox.grid(row=4, column=0, columnspan=1, sticky='we', pady=4) self.find_game_button.grid(row=5, column=0, pady=4, sticky=W) self.refresh_game_styles_button.grid(row=5, column=0, columnspan=1, sticky='', pady=4) self.cancel_stop_game_button.grid(row=5, column=0, sticky=E) self.thinkingTimeLabel.grid(row=6, column=0, sticky=W, pady=4) self.thinking_time_entry.grid(row=6, column=0, sticky=E, pady=4) self.auto_play_next_game_check.grid(row=7, column=0, columnspan=1, sticky=W, pady=4) self.resultText.grid(row=9, column=0, columnspan=2, sticky=W, pady=4) self.middleFrame.grid_columnconfigure(9, weight=1) self.gameTitleLabel.grid(row=0, column=3) self.gameTitleText.grid(row=0, column=3, columnspan=2) self.gameActionLabel.grid(row=11, column=3, sticky='w') if args.botid is not None and args.password is not None: self.auto_play(args) def auto_play(self, args): self.bot_id_entry.insert(0, args.botid) self.bot_password_entry.insert(0, args.password) self.log_in_out_clicked() self.thinking_time_entry.insert(0, args.timeout) if args.playanothergame: self.auto_play_next_game_check.select() if args.dontplaysameuserbot: self.do_not_play_same_user_check.select() if args.closeaftergame: self.close_after_game = True if args.gamestyle is not None: i = 0 for i in range(self.game_styles_listbox.size()): if args.gamestyle in str(self.game_styles_listbox.get(i)): break self.game_styles_listbox.select_set(i, i) self.find_game_clicked() def log_in_out_clicked(self): """Click handler for the 'Login'/'Logout' button.""" # This means we're logging out if self.logged_in: self.resultText.config(text='Logged Out') self.master.title(self.config["APP_TITLE"] + " (Not Logged In)") self.cancel_game() self.bot_id = None self.bot_password = None self.clear_game_title_text() self.gameActionLabel.config(text="") self.reset_game_styles_listbox() self.clear_all_boards() self.opponent.delete("all") self.log_in_out_button.config(text='Login') self.set_login_controls_states(ENABLED) self.set_gamestyle_controls_states(DISABLED) self.gameTypeCmb.config(state="disabled") self.logged_in = False self.bot_password_entry.delete(0, 'end') self.set_balance(0) # This means we're logging in else: self.bot_id = self.bot_id_entry.get() self.bot_password = self.bot_password_entry.get() res = self.get_list_of_game_styles() if res['Result'] == 'SUCCESS': self.resultText.config(text='Logged In') game_styles = res['GameStyles'] self.master.title(self.bot_id + " - " + self.config["APP_TITLE"]) self.set_login_controls_states(DISABLED) self.set_gamestyle_controls_states(ENABLED) self.gameTypeCmb.config(state="readonly") self.set_game_styles_listbox(game_styles) self.set_balance(res['Balance']) self.log_in_out_button.config(text='Logout') self.logged_in = True else: messagebox.showerror( 'Error', 'Invalid login attempt. Please check the username and password entered.' ) def log_in_if_not(self, _): if not self.logged_in: self.log_in_out_clicked() def clear_all_boards(self): self.player.clear_board() self.opponent.clear_board() self.player.delete("all") self.opponent.delete("all") self.player.myBoard = None self.opponent.oppBoard = None def set_in_game(self, value): self.in_game = value def set_game_title_text(self, text, tag): self.gameTitleText.config(state=ENABLED) self.gameTitleText.insert("end", text, ("center", tag)) self.gameTitleText.config(state=DISABLED) def clear_game_title_text(self): self.gameTitleText.config(state=ENABLED) self.gameTitleText.delete("1.0", "end") self.gameTitleText.config(state=DISABLED) def set_login_controls_states(self, state): self.bot_id_entry.config(state=state) self.bot_password_entry.config(state=state) def set_gamestyle_controls_states(self, state): self.specify_opponent_cmb.config(state=state) self.do_not_play_same_user_check.config(state=state) self.game_styles_listbox.config(state=state) self.find_game_button.config(state=state) self.refresh_game_styles_button.config(state=state) self.auto_play_next_game_check.config(state=state) self.thinking_time_entry.config(state=state) self.opponentLabel.config(state=state) self.thinkingTimeLabel.config(state=state) self.balanceLabel.config(state=state) self.balance.config(state=state) self.gameStyleLabel.config(state=state) self.game_styles_listbox.config(state=state) self.player.config(state=state) self.opponent.config(state=state) def set_balance(self, balance): """Set the balance field""" self.balance['text'] = int_with_commas(balance) def get_list_of_game_styles(self): """Get list of game styles from the server.""" req = { 'BotId': self.bot_id, 'BotPassword': self.bot_password, 'GameTypeId': self.game_type } url = self.config["BASE_URL"] + self.config[ "GET_LIST_OF_GAME_STYLES_EXTENSION"] return DemoClient.make_api_call(url, req) def set_game_styles_listbox(self, game_styles): """Set the content of the game styles listbox with a list of GameStyle dictionaries. Keyword Arguments: game_styles -- The list of GameStyle dictionaries, this should be obtained through get_list_of_game_styles(). """ self.reset_game_styles_listbox() for index, game_style in enumerate(game_styles): if self.game_type == self.config["BATTLESHIPS_GAME_TYPE_ID"]: self.game_styles_listbox.insert( index, self.config["BATTLESHIPS_GAME_STYLE_LISTBOX_TEXT"].format( game_style['GameStyleId'], game_style['Stake'], game_style['GameTypeSpecificInfo']['Ships'], game_style['GameTypeSpecificInfo']['Board Size'], game_style['GameTypeSpecificInfo']['Timeout ms'], game_style['GameTypeSpecificInfo']['DealsTotal'], game_style['GameTypeSpecificInfo']['PercentageLand'], game_style['GameTypeSpecificInfo']['RandomLand'])) elif self.game_type == self.config[ "NOUGHTS_AND_CROSSES_GAME_TYPE_ID"]: self.game_styles_listbox.insert( index, self.config["NOUGHTS_AND_CROSSES_GAME_STYLE_LISTBOX_TEXT"]. format(game_style['GameStyleId'], game_style['Stake'], game_style['GameTypeSpecificInfo']['DealsTotal'], game_style['GameTypeSpecificInfo']['Timeout ms'])) elif self.game_type == self.config[ "TRAVELLING_SALESDRONE_GAME_TYPE_ID"]: self.game_styles_listbox.insert( index, self. config["TRAVELLING_SALESDRONE_GAME_STYLE_LISTBOX_TEXT"]. format(game_style['GameStyleId'], game_style['Stake'], game_style['GameTypeSpecificInfo']['TotalCities'], game_style['GameTypeSpecificInfo']['DealLength'])) elif self.game_type == self.config["PREDICTIVE_TEXT_GAME_TYPE_ID"]: self.game_styles_listbox.insert( index, self. config["PREDICTIVE_TEXT_GAME_STYLE_LISTBOX_TEXT"].format( game_style['GameStyleId'], game_style['Stake'], game_style['GameTypeSpecificInfo'] ['Number of Sentences'], game_style['GameTypeSpecificInfo'] ['Switched Words Game'], game_style['GameTypeSpecificInfo']['Timeout ms'])) elif self.game_type == self.config["TWIST_CUBE_GAME_TYPE_ID"]: self.game_styles_listbox.insert( index, self.config["TWIST_CUBE_GAME_STYLE_LISTBOX_TEXT"].format( game_style['GameStyleId'], game_style['Stake'], game_style['GameTypeSpecificInfo']['cubeSize'], game_style['GameTypeSpecificInfo']['GameLength'])) elif self.game_type == self.config["SLIDING_PUZZLE_GAME_TYPE_ID"]: self.game_styles_listbox.insert( index, self.config["SLIDING_PUZZLE_GAME_STYLE_LISTBOX_TEXT"]. format(game_style['GameStyleId'], game_style['Stake'], game_style['GameTypeSpecificInfo']['RowSize'], game_style['GameTypeSpecificInfo']['ColumnSize'], game_style['GameTypeSpecificInfo']['TimeLimit'])) elif self.game_type == self.config["BLURRY_WORD_GAME_TYPE_ID"]: self.game_styles_listbox.insert( index, self.config["BLURRY_WORD_GAME_STYLE_LISTBOX_TEXT"].format( game_style['GameStyleId'], game_style['Stake'], game_style['GameTypeSpecificInfo']['NumImages'], game_style['GameTypeSpecificInfo']['GameLength'])) elif self.game_type == self.config["MASTERMIND_GAME_TYPE_ID"]: self.game_styles_listbox.insert( index, self.config["MASTERMIND_GAME_STYLE_LISTBOX_TEXT"].format( game_style['GameStyleId'], game_style['Stake'], game_style['GameTypeSpecificInfo']['NumPegs'], game_style['GameTypeSpecificInfo']['NumColours'], game_style['GameTypeSpecificInfo'] ['DuplicatesAllowed'])) elif self.game_type == self.config[ "WAREHOUSE_LOGISTICS_GAME_TYPE_ID"]: self.game_styles_listbox.insert( index, self.config["WAREHOUSE_LOGISTICS_GAME_STYLE_LISTBOX_TEXT"]. format( game_style['GameStyleId'], game_style['Stake'], game_style['GameTypeSpecificInfo'] ['WarehouseDimensions'][0], game_style['GameTypeSpecificInfo'] ['WarehouseDimensions'][1])) elif self.game_type == self.config["FOUR_IN_A_ROW_GAME_TYPE_ID"]: self.game_styles_listbox.insert( index, self.config["FOUR_IN_A_ROW_GAME_STYLE_LISTBOX_TEXT"]. format(game_style['GameStyleId'], game_style['Stake'], game_style['GameTypeSpecificInfo']['Dimensions'][0], game_style['GameTypeSpecificInfo']['Dimensions'][1], game_style['GameTypeSpecificInfo']['Connections'])) elif self.game_type == self.config["WHO_IS_WHO_GAME_TYPE_ID"]: self.game_styles_listbox.insert( index, self.config["WHO_IS_WHO_GAME_STYLE_LISTBOX_TEXT"].format( game_style['GameStyleId'], game_style['Stake'], game_style['GameTypeSpecificInfo']['NumCharacters'], game_style['GameTypeSpecificInfo']['ComparisonRound'])) elif self.game_type == self.config[ "REVERSING_STONES_GAME_TYPE_ID"]: self.game_styles_listbox.insert( index, self.config["REVERSING_STONES_GAME_STYLE_LISTBOX_TEXT"]. format(game_style['GameStyleId'], game_style['Stake'], game_style['GameTypeSpecificInfo']['Dimensions'][0], game_style['GameTypeSpecificInfo']['Dimensions'][1], game_style['GameTypeSpecificInfo']['Holes'], game_style['GameTypeSpecificInfo']['Timeout ms'])) elif self.game_type == self.config["CHECKERS_GAME_TYPE_ID"]: self.game_styles_listbox.insert( index, self.config["CHECKERS_GAME_STYLE_LISTBOX_TEXT"].format( game_style['GameStyleId'], game_style['Stake'], game_style['GameTypeSpecificInfo']['Dimensions'][0], game_style['GameTypeSpecificInfo']['Dimensions'][1], game_style['GameTypeSpecificInfo']['Timeout ms'])) elif self.game_type == self.config["GO_GAME_TYPE_ID"]: self.game_styles_listbox.insert( index, self.config["GO_GAME_STYLE_LISTBOX_TEXT"].format( game_style['GameStyleId'], game_style['Stake'], game_style['GameTypeSpecificInfo']['Dimensions'][0], game_style['GameTypeSpecificInfo']['Dimensions'][1], "CAPTURE" if game_style['GameTypeSpecificInfo']['IsCaptureGo'] else game_style['GameTypeSpecificInfo']['ScoringMethod'], game_style['GameTypeSpecificInfo']['Timeout ms'])) elif self.game_type == self.config["LEXICO_GAME_TYPE_ID"]: self.game_styles_listbox.insert( index, self.config["LEXICO_GAME_STYLE_LISTBOX_TEXT"].format( game_style['GameStyleId'], game_style['Stake'], game_style['GameTypeSpecificInfo']['Dimensions'][0], game_style['GameTypeSpecificInfo']['Dimensions'][1], game_style['GameTypeSpecificInfo']['TileMultipliers'], game_style['GameTypeSpecificInfo']['Timeout ms'])) elif self.game_type == self.config["DOMINOES_GAME_TYPE_ID"]: self.game_styles_listbox.insert( index, self.config["DOMINOES_GAME_STYLE_LISTBOX_TEXT"].format( game_style['GameStyleId'], game_style['Stake'], game_style['GameTypeSpecificInfo']['SpotNo'], game_style['GameTypeSpecificInfo']['Timeout ms'])) else: raise ValueError('INVALID GAME TYPE PARAMETER') self.game_style_ids.append(game_style['GameStyleId']) # self.game_styles_listbox.select_set(GAME_STYLE_LISTBOX_DEFAULT_SELECTION) def reset_game_styles_listbox(self): """Clear the content of the game styles listbox.""" if self.game_styles_listbox.size() != 0: self.game_styles_listbox.delete(0, 'end') self.game_style_ids = [] def refresh_game_styles_clicked(self): """Click handler for the 'Refresh Game Styles' button.""" res = self.get_list_of_game_styles() game_styles = res['GameStyles'] self.set_game_styles_listbox(game_styles) def find_game_clicked(self): """Click handler for the 'Find Game' button""" self.find_game_button.config(state=DISABLED) self.cancel_stop_game_button.config(state=ENABLED) self.game_styles_listbox.unbind('<Double-1>') self.game_styles_listbox.unbind('<Return>') self.game_styles_listbox.config(state=DISABLED) self.clear_all_boards() # Here we dispatch the work to a separate thread, to keep the GUI responsive. if not MAC: threading.Thread(target=self.game_loop, daemon=True).start() else: self.game_loop() # Doesn't work on MACs def find_game_double_clicked(self, _): self.find_game_clicked() def game_type_selected(self, _): self.game_type = self.config["COMBOBOX_INDEX"][ self.gameTypeCmb.current()][1] res = self.get_list_of_game_styles() if res['Result'] == 'SUCCESS': game_styles = res['GameStyles'] self.set_game_styles_listbox(game_styles) self.get_icon() self.player.destroy() self.opponent.destroy() self.create_visuals() def get_icon(self): try: if WINDOWS: self.master.iconbitmap("assets/{0}/icon.ico".format( self.game_type)) else: self.master.iconbitmap("./assets/{0}/icon.xbm".format( self.game_type)) except Exception as e: print(e) def create_visuals(self): if self.game_type == self.config["NULL_GAME_TYPE_ID"]: self.player = null_visuals.NullVisuals( self.middleFrameRight) # Game Display Table self.opponent = null_visuals.NullVisuals( self.middleFrameRight) # Game Display Table elif self.game_type == self.config["BATTLESHIPS_GAME_TYPE_ID"]: self.player = battleships_visuals.BattleshipsVisuals( self.middleFrameRight) # Game Display Table self.opponent = battleships_visuals.BattleshipsVisuals( self.middleFrameRight) # Game Display Table elif self.game_type == self.config["NOUGHTS_AND_CROSSES_GAME_TYPE_ID"]: self.player = noughts_and_crosses_visuals.NoughtsAndCrossesVisuals( self.middleFrameRight) # Game Display Table self.opponent = noughts_and_crosses_visuals.NoughtsAndCrossesVisuals( self.middleFrameRight) # Game Display Table elif self.game_type == self.config[ "TRAVELLING_SALESDRONE_GAME_TYPE_ID"]: self.player = travelling_salesdrone_visuals.TravellingSalesdroneVisuals( self.middleFrameRight) # Game Display Table self.opponent = travelling_salesdrone_visuals.TravellingSalesdroneVisuals( self.middleFrameRight) # Game Display Table elif self.game_type == self.config["PREDICTIVE_TEXT_GAME_TYPE_ID"]: self.player = predictive_text_visuals.PredictiveTextVisuals( self.middleFrameRight) # Game Display Table self.opponent = predictive_text_visuals.PredictiveTextVisuals( self.middleFrameRight) # Game Display Table elif self.game_type == self.config["TWIST_CUBE_GAME_TYPE_ID"]: self.player = twist_cube_visuals.TwistCubeVisuals( self.middleFrameRight) # Game Display Table self.opponent = twist_cube_visuals.TwistCubeVisuals( self.middleFrameRight) # Game Display Table elif self.game_type == self.config["SLIDING_PUZZLE_GAME_TYPE_ID"]: self.player = sliding_puzzle_visuals.SlidingPuzzleVisuals( self.middleFrameRight) # Game Display Table self.opponent = sliding_puzzle_visuals.SlidingPuzzleVisuals( self.middleFrameRight) # Game Display Table elif self.game_type == self.config["BLURRY_WORD_GAME_TYPE_ID"]: self.player = blurry_word_visuals.MicrosoftCognitiveChallengeVisuals( self.middleFrameRight) # Game Display Table self.opponent = blurry_word_visuals.MicrosoftCognitiveChallengeVisuals( self.middleFrameRight) # Game Display Table elif self.game_type == self.config["MASTERMIND_GAME_TYPE_ID"]: self.player = mastermind_visuals.MastermindVisuals( self.middleFrameRight) # Game Display Table self.opponent = mastermind_visuals.MastermindVisuals( self.middleFrameRight) # Game Display Table elif self.game_type == self.config["WAREHOUSE_LOGISTICS_GAME_TYPE_ID"]: self.player = warehouse_logistics_visuals.WarehouseLogisticsVisuals( self.middleFrameRight) # Game Display Table self.opponent = warehouse_logistics_visuals.WarehouseLogisticsVisuals( self.middleFrameRight) # Game Display Table elif self.game_type == self.config["FOUR_IN_A_ROW_GAME_TYPE_ID"]: self.player = four_in_a_row_visuals.FourInARowVisuals( self.middleFrameRight) # Game Display Table self.opponent = four_in_a_row_visuals.FourInARowVisuals( self.middleFrameRight) # Game Display Table elif self.game_type == self.config["WHO_IS_WHO_GAME_TYPE_ID"]: self.player = who_is_who_visuals.WhoIsWhoVisuals( self.middleFrameRight) # Game Display Table self.opponent = who_is_who_visuals.WhoIsWhoVisuals( self.middleFrameRight) # Game Display Table elif self.game_type == self.config["REVERSING_STONES_GAME_TYPE_ID"]: self.player = reversing_stones_visuals.ReversingStonesVisuals( self.middleFrameRight) # Game Display Table self.opponent = reversing_stones_visuals.ReversingStonesVisuals( self.middleFrameRight) # Game Display Table elif self.game_type == self.config["CHECKERS_GAME_TYPE_ID"]: self.player = checkers_visuals.CheckersVisuals( self.middleFrameRight) # Game Display Table self.opponent = checkers_visuals.CheckersVisuals( self.middleFrameRight) # Game Display Table elif self.game_type == self.config["GO_GAME_TYPE_ID"]: self.player = go_visuals.GoVisuals( self.middleFrameRight) # Game Display Table self.opponent = go_visuals.GoVisuals( self.middleFrameRight) # Game Display Table elif self.game_type == self.config["LEXICO_GAME_TYPE_ID"]: self.player = lexico_visuals.LexicoVisuals( self.middleFrameRight) # Game Display Table self.opponent = lexico_visuals.LexicoVisuals( self.middleFrameRight) # Game Display Table elif self.game_type == self.config["DOMINOES_GAME_TYPE_ID"]: self.player = dominoes_visuals.DominoesVisuals( self.middleFrameRight) # Game Display Table self.opponent = dominoes_visuals.DominoesVisuals( self.middleFrameRight) # Game Display Table else: raise ValueError('INVALID GAME TYPE PARAMETER') self.player.grid(row=1, column=3) self.opponent.grid(row=1, column=4) def game_loop(self): """Loop through finding and playing games.""" while True: self.clear_all_boards() mover.persistentData = {} self.find_game() self.update_balance() if self.game_cancelled: break self.play_game() self.update_balance() if self.close_after_game: self.close_button.invoke() if self.game_cancelled: break if not self.play_again.get(): break self.find_game_button.config(state=ENABLED) self.cancel_stop_game_button.config(state=DISABLED, text=CANCEL_GAME_TEXT) self.game_styles_listbox.bind('<Double-1>', self.find_game_double_clicked) self.game_styles_listbox.bind('<Return>', self.find_game_double_clicked) self.game_styles_listbox.config(state=ENABLED) self.game_cancelled = False def find_game(self): """Find a game.""" offer_game_res = self.offer_game() if offer_game_res['Result'] == 'INVALID_LOGIN_OR_PASSWORD': self.cancel_stop_game_clicked() if 'ErrorMessage' in offer_game_res and offer_game_res[ 'ErrorMessage'] == 'Check of OpponentId failed': self.resultText.config(text='Invalid Opponent ID') else: self.resultText.config(text='Invalid login or password') elif offer_game_res['Result'] == 'INSUFFICIENT_BALANCE': self.cancel_stop_game_clicked() self.resultText.config(text='Insufficient balance') elif offer_game_res['Result'] == 'BOT_IS_INACTIVE': self.cancel_stop_game_clicked() self.resultText.config(text='Bot is inactive') else: self.player_key = offer_game_res['PlayerKey'] if offer_game_res['Result'] == 'WAITING_FOR_GAME': self.wait_for_game() def offer_game(self): """Offer a game.""" self.cancel_game( ) # Cancel the last outstanding game offer that was made opponent_id = self.specify_opponent_cmb.get() if len(opponent_id) == 0: opponent_id = None try: game_style_id = self.game_style_ids[int( self.game_styles_listbox.curselection()[0])] except IndexError: self.game_styles_listbox.select_set( GAME_STYLE_LISTBOX_DEFAULT_SELECTION) game_style_id = self.game_style_ids[0] req = { 'BotId': self.bot_id, 'BotPassword': self.bot_password, 'MaximumWaitTime': 1000, 'GameStyleId': game_style_id, 'DontPlayAgainstSameUser': self.do_not_play_same_user.get(), 'DontPlayAgainstSameBot': False, 'OpponentId': opponent_id } url = self.config["BASE_URL"] + self.config["OFFER_GAME_EXTENSION"] return DemoClient.make_api_call(url, req) def wait_for_game(self): """Wait for game to start.""" self.resultText.config(text='Waiting for game') while True: if self.game_cancelled: self.cancel_game() self.find_game_button.config(state=ENABLED) self.cancel_stop_game_button.config(state=DISABLED, text=CANCEL_GAME_TEXT) self.game_styles_listbox.bind('<Double-1>', self.find_game_double_clicked) self.game_styles_listbox.bind('<Return>', self.find_game_double_clicked) self.game_styles_listbox.config(state=ENABLED) break poll_results = self.poll_for_game_state() if poll_results['Result'] == 'SUCCESS': break if poll_results['Result'] == 'INVALID_PLAYER_KEY' or poll_results[ 'Result'] == 'GAME_HAS_ENDED' or poll_results[ 'Result'] == 'GAME_WAS_STOPPED': self.game_cancelled = True time.sleep(2) def play_game(self): """Play a game.""" self.resultText.config(text='Playing game') self.in_game = True poll_results = self.poll_for_game_state() if poll_results["Result"] != "SUCCESS": return game_state = poll_results['GameState'] title = format('Game ID: ' + str(game_state['GameId'])) title += format(' / Style: ' + str(self.game_style_ids[int( self.game_styles_listbox.curselection()[0])])) title += "\n" versus = format(self.bot_id + ' vs ' + game_state['OpponentId']) self.clear_game_title_text() self.set_game_title_text(title, "") self.set_game_title_text(versus, "bold") self.middleFrame.update() while True: if self.game_cancelled: break if game_state['IsMover']: self.resultText.config(text='Playing Game - Your Turn') move = mover.calculate_move(self.game_type, game_state) move_results = self.make_move(move) if move_results['Result'] == 'INVALID_MOVE': self.resultText.config(text="Invalid Move") elif move_results['Result'] != 'SUCCESS': self.resultText.config(text='Game has ended: ' + move_results['Result']) print(str(move_results)) print("Game ended") break else: game_state = move_results['GameState'] else: self.resultText.config(text="Playing Game - Opponent's Turn") # ---- Code here will be called on your opponent's turn ---- # ---------------------------------------------------------- poll_results = self.poll_for_game_state() if poll_results['Result'] != 'SUCCESS': self.resultText.config(text='Game has ended: ' + poll_results['Result']) break game_state = poll_results['GameState'] if game_state['GameStatus'] != 'RUNNING': break self.middleFrameRight.update() try: if int(self.thinking_time_entry.get()) > 0: time.sleep((int(self.thinking_time_entry.get()) / 1000)) else: time.sleep(0.1) except ValueError: time.sleep(0.1) self.set_in_game(False) def make_move(self, move): """Make a move.""" req = { 'BotId': self.bot_id, 'BotPassword': self.bot_password, 'PlayerKey': self.player_key, 'Move': move } url = self.config["BASE_URL"] + self.config["MAKE_MOVE_EXTENSION"] result = DemoClient.make_api_call(url, req) if result['Result'] == 'SUCCESS' or "GAME_HAS_ENDED" in result[ 'Result']: print(result) try: self.player.draw_game_state(result['GameState'], True) self.opponent.draw_game_state(result['GameState'], False) except Exception as e: print("Gamestate error: " + str(e)) return result def poll_for_game_state(self): """Poll the server for the latest GameState.""" req = { 'BotId': self.bot_id, 'BotPassword': self.bot_password, 'MaximumWaitTime': 1000, 'PlayerKey': self.player_key } url = self.config["BASE_URL"] + self.config[ "POLL_FOR_GAME_STATE_EXTENSION"] result = DemoClient.make_api_call(url, req) if result['Result'] == 'SUCCESS' or "GAME_HAS_ENDED" in result[ 'Result']: self.player.draw_game_state(result['GameState'], True) self.opponent.draw_game_state(result['GameState'], False) return result def cancel_stop_game_clicked(self): self.game_cancelled = True self.cancel_game() self.find_game_button.config(state=ENABLED) self.cancel_stop_game_button.config(state=DISABLED, text=CANCEL_GAME_TEXT) self.game_styles_listbox.bind('<Double-1>', self.find_game_double_clicked) self.game_styles_listbox.bind('<Return>', self.find_game_double_clicked) self.game_styles_listbox.config(state=ENABLED) def cancel_game(self): print("Cancelling last game offer") if self.player_key is None: return req = { 'BotId': self.bot_id, 'BotPassword': self.bot_password, 'PlayerKey': self.player_key } url = self.config["BASE_URL"] + self.config[ "CANCEL_GAME_OFFER_EXTENSION"] DemoClient.make_api_call(url, req) try: self.resultText.config(text='Cancelled game') except Exception as e: print(str(e) + " -- Demo client has been closed") def update_balance(self): res = self.get_list_of_game_styles() self.set_balance(res['Balance']) @staticmethod def make_api_call(url, req): """Make an API call.""" while True: try: res = requests.post(url, json=req, headers=API_CALL_HEADERS, timeout=60.0) try: jres = res.json() if 'Result' in jres: return jres time.sleep(0.1) except ValueError: time.sleep(0.1) except requests.ConnectionError: time.sleep(0.1) except requests.Timeout: time.sleep(0.1) except requests.HTTPError: time.sleep(0.1) except BaseException as e: # Bad code but needed for testing purposes print(e) time.sleep(0.1)
class MainScreen: def __init__(self, master, connection): #Reset Database if necessary Globals.ClearUserTables(connection) self.Config = configparser.ConfigParser() self.Config.read('config.ini') #Main Window self.Master = master self.Master.title("Hour Registration") #Database connection self.dbConnection = connection #Initialize Cache self.Cache = Cache.Cache(connection) #Initialize String Vars self.RecordTypeValue = StringVar() self.ProjectValue = StringVar() self.DescriptionValue = StringVar() self.LastLogon = StringVar() self.LastLogon.set(Globals.GetLastLogon()) #Designer self.DaysCombo = ttk.Combobox(master) self.DaysCombo.grid(row=0, column=0, sticky='NSEW', columnspan=3) self.RecordButton = Button(master, text="Start Recording", command=self.StartRecording) self.RecordButton.grid(row=1, column=0, sticky='NSEW') self.RecordIcon = PhotoImage(file=".\\Resources\\add.png") self.RecordButton.config(image=self.RecordIcon, width="32", height="32") self.DeleteRecordButton = Button(master, text="Delete Record", command=self.DeleteRecord) self.DeleteRecordButton.grid(row=1, column=1, sticky='NSEW') self.DeleteRecordIcon = PhotoImage(file=".\\Resources\\delete.png") self.DeleteRecordButton.config(image=self.DeleteRecordIcon, width="32", height="32") self.StopRecordButton = Button(master, text="Stop Recording", command=self.StopRecording) self.StopRecordButton.grid(row=1, column=2, sticky='NSEW') self.StopRecordIcon = PhotoImage(file=".\\Resources\\stop.png") self.StopRecordButton.config(image=self.StopRecordIcon, width="32", height="32") self.CopyToCodexButton = Button(master, text="Copy To Codex", command=self.CopyToCodex) self.CopyToCodexButton.grid(row=2, column=0, sticky='NSEW') self.CopyIcon = PhotoImage(file=".\\Resources\\copyCodex.png") self.CopyToCodexButton.config(image=self.CopyIcon, width="32", height="32") self.ExcelButton = Button(master, text="Export", command=self.ExportToExcel) self.ExcelButton.grid(row=2, column=1, sticky='NSEW') self.ExcelIcon = PhotoImage(file=".\\Resources\\excel.png") self.ExcelButton.config(image=self.ExcelIcon, width="32", height="32") self.ProjectButton = Button(master, text="Project", command=self.OpenProjectListForm) self.ProjectButton.grid(row=2, column=2, sticky='NSEW') self.ProjectIcon = PhotoImage(file=".\\Resources\\add_project.png") self.ProjectButton.config(image=self.ProjectIcon, width="32", height="32") self.CopyRecordButton = Button(master, text="CopyRecord", command=self.CopyRecord) self.CopyRecordButton.grid(row=3, column=0, sticky='NSEW') self.CopyRecordIcon = PhotoImage(file=".\\Resources\\copy.png") self.CopyRecordButton.config(image=self.CopyRecordIcon, width="32", height="32") self.OneNoteButton = Button(master, text="OneNote", command=self.OpenInOneNote) self.OneNoteButton.grid(row=3, column=1, sticky='NSEW') self.OneNoteIcon = PhotoImage(file=".\\Resources\\onenote.png") self.OneNoteButton.config(image=self.OneNoteIcon, width="32", height="32") self.AddTimeRecordButton = Button(master, text="AddTimeRecordButton", command=self.ShowNewEditForm) self.AddTimeRecordButton.grid(row=3, column=2, sticky="NSEW") self.AddTimeRecordIcon = PhotoImage( file=".\\Resources\\application_add.png") self.AddTimeRecordButton.config(image=self.AddTimeRecordIcon, width="32", height="32") self.BackupButton = Button(master, text="BackupButton", command=self.DatabaseBackup) self.BackupButton.grid(row=4, column=0, sticky="NSEW") self.BackupButtonIcon = PhotoImage(file=".\\Resources\\angel.png") self.BackupButton.config(image=self.BackupButtonIcon, width="32", height="32") self.RecordTypeButton = Button(master, text="RecordType", command=self.OpenRecordTypeListForm) self.RecordTypeButton.grid(row=4, column=1, sticky="NSEW") self.RecordTypeButtonIcon = PhotoImage( file=".\\Resources\\recordType.png") self.RecordTypeButton.config(image=self.RecordTypeButtonIcon, width="32", height="32") self.ExportToGraphsButton = Button(master, text="ExportToGraphs", command=self.ExportToGraph) self.ExportToGraphsButton.grid(row=4, column=2, sticky="NSEW") self.ExportToGraphsButtonIcon = PhotoImage( file=".\\Resources\\chart.png") self.ExportToGraphsButton.config(image=self.ExportToGraphsButtonIcon, width="32", height="32") self.ProjectsCombo = ttk.Combobox(master, textvariable=self.ProjectValue) self.ProjectsCombo.grid(row=0, column=3, columnspan=2, sticky='NSEW') self.RecordTypeCombo = ttk.Combobox(master, textvariable=self.RecordTypeValue) self.RecordTypeCombo.grid(row=1, column=3, columnspan=2, sticky='NSEW') self.DescriptionTextBox = Entry(master, textvariable=self.DescriptionValue) self.DescriptionTextBox.grid(row=2, column=3, columnspan=2, sticky='NSEW') self.RecordsListBox = Listbox(master, width=50) self.RecordsListBox.grid(row=3, column=3, rowspan=7, columnspan=1, sticky='NSEW') self.CommentListBox = Listbox(master, width=70) self.CommentListBox.grid(row=3, column=4, rowspan=7, columnspan=2, sticky='NSEW') self.CommentListBox.bindtags((self.CommentListBox, master, "all")) self.EventLogExplanationLabel = Label(master, text="Laatst aangemeld op: ") self.EventLogExplanationLabel.grid(row=0, column=5) self.EventLogLabel = Label(master, textvariable=self.LastLogon) self.EventLogLabel.grid(row=1, column=5) self.DaysCombo.bind("<<ComboboxSelected>>", self.DaysCombo_SelectedItemChanged) self.RecordsListBox.bind("<<ListboxSelect>>", self.RecordsListBox_SelectedItemChanged) self.RecordsListBox.bind('<Double-1>', lambda x: self.ShowEditForm()) #End Designer #Set Form Controls self.FillCombos() self.SetButtonsEnabled() self.Queue = queue.Queue(10) self.KillEvent = threading.Event() self.ControllerThread = threading.Thread(target=self.ctrl, args=(self.Queue, self.KillEvent)) self.ControllerThread.start() Logger.LogInfo(self.ControllerThread.getName() + ' started.') self.CheckForUpdatesFromController() def ctrl(self, queue, killEvent): dac = DAController.DAController(queue, killEvent) dac.Listen() def DatabaseBackup(self): source = self.Config['DEFAULT']['databasename'] destination = self.Config['DEFAULT'][ 'databasebackuplocation'] + '{}.db'.format( time.strftime('%Y%m%d%H%M')) copyfile(source, destination) messagebox.showinfo('Backup', 'Database backup made') def CheckForUpdatesFromController(self): if not self.Queue.empty(): queue = self.Queue.get() blPr = BLProject.BLProject(self.dbConnection) project = blPr.GetByButton(queue) if project is not None: print(project.Description) recordType = 1 blTr = BLTimeRecord.BLTimeRecord(self.dbConnection) for record in self.Cache.TimeRecords: if record.StatusID == TimeRecordStatusEnum.TimeRecordStatusEnum.Gestart.value: record.StatusID = TimeRecordStatusEnum.TimeRecordStatusEnum.Gestopt.value record.EndHour = Globals.GetCurrentTime() blTr.Update(record) timeRecord = TimeRecord.TimeRecord( None, Globals.GetCurrentTime(), None, project.ID, recordType, 'Automatically generated', TimeRecordStatusEnum.TimeRecordStatusEnum.Gestart.value, 0, None, None) valid = TimeRecordValidation.TimeRecordValidation() validationMessage = valid.ValidateOnCreation(timeRecord) if not len(validationMessage) == 0: errorMessage = '' for i in validationMessage: errorMessage = errorMessage + i + '\n' messagebox.showerror('Error', errorMessage) else: index = self.DaysCombo.current() blTr.Create(timeRecord) self.Cache.RefreshAllStaticData() self.FillCombos() if index == -1: index = 0 self.DaysCombo.current(index) self.RefreshTimeRecords() self.Master.after(500, self.CheckForUpdatesFromController) def OpenInOneNote(self): sel = self.RecordsListBox.curselection()[0] timeRecordView = self.Cache.TimeRecordViews[sel] os.system("start " + timeRecordView.OneNoteLink) def CopyRecord(self): blTr = BLTimeRecord.BLTimeRecord(self.dbConnection) sel = self.RecordsListBox.curselection()[0] timeRecordView = self.Cache.TimeRecordViews[sel] timeRecord = blTr.GetById(timeRecordView.ID) blTr.CopyTimeRecord(timeRecord) self.Refresh() def Refresh(self): index = self.DaysCombo.current() self.DaysCombo.current(0) self.Cache.RefreshAllStaticData() self.FillCombos() self.DaysCombo.current(index) self.RefreshTimeRecords() self.SetButtonsEnabled() def RecordsListBox_SelectedItemChanged(self, eventObject): self.SetButtonsEnabled() def DaysCombo_SelectedItemChanged(self, eventObject): self.RefreshTimeRecords() self.SetButtonsEnabled() def RefreshTimeRecords(self): index = self.DaysCombo.current() if not index == -1: date = self.Cache.DayViews[index].Date self.Cache.RefreshTimeRecordsForDate(date) self.FillTimeRecords(self.Cache.TimeRecordViews) else: self.RecordsListBox.delete(0, END) self.CommentListBox.delete(0, END) def Show(self): self.Master.mainloop() def FillCombos(self): self.FillProjectCombo() self.FillRecordTypeCombo() self.FillDays() def FillProjectCombo(self): self.ProjectsCombo['value'] = self.Cache.ActiveProjects def FillRecordTypeCombo(self): self.RecordTypeCombo['value'] = self.Cache.RecordTypes def FillDays(self): self.DaysCombo['value'] = self.Cache.DayViews def FillTimeRecords(self, timeRecordViews): self.RecordsListBox.delete(0, END) self.CommentListBox.delete(0, END) for item in timeRecordViews: self.RecordsListBox.insert(END, item) self.CommentListBox.insert(END, item.Description) for i in range(0, self.RecordsListBox.size()): item = timeRecordViews[i] itemStatus = item.Status if itemStatus == 'Gestart': self.RecordsListBox.itemconfig(i, {'bg': 'red'}) elif itemStatus == 'Gestopt': self.RecordsListBox.itemconfig(i, {'bg': 'green'}) elif itemStatus == 'Gekopieerd': self.RecordsListBox.itemconfig(i, {'bg': 'orange'}) def StartRecording(self): recordIndex = self.RecordTypeCombo.current() projectIndex = self.ProjectsCombo.current() if recordIndex == -1: recordType = '' else: recordType = self.Cache.RecordTypes[recordIndex].ID if projectIndex == -1: project = None else: project = self.Cache.ActiveProjects[projectIndex].ID timeRecord = TimeRecord.TimeRecord( None, Globals.GetCurrentTime(), None, project, recordType, self.DescriptionValue.get(), TimeRecordStatusEnum.TimeRecordStatusEnum.Gestart.value, 0, None, None) valid = TimeRecordValidation.TimeRecordValidation() validationMessage = valid.ValidateOnCreation(timeRecord) if not len(validationMessage) == 0: errorMessage = '' for i in validationMessage: errorMessage = errorMessage + i + '\n' messagebox.showerror('Error', errorMessage) else: index = self.DaysCombo.current() blTr = BLTimeRecord.BLTimeRecord(self.dbConnection) blTr.Create(timeRecord) self.Cache.RefreshAllStaticData() self.FillCombos() if index == -1: index = 0 self.DaysCombo.current(index) self.RefreshTimeRecords() def StopRecording(self): blTr = BLTimeRecord.BLTimeRecord(self.dbConnection) sel = self.RecordsListBox.curselection()[0] timeRecordView = self.Cache.TimeRecordViews[sel] timeRecord = blTr.GetById(timeRecordView.ID) timeRecord.EndHour = Globals.GetCurrentTime() timeRecord.StatusID = TimeRecordStatusEnum.TimeRecordStatusEnum.Gestopt.value blTr.Update(timeRecord) index = self.DaysCombo.current() self.DaysCombo.current(0) self.Cache.RefreshAllStaticData() self.FillCombos() self.DaysCombo.current(index) self.RefreshTimeRecords() self.SetButtonsEnabled() def CopyToCodex(self): self.Master.clipboard_clear() index = self.DaysCombo.current() date = self.Cache.DayViews[index].Date self.Master.clipboard_append( Globals.CopyToCodex(self.dbConnection, date)) self.RefreshTimeRecords() def ShowEditForm(self): timeRecordView = self.Cache.TimeRecordViews[ self.RecordsListBox.curselection()[0]] edit = TimeRecordEditForm(self.dbConnection, timeRecordView, self.Cache) edit.Show() index = self.DaysCombo.current() self.DaysCombo.current(0) self.Cache.RefreshAllStaticData() self.FillCombos() self.DaysCombo.current(index) self.RefreshTimeRecords() edit.Master.destroy() def ShowNewEditForm(self): tr = TimeRecordView.TimeRecordView(None, None, None, None, None, None, None, None, None, None, None) index = self.DaysCombo.current() tr.Date = self.Cache.DayViews[index].Date edit = TimeRecordEditForm(self.dbConnection, tr, self.Cache) edit.Show() index = self.DaysCombo.current() self.DaysCombo.current(0) self.Cache.RefreshAllStaticData() self.FillCombos() self.DaysCombo.current(index) self.RefreshTimeRecords() edit.Master.destroy() def OpenProjectListForm(self): projectListForm = ProjectListForm(self.Cache, self.dbConnection) projectListForm.Show() self.Cache.RefreshAllStaticData() self.FillCombos() projectListForm.Master.destroy() def OpenRecordTypeListForm(self): recordTypeListForm = RecordTypeListForm(self.Cache, self.dbConnection) recordTypeListForm.Show() self.Cache.RefreshAllStaticData() self.FillCombos() recordTypeListForm.Master.destroy() def ExportToExcel(self): excel = ExportToExcelForm(self.dbConnection) excel.Show() excel.Master.destroy() def ExportToGraph(self): graph = ExportToGraphsForm(self.dbConnection, self.Cache) graph.Show() graph.Master.destroy() def DeleteRecord(self): bl = BLTimeRecord.BLTimeRecord(self.dbConnection) indexRecordsListBox = self.RecordsListBox.curselection()[0] record = self.Cache.TimeRecordViews[indexRecordsListBox] bl.DeleteByID(record.ID) index = self.DaysCombo.current() self.Cache.RefreshAllStaticData() self.FillCombos() #Hier schiet nog 1 record over; het is nog niet verwijderd uit Cache op dit moment if len(self.Cache.TimeRecordViews) == 1: self.DaysCombo.set('') else: self.DaysCombo.current(index) self.RefreshTimeRecords() self.SetButtonsEnabled() def SetButtonsEnabled(self): enableStop = True enableCopyToCodex = True enableDelete = True enableCopyRecord = True enableOpenOneNote = True indexDaysCombo = self.DaysCombo.current() indexRecordsListBox = self.RecordsListBox.curselection() current = Globals.GetCurrentDay() if indexDaysCombo == -1: enableStop = False enableCopyToCodex = False else: date = self.Cache.DayViews[indexDaysCombo].Date if not current == date: enableStop = False bl = BLTimeRecord.BLTimeRecord(self.dbConnection) records = bl.GetAllForDate(date) for record in records: if record.StatusID == TimeRecordStatusEnum.TimeRecordStatusEnum.Gestart.value: enableCopyToCodex = False if len(indexRecordsListBox) == 0: enableStop = False enableDelete = False enableCopyRecord = False enableOpenOneNote = False else: trView = self.Cache.TimeRecordViews[indexRecordsListBox[0]] if trView.OneNoteLink == 'None' or trView.OneNoteLink == "": enableOpenOneNote = False self.SetButton(enableStop, self.StopRecordButton) self.SetButton(enableCopyToCodex, self.CopyToCodexButton) self.SetButton(enableDelete, self.DeleteRecordButton) self.SetButton(enableCopyRecord, self.CopyRecordButton) self.SetButton(enableOpenOneNote, self.OneNoteButton) def SetButton(self, enabled, button): if enabled: button.config(state=NORMAL) else: button.config(state=DISABLED)
class ConnectedFrame: def __init__(self, logicManager, root): self.logicManger = logicManager self.deviceName = self.logicManger.getDeviceName() self.battery = self.logicManger.getBattery() # images setup self.backgroundImg = None self.batteryImg = None self.logoutImg = None self.initPictures() # frame setup self.frame = None self.nameLabel = None self.batteryLabel = None self.moveLabel = None self.files_list = None self.logout_button = None self.timeUpdate = 1000 # in ms self.initFrame(root) def initPictures(self): self.backgroundImg = getPhoto('\\img\\MainScreen.png') self.batteryImg = getPhoto('\\img\\battery.png') self.logoutImg = getPhoto('\\img\\LogoutButton.png') def initFrame(self, root): self.frame = Canvas(root, bg=BLACK) self.frame.create_image(0, 0, anchor=NW, image=self.backgroundImg) self.frame.pack(expand="true", fill="both") y_grid = 1 x_grid = 0 pady = (45, 20) padx = 20 y_grid = self.initHeader(self.frame, y_grid, x_grid, pady, padx) pady = 0 y_grid = self.initMainBlock(self.frame, y_grid, x_grid, pady, padx) pady = 15 padx = 10 self.initButton(self.frame, y_grid, pady, padx) self.frame.after(self.timeUpdate, self.updateFrame) def initHeader(self, frame, y_grid, x_grid, pady, padx): rapper_frame = Frame(frame, bg=WHITE) inner_frame = Frame(rapper_frame, bg=DARK_GRAY_BLUE, height=100) inner_frame.pack() devicename = self.deviceName if devicename is not None and len(devicename) > 12: devicename = devicename[0:14] + '\n' + devicename[14:] self.nameLabel = Label(inner_frame, text=devicename, width=16, font=DEVICE_HEADER_FONT, bg=DARK_GRAY_BLUE, fg=WHITE) self.nameLabel.grid(row=0, column=0) battery = str(self.battery) + '% ' self.batteryLabel = Label(inner_frame, text=battery, width=85, font=BATTERY_HEADER_FONT, bg=DARK_GRAY_BLUE, image=self.batteryImg, fg=BLACK, compound="center") self.batteryLabel.grid(row=0, column=1, padx=(15, 0)) rapper_frame.grid(row=y_grid, column=x_grid, rowspan=1, columnspan=1, padx=padx, pady=pady) return y_grid + 1 def initMainBlock(self, frame, y_grid, x_grid, pady, padx): rapper_frame = Frame(frame, bg=WHITY_BLUE) rapper_frame.grid(row=y_grid, column=x_grid, rowspan=1, columnspan=2) self.initMouseMovementView(rapper_frame, y_grid, 0, pady, padx) self.initFilesView(rapper_frame, y_grid + 1, 0, pady, 0) return y_grid + 2 def initMouseMovementView(self, frame, y_grid, x_grid, pady, padx): inner_frame = Frame(frame, bg=WHITY_BLUE) inner_frame.grid(row=y_grid, column=x_grid, rowspan=1, columnspan=1, padx=(4, 11)) label = Label(inner_frame, text='Last Mouse Move:', width=18, font=BATTERY_HEADER_FONT, bg=DARK_GRAY_BLUE, fg=WHITE) label.pack(side="left") self.moveLabel = Label(inner_frame, text='', width=7, font=BATTERY_HEADER_FONT, bg=WHITY_BLUE, fg=BLACK) self.moveLabel.pack(side="right") return y_grid + 2 def initFilesView(self, frame, y_grid, x_grid, pady, padx): inner_frame = Frame(frame, bg=BLACK) inner_frame.grid(row=y_grid, column=x_grid, rowspan=2, columnspan=2, padx=padx, pady=pady) title = Label(inner_frame, text='Recived Files:', width=26, font=BATTERY_HEADER_FONT, bg=DARK_GRAY_BLUE, fg=WHITE) title.pack() def open(event): file = self.files_list.curselection() file = self.files_list.get(file) self.logicManger.openFile(file) self.files_list = Listbox(inner_frame, bd=0, font=LISTBOX_FONT, width=29, height=10) self.files_list.pack(side="left", fill="y", padx=(1, 0), pady=1) self.files_list.contains = lambda x: x in self.files_list.get(0, "end") self.files_list.bind('<Double-1>', open) scrollbar = Scrollbar(inner_frame, orient="vertical") scrollbar.config(command=self.files_list) scrollbar.pack(side="right", fill="y", padx=(0, 2), pady=1) self.files_list.config(yscrollcommand=scrollbar.set) return y_grid + 2 def initButton(self, frame, y_grid, pady, padx): rapper_frame = Frame(frame, bg=WHITE) self.logout_button = Button(rapper_frame, image=self.logoutImg, bg=GRAY, font=SMALL_BUTTON_FONT) self.logout_button.pack(anchor=E) rapper_frame.grid(row=y_grid, column=0, columnspan=2, pady=pady) def setLogoutButtonFunction(self, func): self.logout_button["command"] = func def hideFrame(self): self.frame.pack_forget() def updateFrame(self): self.getFiles() self.getDirection() self.getBattery() self.frame.after(self.timeUpdate, self.updateFrame) def getFiles(self): files = self.logicManger.getFiles() for file in files: if not self.files_list.contains(file): name = self.logicManger.getFileName(file) arr = name.split('.') print('name recived ', name) path = filedialog.asksaveasfilename(initialfile=name, filetypes=[(arr[-1], '*.' + arr[-1]) ]) arr_p = path.split('/') if name != arr_p[-1]: path += '.' + arr[-1] self.logicManger.saveFileWithPath(file, path) index = self.files_list.size() self.files_list.insert(index, file) def getDirection(self): direction = self.logicManger.getDirection() self.moveLabel['text'] = direction def getBattery(self): battery = self.logicManger.getBattery() battery = str(battery) + '% ' self.batteryLabel['text'] = battery
class PyLatency: """Ping tool visualization with tkinter""" def __init__(self, root): """Setup window geometry & widgets + layout, init counters""" self.master = root self.master.title("pyLatency") self.appdata_dir = getenv("APPDATA") + "/pyLatency" self.options_path = self.appdata_dir + "/options.json" self.log_dir = self.appdata_dir + "/logs" self.logfile = None self.options_logging = BooleanVar() self.options_geometry = "" self.options = self.init_options() if self.options: self.options_geometry = self.options["geometry"] self.options_logging.set(self.options["logging"]) if self.options_geometry: self.master.geometry(self.options_geometry) else: self.master.geometry("400x200") self.master.minsize(width=400, height=200) self.master.update() self.running = False self.hostname = None self.RECT_SCALE_FACTOR = 2 self.TIMEOUT = 5000 self.minimum = self.TIMEOUT self.maximum = 0 self.average = 0 self.SAMPLE_SIZE = 1000 self.sample = deque(maxlen=self.SAMPLE_SIZE) self.pcount = 0 self.max_bar = None self.min_bar = None # Widgets: self.frame = Frame(self.master) self.lbl_entry = Label(self.frame, text="Host:") self.lbl_status_1 = Label(self.frame, text="Ready") self.lbl_status_2 = Label(self.frame, fg="red") self.entry = Entry(self.frame) self.btn_start = Button(self.frame, text="Start", command=self.start) self.btn_stop = Button(self.frame, text="Stop", command=self.stop) self.chk_log = Checkbutton(self.frame, text="Enable log", variable=self.options_logging) self.delay_scale = Scale( self.frame, label="Interval (ms)", orient="horizontal", from_=100, to=self.TIMEOUT, resolution=100, ) self.delay_scale.set(1000) self.paneview = PanedWindow(self.master, sashwidth=5, bg="#cccccc") self.left_pane = PanedWindow(self.paneview) self.right_pane = PanedWindow(self.paneview) self.paneview.add(self.left_pane) self.paneview.add(self.right_pane) self.canvas_scroll_y = Scrollbar(self.left_pane) self.canvas = Canvas(self.left_pane, bg="#FFFFFF", yscrollcommand=self.canvas_scroll_y.set) self.canvas_scroll_y.config(command=self.canvas.yview) self.left_pane.add(self.canvas_scroll_y) self.ping_list_scroll = Scrollbar(self.master) self.ping_list = Listbox(self.right_pane, highlightthickness=0, font=14, selectmode="disabled", yscrollcommand=self.ping_list_scroll.set) self.ping_list_scroll.config(command=self.ping_list.yview) self.right_pane.add(self.ping_list_scroll) self.left_pane.add(self.canvas) self.right_pane.add(self.ping_list) # Layout: self.master.columnconfigure(0, weight=1) self.master.rowconfigure(1, weight=1) self.frame.columnconfigure(1, weight=1) self.frame.grid(row=0, column=0, sticky="nsew") self.lbl_entry.grid(row=0, column=0) self.lbl_status_1.grid(row=1, column=0, columnspan=4) self.lbl_status_2.grid(row=2, column=0, columnspan=4) self.entry.grid(row=0, column=1, sticky="ew") self.btn_start.grid(row=0, column=2) self.btn_stop.grid(row=0, column=3) self.chk_log.grid(row=1, column=2, columnspan=2) self.delay_scale.grid(row=0, column=4, rowspan=2) # self.canvas_scroll_y.grid(row=1, column=2, sticky="ns") self.paneview.grid(row=1, column=0, sticky="nsew") # self.ping_list_scroll.grid(row=1, column=1, sticky="ns") self.paneview.paneconfigure( self.left_pane, width=(self.master.winfo_width() - self.delay_scale.winfo_reqwidth()), ) #Bindings: self.canvas.bind("<MouseWheel>", self.scroll_canvas) self.master.bind("<Return>", self.start) self.master.bind("<Escape>", self.stop) self.master.bind("<Control-w>", lambda event: self.master.destroy()) self.master.bind( "<Up>", lambda event: self.delay_scale.set(self.delay_scale.get() + 100)) self.master.bind( "<Down>", lambda event: self.delay_scale.set(self.delay_scale.get() - 100)) self.master.protocol("WM_DELETE_WINDOW", self.master_close) def __str__(self): """Return own address""" return f"pyLatency GUI @ {hex(id(self))}" def start(self, event=None): """ Reset the GUI, create & start a thread so we don't block the mainloop during each poll. """ if not self.running: self.hostname = self.entry.get() if self.hostname: self.ping_list.delete(0, "end") self.canvas.delete("all") self.lbl_status_1.config(text="Running", fg="green") self.lbl_status_2.config(text="") self.sample.clear() (self.minimum, self.maximum, self.average, self.pcount) = self.TIMEOUT, 0, 0, 0 self.running = True self.thread = Thread(target=self.run, daemon=True) self.thread.start() else: self.lbl_status_2.config(text="Missing Hostname") def logged(fn): """ decorates self.run(), create a log directory if one doesn't exist, create a filename with a date & timestamp, call self.run() with logging enabled or disabled """ @wraps(fn) def inner(self): if self.options_logging.get(): if not exists(self.log_dir): mkdir(self.log_dir) timestamp = datetime.now() fname = timestamp.strftime("%a %b %d @ %H-%M-%S") with open(self.log_dir + f"/{fname}.txt", "w+") as self.logfile: self.logfile.write(f"pyLatency {fname}\n") self.logfile.write(f"Host: {self.hostname}\n") self.logfile.write("-" * 40 + "\n") start = default_timer() fn(self) end = default_timer() elapsed = end - start self.logfile.write("-" * 40 + "\n") self.logfile.write( f"Logged {self.pcount} pings over {int(elapsed)} seconds" ) else: fn(self) return inner @logged def run(self): """ Continuously shell out to ping, get an integer result, update the GUI, and wait. """ while self.running: latency = self.ping(self.hostname) self.pcount += 1 if latency is None: self.stop() self.lbl_status_2.config(text="Unable to ping host") return if latency > self.maximum: self.maximum = latency if latency < self.minimum: self.minimum = latency self.sample.append(latency) self.average = sum(self.sample) / len(self.sample) if self.logfile: self.logfile.write(str(latency) + "\n") self.update_gui(latency) sleep(self.delay_scale.get() / 1000) def update_gui(self, latency): """ Update the listbox, shift all existing rectangles, draw the latest result from self.ping(), cleanup unused rectangles, update the mainloop """ if self.ping_list.size() >= self.SAMPLE_SIZE: self.ping_list.delete(self.SAMPLE_SIZE - 1, "end") self.ping_list.insert(0, str(latency) + "ms") self.canvas.move("rect", 10, 0) self.canvas.create_rectangle(0, 0, 10, int(latency * self.RECT_SCALE_FACTOR), fill="#333333", tags="rect", width=0) self.canvas.delete(self.max_bar) self.max_bar = self.canvas.create_line( 0, self.maximum * self.RECT_SCALE_FACTOR, self.canvas.winfo_width(), self.maximum * self.RECT_SCALE_FACTOR, fill="red", ) self.canvas.delete(self.min_bar) self.min_bar = self.canvas.create_line( 0, self.minimum * self.RECT_SCALE_FACTOR, self.canvas.winfo_width(), self.minimum * self.RECT_SCALE_FACTOR, fill="green", ) # canvas scrollable region is not updated automatically self.canvas.configure(scrollregion=self.canvas.bbox("all")) self.lbl_status_2.config(fg="#000000", text=f"Min: {self.minimum} " f"Max: {self.maximum} " f"Avg: {round(self.average,2):.2f}") self.cleanup_rects() self.master.update() def scroll_canvas(self, event): """ Bound to <MouseWheel> tkinter event on self.canvas. Respond to Linux or Windows mousewheel event, and scroll the canvas accordingly """ count = None if event.num == 5 or event.delta == -120: count = 1 if event.num == 4 or event.delta == 120: count = -1 self.canvas.yview_scroll(count, "units") def cleanup_rects(self): """Delete rectangles that are outside the bbox of the canvas""" for rect in self.canvas.find_withtag("rect"): if self.canvas.coords(rect)[0] > self.canvas.winfo_width(): self.canvas.delete(rect) def stop(self, event=None): """Satisfy the condition in which self.thread exits""" if self.running: self.running = False self.lbl_status_1.config(text="Stopped", fg="red") def master_close(self, event=None): """Writes window geometry/options to the disk.""" options = dumps({ "geometry": self.master.geometry(), "logging": self.options_logging.get() }) if not exists(self.appdata_dir): mkdir(self.appdata_dir) with open(self.options_path, "w+") as options_file: options_file.write(options) self.master.destroy() def init_options(self): """Called on startup, loads, parses, and returns options from json.""" if exists(self.options_path): with open(self.options_path, "r") as options_file: options_json = options_file.read() return loads(options_json) else: return None @staticmethod def ping(url): """ Shell out to ping and return an integer result. Returns None if ping fails for any reason: timeout, bad hostname, etc. """ flag = "-n" if platform == "win32" else "-c" result = run(["ping", flag, "1", "-w", "5000", url], capture_output=True, creationflags=DETACHED_PROCESS) output = result.stdout.decode("utf-8") try: duration = findall("\\d+ms", output)[0] return int(duration[:-2]) except IndexError: return None
class GMPE_lt(): def __init__(self, available_GMPE, Domain_in_model, Run_Name): self.available_GMPE = available_GMPE self.Domain_in_model = Domain_in_model self.Run_Name = Run_Name self.initialize() def initialize(self): self.XMLfile = open(str(self.Run_Name) + '/GMPE_Logic_tree.xml', 'w') Ligne = '<?xml version=\'1.0\' encoding=\'utf-8\'?>\n\n' self.XMLfile.write(Ligne) Ligne = '<nrml xmlns:gml="http://www.opengis.net/gml"\n' self.XMLfile.write(Ligne) Ligne = '\txmlns="http://openquake.org/xmlns/nrml/0.4">\n' self.XMLfile.write(Ligne) Ligne = '\t<logicTree logicTreeID="lt_gmpe">\n\n' self.XMLfile.write(Ligne) self.i_Domain = 0 while self.i_Domain < len(self.Domain_in_model): self.Domain = self.Domain_in_model[self.i_Domain] self.weight = [] self.fen1 = tk.Tk() self.GMPESelect = StringVar() Tex_box = Text(self.fen1, height=2, width=50) Tex_box.insert(INSERT, "Apply to : " + str(self.Domain)) Tex_box.pack() self.Box_GMPE = Combobox(self.fen1, textvariable=self.GMPESelect, values=self.available_GMPE, state='readonly', height=5, width=50) self.Box_GMPE.pack() bou_add = Button(self.fen1, text=u'Add GMPE', command=self.Add_gmpe) bou_add.pack() self.listechoix_gmpe = Listbox(self.fen1, width=50) self.listechoix_gmpe.pack() if not (self.i_Domain + 1) == len(self.Domain_in_model): bou_quit = Button(self.fen1, text='Next Domain', command=self.Next_Domain) else: bou_quit = Button(self.fen1, text='Build GMPE Logic Tree', command=self.Finalize_LT) bou_quit.pack() self.fen1.mainloop() self.i_Domain += 1 def Add_gmpe(self): longueur_liste = self.listechoix_gmpe.size() compteur = 0 for i in range(longueur_liste): if self.Box_GMPE.get() == self.listechoix_gmpe.get(i): compteur = compteur + 1 if compteur == 0: self.listechoix_gmpe.insert(END, self.Box_GMPE.get()) self.fen2 = tk.Tk() tex1 = Label(self.fen2, text='Associated weight:') tex1.pack() self.e = Entry(self.fen2) self.e.pack() bou_quit = Button(self.fen2, text='Apply weigth', command=self.Apply_weight) bou_quit.pack() self.fen2.mainloop() else: messagebox.showerror('Error', 'GMPE already selected') def Apply_weight(self): self.weight.append(float(self.e.get())) self.fen2.destroy() def Next_Domain(self): if not sum(self.weight) == 1: self.wind_err = tk.Tk() Text_box_err = Text(self.wind_err, height=1, width=80) Text_box_err.insert( INSERT, 'Sum of weigths must be equal to one! Please enter GMPEs again.' ) Text_box_err.pack() bou_quit_box_err = Button(self.wind_err, text='OK', command=self.Delete_gmpe) bou_quit_box_err.pack() self.wind_err.mainloop() else: Ligne = '\t\t<logicTreeBranchingLevel branchingLevelID="gmpe_bl' + str( self.i_Domain + 1) + '">\n' self.XMLfile.write(Ligne) Ligne = '\t\t\t<logicTreeBranchSet uncertaintyType="gmpeModel" branchSetID="' + str( self.Domain) + '"\n' self.XMLfile.write(Ligne) Ligne = '\t\t\t\t\tapplyToTectonicRegionType="' + str( self.Domain) + '">\n\n' self.XMLfile.write(Ligne) for i in range(self.listechoix_gmpe.size()): gmpe = self.listechoix_gmpe.get(i) Ligne = '\t\t\t\t<logicTreeBranch branchID="' + str( gmpe) + '">\n' self.XMLfile.write(Ligne) Ligne = '\t\t\t\t\t<uncertaintyModel>' + str( gmpe) + '</uncertaintyModel>\n' self.XMLfile.write(Ligne) Ligne = '\t\t\t\t\t<uncertaintyWeight>' + str( self.weight[i]) + '</uncertaintyWeight>\n' self.XMLfile.write(Ligne) Ligne = '\t\t\t\t</logicTreeBranch>\n\n' self.XMLfile.write(Ligne) Ligne = '\t\t\t</logicTreeBranchSet>\n' self.XMLfile.write(Ligne) Ligne = '\t\t</logicTreeBranchingLevel>\n\n' self.XMLfile.write(Ligne) self.fen1.destroy() def Finalize_LT(self): if not sum(self.weight) == 1: self.wind_err = tk.Tk() Text_box_err = Text(self.wind_err, height=1, width=80) Text_box_err.insert( INSERT, 'Sum of weigths must be equal to one! Please enter GMPEs again.' ) Text_box_err.pack() bou_quit_box_err = Button(self.wind_err, text='OK', command=self.Delete_gmpe) bou_quit_box_err.pack() self.wind_err.mainloop() else: Ligne = '\t\t<logicTreeBranchingLevel branchingLevelID="gmpe_bl' + str( self.i_Domain + 1) + '">\n' self.XMLfile.write(Ligne) Ligne = '\t\t\t<logicTreeBranchSet uncertaintyType="gmpeModel" branchSetID="' + str( self.Domain) + '"\n' self.XMLfile.write(Ligne) Ligne = '\t\t\t\t\tapplyToTectonicRegionType="' + str( self.Domain) + '">\n\n' self.XMLfile.write(Ligne) for i in range(self.listechoix_gmpe.size()): gmpe = self.listechoix_gmpe.get(i) Ligne = '\t\t\t\t<logicTreeBranch branchID="' + str( gmpe) + '">\n' self.XMLfile.write(Ligne) Ligne = '\t\t\t\t\t<uncertaintyModel>' + str( gmpe) + '</uncertaintyModel>\n' self.XMLfile.write(Ligne) Ligne = '\t\t\t\t\t<uncertaintyWeight>' + str( self.weight[i]) + '</uncertaintyWeight>\n' self.XMLfile.write(Ligne) Ligne = '\t\t\t\t</logicTreeBranch>\n\n' self.XMLfile.write(Ligne) Ligne = '\t\t\t</logicTreeBranchSet>\n' self.XMLfile.write(Ligne) Ligne = '\t\t</logicTreeBranchingLevel>\n\n' self.XMLfile.write(Ligne) Ligne = '\t</logicTree>\n' self.XMLfile.write(Ligne) Ligne = '</nrml>\n' self.XMLfile.write(Ligne) self.XMLfile.close() self.fen1.destroy() def Delete_gmpe(self): for i in range(self.listechoix_gmpe.size()): self.listechoix_gmpe.delete(i) self.wind_err.destroy() self.i_Domain -= 1 self.fen1.destroy()
class MyApp(Frame): def __init__(self): self.root = Tk() Frame.__init__(self, self.root) # high level GUI configuration self.root.geometry('800x600') self.root.resizable(width=1, height=1) self.root.option_add('*tearOff', False) # keeps file menus from looking weird # members related to the background thread and operator instance self.long_thread = None self.background_operator = None # tk variables we can access later self.label_string = StringVar() self.build_dir_1_var = StringVar() self.build_dir_2_var = StringVar() self.run_period_option = StringVar() self.run_period_option.set(RunOptions.DONT_FORCE) self.reporting_frequency = StringVar() self.reporting_frequency.set(ReportingFrequency.HOURLY) # widgets that we might want to access later self.build_dir_1_button = None self.build_dir_2_button = None self.run_button = None self.stop_button = None self.build_dir_1_label = None self.build_dir_1_var.set('/eplus/repos/1eplus/builds') # "<Select build dir 1>") self.build_dir_2_label = None self.build_dir_2_var.set('/eplus/repos/1eplus/builds') # "<Select build dir 2>") self.progress = None self.log_message_listbox = None self.results_tree = None self.num_threads_spinner = None self.full_idf_listbox = None self.move_idf_to_active_button = None self.active_idf_listbox = None self.remove_idf_from_active_button = None self.idf_select_all_button = None self.idf_deselect_all_button = None self.idf_select_n_random_button = None self.run_period_option_menu = None self.reporting_frequency_option_menu = None # some data holders self.tree_folders = dict() self.valid_idfs_in_listing = False self.run_button_color = '#008000' # initialize the GUI self.init_window() # wire up the background thread pub.subscribe(self.status_handler, PubSubMessageTypes.STATUS) pub.subscribe(self.finished_handler, PubSubMessageTypes.FINISHED) pub.subscribe(self.cancelled_handler, PubSubMessageTypes.CANCELLED) def init_window(self): # changing the title of our master widget self.root.title("EnergyPlus Regression Tool 2") self.root.protocol("WM_DELETE_WINDOW", self.client_exit) # create the menu menu = Menu(self.root) self.root.config(menu=menu) file_menu = Menu(menu) file_menu.add_command(label="Exit", command=self.client_exit) menu.add_cascade(label="File", menu=file_menu) # main notebook holding everything main_notebook = ttk.Notebook(self.root) # run configuration pane_run = Frame(main_notebook) group_build_dir_1 = LabelFrame(pane_run, text="Build Directory 1") group_build_dir_1.pack(fill=X, padx=5) self.build_dir_1_button = Button(group_build_dir_1, text="Change...", command=self.client_build_dir_1) self.build_dir_1_button.grid(row=1, column=1, sticky=W) self.build_dir_1_label = Label(group_build_dir_1, textvariable=self.build_dir_1_var) self.build_dir_1_label.grid(row=1, column=2, sticky=E) group_build_dir_2 = LabelFrame(pane_run, text="Build Directory 2") group_build_dir_2.pack(fill=X, padx=5) self.build_dir_2_button = Button(group_build_dir_2, text="Change...", command=self.client_build_dir_2) self.build_dir_2_button.grid(row=1, column=1, sticky=W) self.build_dir_2_label = Label(group_build_dir_2, textvariable=self.build_dir_2_var) self.build_dir_2_label.grid(row=1, column=2, sticky=E) group_run_options = LabelFrame(pane_run, text="Run Options") group_run_options.pack(fill=X, padx=5) Label(group_run_options, text="Number of threads for suite: ").grid(row=1, column=1, sticky=E) self.num_threads_spinner = Spinbox(group_run_options, from_=1, to_=48) # validate later self.num_threads_spinner.grid(row=1, column=2, sticky=W) Label(group_run_options, text="Test suite run configuration: ").grid(row=2, column=1, sticky=E) self.run_period_option_menu = OptionMenu(group_run_options, self.run_period_option, *RunOptions.get_all()) self.run_period_option_menu.grid(row=2, column=2, sticky=W) Label(group_run_options, text="Minimum reporting frequency: ").grid(row=3, column=1, sticky=E) self.reporting_frequency_option_menu = OptionMenu( group_run_options, self.reporting_frequency, *ReportingFrequency.get_all() ) self.reporting_frequency_option_menu.grid(row=3, column=2, sticky=W) main_notebook.add(pane_run, text='Configuration') # now let's set up a list of checkboxes for selecting IDFs to run pane_idfs = Frame(main_notebook) group_idf_tools = LabelFrame(pane_idfs, text="IDF Selection Tools") group_idf_tools.pack(fill=X, padx=5) self.idf_select_all_button = Button( group_idf_tools, text="Refresh", command=self.client_idf_refresh ) self.idf_select_all_button.pack(side=LEFT, expand=1) self.idf_select_all_button = Button( group_idf_tools, text="Select All", command=self.idf_select_all ) self.idf_select_all_button.pack(side=LEFT, expand=1) self.idf_deselect_all_button = Button( group_idf_tools, text="Deselect All", command=self.idf_deselect_all ) self.idf_deselect_all_button.pack(side=LEFT, expand=1) self.idf_select_n_random_button = Button( group_idf_tools, text="Select N Random", command=self.idf_select_random ) self.idf_select_n_random_button.pack(side=LEFT, expand=1) group_full_idf_list = LabelFrame(pane_idfs, text="Full IDF List") group_full_idf_list.pack(fill=X, padx=5) scrollbar = Scrollbar(group_full_idf_list) self.full_idf_listbox = Listbox(group_full_idf_list, yscrollcommand=scrollbar.set) self.full_idf_listbox.bind('<Double-1>', self.idf_move_to_active) self.full_idf_listbox.pack(fill=BOTH, side=LEFT, expand=True) scrollbar.pack(fill=Y, side=LEFT) scrollbar.config(command=self.full_idf_listbox.yview) self.move_idf_to_active_button = Button( pane_idfs, text="↓ Add to Active List ↓", command=self.idf_move_to_active ) self.move_idf_to_active_button.pack(side=TOP, fill=X, expand=True) self.remove_idf_from_active_button = Button( pane_idfs, text="↑ Remove from Active List ↑", command=self.idf_remove_from_active ) self.remove_idf_from_active_button.pack(side=TOP, fill=X, expand=True) group_active_idf_list = LabelFrame(pane_idfs, text="Active IDF List") group_active_idf_list.pack(fill=X, padx=5) scrollbar = Scrollbar(group_active_idf_list) self.active_idf_listbox = Listbox(group_active_idf_list, yscrollcommand=scrollbar.set) self.active_idf_listbox.bind('<Double-1>', self.idf_remove_from_active) self.active_idf_listbox.pack(fill=BOTH, side=LEFT, expand=True) scrollbar.pack(fill=Y, side=LEFT) scrollbar.config(command=self.active_idf_listbox.yview) self.build_idf_listing(initialize=True) main_notebook.add(pane_idfs, text="IDF Selection") # set up a scrolled listbox for the log messages frame_log_messages = Frame(main_notebook) group_log_messages = LabelFrame(frame_log_messages, text="Log Message Tools") group_log_messages.pack(fill=X, padx=5) Button(group_log_messages, text="Clear Log Messages", command=self.clear_log).pack(side=LEFT, expand=1) Button(group_log_messages, text="Copy Log Messages", command=self.copy_log).pack(side=LEFT, expand=1) scrollbar = Scrollbar(frame_log_messages) self.log_message_listbox = Listbox(frame_log_messages, yscrollcommand=scrollbar.set) self.add_to_log("Program started!") self.log_message_listbox.pack(fill=BOTH, side=LEFT, expand=True) scrollbar.pack(fill=Y, side=LEFT) scrollbar.config(command=self.log_message_listbox.yview) main_notebook.add(frame_log_messages, text="Log Messages") # set up a tree-view for the results frame_results = Frame(main_notebook) scrollbar = Scrollbar(frame_results) self.results_tree = ttk.Treeview(frame_results, columns=("Base File", "Mod File", "Diff File")) self.results_tree.heading("#0", text="Results") self.results_tree.column('#0', minwidth=200, width=200) self.results_tree.heading("Base File", text="Base File") self.results_tree.column("Base File", minwidth=100, width=100) self.results_tree.heading("Mod File", text="Mod File") self.results_tree.column("Mod File", minwidth=100, width=100) self.results_tree.heading("Diff File", text="Diff File") self.results_tree.column("Diff File", minwidth=100, width=100) self.build_results_tree() self.results_tree.pack(fill=BOTH, side=LEFT, expand=True) scrollbar.pack(fill=Y, side=LEFT) scrollbar.config(command=self.results_tree.yview) main_notebook.add(frame_results, text="Run Control and Results") # pack the main notebook on the window main_notebook.pack(fill=BOTH, expand=1) # status bar at the bottom frame_status = Frame(self.root) self.run_button = Button(frame_status, text="Run", bg=self.run_button_color, command=self.client_run) self.run_button.pack(side=LEFT, expand=0) self.stop_button = Button(frame_status, text="Stop", command=self.client_stop, state='disabled') self.stop_button.pack(side=LEFT, expand=0) self.progress = ttk.Progressbar(frame_status) self.progress.pack(side=LEFT, expand=0) label = Label(frame_status, textvariable=self.label_string) self.label_string.set("Initialized") label.pack(side=LEFT, anchor=W) frame_status.pack(fill=X) def run(self): self.root.mainloop() def build_idf_listing(self, initialize=False, desired_selected_idfs=None): # clear any existing ones self.active_idf_listbox.delete(0, END) self.full_idf_listbox.delete(0, END) # now rebuild them self.valid_idfs_in_listing = False path_1 = Path(self.build_dir_1_var.get()) path_2 = Path(self.build_dir_2_var.get()) if path_1.exists() and path_2.exists(): idf_dir_1 = dummy_get_idf_dir(path_1) idfs_dir_1 = dummy_get_idfs_in_dir(idf_dir_1) idf_dir_2 = dummy_get_idf_dir(path_2) idfs_dir_2 = dummy_get_idfs_in_dir(idf_dir_2) common_idfs = idfs_dir_1.intersection(idfs_dir_2) for idf in sorted(common_idfs): self.full_idf_listbox.insert(END, str(idf)) self.valid_idfs_in_listing = True elif initialize: self.full_idf_listbox.insert(END, "This will be the master list") self.full_idf_listbox.insert(END, "Select build folders to fill listing") elif path_1.exists(): self.full_idf_listbox.insert(END, "Cannot update master list master list") self.full_idf_listbox.insert(END, "Build folder path #2 is invalid") self.full_idf_listbox.insert(END, "Select build folders to fill listing") elif path_2.exists(): self.full_idf_listbox.insert(END, "Cannot update master list master list") self.full_idf_listbox.insert(END, "Build folder path #1 is invalid") self.full_idf_listbox.insert(END, "Select build folders to fill listing") else: self.full_idf_listbox.insert(END, "Cannot update master list master list") self.full_idf_listbox.insert(END, "Both build folders are invalid") self.full_idf_listbox.insert(END, "Select build folders to fill listing") if desired_selected_idfs is None: ... # add things to the listbox def build_results_tree(self, results=None): self.results_tree.delete(*self.results_tree.get_children()) for root in ResultsTreeRoots.get_all(): self.tree_folders[root] = self.results_tree.insert( parent="", index='end', text=root, values=("", "", "") ) if results: self.results_tree.insert( parent=self.tree_folders[root], index="end", text="Pretend", values=("These", "Are", "Real") ) else: self.results_tree.insert( parent=self.tree_folders[root], index="end", text="Run test for results", values=("", "", "") ) def add_to_log(self, message): self.log_message_listbox.insert(END, f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}]: {message}") def clear_log(self): self.log_message_listbox.delete(0, END) def copy_log(self): messages = self.log_message_listbox.get(0, END) message_string = '\n'.join(messages) self.root.clipboard_append(message_string) def client_idf_refresh(self): self.build_idf_listing() def idf_move_to_active(self, _): if not self.valid_idfs_in_listing: simpledialog.messagebox.showerror("IDF Selection Error", "Invalid build folders or IDF list") return current_selection = self.full_idf_listbox.curselection() if not current_selection: simpledialog.messagebox.showerror("IDF Selection Error", "No IDF Selected") return currently_selected_idf = self.full_idf_listbox.get(current_selection) try: self.active_idf_listbox.get(0, "end").index(currently_selected_idf) simpledialog.messagebox.showwarning("IDF Selection Warning", "IDF already exists in active list") return except ValueError: pass # the value error indicates it was _not_ found, so this is success self.active_idf_listbox.insert(END, currently_selected_idf) self.idf_refresh_count_status(currently_selected_idf, True) def idf_remove_from_active(self, event=None): if not self.valid_idfs_in_listing: simpledialog.messagebox.showerror("IDF Selection Error", "Invalid build folders or IDF list") return current_selection = self.active_idf_listbox.curselection() if not current_selection: if event: return simpledialog.messagebox.showerror("IDF Selection Error", "No IDF Selected") return self.active_idf_listbox.delete(current_selection) self.idf_refresh_count_status(current_selection, False) def idf_select_all(self): self.idf_deselect_all() if not self.valid_idfs_in_listing: simpledialog.messagebox.showerror("IDF Selection Error", "Invalid build folders or IDF list") return all_idfs = self.full_idf_listbox.get(0, END) for idf in all_idfs: self.active_idf_listbox.insert(END, idf) self.idf_refresh_count_status() def idf_deselect_all(self): if not self.valid_idfs_in_listing: simpledialog.messagebox.showerror("IDF Selection Error", "Invalid build folders or IDF list") return self.active_idf_listbox.delete(0, END) self.idf_refresh_count_status() def idf_select_random(self): if not self.valid_idfs_in_listing: simpledialog.messagebox.showerror("IDF Selection Error", "Invalid build folders or IDF list") return potential_number_to_select = simpledialog.askinteger("Input Amount", "How many would you like to select?") if not potential_number_to_select: return self.idf_deselect_all() number_to_select = int(potential_number_to_select) number_of_idf_files = self.full_idf_listbox.size() if number_of_idf_files <= number_to_select: # just take all of them self.idf_select_all() else: # down select randomly indices_to_take = random.sample(range(number_of_idf_files), number_to_select) idfs_to_take = list() for i in indices_to_take: idf_to_get = self.full_idf_listbox.get(i) idfs_to_take.append(idf_to_get) for idf_to_get in sorted(idfs_to_take): self.active_idf_listbox.insert(END, idf_to_get) self.idf_refresh_count_status() def idf_refresh_count_status(self, test_case=None, checked=False): if not self.valid_idfs_in_listing: return num_total = self.full_idf_listbox.size() num_active = self.active_idf_listbox.size() if test_case: chk_string = "Checked" if checked else "Unchecked" if checked: self.label_string.set(f"{chk_string} {test_case} ({num_active}/{num_total} selected)") else: self.label_string.set(f"{num_active}/{num_total} selected") def set_gui_status_for_run(self, is_running: bool): if is_running: run_button_state = 'disabled' stop_button_state = 'normal' else: run_button_state = 'normal' stop_button_state = 'disabled' self.build_dir_1_button.configure(state=run_button_state) self.build_dir_2_button.configure(state=run_button_state) self.run_button.configure(state=run_button_state) self.idf_select_all_button.configure(state=run_button_state) self.idf_deselect_all_button.configure(state=run_button_state) self.idf_select_n_random_button.configure(state=run_button_state) self.move_idf_to_active_button.configure(state=run_button_state) self.remove_idf_from_active_button.configure(state=run_button_state) self.run_period_option_menu.configure(state=run_button_state) self.reporting_frequency_option_menu.configure(state=run_button_state) self.num_threads_spinner.configure(state=run_button_state) self.stop_button.configure(state=stop_button_state) def client_build_dir_1(self): selected_dir = filedialog.askdirectory() if selected_dir: self.build_dir_1_var.set(selected_dir) self.build_idf_listing() def client_build_dir_2(self): selected_dir = filedialog.askdirectory() if selected_dir: self.build_dir_2_var.set(selected_dir) self.build_idf_listing() def client_run(self): if self.long_thread: messagebox.showerror("Cannot run another thread, wait for the current to finish -- how'd you get here?!?") return potential_num_threads = self.num_threads_spinner.get() try: num_threads = int(potential_num_threads) except ValueError: messagebox.showerror("Invalid Configuration", "Number of threads must be an integer") return idfs_to_run = list() for i in self.active_idf_listbox.get(0, END): idfs_to_run.append(i) self.background_operator = BackgroundOperation(num_threads, idfs_to_run) self.background_operator.get_ready_to_go( MyApp.status_listener, MyApp.finished_listener, MyApp.cancelled_listener ) self.set_gui_status_for_run(True) self.long_thread = Thread(target=self.background_operator.run) self.add_to_log("Starting a new set of tests") self.long_thread.start() def client_stop(self): self.add_to_log("Attempting to cancel") self.label_string.set("Attempting to cancel...") self.background_operator.please_stop() def client_exit(self): if self.long_thread: messagebox.showerror("Uh oh!", "Cannot exit program while operations are running; abort them then exit") return exit() def client_done(self): self.set_gui_status_for_run(False) self.long_thread = None # -- Callbacks from the background thread coming via PyPubSub @staticmethod def status_listener(status, object_completed, percent_complete): """Operates on background thread, just issues a pubsub message""" pub.sendMessage( PubSubMessageTypes.STATUS, status=status, object_completed=object_completed, percent_complete=percent_complete) def status_handler(self, status, object_completed, percent_complete): self.add_to_log(object_completed) self.progress['value'] = percent_complete self.label_string.set(f"Hey, status update: {str(status)}") @staticmethod def finished_listener(results_dict): """Operates on background thread, just issues a pubsub message""" pub.sendMessage(PubSubMessageTypes.FINISHED, results=results_dict) def finished_handler(self, results): self.add_to_log("All done, finished") self.label_string.set("Hey, all done!") self.build_results_tree(results) self.client_done() @staticmethod def cancelled_listener(): """Operates on background thread, just issues a pubsub message""" pub.sendMessage(PubSubMessageTypes.CANCELLED) def cancelled_handler(self): self.add_to_log("Cancelled!") self.label_string.set("Properly cancelled!") self.client_done()