class SomeClass1(threading.Thread): def __init__(self, q, root, total_rows, loop_time=1.0 / 60): self.q = q self.timeout = loop_time self.total_rows = 50 self.root1 = tk.Tk() self.root_ref = root self.processed = 0 self.progress = Progressbar(root, orient=HORIZONTAL, variable=1, length=120) self.progress.config(maximum=MAX, mode='determinate', value=1) self.progress.step(1) self.progress.grid(row=0, column=1) super(SomeClass1, self).__init__() def onThread(self, function, *args, **kwargs): self.q.put((function, args, kwargs)) def run(self): while True: try: function, args, kwargs = self.q.get(timeout=self.timeout) function(*args, **kwargs) print("run processed") except queue.Empty: self.idle() print("run empty") def idle(self): # put the code you would have put in the `run` loop here print("idle") self.progress = Progressbar(self.root_ref, orient=HORIZONTAL, variable=self.processed, length=120) self.progress.config(maximum=MAX, mode='determinate', value=1) def doSomething(self, processed_row): global processed print("waiting in increment_progress_bar...", processed_row, ":", self.total_rows) #int_processed_row = int(processed_row,10) if (processed_row >= self.total_rows): print("in progress stop") self.progress.stop() self.progress.grid_forget() else: print("in progress step") #self.progress.step(processed_row) self.processed = processed_row print("updated progress bar...") def doSomethingElse(self, b): print("doSomethingElse", b) self.progress.step(1) time.sleep(2)
class App: file_name = None input_dir = None def __init__(self, master): master.minsize(width=520, height=100) master.maxsize(width=520, height=100) master.title('DocCleaner v1.0') Label(master, text="Directory:").grid(row=0, column=0, sticky='e') global input_dir input_dir = Entry(master, width=60) input_dir.grid(row=0, column=1, padx=2, pady=2, sticky='we', columnspan=9) Button(master, text="Select File", command=self.open_file).grid(row=0, column=10, sticky='e' + 'w', padx=10, pady=2) self.btn = Button(master, text="Process File", command=self.submit_file) self.btn.grid(row=1, column=10, sticky='e' + 'w', padx=10, pady=2) self.progress = Progressbar(master, orient=HORIZONTAL, length=300, mode='indeterminate') @staticmethod def open_file(event=None): input_file_name = tkinter.filedialog\ .askopenfilename(filetypes=[("All Files", "*.*"), ("MS Word", "*.doc;*.docx")]) if input_file_name: global file_name file_name = input_file_name input_dir.delete(0, END) input_dir.insert(0, file_name) def submit_file(self): def real_progress(): self.progress.grid(row=1, column=1, sticky='e') self.progress.start() global input_dir if input_dir.get() != "": tc = TextExtractor(file_name) tc.process_text() time.sleep(5) self.progress.stop() self.progress.grid_forget() input_dir.delete(0, END) self.btn['state'] = 'normal' self.btn['state'] = 'disabled' threading.Thread(target=real_progress).start()
class ChargeProgress(Tk): def __init__(self): super().__init__() self.progress = Progressbar(self, orient=HORIZONTAL, mode='determinate') def runbar(self, event=None): def real_runbar(): self.progress.pack(expand=True, fill=BOTH, side=TOP) self.progress.start(3) time.sleep(0.3) self.progress.stop() self.progress.grid_forget() threading.Thread(target=real_runbar).start()
class App_Build(): def __init__(self, master): self = tkinter.Tk() self.geometry("600x600") self.resizable(width=False, height=False) self.title("FlashLAB") self.configure(background='#6abea7') self.iconbitmap('img/logooooico.ico') self.Btn() # Text # T = Text(self, height=100, width=300) # T.pack() # T.insert(END, "fhsdhfidshf") # Button, Launching progress bar # self.btn = Button(self, text='Deploy', command=self.traitement) # self.btn.grid(row=2,column=10) # self.progress = Progressbar(self, orient=HORIZONTAL,length=500, mode='indeterminate') def Btn(self): self.btn = Button(self, text='Deploy', command=self.traitement) self.btn.grid(row=2, column=10) self.progress = Progressbar(self, orient=HORIZONTAL, length=500, mode='indeterminate') def traitement(self): def real_traitement(): self.progress.grid(row=0, column=0) self.progress.start() # Tps attente avant disparition de la barre time.sleep(10) self.progress.stop() self.progress.grid_forget() self.btn['state'] = 'normal' self.btn['state'] = 'disabled' threading.Thread(target=real_traitement).start()
class MonApp(Tk): def __init__(self): super().__init__() self.btn = Button(self, text='Traitement', command=self.traitement) self.btn.grid(row=0,column=0) self.progress = Progressbar(self, orient=HORIZONTAL,length=100, mode='indeterminate') def traitement(self): def real_traitement(): self.progress.grid(row=1,column=0) self.progress.start() time.sleep(5) self.progress.stop() self.progress.grid_forget() self.btn['state']='normal' self.btn['state']='disabled' threading.Thread(target=real_traitement).start()
def login_all(self): progress_bar = Progressbar(orient=tk.HORIZONTAL, length=100, mode='determinate') progress_bar.grid(row=4, columnspan=2, sticky=tk.N + tk.E + tk.S + tk.W) errors = "" for i in range(self.list_box.size()): puppet = self.list_box.get(i) error_message = self.login(puppet[0], puppet[1]) if error_message != "Login successful": errors += (puppet[0] + ": " + error_message + "\n") time.sleep(0.6) progress_bar['value'] += (100 / self.list_box.size()) root.update_idletasks() progress_bar.grid_forget() if errors == "": messagebox.showinfo(title="Information", message="All logins successful") else: messagebox.showinfo(title="Information", message=errors)
class MonApp(Tk): def __init__(self): super().__init__() self.initWin() self.initBtn() def initWin(self): self.geometry("600x600") self.resizable(width=False, height=False) self.title("FlashLAB") self.configure(background='#6abea7') self.iconbitmap('img/logooooico.ico') def initBtn(self): self.btn = Button(self, text='Deploy', width=25, command=self.traitement, bg='#6abea7') self.btn.grid(row=5, column=5) self.progress = Progressbar(self, orient=HORIZONTAL, length=500, mode='indeterminate') # Progress bar def traitement(self): def real_traitement(): self.progress.grid(row=5, column=5) time.sleep(3) self.progress.start() time.sleep(3) self.progress.stop() self.progress.grid_forget() self.btn['state'] = 'normal' self.btn['state'] = 'disabled' threading.Thread(target=real_traitement).start()
def splashScreen(): from tkinter import Button, Tk, HORIZONTAL from tkinter.ttk import Progressbar import time import threading root0 = tkinter.Tk() root0.title("OdCrypt v 1.0 ") root0.geometry("500x500") root0.configure(background='turquoise') progress = Progressbar(orient=HORIZONTAL, length=100, mode='indeterminate') progress.pack() progress.start() time.sleep(15) progress.stop() progress.grid_forget() threading.Thread(target=splashScreen).start() encryptionButton() root0.mainloop()
class MonApp(Tk): def __init__(self): super().__init__() self.btn = Button(self, text='Export employee data', command=self.start) self.btn.grid(row=0,column=0) self.label = Label(self,text="") self.label.grid(row=0, column=1) self.progress = Progressbar(self, orient=HORIZONTAL,length=200, mode='indeterminate') def start(self): def real_start(): self.progress.grid(row=1,column=0) self.progress.start() self.label['text'] = 'Data processing...' time.sleep(5) self.progress.stop() self.progress.grid_forget() self.label['text'] = 'Done.' self.btn['state']='normal' self.btn['state']='disabled' threading.Thread(target=real_start).start()
class control_FPGA(): def __init__(self): self.version = "V7.6" print(f"> Interfaz Sistema de Autoenfoque OpenFlexure {self.version} ") # Fecha y hora para los archivos self.timestamp = '{:%m%d-%H%M}'.format(datetime.datetime.now()) # Comprueba si se ha seleccionado el path self.flag_carpeta = False # variable auxiliar contador de número de imagenes desde que inicio la interfaz self.aux = 0 self.aux_af = 0 self.count_m1 = 0 self.count_m2 = 0 self.count_m3 = 0 #inicialización de variables self.directorio = "" self.flag_carpeta = False self.dirflag = False self.homeflag = False self.M1_is_on = True self.M2_is_on = True self.M3_is_on = True self.M_is_on = True self.DIR_is_on = True self.sobel_is_on = False self.btnHOME_is_on = True self.cap_is_on = False self.on = "ON" self.off = "OFF" self.img_enf_maximo=False # ----------------- # --- FUNCIONES --- # ----------------- # Función para determinar la carpeta de trabajo donde guardar las imagenes def carpeta_imagenes(self): self.flag_carpeta = True directorio = filedialog.askdirectory() print(f'> Ruta establecida para guardar las imágenes: {directorio}') self.dir_simples = directorio + '/IMG_Simples' os.makedirs(self.dir_simples, exist_ok=True) self.dir_autoenfoque = directorio + '/IMG_Autoenfoque' os.makedirs(self.dir_autoenfoque, exist_ok=True) self.directorio_trabajo.delete(0, tkinter.END) self.directorio_trabajo.insert(0, directorio) self.pos.config(text="Estado: Directorio seleccionado") # Función para reiniciar la interfaz def reset(self): print("> Interfaz reseteada") self.root.destroy() interfaz = control_FPGA() interfaz.createGUI() # Mueve las imágenes al directorio correspondiente def ordena_img(self, nombrebin, nombre, direccion): shutil.copy(nombrebin + '.bin', direccion) shutil.copy(nombre + '.png', direccion) os.remove(nombrebin + '.bin') os.remove(nombre + '.png') # Funcion para enviar las instrucciones a la FPGA por el puerto serie def env_serial(self, arg): global ser bin_num = arg.to_bytes(8, byteorder='big') ser.write(bin_num) if arg == 0 or arg == 255: pass else: print("- Instruccion " + str(arg) + " enviada") print("----") # Generación del archivo PGM: def bin_to_png(self, ancho, alto, nombre_bin, nombre_png): # - Se crea una array de numpy con los bytes del archivo .bin archivo_bin = nombre_bin + ".bin" arr = np.fromfile(archivo_bin, dtype=np.uint8, count=-1, sep='', offset=0) data_png = struct.pack('B' * len(arr), *[pixel for pixel in arr]) size = 320, 240 archivo_png = Image.frombuffer('L', size, data_png) archivo_png.save(nombre_png + '.png') self.imagen_interfaz = archivo_png suma = np.sum(arr) return (suma) # Función que capturar la imagen def captura_img_serie(self): if self.cap_is_on: self.cap.config(text="Activar cam") self.cap_is_on = False print("- Imagen capturada") self.env_serial(2) self.pos.config(text="Estado Inicial: Esperando instrucciones... ") else: self.cap.config(text="Capturar IMG") self.cap_is_on = True print("- Captura deshabilitada") self.env_serial(1) self.pos.config(text="Estado: Imagen capturada ") #Activa/Desactiva el filtro sobel def sobel(self): if self.sobel_is_on: self.sobel_is_on = False print("- Filtro Sobel-H OFF") self.env_serial(192) self.env_serial(0) else: self.sobel_is_on = True print("- Filtro Sobel-H ON") self.env_serial(192) self.env_serial(0) #--- # Función que manda la instrucción para iniciar el sist. de AutoEnfoque def autoenfoque(self): if self.homeflag == True: self.env_serial(5) self.env_serial(0) self.env_serial(133) self.env_serial(0) self.img = PhotoImage(file=r"C:\Users\carlo\PycharmProjects\pythonProject\serial\img\img_micro22.png") self.panel = Label(self.root, image=self.img) self.panel.grid(row=3, column=3, columnspan=4, rowspan=7, padx=5, pady=5) self.save_img_autofocus() # como no detecto cuando la FGPA termina el mov del motor y manda la siguiente foto lo hago por "software" self.img_enf_maximo=True self.pos.config(text="Estado: Ajustando a la mejor posición" ) self.save_img_serie() self.img_enf_maximo=False self.pos.config(text="Estado: IMANGEN ENFOCADA GUARDADA " ) print("-- IMANGEN ENFOCADA GUARDADA -- ") time.sleep(0.5) self.pos.config(text="Estado: Esperando instrucciones... " ) else: self.pos.config(text="Estado: Primero seleccione un directorio! ") # Guarda las imagenes en la estructura de directorios creada def save_img_serie(self): if self.flag_carpeta == True: self.root.update() self.env_serial(4) nombrebin = "IMG_BIN_" + str(self.aux) + '_' + self.timestamp if self.img_enf_maximo==False: self.pos.config(text="Estado: Guardando imagen..." ) nombre = "IMG_" + str(self.aux) + '_' + self.timestamp self.aux = self.aux + 1 else: self.pos.config(text="Estado: Guardando imagen enfocada..." ) nombre = "IMG_ENFOCADA" + str(self.aux_af) + '_' + self.timestamp self.aux_af = self.aux_af + 1 print("> Guardando imagen...") self.progress_bar.grid(row=6, column=3, columnspan=4, padx=5, pady=5) self.lee_serial(nombrebin, 320, 240) self.progress_bar.grid(row=6, column=3, columnspan=4, padx=5, pady=5) self.progress_bar.grid_forget() self.bin_to_png(320, 240, nombrebin, nombre) img_interfaz = ImageTk.PhotoImage(self.imagen_interfaz) self.panel.configure(image=img_interfaz) self.panel.image = img_interfaz print("> Imagen .PNG recibida") print("----------------------------------") x = threading.Thread(target= self.ordena_img, args=(nombrebin, nombre, self.dir_simples)) x.start() self.pos.config(text="Estado: Imagen recibida " ) self.root.update() time.sleep(0.5) self.pos.config(text="Estado inicial: Esperando instrucciones... " ) self.root.update() else: self.pos.config(text="Estado: Primero seleccione un directorio! ") print("! Seleccione un directorio para guardar las imágenes") # Lectura del puerto serie, para recibir la imagen def lee_serial(self, nombre_bin, ancho, alto): self.dimensiones = ancho * alto archivo_bin = nombre_bin + ".bin" fout = open(archivo_bin, 'wb') self.total_bits = 0 while self.total_bits < self.dimensiones: bytesToRead = ser.inWaiting() data = ser.read(bytesToRead) fout.write(data) self.total_bits = len(data) + self.total_bits if self.total_bits < (self.dimensiones * 1 / 5): self.barra_progreso(0) self.root.update_idletasks() elif (self.dimensiones * 1 / 5) < self.total_bits < (self.dimensiones * 2 / 5): self.barra_progreso(20) self.root.update_idletasks() elif (self.dimensiones * 2 / 5) < self.total_bits < (self.dimensiones * 3 / 5): self.barra_progreso(40) self.root.update_idletasks() elif (self.dimensiones * 3 / 5) < self.total_bits < (self.dimensiones * 4 / 5): self.barra_progreso(60) self.root.update_idletasks() elif (self.dimensiones * 4 / 5) < self.total_bits < (self.dimensiones): self.barra_progreso(80) self.root.update_idletasks() elif self.total_bits == (self.dimensiones): self.barra_progreso(100) self.root.update_idletasks() time.sleep(0.1) print("- total bits recibidos:" + str(self.total_bits)) # Función para guardar las imaágenes obtenidas en el modo AutoEnfoque def save_img_autofocus(self): if self.flag_carpeta == True: self.env_serial(4) lista_datos_enfoque = [] max_ele = 0 for i in range(0, 3): nombrebin = "IMG_BIN_AF" + str(i) + '_' + self.timestamp nombre = "IMG_AF" + str(i) + '_' + self.timestamp self.pos.config(text="Estado: proceso de autoenfoque... %s/3" % i ) #-- self.lee_serial(nombrebin, 320, 240) #-- a = self.bin_to_png(320, 240, nombrebin, nombre) time.sleep(0.5) print("- Archivo procesado, PNG listo") print(str(i) + ")------------------------") print("Suma DEC:" + str(a)) print("Suma HEX:" + str(hex(a))) lista_datos_enfoque.append(a) print("----------------------------------") # mueve imgs x = threading.Thread(target=self.ordena_img(nombrebin, nombre, self.dir_autoenfoque)) x.start() for j in range(1, len(lista_datos_enfoque)): if int(lista_datos_enfoque[i]) > max_ele: max_ele = int(lista_datos_enfoque[i]) print("Lista de datos obtenidos:") print(lista_datos_enfoque) print( "- Posición máximo: " + str( lista_datos_enfoque.index(max(lista_datos_enfoque))) + " - Valor: " + str( max(lista_datos_enfoque))) print("----------------------------------") time.sleep(0.2) else: self.pos.config(text="Estado: Primero seleccione un directorio! ") print("! Seleccione un directorio para guardar las imágenes") # -------- Control de los Motores ---------- def btnHOME(self): if self.btnHOME_is_on: self.pos.config(text="Estado: Colocando en posición de referencia...") self.btnHOME_is_on = False print("btn HOME on") if self.flag_carpeta == True: self.env_serial(3) self.info.configure(text=f"Posición muestra: {self.count_m1}-{self.count_m2}-{self.count_m3}") else: self.pos.config(text="Estado: Primero seleccione un directorio") self.homeflag = True self.M1.config(text= "Ajustar") self.M2.config(text= "Ajustar") self.M3.config(text= "Ajustar") self.M.config(text= "Ajustar") self.dir.config(text="ARRIBA") self.DIR_is_on = True else: self.pos.config(text="Estado Inicial: Esperando instrucciones... ") self.btnHOME_is_on = True print("btn HOME off") self.env_serial(0) self.homeflag = False self.count_m1 = 0 self.count_m2 = 0 self.count_m3 = 0 def switchDIR(self): if self.DIR_is_on: self.dir.config(text="ABAJO") # elimnino dir_on self.DIR_is_on = False print("Movimiento descendente") self.env_serial(128) self.env_serial(0) self.dirflag = False else: self.dir.config(text="ARRIBA") self.DIR_is_on = True print("Movimiento ascendente") self.env_serial(128) self.env_serial(0) self.dirflag = True def switchM1(self): if self.homeflag == False: if self.M1_is_on: self.M1.config(text=self.on) self.M1_is_on = False print("Motor1 on") self.env_serial(129) self.env_serial(0) else: self.M1.config(text=self.off) self.M1_is_on = True print("Motor1 off") self.env_serial(129) self.env_serial(0) else: self.M1.config(text= "Ajustar") self.M1_is_on = False print("Motor1 pulsado") self.env_serial(129) self.env_serial(0) if self.dirflag == True: self.count_m1 = self.count_m1 + 1 elif self.dirflag == False: if self.count_m1 == 0: self.count_m1 = self.count_m1 else: self.count_m1 = self.count_m1 - 1 self.pos.config(text="Estado: Ajuste pre-autoenfoque") self.info.configure(text=f"Posición muestra: {self.count_m1}-{self.count_m2}-{self.count_m3}") self.root.update() def switchM2(self): if self.homeflag == False: if self.M2_is_on: self.M2.config(text= self.on) self.M2_is_on = False print("Motor2 on") self.env_serial(130) self.env_serial(0) # 255 else: self.M2.config(text= self.off) self.M2_is_on = True print("Motor2 off") self.env_serial(130) self.env_serial(0) else: self.M2.config(text= "Ajustar") self.M2_is_on = False print("Motor2 pulsado") self.env_serial(130) self.env_serial(0) if self.dirflag == True: self.count_m2 = self.count_m2 + 1 elif self.dirflag == False: if self.count_m2 == 0: self.count_m2 = self.count_m2 else: self.count_m2 = self.count_m2 - 1 self.pos.config(text="Estado: Ajuste pre-autoenfoque") self.info.configure(text=f"Posición muestra: {self.count_m1}-{self.count_m2}-{self.count_m3}") self.root.update() def switchM3(self): if self.homeflag == False: if self.M3_is_on: self.M3.config(text=self.on) self.M3_is_on = False print("Motor3 on") self.env_serial(131) self.env_serial(0) else: self.M3.config(text=self.off) self.M3_is_on = True print("Motor3 off") self.env_serial(131) self.env_serial(0) else: self.M3.config(text= "Ajustar") self.M3_is_on = False print("Motor2 pulsado") self.env_serial(131) self.env_serial(0) if self.dirflag == True: self.count_m3 = self.count_m3 + 1 elif self.dirflag == False: if self.count_m3 == 0: self.count_m3 = self.count_m3 else: self.count_m3 = self.count_m3 - 1 self.pos.config(text="Estado: Ajuste pre-autoenfoque") self.info.configure(text=f"Posición muestra: {self.count_m1}-{self.count_m2}-{self.count_m3}") self.root.update() def switchM(self): if self.homeflag == False: if self.M_is_on: self.M.config(text=self.on) self.M1.config(text=self.on) self.M2.config(text=self.on) self.M3.config(text=self.on) self.M_is_on = False self.M1_is_on = False self.M2_is_on = False self.M3_is_on = False print("All Motor on") self.env_serial(132) self.env_serial(0) else: self.M.config(text=self.off) self.M1.config(text=self.off) self.M2.config(text=self.off) self.M3.config(text=self.off) self.M_is_on = True self.M1_is_on = True self.M2_is_on = True self.M3_is_on = True print("All Motor off") self.env_serial(132) self.env_serial(0) else: self.M.config(text= "Ajustar") self.M1.config(text= "Ajustar") self.M2.config(text= "Ajustar") self.M3.config(text= "Ajustar") self.M_is_on = False self.M1_is_on = False self.M2_is_on = False self.M3_is_on = False print("All Motor on") self.env_serial(132) self.env_serial(0) if self.dirflag == True: self.count_m1 = self.count_m1 + 1 self.count_m2 = self.count_m2 + 1 self.count_m3 = self.count_m3 + 1 elif self.dirflag == False: if self.count_m1 == 0: self.count_m1 = self.count_m1 else: self.count_m1 = self.count_m1 - 1 if self.count_m2 == 0: self.count_m2 = self.count_m2 else: self.count_m2 = self.count_m2 - 1 if self.count_m3 == 0: self.count_m3 = self.count_m3 else: self.count_m3 = self.count_m3 - 1 self.pos.config(text="Estado: Ajuste pre-autoenfoque") self.info.configure(text=f"Posición muestra: {self.count_m1}-{self.count_m2}-{self.count_m3}") self.root.update() # ---------------------------INTERFAZ---------------------------------------------- def createGUI(self): self.root = Tk() self.root.resizable(width=False, height=False) self.color_fondo = "#FFFFFF" self.root['background'] = self.color_fondo #canvas.create_image(0,0,image=bg, anchor="nw") #self.root.geometry("523x502") # titulo de ventana - icono self.root.title('- FPGA - Interfaz de control del microscopio') self.root.iconbitmap('C:\\Users\\carlo\\PycharmProjects\\pythonProject\\serial\\img\\logo.ico') # Define el directorio de trabajo: selectdir = Button(self.root, text="Path", font=("Helvetica", 8), command=lambda: self.carpeta_imagenes()) selectdir.grid(row=0, column=1, sticky=E, padx=5, pady=10) self.carpeta_trabajo = Entry(self.root, width=50, text="Seleccionar carpeta", font=("Calibri Light", 10)) self.carpeta_trabajo.grid(row=0, column=2, columnspan=3, sticky=W, padx=5, pady=10) self.carpeta_trabajo.insert(0, "Seleccione un directorio para guardar las imágenes") self.directorio_trabajo = self.carpeta_trabajo # Etiqueta que define la posición de la muestra self.pos = Label(self.root, text="Estado inicial: Esperando instrucciones... ", font=('Calibri Light', 11), bg=self.color_fondo) self.pos.grid(row=1, column=1, sticky=W+E, padx=10, pady=10, columnspan=15) # Etiqueta que define el estado en el que se encuentra trabajando el microscopio self.info = Label(self.root, text="Posición muestra: %-%-%", font=('Calibri Light', 9), bg=self.color_fondo) self.info.grid(row=3, column=1, sticky=W+E, padx=10, pady=0, columnspan=2) # Botón que inicia el movimiento del microscopio, desplazandose al punto de referencia self.btn_home = Button(self.root, text="HOME", font=("Helvetica", 9), bg=None, command=lambda: self.btnHOME()) self.btn_home.grid(row=2, column=2, sticky=E, pady=10) # Botón que inicia el proceso de AUTOENFOQUE self.btn_focus = Button(self.root, text="AUTOENFOQUE", font=("Helvetica", 9), bg=None, command=lambda: self.autoenfoque()) self.btn_focus.grid(row=2, column=3, pady=10) # Botón que activa el filtro SOBEL self.btn_sobel = Button(self.root, text="SOBEL", font=("Helvetica", 9), bg=None, command=lambda: self.sobel()) self.btn_sobel.grid(row=2, column=4, sticky=W, pady=10) # Botones de control de los motores: self.M1 = Label(self.root, text="Estado", font=("Calibri Light", 10), bg=self.color_fondo) self.M1.grid(row=4, column=2, sticky=W, pady=2) self.btnM1 = Button(self.root, text="Motor M1", font=("Calibri Light", 10), command=lambda: self.switchM1()) self.btnM1.grid(row=4, column=1, sticky=E, pady=2) self.M2 = Label(self.root, text="Estado", font=("Calibri Light", 10), bg=self.color_fondo) self.M2.grid(row=5, column=2, sticky=W, pady=2) self.btnM2 = Button(self.root, text="Motor M2", font=("Calibri Light", 10), command=lambda: self.switchM2()) self.btnM2.grid(row=5, column=1, sticky=E, pady=2) self.M3 = Label(self.root, text="Estado", font=("Calibri Light", 10), bg=self.color_fondo) self.M3.grid(row=6, column=2, sticky=W, pady=2) self.btnM3 = Button(self.root, text="Motor M3", font=("Calibri Light", 10), command=lambda: self.switchM3()) self.btnM3.grid(row=6, column=1, sticky=E, pady=2) self.M = Label(self.root, text="Estado", font=("Calibri Light", 10), bg=self.color_fondo) self.M.grid(row=7, column=2, sticky=W, pady=4) self.btnM = Button(self.root, text="Todos", font=("Calibri Light", 10), command=lambda: self.switchM()) self.btnM.grid(row=7, column=1, sticky=E, pady=2) # Botón que define la dirección de los motores self.dir = Label(self.root, text="Estado", font=("Calibri Light", 10), bg=self.color_fondo) self.dir.grid(row=9, column=2, sticky=W, pady=5) self.btnDIR = Button(self.root, text="Dirección", font=("Calibri Light", 10), command=lambda: self.switchDIR()) self.btnDIR.grid(row=9, column=1, sticky=E, pady=2) # Botón que captura la imagen self.cap = Button(self.root, text="Capturar IMG", bg=None, command=lambda: self.captura_img_serie()) self.cap.grid(row=10, column=3, sticky=E, padx=5, pady=5) # Botón para obtener la imagen de la FPGA self.recibir_img = Button(self.root, text="Guardar IMG", bg=None, command=lambda: self.save_img_serie()) self.recibir_img.grid(row=10, column=4, sticky=W, padx=5, pady=5) #Versión del código ejecutado self.version = Label(self.root, text= self.version) self.version.grid(row=12, column=1, sticky=W, pady=2) # Define la imagen obtenida de la FPGA self.img = PhotoImage(file=r"C:\Users\carlo\PycharmProjects\pythonProject\serial\img\img_micro22.png") #self.img1 = self.img.subsample(1, 1) self.panel = Label(self.root, image=self.img) self.panel.grid(row=3, column=3, columnspan=4, rowspan=7, padx=5, pady=5) # Barra de progreso # - para cambiar el estilo de la barra #self.style = ttk.Style() #self.style.theme_use('alt') #self.style.configure("green.Horizontal.TProgressbar", foreground='green', background='green') #ttk.Progressbar(self.root, style="green.Horizontal.TProgressbar", mode='determinate', maximum=4, value=2) self.progress_bar = Progressbar(self.root, orient=HORIZONTAL, length=160, mode='determinate') self.progress_bar.grid(row=6, column=3, columnspan=4, padx=5, pady=5) self.progress_bar.grid_forget() # ---MENU --- menubar = Menu(self.root) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label="Instrucciones", command=self.instrucciones) filemenu.add_command(label="Esquema FPGA", command=self.esquema) filemenu.add_command(label="About", command=self.about) filemenu.add_command(label="Reset", command=self.reset) filemenu.add_command(label="Exit", command=self.root.quit) configmenu = Menu(menubar, tearoff=0) configmenu.add_command(label="Filtro Sobel-H", command=self.sobel) configmenu.add_command(label="Exit", command=self.root.quit) # filemenu.add_separator() menubar.add_cascade(label="Menu", menu=filemenu) menubar.add_cascade(label="Configuración", menu=configmenu) # configuracion self.root.config(menu=menubar) # background = '#1A1A1A') self.root.mainloop() # ---------------------------INFORMACIÓN------------------------------------------- def barra_progreso(self, valor): self.progress_bar['value'] = int(valor) self.root.update_idletasks() def about(self): toplevel = tkinter.Toplevel(self.root) label0 = tkinter.Label(toplevel, text="\n Interfaz de control FPGA", font=("Helvetica", 9, "bold")) label0.grid(row=0, column=1, padx=1, sticky="s") label1 = ttk.Label(toplevel, text="\n Esta trabajo forma parte del TFM : " "\n " "\n SISTEMA DE AUTOENFOQUE MEDIANTE FPGA PARA MICROSCOPIO DE BAJO " "\n COSTE Y HARDWARE LIBRE CON POSICIONAMIENTO DE BISAGRAS FLEXIBLES " "\n " "\n La interfaz permite el control del sistema de posicionamiento, la obtención " "\n de imágenes y un proceso de enfoque automático desarrollado en FPGA. " "\n " "\n Toda la información del proyecto se encuentra disponible en: " "\n https://github.com/URJCMakerGroup/Autofocus_Delta_Stage " "\n ") label1.grid(row=1, column=1, padx=1, sticky="s") close_btn = ttk.Button(toplevel, text=" ok ", command=toplevel.destroy) close_btn.grid(row=2, column=1) label2 = ttk.Label(toplevel, text=" ") label2.grid(row=3, column=1, padx=1, sticky="s") def esquema(self): x = threading.Thread(target=self.info_esquema, args=()) x.start() def info_esquema(self): img = cv2.imread(r"C:\Users\carlo\PycharmProjects\pythonProject\serial\img\esquema.png", cv2.IMREAD_COLOR) cv2.imshow("Esquema control FPGA", img) cv2.waitKey(0) cv2.destroyAllWindows() def instrucciones(self): toplevel = tkinter.Toplevel(self.root) label0 = tkinter.Label(toplevel, text="\n Instrucciones de uso:", font=("Helvetica", 9, "bold")) label0.grid(row=0, column=1, padx=1, sticky="s") label1 = ttk.Label(toplevel, text="\n La interfaz permite el control de los motores para el ajuste de la muestra. " "\n " "\n En primer lugar es preciso definir un directorio de trabajo pulsando el" "\n botón path. A partir de ahí se puede controlar los diferentes motores y" "\n su dirección, capturar imágenes o guardarlas en PNG el path seleccionado." "\n " "\n - El botón HOME, fija el sistema de posicionamiento en el lugar de referencia" "\n Una vez en la posición de referencia se puede realizar el autoenfoque." "\n " "\n - El botón SOBEL, aplica ese filtro a la imagen (de forma horizontal) " "\n " "\n - El botón AUTOENFOQUE, inicia el proceso para obtener la imagen mejor enfocada " "\n ") label1.grid(row=1, column=1, padx=1, sticky="s") close_btn = ttk.Button(toplevel, text=" ok ", command=toplevel.destroy) close_btn.grid(row=2, column=1) label2 = ttk.Label(toplevel, text=" ") label2.grid(row=3, column=1, padx=1, sticky="s")
class Application(tk.Frame): def __init__(self, master=None): super().__init__(master) self.master = master self.master.resizable(0, 0) self.master.protocol("WM_DELETE_WINDOW", self.save_and_exit) self.main_frame = tk.Frame(master) self.main_frame.grid(row=0, column=0, columnspan=2, padx=10) self.spm = SpotipyManager() # Set default settings self.settings = {'cache': True, 'playlists_exclude': []} # Load settings from file try: with open('./data/settings.pickle', 'rb') as file: self.settings = pickle.load(file) except FileNotFoundError: pass self.cache = { 'date_modified': datetime.now(timezone.utc), 'data': None } # Load cache from file try: with open('./data/cache-playlists.pickle', 'rb') as file: self.cache = pickle.load(file) except FileNotFoundError: pass # Thread created even if settings disable cache in case setting is changed later on. cache_thread = threading.Thread(target=self.cache_playlists_helper) cache_thread.daemon = True cache_thread.start() self.create_base_widgets() def save_and_exit(self): """ Saves self.settings to a file and exits """ with open('./data/settings.pickle', 'wb+') as file: pickle.dump(self.settings, file) with open('./data/cache-playlists.pickle', 'wb+') as file: pickle.dump(self.cache, file) self.master.destroy() def cache_playlists_helper(self): """ Sets cache data to correct format of playlists. Function should only called in a thread. """ playlists = self.spm.get_spotipy_client().current_user_playlists() self.cache['data'] = self.spm.cache_songs_in_playlists(playlists) def create_base_widgets(self): """ Initialises all widgets and puts onto the grid the widgets that appear at the start of the application. """ # GUI widgets header = tk.Label(self.main_frame, text="Spotify Playlist Searcher", width=50) header.grid(row=0, column=0, columnspan=2, pady=10) settings_btn = tk.Button( self.main_frame, text="Settings", command=lambda: self.create_settings_widgets()) settings_btn.grid(row=0, column=1, sticky=tk.E) # Song Search self.create_song_widgets() # Playlist Search self.create_playlist_widgets() def create_song_widgets(self): """ Initialises widgets related to searching for songs on Spotify """ song_search = tk.Frame(self.main_frame) song_search.grid(row=1, column=0, columnspan=2, rowspan=3) self.search_bar = tk.Entry(song_search, width=50) self.search_bar.grid(row=0, column=0) self.search_bar.focus() # Lambda expression is necessary because of self arg self.search_bar.bind('<Return>', lambda x: self.search_submit()) search_bar_submit = tk.Button(song_search, text="Search for Song", command=self.search_submit) search_bar_submit.grid(row=0, column=1) search_results_label = tk.Label(song_search, text='Song Results') search_results_label.grid(row=1, column=0, columnspan=2) self.search_results = tk.Listbox(song_search, width=50) self.search_results.grid(row=2, column=0, columnspan=2, padx=5, pady=5) self.search_results.bind('<<ListboxSelect>>', lambda x: self.check_song_selection()) self.search_results.bind('<Return>', lambda x: self.search_playlists()) def create_playlist_widgets(self): """ Initialises widgets related to searching through playlists for a song. Does not display the playlist results listbox and label. """ playlist_search = tk.Frame(self.main_frame) playlist_search.grid(row=4, column=0, columnspan=2, rowspan=3, pady=(0, 10)) self.playlist_search_btn = tk.Button(playlist_search, text="Search Playlists For Song", command=self.search_playlists, state=tk.DISABLED) self.playlist_search_btn.grid(row=0, column=0, columnspan=2, pady=5) # Will be displayed at later point self.playlist_label = tk.Label(playlist_search, text='Playlist Results') self.playlist_results = tk.Listbox(playlist_search, width=50) # Loading Bar loading_style = Style() loading_style.theme_use('alt') loading_style.configure('TProgressbar', thickness=10) self.playlist_loading = Progressbar(self.main_frame, style='TProgressbar', mode='indeterminate', length=150, maximum=50) def search_submit(self): """ Takes search entered and displays the songs in the listbox. Also, initialises a dict mapping the song names to their Spotify uri. """ # Disables playlist button and clears search results self.search_results.delete(0, tk.END) self.playlist_search_btn['state'] = tk.DISABLED self.song_dict = { } # Maps how song appears in listbox to the song's uri for playlist searching search = self.search_bar.get() if search: paging_object = self.spm.get_spotipy_client().search(search) tracks = paging_object['tracks']['items'] for track in tracks: artists = track['artists'] artists_str = '' for i, artist in enumerate(artists): artists_str += f'{artist["name"]}' if not i == len(artists) - 1: artists_str += ', ' output_str = f"{track['name']} - {artists_str}" self.search_results.insert(tk.END, output_str) self.song_dict[output_str] = track['uri'] def check_song_selection(self): """ If a song has been selected in the song listbox, then the button to search through the playlists can be pressed. """ if self.search_results.curselection(): self.playlist_search_btn['state'] = tk.NORMAL else: self.playlist_search_btn['state'] = tk.DISABLED def search_playlists(self): """ Searches through the playlists for the selected song and displays the results in a new listbox. """ def threaded_search(): # If nothing is selected, selection_get() throws an error try: song_selected = self.search_results.selection_get() except: return song_uri = self.song_dict[song_selected] # If caching is enabled and the cache has data, use cached data if self.settings['cache'] and not self.cache['data'] is None: playlist_uris = set() for playlist_uri in self.cache['data']: if song_uri in self.cache['data'][ playlist_uri] and playlist_uri not in self.settings[ 'playlists_exclude']: playlist_uris.add(playlist_uri) else: playlist_uris = self.spm.find_song_in_playlists( song_uri, self.settings['playlists_exclude']) playlist_names = [ self.spm.get_name_from_uri(uri) for uri in playlist_uris ] # Displaying playlist listbox and then inserting playlists self.playlist_label.grid(row=1, column=0, columnspan=2, pady=(10, 5)) self.playlist_results.grid(row=2, column=0, columnspan=2, padx=5) self.playlist_results.delete(0, tk.END) if playlist_names: playlist_names.sort() for name in playlist_names: self.playlist_results.insert(tk.END, name) else: self.playlist_results.insert( tk.END, 'The selected song is not found in any of your playlists.') # Remove Loading Bar self.playlist_loading.stop() self.playlist_loading.grid_forget() # Start and draw Loading Bar self.playlist_loading.grid(row=8, column=0, columnspan=2, sticky=tk.E, pady=(0, 10)) self.playlist_loading.start() # Initialize thread thread = threading.Thread(target=lambda: threaded_search()) thread.daemon = True # Prevents thread from running after application closes thread.start() def create_settings_widgets(self): """ Creates a new window for settings related to the application """ self.settings_window = tk.Toplevel(self.master) self.settings_window.resizable(0, 0) self.settings_window.title('Settings') self.settings_window.protocol("WM_DELETE_WINDOW", self.exit_settings) settings_frame = tk.Frame(self.settings_window) settings_frame.grid(row=0, column=0) settings_header = tk.Label(settings_frame, text='Settings') settings_header.grid(row=0, column=0, columnspan=2) # TODO Implement caching self.cache_toggle_val = tk.BooleanVar() self.cache_toggle_val.set(self.settings['cache']) cache_toggle = tk.Checkbutton( settings_frame, variable=self.cache_toggle_val, text= 'Enable Caching (Inaccurate results if the playlist have been modified recently)' ) cache_toggle.grid(row=1, column=0, sticky=tk.W) playlist_options_frame = tk.LabelFrame(settings_frame, text='Playlists Searched') playlist_options_frame.grid(row=3, column=0, columnspan=2, pady=(0, 10)) self.options_toggle_val = tk.BooleanVar() self.options_toggle_val.set(True) playlist_options_toggle = tk.Checkbutton( playlist_options_frame, text='Toggle all playlists', variable=self.options_toggle_val, command=self.playlists_toggle) playlist_options_toggle.grid(row=0, column=0, columnspan=2, sticky=tk.W) # TODO Add scrollbar if too many playlist options playlists = self.spm.get_spotipy_client().current_user_playlists() self.playlist_exclude_data = [ ] # List of Tuple (Playlist_URI, BooleanVar) # Generates checkboxes for each user playlist for i, playlist in enumerate(playlists['items']): playlist_name = f'{playlist["name"]}' is_playlist_excluded = tk.BooleanVar() if playlist['uri'] in self.settings['playlists_exclude']: is_playlist_excluded.set(False) else: is_playlist_excluded.set(True) self.playlist_exclude_data.append( (playlist["uri"], is_playlist_excluded)) option = tk.Checkbutton(playlist_options_frame, text=playlist_name, variable=self.playlist_exclude_data[i][1]) option.grid(row=i + 1, column=0, columnspan=2, sticky=tk.W) reset_btn = tk.Button(settings_frame, text='Reset Settings', command=self.reset_settings) reset_btn.grid(row=4, column=0, columnspan=2, pady=(0, 10)) def exit_settings(self): """ Saves settings to self.settings before exiting. """ self.settings['cache'] = self.cache_toggle_val.get() self.settings['playlists_exclude'] = [ check_val[0] for check_val in self.playlist_exclude_data if not check_val[1].get() ] self.settings_window.destroy() def reset_settings(self): """ Resets settings to default values. """ self.settings = {'cache': True, 'playlists_exclude': []} self.cache_toggle_val.set(True) for val in self.playlist_exclude_data: val[1].set(True) def playlists_toggle(self): """ Toggles all of the playlist checkboxes on or off """ toggle_val = self.options_toggle_val.get() for check_val in self.playlist_exclude_data: check_val[1].set(toggle_val)
class Application(Frame): def __init__(self, master=None): super().__init__(master, borderwidth=5, width=0.8 * screen_width, height=0.7 * screen_height) self.master = master self.proc = None self.main_widgets = [] self.logoimage = PhotoImage(file="GUIgraphics/logo.png") self.maskerimage = PhotoImage(file="GUIgraphics/masker.png") self.run_func = None self.run_button = None self.progress = None self.progress_row = None set_style() self.grid(row=0, column=0, sticky=N + S + W + E) # self.grid_propagate(False) self.select_analysis() self.chip_para_dict = {} self.selex_para_dict = {} self.mask_para = [] self.motif_scan_para = [] self.selex_gui_dict = {} self.master.grid_columnconfigure(0, weight=1) self.master.grid_rowconfigure(0, weight=1) # clear all widgets in the main panel def clear(self): # destroy widgets, use pack_forget() or grid_forget() to hide for w in self.main_widgets: w.destroy() def select_analysis(self): row_gen = NumGenerator() logo = Label(self, image=self.logoimage) logo.grid(row=row_gen.get()) # l1 = Label(self, text="Choose Analysis Type", style="main.TLabel") l1 = Label(self, text="", style="main.TLabel") l1.grid(row=row_gen.get()) chip_btn = Button(self, text="Chip-seq", style="main.TButton", command=self.init_chipseq_gui) chip_btn.grid(row=row_gen.get(), pady=10) selex_btn = Button(self, text="Selex-seq", style="main.TButton", command=self.init_selexseq_gui) selex_btn.grid(row=row_gen.get(), pady=10) masker_btn = Button(self, text="Masker", style="main.TButton", command=self.init_masker_gui) masker_btn.grid(row=row_gen.get(), pady=10) l2 = Label(self, text="") l2.grid(row=row_gen.get(), padx=40, pady=10) quit_btn = Button(self, text="QUIT", command=self.master.destroy) quit_btn.grid(row=row_gen.get(), pady=10, ipadx=10, ipady=5) # https://stackoverflow.com/questions/45847313/what-does-weight-do-in-tkinter self.master.grid_columnconfigure(0, weight=1) # self.columnconfigure(1, weight=2) # self.columnconfigure(2, weight=1) # self.rowconfigure(0, weight=1) self.main_widgets += [ logo, l1, chip_btn, selex_btn, masker_btn, l2, quit_btn ] def init_masker_gui(self): self.clear() row_gen = NumGenerator() logo = Label(self, image=self.maskerimage) # logo.grid_columnconfigure(0, weight=1) logo.grid(row=row_gen.get(), columnspan=6) irow = row_gen.get() infile_label, infile_entry, infile_button = gen_file_entry( self, 'Input file', './inputfile.fasta', 'Open File') infile_label.grid(row=irow, column=0, columnspan=1, sticky='w') infile_entry.grid(row=irow, column=1, columnspan=1, sticky='w') infile_button.grid(row=irow, column=2, columnspan=1, sticky='w') irow = row_gen.get() outfile_label, outfile_entry, outfile_button = gen_file_entry( self, 'Output file', './output_file.fasta', 'Open File') outfile_label.grid(row=irow, column=0, columnspan=1, sticky='w') outfile_entry.grid(row=irow, column=1, columnspan=1, sticky='w') outfile_button.grid(row=irow, column=2, columnspan=1, sticky='w') irow = row_gen.get() text_list = [ 'Repeat/\nMotif', 'Type', 'Include\nRevCom\nPattern', 'Sequence', 'n_min_repeats/\nn_max_mutation' ] for i, text in enumerate(text_list): tmplabel = Label(self, text=text) tmplabel.grid(row=irow, column=i, pady=20, sticky='w') def add_pattern(master, label_text, type_value, revcom_value, irow, seq_entry_arr, num_entry_arr): if len(seq_entry_arr) >= n_max_pat: return # label, combobox, checkbox, entry1, entry2 widget_list = gen_mask_pattern(master, label_text, type_value, revcom_value) for i, w in enumerate(widget_list): w.grid(row=irow, column=i, sticky='w') revcom_checkbox, seq_entry, num_entry = widget_list[2:] revcom_checkbox.invoke() # print(f'irow={irow}') seq_entry_arr.append(seq_entry) num_entry_arr.append(num_entry) shift_buttons(irow) def shift_buttons(irow): self.progress_row += 1 add_entry_button.grid_forget() add_entry_button['command'] = callback_fun_arr[func_ind_gen.get()] add_entry_button.grid(row=irow, column=5, sticky='w') self.run_button.grid_forget() self.run_button.grid(row=irow + 2, column=2, pady=50, sticky='w') quit_button.grid_forget() quit_button.grid(row=irow + 2, column=4, pady=50, sticky='w') def run_analysis(): self.mask_para = [] n_input_pat = len(seq_entry_arr) masker = Masker() for i in range(n_input_pat): seq = seq_entry_arr[i].get() num = int(num_entry_arr[i].get()) revcom_flag = revcom_arr[i].get() if pat_type_arr[i].get() == 'Repeat': masker.add_reppat(seq, num, revcom_flag) else: masker.add_motif(seq, num, revcom_flag) infile = infile_entry.get() outfile = outfile_entry.get() self.mask_para.append(masker) self.mask_para.append(infile) self.mask_para.append(outfile) self.run_mask() n_max_pat = 20 pat_type_arr = [StringVar() for _ in range(n_max_pat)] revcom_arr = [BooleanVar() for _ in range(n_max_pat)] seq_entry_arr = [] num_entry_arr = [] func_ind_gen = NumGenerator() callback_fun_arr = [ Command(add_pattern, self, f'Pattern {i+1}', pat_type_arr[i], revcom_arr[i], irow + i + 1, seq_entry_arr, num_entry_arr) for i in range(n_max_pat) ] # for cmd in callback_fun_arr: # print(cmd.args) add_entry_button = Button(self, text="Add Pattern", command=callback_fun_arr[func_ind_gen.get()]) add_entry_button.grid(row=irow, column=5, sticky='w') self.progress_row = row_gen.get() irow = row_gen.get() self.run_button = Button(self, text="RUN", command=run_analysis) self.run_button.grid(row=irow, column=2, pady=50, sticky='w') quit_button = Button(self, text="QUIT", command=self.master.destroy) quit_button.grid(row=irow, column=4, pady=50, sticky='w') self.progress = Progressbar(self, orient=HORIZONTAL, length=300, mode='indeterminate') self.columnconfigure(0, weight=1) self.columnconfigure(1, weight=1) self.columnconfigure(2, weight=1) self.columnconfigure(3, weight=1) self.columnconfigure(4, weight=1) self.columnconfigure(5, weight=1) def run_mask(self): def run_mask_task(*args): masker = args[0] infile = args[1] outfile = args[2] self.progress.grid(row=self.progress_row, column=0, columnspan=5, pady=30) self.progress.start() masker.mask_file(infile, outfile) self.progress.stop() self.progress.grid_forget() messagebox.showinfo('Info', "Process completed!") self.run_button['state'] = 'normal' self.run_button['state'] = 'disabled' threading.Thread(target=run_mask_task, args=self.mask_para).start() def init_chipseq_gui(self): self.clear() logo = Label(self, image=self.logoimage) logo.grid(row=0, column=0) note = Notebook(self) main = Frame(note) motif_scan = Frame(note) topkmer = Frame(note) kmer_query = Frame(note) note.add(main, text="Chip-Seq Main") note.add(motif_scan, text="Motif Scan") note.add(topkmer, text='Top kmer') note.add(kmer_query, text='Kmer query') self.init_chipseq_gui_tabmain(main) self.init_motifscan_guitab(motif_scan) self.init_topkmer_guitab(topkmer) self.init_kmerquery_guitab(kmer_query) note.grid(row=1, column=0) self.master.grid_columnconfigure(0, weight=1) self.master.grid_rowconfigure(0, weight=1) self.master.grid_rowconfigure(1, weight=5) # display top kmer information def init_topkmer_guitab(self, master): row_gen = NumGenerator() irow = row_gen.get() infile_label, infile_entry, infile_button = gen_pickel_file_entry( master, 'Result File', 'Open file') infile_label.grid(row=irow, column=0, sticky='w') infile_entry.grid(row=irow, column=1, sticky='w') infile_button.grid(row=irow, column=2, sticky='w') irow = row_gen.get() n_topkmer_label, n_topkmer_entry = gen_label_entry( master, 'Number of top kmer', '6') n_topkmer_label.grid(row=irow, column=0, sticky='w') n_topkmer_entry.grid(row=irow, column=1, sticky='w') # create a Text widget irow = row_gen.get() txt = Text(master, width=32, height=10) txt.grid(row=irow, column=0, columnspan=3, sticky="nsew", padx=2, pady=2) # create a Scrollbar and associate it with txt scrollb = Scrollbar(master, command=txt.yview) scrollb.grid(row=irow, column=3, sticky='nsew') txt['yscrollcommand'] = scrollb.set def run_analysis(): file = infile_entry.get() with open(file, 'rb') as f: fp = pickle.load(f) kc = fp.kmer_counter res = kc.get_top_kmers(int(n_topkmer_entry.get())) str_list = kc.disp_kmer_info(kmer_list=res[0]) txt.delete('1.0', END) txt.insert(END, "\n".join(str_list)) irow = row_gen.get() self.run_button = Button(master, text="RUN", command=run_analysis) self.run_button.grid(row=irow, column=1, pady=20, sticky='w') quit_button = Button(master, text="QUIT", command=self.master.destroy) quit_button.grid(row=irow, column=2, pady=20, sticky='w') master.columnconfigure(0, weight=5) master.columnconfigure(1, weight=10) master.columnconfigure(2, weight=5) master.columnconfigure(3, weight=1) master.rowconfigure(0, weight=1) master.rowconfigure(1, weight=1) master.rowconfigure(2, weight=7) master.rowconfigure(3, weight=1) # query kmer information in a list def init_kmerquery_guitab(self, master): row_gen = NumGenerator() irow = row_gen.get() infile_label, infile_entry, infile_button = gen_pickel_file_entry( master, 'Result File', 'Open file') infile_label.grid(row=irow, column=0, sticky='w') infile_entry.grid(row=irow, column=1, sticky='w') infile_button.grid(row=irow, column=2, sticky='w') irow = row_gen.get() kmer_info_label = Label(master, text='Input kmer list') kmer_info_label.grid(row=irow, column=0, sticky='w') irow = row_gen.get() kmer_input_txt = Text(master, width=32, height=10) kmer_input_txt.grid(row=irow, column=0, columnspan=3, sticky="nsew", padx=2, pady=2) kmer_input_txt.insert(END, 'Input kmers here (one kmer per line)') # create a Scrollbar and associate it with txt kmer_scrollb = Scrollbar(master, command=kmer_input_txt.yview) kmer_scrollb.grid(row=irow, column=3, sticky='nsew') kmer_input_txt['yscrollcommand'] = kmer_scrollb.set irow = row_gen.get() output_info_label = Label(master, text='Output') output_info_label.grid(row=irow, column=0, sticky='w') # create a Text widget irow = row_gen.get() txt = Text(master, width=32, height=10) txt.grid(row=irow, column=0, columnspan=3, sticky="nsew", padx=2, pady=2) # create a Scrollbar and associate it with txt scrollb = Scrollbar(master, command=txt.yview) scrollb.grid(row=irow, column=3, sticky='nsew') txt['yscrollcommand'] = scrollb.set def run_analysis(): file = infile_entry.get() with open(file, 'rb') as f: fp = pickle.load(f) kc = fp.kmer_counter tmpstr = kmer_input_txt.get("1.0", "end-1c") kmer_list = tmpstr.split("\n") str_list = [] for i, kmer in enumerate(kmer_list): tmpstr = f'line {i}, ' if len(kmer) != kc.k: tmpstr += f'{kmer}, kmer length must be {kc.k}. Return!' txt.delete('1.0', END) txt.insert(END, tmpstr) return str_list = kc.disp_kmer_info(kmer_list=kmer_list) txt.delete('1.0', END) txt.insert(END, "\n".join(str_list)) irow = row_gen.get() self.run_button = Button(master, text="RUN", command=run_analysis) self.run_button.grid(row=irow, column=1, pady=20, sticky='w') quit_button = Button(master, text="QUIT", command=self.master.destroy) quit_button.grid(row=irow, column=2, pady=20, sticky='w') master.columnconfigure(0, weight=5) master.columnconfigure(1, weight=10) master.columnconfigure(2, weight=5) master.columnconfigure(3, weight=1) master.rowconfigure(0, weight=1) master.rowconfigure(1, weight=1) master.rowconfigure(2, weight=3) master.rowconfigure(3, weight=1) master.rowconfigure(4, weight=3) master.rowconfigure(5, weight=1) def run_scan(self): def run_scan_task(*args): scanner = args[0] infile = args[1] outfile = args[2] self.progress.grid(row=self.progress_row, column=0, columnspan=3, pady=30) self.progress.start() scanner.scan_file(infile, outfile) self.progress.stop() self.progress.grid_forget() messagebox.showinfo('Info', "Process completed!") self.run_button['state'] = 'normal' self.run_button['state'] = 'disabled' threading.Thread(target=run_scan_task, args=self.motif_scan_para).start() def init_motifscan_guitab(self, master): row_gen = NumGenerator() irow = row_gen.get() infile_label, infile_entry, infile_button = gen_file_entry( master, 'Input file', './inputfile.fasta', 'Open File') infile_label.grid(row=irow, column=0, columnspan=1, sticky='w') infile_entry.grid(row=irow, column=1, columnspan=1, sticky='w') infile_button.grid(row=irow, column=2, columnspan=1, sticky='w') irow = row_gen.get() outfile_label, outfile_entry, outfile_button = gen_file_entry( master, 'Output file', './output_file.html', 'Open File') outfile_label.grid(row=irow, column=0, columnspan=1, sticky='w') outfile_entry.grid(row=irow, column=1, columnspan=1, sticky='w') outfile_button.grid(row=irow, column=2, columnspan=1, sticky='w') irow = row_gen.get() text_list = [ 'Motif', 'Include\nRevCom', 'Consensus Sequence', 'n_max_mutation' ] for i, text in enumerate(text_list): tmplabel = Label(master, text=text) tmplabel.grid(row=irow, column=i, pady=20, sticky='w') def add_pattern(master, label_text, revcom_value, irow, seq_entry_arr, num_entry_arr): # allow no more than 2 motifs if len(seq_entry_arr) >= 2: return # label, checkbox, entry1, entry2 widget_list = gen_motif_row(master, label_text, revcom_value) for i, w in enumerate(widget_list): w.grid(row=irow, column=i, sticky='w') revcom_checkbox, seq_entry, num_entry = widget_list[1:] revcom_checkbox.invoke() seq_entry_arr.append(seq_entry) num_entry_arr.append(num_entry) shift_buttons(irow) def shift_buttons(irow): self.progress_row += 1 add_entry_button.grid_forget() add_entry_button['command'] = callback_fun_arr[func_ind_gen.get()] add_entry_button.grid(row=irow, column=4, sticky='w') run_button.grid_forget() run_button.grid(row=irow + 2, column=2, pady=50, sticky='w') quit_button.grid_forget() quit_button.grid(row=irow + 2, column=4, pady=50, sticky='w') def run_analysis(): self.motif_scan_para = [] n_input_pat = len(seq_entry_arr) scanner = MotifScanner() for i in range(n_input_pat): seq = seq_entry_arr[i].get() num = int(num_entry_arr[i].get()) revcom_flag = revcom_arr[i].get() scanner.add_motif(seq, num, revcom_flag) infile = infile_entry.get() outfile = outfile_entry.get() self.motif_scan_para.append(scanner) self.motif_scan_para.append(infile) self.motif_scan_para.append(outfile) self.run_scan() n_max_pat = 10 revcom_arr = [BooleanVar() for _ in range(n_max_pat)] seq_entry_arr = [] num_entry_arr = [] func_ind_gen = NumGenerator() callback_fun_arr = [ Command(add_pattern, master, f'Motif {i+1}', revcom_arr[i], irow + i + 1, seq_entry_arr, num_entry_arr) for i in range(n_max_pat) ] # for cmd in callback_fun_arr: # print(cmd.args) add_entry_button = Button(master, text="Add Motif", command=callback_fun_arr[func_ind_gen.get()]) add_entry_button.grid(row=irow, column=4, sticky='w') self.progress_row = row_gen.get() irow = row_gen.get() run_button = Button(master, text="RUN", command=run_analysis) run_button.grid(row=irow, column=2, pady=50, sticky='w') quit_button = Button(master, text="QUIT", command=self.master.destroy) quit_button.grid(row=irow, column=4, pady=50, sticky='w') self.progress = Progressbar(master, orient=HORIZONTAL, length=300, mode='indeterminate') def init_chipseq_gui_tabmain(self, master): # def enter_filename(): # file = filedialog.askopenfilename(initialdir='.',title = "Select file", filetypes = (("fasta files",".fasta .fa .gz"),("all files","*.*"))) # infile_entry.delete(0,END) # infile_entry.insert(0,file) # def enter_outdir(): # outdir = filedialog.askdirectory(initialdir='.') # outdir_entry.delete(0,END) # outdir_entry.insert(0,outdir) def run_analysis(): self.chip_para_dict = { "identifier": identifier_entry.get(), "file_name": infile_entry.get(), "out_dir": outdir_entry.get(), "min_kmer_len": int(min_kmer_len_entry.get()), "max_kmer_len": int(max_kmer_len_entry.get()) } self.run_chipseq() # def validate_identifier(in_str): # if in_str: # return True # else: # return False # vcmd1 = (master.register(validate_identifier), '%P') # def identifiercolour(event): # identifier_entry.config({"background": "light green"}) # #identifier_entry.config({"background": "tomoato"}) # def infilecolour(event): # if os.path.exists(str(infile_entry.get())): # infile_entry.config({"background": "light green"}) # else: # infile_entry.config({"background": "tomato"}) # def outdircolour(event): # if os.access(str(outdir_entry.get()), os.W_OK): # outdir_entry.config({"background": "light green"}) # else: # outdir_entry.config({"background": "tomato"}) # def minkmercolour(event): # if int(min_kmer_len_entry.get()) >= 0: # min_kmer_len_entry.config({"background": "light green"}) # else: # min_kmer_len_entry.config({"background": "tomato"}) # def maxkmercolour(event): # if int(max_kmer_len_entry.get()) >= int(min_kmer_len_entry.get()): # max_kmer_len_entry.config({"background": "light green"}) # else: # max_kmer_len_entry.config({"background": "tomato"}) row_gen = NumGenerator() irow = row_gen.get() identifier_label, identifier_entry = gen_label_entry( master, "Identifier", "TF_name") # identifier_label = Label(master, text="Identifier") # identifier_entry = Entry(master, validate="focusout", validatecommand=vcmd1) # identifier_entry.insert(END, 'TF_name') # identifier_entry['validate']="focusout" # identifier_entry['validatecommand']=vcmd1 identifier_label.grid(row=irow, column=0) identifier_entry.grid(row=irow, column=1) # identifier_entry.bind("<FocusOut>", identifiercolour) # def validate_inputfile(in_str): # return os.path.exists(in_str) # vcmd2 = (master.register(validate_inputfile), '%P') irow = row_gen.get() infile_label, infile_entry, infile_button = gen_file_entry( master, "Input file", 'path_to_input_fasta_file', 'Open File') # infile_label = Label(master, text="Input file") # infile_entry = Entry(master) # # infile_entry = Entry(master, validate="focusout", validatecommand=vcmd2) # infile_entry.insert(END, 'path_to_input_fasta_file') # infile_button = Button(master, text="Open File", command=enter_filename) infile_label.grid(row=irow, column=0) infile_entry.grid(row=irow, column=1) infile_button.grid(row=irow, column=2) # infile_entry.bind("<FocusOut>", infilecolour) # irow = row_gen.get() # outdir_label = Label(master, text="Output Directory") # outdir_entry = Entry(master) # # outdir_entry.insert(END, 'path_to_output_directory') # outdir_button = Button(master, text="Open Directory", command=enter_outdir) outdir_label, outdir_entry, outdir_button = gen_directory_entry( master, "Output Directory", "", "Open Directory") outdir_label.grid(row=irow, column=0) outdir_entry.grid(row=irow, column=1) outdir_button.grid(row=irow, column=2) # outdir_entry.bind("<FocusOut>", outdircolour) # def validate_kmer_len(in_str): # val = int(in_str) # if val<1: # return False # else: # return True # vcmd4 = (master.register(validate_kmer_len), '%P') irow = row_gen.get() min_kmer_len_label, min_kmer_len_entry = gen_label_entry( master, "Minimum Kmer Length", "") # min_kmer_len_label = Label(master, text="Minimum Kmer Length") # min_kmer_len_entry = Entry(master) # min_kmer_len_entry = Entry(master, validate="key", validatecommand=vcmd4) min_kmer_len_label.grid(row=irow, column=0) min_kmer_len_entry.grid(row=irow, column=1) # min_kmer_len_entry.bind("<FocusOut>", minkmercolour) irow = row_gen.get() max_kmer_len_label, max_kmer_len_entry = gen_label_entry( master, "Maximum Kmer Length", "") # max_kmer_len_label = Label(master, text="Maximum Kmer Length") # max_kmer_len_entry = Entry(master) # max_kmer_len_entry = Entry(master,validate="key", validatecommand=vcmd4) max_kmer_len_label.grid(row=irow, column=0) max_kmer_len_entry.grid(row=irow, column=1) # max_kmer_len_entry.bind("<FocusOut>", maxkmercolour) self.progress_row = row_gen.get() irow = row_gen.get() self.run_button = Button(master, text="Run", command=run_analysis) self.run_button.grid(row=irow, column=1, pady=10) quit_button = Button(master, text="QUIT", command=self.master.destroy) quit_button.grid(row=irow, column=2, pady=10) self.progress = Progressbar(master, orient=HORIZONTAL, length=300, mode='indeterminate') # see # https://stackoverflow.com/questions/33768577/tkinter-gui-with-progress-bar # https://www.youtube.com/watch?v=o_Ct13fHeck def run_chipseq(self): def chipseq(**kwargs): self.progress.grid(row=self.progress_row, column=0, columnspan=3) self.progress.start() csp = ChipSeqProcessor(**kwargs) csp.run() self.progress.stop() self.progress.grid_forget() messagebox.showinfo('Info', "Process completed!") self.run_button['state'] = 'normal' # print(self.chip_para_dict) self.run_button['state'] = 'disabled' threading.Thread(target=chipseq, kwargs=self.chip_para_dict).start() def init_selexseq_gui(self): self.clear() row_gen = NumGenerator() logo = Label(self, image=self.logoimage) logo.grid_columnconfigure(0, weight=1) logo.grid(row=row_gen.get()) note = Notebook(self) main = Frame(note) motif_scan = Frame(note) topkmer = Frame(note) kmer_query = Frame(note) note.add(main, text="SELEX-SEQ Main") note.add(motif_scan, text="Motif Scan") note.add(topkmer, text='Top kmer') note.add(kmer_query, text='Kmer query') self.init_selexseq_gui_tabmain_step0(main) self.init_motifscan_guitab(motif_scan) self.init_topkmer_guitab(topkmer) self.init_kmerquery_guitab(kmer_query) note.grid(row=row_gen.get(), column=0) # self.columnconfigure(0,weight=1) self.master.grid_columnconfigure(0, weight=1) self.master.grid_rowconfigure(0, weight=1) self.master.grid_rowconfigure(1, weight=5) def init_selexseq_gui_tabmain_step0(self, master): # def validate_identifier(in_str): # if in_str: # return True # else: # return False # vcmd1 = (master.register(validate_identifier), '%P') def call_next(): self.selex_gui_dict = { "identifier_label": identifier_label, "identifier_entry": identifier_entry, "min_round_label": min_round_label, "min_round_entry": min_round_entry, "max_round_label": max_round_label, "max_round_entry": max_round_entry, "next_button": next_button } self.selex_para_dict = { "curr_row": irow, "identifier": identifier_entry.get(), "min_selex_round": int(min_round_entry.get()), "max_selex_round": int(max_round_entry.get()) } self.init_selexseq_gui_tabmain_step1(master) # def identifiercolour(event): # identifier_entry.config({"background": "light green"}) # #identifier_entry.config({"background": "tomoato"}) # def minroundcolour(event): # if int(min_round_entry.get()) >= 0: # min_round_entry.config({"background": "light green"}) # else: # min_round_entry.config({"background": "tomato"}) # def maxroundcolour(event): # if int(max_round_entry.get()) >= int(min_round_entry.get()): # max_round_entry.config({"background": "light green"}) # else: # max_round_entry.config({"background": "tomato"}) row_gen = NumGenerator() irow = row_gen.get() identifier_label, identifier_entry = gen_label_entry(master, "Identifier", "TF_name", grid_on=True, irow=irow) # identifier_label = Label(master, text="Identifier") # identifier_entry = Entry(master, validate="focusout", validatecommand=vcmd1) # identifier_entry.insert(END, 'TF_name') # identifier_label.grid(row=0, column=0) # identifier_entry.grid(row=0, column=1) # identifier_entry.bind("<FocusOut>", identifiercolour) irow = row_gen.get() min_round_label, min_round_entry = gen_label_entry( master, "Minimum SELEX round number", "", grid_on=True, irow=irow) # irow = 1 # min_round_label = Label(master, text="Minimum SELEX round number") # min_round_entry = Entry(master) # # min_round_entry = Entry(master, validate="key", validatecommand=vcmd4) # min_round_label.grid(row=irow, column=0) # min_round_entry.grid(row=irow, column=1) # min_round_entry.bind("<FocusOut>", minroundcolour) irow = row_gen.get() max_round_label, max_round_entry = gen_label_entry( master, "Maximum SELEX round numer", "", grid_on=True, irow=irow) # irow = 2 # max_round_label = Label(master, text="Maximum SELEX round numer") # max_round_entry = Entry(master) # # max_round_entry = Entry(master, validate="key", validatecommand=vcmd4) # max_round_label.grid(row=irow, column=0) # max_round_entry.grid(row=irow, column=1) # max_round_entry.bind("<FocusOut>", maxroundcolour) # irow = 3 irow = row_gen.get() next_button = Button(master, text="Next", command=call_next) next_button.grid(row=irow, column=1, pady=10) def init_selexseq_gui_tabmain_step1(self, master): def call_prev(): self.selex_para_dict['curr_row'] = curr_row for obj in selex_infile_entry_arr + selex_infile_label_arr + selex_infile_button_arr: obj.destroy() back_button.destroy() for key in self.selex_gui_dict: self.selex_gui_dict[key].destroy() self.init_selexseq_gui_tabmain_step0(master) def call_next(): back_button.destroy() self.selex_gui_dict['next_button'].destroy() del self.selex_gui_dict['next_button'] self.selex_para_dict['curr_row'] = curr_row self.selex_gui_dict[ 'selex_infile_entry_arr'] = selex_infile_entry_arr file_name_arr = [] for obj in selex_infile_entry_arr: file_name_arr.append(obj.get()) self.selex_para_dict['file_name_arr'] = file_name_arr self.init_selexseq_gui_tabmain_step2(master) # def enter_filename(i): # file = filedialog.askopenfilename(initialdir='.',title = "Select file", filetypes = (("fasta files",".fasta .fa .gz"),("all files","*.*"))) # selex_infile_entry_arr[i].delete(0,END) # selex_infile_entry_arr[i].insert(0,file) self.selex_gui_dict['next_button'].grid_forget() # def roundfilescolour(event, relround): # if os.path.exists(str(selex_infile_entry_arr[relround].get())): # selex_infile_entry_arr[relround].config({"background": "light green"}) # else: # selex_infile_entry_arr[relround].config({"background": "tomato"}) curr_row = self.selex_para_dict['curr_row'] selex_infile_label_arr = [] selex_infile_entry_arr = [] selex_infile_button_arr = [] for i_row, i_round in enumerate( range(self.selex_para_dict["min_selex_round"], self.selex_para_dict["max_selex_round"] + 1)): tmplabel, tmpentry, tmpbutton = gen_file_entry( master, f'Selex Round {i_round}', "", "Open File", grid_on=True, irow=curr_row + i_row) # tmplabel = Label(master, text=f'Selex Round {i_round}') # tmpentry = Entry(master) # #tmpentry.bind("<FocusOut>", lambda event : roundfilescolour(event, i_row)) # tmpbutton = Button(master, text="Open File", command=Command(enter_filename, i_row) ) # tmplabel.grid(row=curr_row+i_row, column=0) # tmpentry.grid(row=curr_row+i_row, column=1) # tmpbutton.grid(row=curr_row+i_row, column=2) selex_infile_label_arr.append(tmplabel) selex_infile_entry_arr.append(tmpentry) # selex_infile_entry_arr[i_row].bind("<FocusOut>", lambda event, relround=(i_row): roundfilescolour(event, relround)) selex_infile_button_arr.append(tmpbutton) curr_row += i_row back_button = Button(master, text="Back", command=call_prev) back_button.grid(row=curr_row + 1, column=0, pady=10) self.selex_gui_dict['next_button']['command'] = call_next self.selex_gui_dict['next_button'].grid(row=curr_row + 1, column=2, pady=10) def init_selexseq_gui_tabmain_step2(self, master): def run_analysis(): self.selex_para_dict["out_dir"] = outdir_entry.get() self.selex_para_dict["min_kmer_len"] = int( min_kmer_len_entry.get()) self.selex_para_dict["max_kmer_len"] = int( max_kmer_len_entry.get()) self.run_selexseq() # def enter_outdir(): # outdir = filedialog.askdirectory(initialdir='.') # outdir_entry.delete(0,END) # outdir_entry.insert(0,outdir) curr_row = self.selex_para_dict['curr_row'] + 1 # def outdircolour(event): # if os.access(str(outdir_entry.get()), os.W_OK): # outdir_entry.config({"background": "light green"}) # else: # outdir_entry.config({"background": "tomato"}) # def minkmercolour(event): # if int(min_kmer_len_entry.get()) >= 0: # min_kmer_len_entry.config({"background": "light green"}) # else: # min_kmer_len_entry.config({"background": "tomato"}) # def maxkmercolour(event): # if int(max_kmer_len_entry.get()) >= int(min_kmer_len_entry.get()): # max_kmer_len_entry.config({"background": "light green"}) # else: # max_kmer_len_entry.config({"background": "tomato"}) # outdir_label = Label(master, text="Output Directory") # outdir_entry = Entry(master) # outdir_entry.insert(END, 'path_to_output_directory') # outdir_button = Button(master, text="Open Directory", command=enter_outdir) # outdir_label.grid(row=curr_row, column=0) # outdir_entry.grid(row=curr_row, column=1) # outdir_button.grid(row=curr_row, column=2) # outdir_entry.bind("<FocusOut>", outdircolour) row_gen = NumGenerator() irow = row_gen.get() outdir_label, outdir_entry, outdir_button = gen_directory_entry( master, "Output Directory", 'path_to_output_directory', "Open Directory", grid_on=True, irow=curr_row + irow) irow = row_gen.get() min_kmer_len_label, min_kmer_len_entry = gen_label_entry( master, "Minimum Kmer Length", "", grid_on=True, irow=curr_row + irow) # min_kmer_len_label = Label(master, text="Minimum Kmer Length") # min_kmer_len_entry = Entry(master) # min_kmer_len_label.grid(row=curr_row+irow, column=0) # min_kmer_len_entry.grid(row=curr_row+irow, column=1) # min_kmer_len_entry.bind("<FocusOut>", minkmercolour) irow = row_gen.get() max_kmer_len_label, max_kmer_len_entry = gen_label_entry( master, "Maximum Kmer Length", "", grid_on=True, irow=curr_row + irow) # irow = 2 # max_kmer_len_label = Label(master, text="Maximum Kmer Length") # max_kmer_len_entry = Entry(master) # max_kmer_len_label.grid(row=curr_row+irow, column=0) # max_kmer_len_entry.grid(row=curr_row+irow, column=1) # max_kmer_len_entry.bind("<FocusOut>", maxkmercolour) self.progress_row = row_gen.get( ) + curr_row # reserve for progress bar # irow = 3 irow = row_gen.get() self.run_button = Button(master, text="Run", command=run_analysis) self.run_button.grid(row=curr_row + irow, column=1, pady=10) # irow = 3 quit_button = Button(master, text="QUIT", command=self.master.destroy) quit_button.grid(row=curr_row + irow, column=2, pady=10) self.progress = Progressbar(master, orient=HORIZONTAL, length=300, mode='indeterminate') def run_selexseq(self): def selexseq(**kwargs): self.progress.grid(row=self.progress_row, column=0, columnspan=3) self.progress.start() if 'curr_row' in kwargs: del kwargs['curr_row'] ssp = SelexSeqProcessor(**kwargs) ssp.run() self.progress.stop() self.progress.grid_forget() messagebox.showinfo('Info', "Process completed!") self.run_button['state'] = 'normal' self.run_button['state'] = 'disabled' threading.Thread(target=selexseq, kwargs=self.selex_para_dict).start()
class Application(Frame): def __init__(self, master=None): # screen_width = master.winfo_screenwidth() # screen_height = master.winfo_screenheight() # print(screen_width, screen_height) super().__init__(master, borderwidth=5, width=0.5*screen_width, height=0.5*screen_height) self.master = master self.proc = None self.run_func = None self.run_button = None self.progress = None self.pictureframe = Frame(self.master) self.pictureframe.grid(row=0, column=0) self.logoimage = PhotoImage(file="GUIgraphics/logo.png") self.logo = Label(self.pictureframe, image=self.logoimage) self.logo.grid(row=0, column=0) self.grid(row=0, column=0,sticky='nswe') self.grid_propagate(False) self.select_analysis() self.chip_para_dict = {} self.selex_para_dict = {} self.selex_gui_dict = {} # clear all widgets in the main panel def clear(self): self.l1.destroy() self.l2.destroy() self.chip.destroy() self.selex.destroy() self.quit.destroy() # self.chip.pack_forget() # self.selex.pack_forget() # self.quit.pack_forget() def select_analysis(self): self.l1 = Label(self, text="Choose Analysis Type") self.l1.grid(row=0,pady=10,padx=5) self.logoimage = PhotoImage(file="GUIgraphics/logo.png") self.logo = Label(self, image=self.logoimage) self.logo.place(relx=0.5, rely=0.1, anchor="n") self.chip = Button(self, text="Chip-seq", command=self.init_chipseq_gui) self.chip.grid(row=1,pady=10) self.selex = Button(self, text="Selex-seq", command=self.init_selexseq_gui) self.selex.grid(row=2,pady=10) self.l2 = Label(self, text="") self.l2.grid(row=3, padx=50, pady=10) self.quit = Button(self, text="QUIT", command=self.master.destroy) self.quit.grid(row=4, pady=10, ipadx=10, ipady=5) def init_chipseq_gui(self): self.clear() self.logoimage = PhotoImage(file="GUIgraphics/logo.png") self.logo = Label(self, image=self.logoimage) self.logo.place(relx=0.5, rely=0.1, anchor="n") note = Notebook() self.notebook = note main = Frame(note) masker = Frame(note) win_extract = Frame(note) note.add(main, text = "Chip-Seq Main") note.add(masker, text = "Masker") note.add(win_extract, text = "Chip-Seq Window Extract") self.init_chipseq_gui_tabmain(main) note.grid_rowconfigure(0, weight=1) note.grid_columnconfigure(0, weight=1) note.grid(row=0,column=0, sticky=N, pady=(250, 10)) def init_chipseq_gui_tabmain(self,master): def enter_filename(): file = filedialog.askopenfilename(initialdir='.',title = "Select file", filetypes = (("fasta files",".fasta .fa .gz"),("all files","*.*"))) infile_entry.delete(0,END) infile_entry.insert(0,file) def enter_outdir(): outdir = filedialog.askdirectory(initialdir='.') outdir_entry.delete(0,END) outdir_entry.insert(0,outdir) def run_analysis(): self.chip_para_dict = {"identifier":identifier_entry.get(), "file_name":infile_entry.get(), "out_dir":outdir_entry.get(), "min_kmer_len":int(min_kmer_len_entry.get()), "max_kmer_len":int(max_kmer_len_entry.get())} self.run_chipseq() def validate_identifier(in_str): if in_str: return True else: return False vcmd1 = (master.register(validate_identifier), '%P') def identifiercolour(event): identifier_entry.config({"background": "light green"}) #identifier_entry.config({"background": "tomoato"}) def infilecolour(event): if os.path.exists(str(infile_entry.get())): infile_entry.config({"background": "light green"}) else: infile_entry.config({"background": "tomato"}) def outdircolour(event): if os.access(str(outdir_entry.get()), os.W_OK): outdir_entry.config({"background": "light green"}) else: outdir_entry.config({"background": "tomato"}) def minkmercolour(event): if int(min_kmer_len_entry.get()) >= 0: min_kmer_len_entry.config({"background": "light green"}) else: min_kmer_len_entry.config({"background": "tomato"}) def maxkmercolour(event): if int(max_kmer_len_entry.get()) >= int(min_kmer_len_entry.get()): max_kmer_len_entry.config({"background": "light green"}) else: max_kmer_len_entry.config({"background": "tomato"}) identifier_label = Label(master, text="Identifier") identifier_entry = Entry(master, validate="focusout", validatecommand=vcmd1) identifier_entry.insert(END, 'TF_name') identifier_label.grid(row=0, column=0) identifier_entry.grid(row=0, column=1) identifier_entry.bind("<FocusOut>", identifiercolour) # def validate_inputfile(in_str): # return os.path.exists(in_str) # vcmd2 = (master.register(validate_inputfile), '%P') irow = 1 infile_label = Label(master, text="Input file") infile_entry = Entry(master) # infile_entry = Entry(master, validate="focusout", validatecommand=vcmd2) infile_entry.insert(END, 'path_to_input_fasta_file') infile_button = Button(master, text="Open File", command=enter_filename) infile_label.grid(row=irow, column=0) infile_entry.grid(row=irow, column=1) infile_button.grid(row=irow, column=2) infile_entry.bind("<FocusOut>", infilecolour) irow = 2 outdir_label = Label(master, text="Output Directory") outdir_entry = Entry(master) # outdir_entry.insert(END, 'path_to_output_directory') outdir_button = Button(master, text="Open Directory", command=enter_outdir) outdir_label.grid(row=irow, column=0) outdir_entry.grid(row=irow, column=1) outdir_button.grid(row=irow, column=2) outdir_entry.bind("<FocusOut>", outdircolour) # def validate_kmer_len(in_str): # val = int(in_str) # if val<1: # return False # else: # return True # vcmd4 = (master.register(validate_kmer_len), '%P') irow = 3 min_kmer_len_label = Label(master, text="Minimum Kmer Length") min_kmer_len_entry = Entry(master) # min_kmer_len_entry = Entry(master, validate="key", validatecommand=vcmd4) min_kmer_len_label.grid(row=irow, column=0) min_kmer_len_entry.grid(row=irow, column=1) min_kmer_len_entry.bind("<FocusOut>", minkmercolour) irow = 4 max_kmer_len_label = Label(master, text="Maximum Kmer Length") max_kmer_len_entry = Entry(master) # max_kmer_len_entry = Entry(master,validate="key", validatecommand=vcmd4) max_kmer_len_label.grid(row=irow, column=0) max_kmer_len_entry.grid(row=irow, column=1) max_kmer_len_entry.bind("<FocusOut>", maxkmercolour) irow = 6 self.run_button = Button(master, text="Run", command=run_analysis) self.run_button.grid(row=irow,column=1, pady=10) irow = 6 quit_button = Button(master, text="QUIT", command=self.master.destroy) quit_button.grid(row=irow, column=2, pady=10) self.progress = Progressbar(master, orient=HORIZONTAL, length=300, mode='indeterminate') # see # https://stackoverflow.com/questions/33768577/tkinter-gui-with-progress-bar # https://www.youtube.com/watch?v=o_Ct13fHeck def run_chipseq(self): def chipseq(**kwargs): self.progress.grid(row=5,column=0,columnspan=3) self.progress.start() csp = ChipSeqProcessor(**kwargs) csp.run() self.progress.stop() self.progress.grid_forget() messagebox.showinfo('Info', "Process completed!") self.run_button['state']='normal' # print(self.chip_para_dict) self.run_button['state']='disabled' threading.Thread(target=chipseq, kwargs=self.chip_para_dict).start() def init_selexseq_gui(self): self.clear() self.logoimage = PhotoImage(file="GUIgraphics/logo.png") self.logo = Label(self, image=self.logoimage) self.logo.place(relx=0.5, rely=0.1, anchor="n") note = Notebook() self.notebook = note main = Frame(note) masker = Frame(note) note.add(main, text = "SELEX-SEQ Main") note.add(masker, text = "Masker") self.init_selexseq_gui_tabmain_step0(main) note.grid_rowconfigure(0, weight=1) note.grid_columnconfigure(0, weight=1) note.grid(row=0,column=0, sticky=N, pady=(250, 10)) def init_selexseq_gui_tabmain_step0(self, master): def validate_identifier(in_str): if in_str: return True else: return False vcmd1 = (master.register(validate_identifier), '%P') def call_next(): self.selex_gui_dict = {"identifier_label":identifier_label, "identifier_entry":identifier_entry, "min_round_label":min_round_label, "min_round_entry":min_round_entry, "max_round_label":max_round_label, "max_round_entry":max_round_entry, "next_button":next_button} self.selex_para_dict = { "curr_row":3, "identifier":identifier_entry.get(), "min_selex_round":int(min_round_entry.get()), "max_selex_round":int(max_round_entry.get()) } self.init_selexseq_gui_tabmain_step1(master) def identifiercolour(event): identifier_entry.config({"background": "light green"}) #identifier_entry.config({"background": "tomoato"}) def minroundcolour(event): if int(min_round_entry.get()) >= 0: min_round_entry.config({"background": "light green"}) else: min_round_entry.config({"background": "tomato"}) def maxroundcolour(event): if int(max_round_entry.get()) >= int(min_round_entry.get()): max_round_entry.config({"background": "light green"}) else: max_round_entry.config({"background": "tomato"}) identifier_label = Label(master, text="Identifier") identifier_entry = Entry(master, validate="focusout", validatecommand=vcmd1) identifier_entry.insert(END, 'TF_name') identifier_label.grid(row=0, column=0) identifier_entry.grid(row=0, column=1) identifier_entry.bind("<FocusOut>", identifiercolour) irow = 1 min_round_label = Label(master, text="Minimum SELEX round number") min_round_entry = Entry(master) # min_round_entry = Entry(master, validate="key", validatecommand=vcmd4) min_round_label.grid(row=irow, column=0) min_round_entry.grid(row=irow, column=1) min_round_entry.bind("<FocusOut>", minroundcolour) irow = 2 max_round_label = Label(master, text="Maximum SELEX round numer") max_round_entry = Entry(master) # max_round_entry = Entry(master, validate="key", validatecommand=vcmd4) max_round_label.grid(row=irow, column=0) max_round_entry.grid(row=irow, column=1) max_round_entry.bind("<FocusOut>", maxroundcolour) irow = 3 next_button = Button(master, text="Next", command=call_next) next_button.grid(row=irow,column=1, pady=10) def init_selexseq_gui_tabmain_step1(self, master): def call_prev(): self.selex_para_dict['curr_row'] = curr_row for obj in selex_infile_entry_arr + selex_infile_label_arr + selex_infile_button_arr: obj.destroy() back_button.destroy() for key in self.selex_gui_dict: self.selex_gui_dict[key].destroy() self.init_selexseq_gui_tabmain_step0(master) def call_next(): back_button.destroy() self.selex_gui_dict['next_button'].destroy() del self.selex_gui_dict['next_button'] self.selex_para_dict['curr_row'] = curr_row self.selex_gui_dict['selex_infile_entry_arr'] = selex_infile_entry_arr file_name_arr = [] for obj in selex_infile_entry_arr: file_name_arr.append(obj.get()) self.selex_para_dict['file_name_arr'] = file_name_arr self.init_selexseq_gui_tabmain_step2(master) def enter_filename(i): file = filedialog.askopenfilename(initialdir='.',title = "Select file", filetypes = (("fasta files",".fasta .fa .gz"),("all files","*.*"))) selex_infile_entry_arr[i].delete(0,END) selex_infile_entry_arr[i].insert(0,file) self.selex_gui_dict['next_button'].grid_forget() def roundfilescolour(event, relround): if os.path.exists(str(selex_infile_entry_arr[relround].get())): selex_infile_entry_arr[relround].config({"background": "light green"}) else: selex_infile_entry_arr[relround].config({"background": "tomato"}) curr_row = self.selex_para_dict['curr_row'] selex_infile_label_arr = [] selex_infile_entry_arr = [] selex_infile_button_arr = [] for i_row, i_round in enumerate(range(self.selex_para_dict["min_selex_round"],self.selex_para_dict["max_selex_round"]+1)): tmplabel = Label(master, text=f'Selex Round {i_round}') tmpentry = Entry(master) #tmpentry.bind("<FocusOut>", lambda event : roundfilescolour(event, i_row)) tmpbutton = Button(master, text="Open File", command=Command(enter_filename, i_row) ) tmplabel.grid(row=curr_row+i_row, column=0) tmpentry.grid(row=curr_row+i_row, column=1) tmpbutton.grid(row=curr_row+i_row, column=2) selex_infile_label_arr.append(tmplabel) selex_infile_entry_arr.append(tmpentry) selex_infile_entry_arr[i_row].bind("<FocusOut>", lambda event, relround=(i_row): roundfilescolour(event, relround)) selex_infile_button_arr.append(tmpbutton) curr_row += i_row back_button = Button(master, text="Back", command=call_prev) back_button.grid(row=curr_row+1,column=0, pady=10) self.selex_gui_dict['next_button']['command']=call_next self.selex_gui_dict['next_button'].grid(row=curr_row+1, column=2, pady=10) def init_selexseq_gui_tabmain_step2(self, master): def run_analysis(): self.selex_para_dict["curr_row"] = curr_row self.selex_para_dict["out_dir"]=outdir_entry.get() self.selex_para_dict["min_kmer_len"]=int(min_kmer_len_entry.get()) self.selex_para_dict["max_kmer_len"]=int(max_kmer_len_entry.get()) self.run_selexseq() def enter_outdir(): outdir = filedialog.askdirectory(initialdir='.') outdir_entry.delete(0,END) outdir_entry.insert(0,outdir) curr_row = self.selex_para_dict['curr_row']+1 def outdircolour(event): if os.access(str(outdir_entry.get()), os.W_OK): outdir_entry.config({"background": "light green"}) else: outdir_entry.config({"background": "tomato"}) def minkmercolour(event): if int(min_kmer_len_entry.get()) >= 0: min_kmer_len_entry.config({"background": "light green"}) else: min_kmer_len_entry.config({"background": "tomato"}) def maxkmercolour(event): if int(max_kmer_len_entry.get()) >= int(min_kmer_len_entry.get()): max_kmer_len_entry.config({"background": "light green"}) else: max_kmer_len_entry.config({"background": "tomato"}) outdir_label = Label(master, text="Output Directory") outdir_entry = Entry(master) outdir_entry.insert(END, 'path_to_output_directory') outdir_button = Button(master, text="Open Directory", command=enter_outdir) outdir_label.grid(row=curr_row, column=0) outdir_entry.grid(row=curr_row, column=1) outdir_button.grid(row=curr_row, column=2) outdir_entry.bind("<FocusOut>", outdircolour) irow = 1 min_kmer_len_label = Label(master, text="Minimum Kmer Length") min_kmer_len_entry = Entry(master) min_kmer_len_label.grid(row=curr_row+irow, column=0) min_kmer_len_entry.grid(row=curr_row+irow, column=1) min_kmer_len_entry.bind("<FocusOut>", minkmercolour) irow = 2 max_kmer_len_label = Label(master, text="Maximum Kmer Length") max_kmer_len_entry = Entry(master) max_kmer_len_label.grid(row=curr_row+irow, column=0) max_kmer_len_entry.grid(row=curr_row+irow, column=1) max_kmer_len_entry.bind("<FocusOut>", maxkmercolour) irow = 3 self.run_button = Button(master, text="Run", command=run_analysis) self.run_button.grid(row=curr_row+irow,column=1, pady=10) irow = 3 quit_button = Button(master, text="QUIT", command=self.master.destroy) quit_button.grid(row=curr_row+irow, column=2, pady=10) curr_row += 4 # reserve for progress bar self.progress = Progressbar(master, orient=HORIZONTAL, length=300, mode='indeterminate') def run_selexseq(self): def selexseq(**kwargs): self.progress.grid(row=self.selex_para_dict["curr_row"],column=0,columnspan=3) self.progress.start() del kwargs['curr_row'] ssp = SelexSeqProcessor(**kwargs) ssp.run() self.progress.stop() self.progress.grid_forget() messagebox.showinfo('Info', "Process completed!") self.run_button['state']='normal' self.run_button['state']='disabled' threading.Thread(target=selexseq, kwargs=self.selex_para_dict).start()
class App: def __init__(self, master): self.master = master self.master.title("DIEGO'S MOVIE PICKER") title_font = font.Font(family='Times', size=25) label_font = font.Font(family='Arial', size=10) menubar = tk.Menu(master) filemenu = tk.Menu(menubar, tearoff=0) filemenu.add_command(label="Guide", command=lambda: messagebox.showinfo("How to use", "Select your year and score range. Then, you can select or a key-word or up to two genres. The query can take A LOT of time (~10min). Same movie query should get different random results every time.")) filemenu.add_command(label="Genres", command=lambda: messagebox.showinfo("Genres Information", "Can select up to two genres from: action, adventure, animation, children, comedy, crime, documentary, drama, fantasy, film-noir, horror, musical, mystery, romance, sci-fi, thriller, war and western. SHOULD BE THE SAME NAME.")) filemenu.add_command(label="Key-Words", command=lambda: messagebox.showinfo("Key-Words Information", "Selec a theme (ie. aliens, superheroes, weddings, ... ). The results should be VERY different for the same key-word query.")) filemenu.add_command(label="Troubleshoot", command=lambda: messagebox.showinfo("Troubleshoot", "Should take a lot of time, up to 10 minutes. If no results were found or the movies are not satifing, search again without changing anything and should change the output. YOU CAN'T SELECT KEYWORDS AND GENRES, JUST ONE OF BOTH.")) filemenu.add_separator() filemenu.add_command(label="Exit", command=master.quit) menubar.add_cascade(label="Help", menu=filemenu) master.config(menu=menubar) self.label = tk.Label(text="DIEGO'S MOVIE PICKER", font=title_font) self.label.grid(column=1, row=0) self.label = tk.Label(text='Min Score:', font=label_font) self.label.grid(column=0, row=1) self.min_score_var = tk.IntVar() self.min_score = tk.Scale(orient=tk.HORIZONTAL, from_=0, to=100, variable=self.min_score_var) self.min_score.grid(column=0, row=2) self.min_score.set(60) self.label = tk.Label(text='Max Score:', font=label_font) self.label.grid(column=0, row=3) self.max_score_var = tk.IntVar() self.max_score = tk.Scale(orient=tk.HORIZONTAL, from_=0, to=100, variable=self.max_score_var) self.max_score.grid(column=0, row=4) self.max_score.set(100) self.label = tk.Label(text='Min Year:', font=label_font) self.label.grid(column=2, row=1) self.min_year_var = tk.IntVar() self.min_score = tk.Scale(orient=tk.HORIZONTAL, from_=1900, to=datetime.datetime.now().year, variable=self.min_year_var) self.min_score.grid(column=2, row=2) self.min_score.set(1960) self.label = tk.Label(text='Max Year:', font=label_font) self.label.grid(column=2, row=3) self.max_year_var = tk.IntVar() self.max_score = tk.Scale(orient=tk.HORIZONTAL, from_=1900, to=datetime.datetime.now().year, variable=self.max_year_var) self.max_score.grid(column=2, row=4) self.max_score.set(datetime.datetime.now().year) self.label_query = tk.Label(text='Query Progress:', font=label_font) self.progressbar = Progressbar(orient=tk.HORIZONTAL, length=100, mode='determinate') self.label = tk.Label(text='Max number of movies to display:', font=label_font) self.label.grid(column=1, row=3) self.MOVIE_LIMIT = tk.IntVar() self.max_score = tk.Scale(orient=tk.HORIZONTAL, from_=1, to=20, variable=self.MOVIE_LIMIT) self.max_score.grid(column=1, row=4) self.max_score.set(7) self.label = tk.Label(text='Key-Word:', font=label_font) self.label.grid(column=0, row=5) self.key_word = tk.Entry() self.key_word.grid(column=0, row=6) self.label = tk.Label(text='Genre 1:', font=label_font) self.label.grid(column=1, row=5) self.genre_1 = tk.Entry() self.genre_1.grid(column=1, row=6) self.label = tk.Label(text='Genre 2:', font=label_font) self.label.grid(column=2, row=5) self.genre_2 = tk.Entry() self.genre_2.grid(column=2, row=6) self.button1 = tk.Button(text='Enlighten me!', command=self.start_search) self.button1.grid(column=1, row=7) self.ia = imdb.IMDb() self.data = pd.read_csv('movies.csv') self.genres_list = ["action", "adventure", "animation", "children", "comedy", "crime", "documentary", "drama", "fantasy", "film-noir", "horror", "musical", "mystery", "romance", "sci-fi", "thriller", "war", "western"] self.known_movies_title_list = [] self.known_movies_years_list = [] self.known_movies_genres_list = [] for idx, (title, genre) in enumerate(zip(self.data['title'], self.data['genres'])): self.known_movies_title_list.append(' '.join(title.split(' ')[:-1])) year = int(title.split(' ')[-1][1:-1]) self.known_movies_years_list.append(year) self.known_movies_genres_list.append([g.lower() for g in genre.split('|')]) def create_movie_dict(self, title, info=False): movies = self.ia.search_movie(title) if info: print("\nProcessing", title) score = (self.min_score_var.get(), self.max_score_var.get()) year = (self.min_year_var.get(), self.max_year_var.get()) movie = None for m in movies: y = m.get('year') if not y: if info: print("No year info ...") return None if year[0] <= y <= year[1]: movie = m break if not movie: if info: print("Movie not found or not in year period ...") return None movieID = movie.movieID movie = self.ia.get_movie(movieID) score_met = self.ia.get_movie_critic_reviews(movieID)['data'] if score_met: score_met = score_met.get('metascore') if score_met is None: if info: print("No score found ...") return None if not score[0] <= int(score_met) <= score[1]: if info: print("Score not in range ...") return None else: if info: print("No score found ...") return None if info: print("PROCESSED!") box_office = movie.get('box office') if box_office: box_office = box_office.get('Cumulative Worldwide Gross') title = movie.get('title') year = movie.get('year') genres = movie.get('genre') plot = movie.get('plot') if plot: plot = plot[0] cast = movie.get('cast') cover = movie.get('cover url') director = movie.get('director') url = self.ia.get_imdbURL(movie) return {'title': title, 'year': year, 'director': director, 'score': score_met, 'genres': genres, 'box_office': int(''.join([b for b in box_office if b.isdigit()])) if box_office is not None else 0, 'cast': cast, 'cover': cover, 'plot': plot, 'url': url} def start_search(self): self.progressbar.grid(column=1, row=2) self.label_query.grid(column=1, row=1) self.data = self.data.reindex(np.random.permutation(self.data.index)) if self.key_word.get(): possible_keywords = self.ia.search_keyword(self.key_word.get()) possible_movies = [] keyword = random.choice(possible_keywords) self.key_word.delete(0, "end") self.key_word.insert(0, keyword) movies = self.ia.get_keyword(keyword) random.shuffle(movies) for movie in movies: self.progressbar['value'] = int(len(possible_movies) / self.MOVIE_LIMIT.get() * 100) root.update_idletasks() if len(possible_movies) >= self.MOVIE_LIMIT.get(): break movie_dic = self.create_movie_dict(movie['title']) if movie_dic: possible_movies.append(movie_dic) else: if not self.genre_1.get() and not self.genre_2.get(): messagebox.showinfo("Are you OK?", "No genres or key-words were set ...") return possible_movies = [] for title, year, genres in zip(self.known_movies_title_list, self.known_movies_years_list, self.known_movies_genres_list): self.progressbar['value'] = int(len(possible_movies) / self.MOVIE_LIMIT.get() * 100) root.update_idletasks() if len(possible_movies) == self.MOVIE_LIMIT.get(): break if self.min_year_var.get() < int(year) < self.max_year_var.get(): if self.genre_1.get(): if self.genre_2.get(): if self.genre_1.get() in genres and self.genre_2.get() in genres: movie_dic = self.create_movie_dict(title) if movie_dic: possible_movies.append(movie_dic) elif self.genre_1.get() in genres: movie_dic = self.create_movie_dict(title) if movie_dic: possible_movies.append(movie_dic) elif self.genre_2.get(): if self.genre_2.get() in genres: movie_dic = self.create_movie_dict(title) if movie_dic: possible_movies.append(movie_dic) if not possible_movies: messagebox.showinfo("Ouff", "ANY movie could fit your description ...") self.label_query.grid_forget() self.progressbar.grid_forget() return messagebox.showinfo("Success", f"{len(possible_movies)} movies matching your description were found!") global query_movies query_movies = [] query_movies = possible_movies self.label_query.grid_forget() self.progressbar.grid_forget() movieList()
class App(): def __init__(self): """ tkinter application that uses HazPy to export Hazus results""" # Create app self.root = tk.Tk() # self.root.grid_propagate(0) # load config self.config = json.loads(open('src/config.json').read()) # global styles self.globalStyles = self.config['themes'][self.config['activeTheme']] self.backgroundColor = self.globalStyles['backgroundColor'] self.foregroundColor = self.globalStyles['foregroundColor'] self.hoverColor = self.globalStyles['hoverColor'] self.fontColor = self.globalStyles['fontColor'] self.textEntryColor = self.globalStyles['textEntryColor'] self.starColor = self.globalStyles['starColor'] self.padl = 15 # tk styles self.textBorderColor = self.globalStyles['textBorderColor'] self.textHighlightColor = self.globalStyles['textHighlightColor'] # ttk styles classes self.style = ttk.Style() self.style.configure("BW.TCheckbutton", foreground=self.fontColor, background=self.backgroundColor, bordercolor=self.backgroundColor, side='LEFT') self.style.configure('TCombobox', background=self.backgroundColor, bordercolor=self.backgroundColor, relief='flat', lightcolor=self.backgroundColor, darkcolor=self.backgroundColor, borderwidth=4, foreground=self.foregroundColor) # App parameters self.root.title('Export Tool') self.root.configure(background=self.backgroundColor, highlightcolor='#fff') # App images self.root.wm_iconbitmap('Python_env/assets/images/Hazus.ico') self.img_data = ImageTk.PhotoImage( Image.open("Python_env/assets/images/data_blue.png").resize( (20, 20), Image.BICUBIC)) self.img_edit = ImageTk.PhotoImage( Image.open("Python_env/assets/images/edit_blue.png").resize( (20, 20), Image.BICUBIC)) self.img_folder = ImageTk.PhotoImage( Image.open("Python_env/assets/images/folder_icon.png").resize( (20, 20), Image.BICUBIC)) # Init dynamic row self.row = 0 def updateProgressBar(self, value, message): """ Updates the progress bar text and position when processing """ self.label_progress.config(text=message) self.root.update_idletasks() self.bar_progress['value'] = value def browsefunc(self): """ Opens a file explorer window and sets the ouputDirectory as the selection """ self.outputDirectory = filedialog.askdirectory() self.outputDirectory = self.outputDirectory.replace('\n', '') self.text_outputDirectory.delete("1.0", 'end-1c') if len(self.dropdown_studyRegion.get()) > 0: self.text_outputDirectory.insert( "1.0", self.outputDirectory + '/' + self.dropdown_studyRegion.get()) self.root.update_idletasks() else: self.text_outputDirectory.insert("1.0", self.outputDirectory) self.root.update_idletasks() def focus_next_widget(self, event): """ makes the interface focus on the next widget """ event.widget.tk_focusNext().focus() return ("break") def focus_previous_widget(self, event): """ makes the interface focus on the previous widget """ event.widget.tk_focusPrev().focus() return ("break") # TODO update hover actions def on_enter_dir(self, e): self.button_outputDir['background'] = self.hoverColor def on_leave_dir(self, e): self.button_outputDir['background'] = self.backgroundColor def on_enter_run(self, e): self.button_run['background'] = '#006b96' def on_leave_run(self, e): self.button_run['background'] = '#0078a9' def run(self): """ runs the export with all the user parameters selected """ try: # init time t0 = time() # make sure all options are selected and get all info if not self.validateRequiredFields(): ctypes.windll.user32.MessageBoxW( None, u"Please select these required fields prior to exporting: {e}" .format(e=self.selection_errors), u'HazPy - Message', 0) return None # (extra) draft email if the checkbox is selected try: if 'opt_draftEmail' in dir(self): if self.exportOptions['draftEmail']: draftEmail(self.studyRegion) # return if only draftEmail is checked if self.exportOptions['csv'] + self.exportOptions[ 'shapefile'] + self.exportOptions[ 'geojson'] + self.exportOptions['report'] == 0: tk.messagebox.showinfo( "HazPy", "Complete - Draft email can be found in the draft folder of Outlook" ) return except: print('unable to draft email') # add progress bar self.addWidget_progress() # calculate progress bar increments exportOptionsCount = 0 if self.exportOptions['csv']: exportOptionsCount += 4 if self.exportOptions['shapefile']: exportOptionsCount += 3 if self.exportOptions['geojson']: exportOptionsCount += 3 if self.exportOptions['report']: exportOptionsCount += 2 progressIncrement = 100 / exportOptionsCount progressValue = 0 # create a directory for the output files outputPath = self.text_outputDirectory.get("1.0", 'end') outputPath = outputPath.replace('\n', '') if not os.path.exists(outputPath): os.mkdir(outputPath) # get bulk of results try: progressValue = progressValue + progressIncrement msg = 'Retrieving base results' self.updateProgressBar(progressValue, msg) results = self.studyRegion.getResults() essentialFacilities = self.studyRegion.getEssentialFacilities() # check if the study region contains result data if len(results) < 1: tk.messagebox.showwarning( 'HazPy', 'No results found. Please check your study region and try again.' ) except: ctypes.windll.user32.MessageBoxW( None, u"Unexpected error retrieving base results: " + str(sys.exc_info()[0]), u'HazPy - Message', 0) # export study region to csv if the checkbox is selected if self.exportOptions['csv']: try: progressValue = progressValue + progressIncrement self.updateProgressBar(progressValue, 'Writing results to CSV') try: results.toCSV(outputPath + '/results.csv') except: print('Base results not available to export.') try: progressValue = progressValue + progressIncrement self.updateProgressBar( progressValue, 'Writing building damage by occupancy to CSV') buildingDamageByOccupancy = self.studyRegion.getBuildingDamageByOccupancy( ) buildingDamageByOccupancy.toCSV( outputPath + '/building_damage_by_occupancy.csv') except: print( 'Building damage by occupancy not available to export.' ) try: progressValue = progressValue + progressIncrement self.updateProgressBar( progressValue, 'Writing building damage by type to CSV') buildingDamageByType = self.studyRegion.getBuildingDamageByType( ) buildingDamageByType.toCSV( outputPath + '/building_damage_by_type.csv') except: print( 'Building damage by type not available to export.') try: progressValue = progressValue + progressIncrement self.updateProgressBar( progressValue, 'Writing damaged facilities to CSV') essentialFacilities.toCSV(outputPath + '/damaged_facilities.csv') except: print('Damaged facilities not available to export.') except: ctypes.windll.user32.MessageBoxW( None, u"Unexpected error exporting CSVs: " + str(sys.exc_info()[0]), u'HazPy - Message', 0) # export study region to Shapefile if the checkbox is selected if self.exportOptions['shapefile']: try: progressValue = progressValue + progressIncrement self.updateProgressBar(progressValue, 'Writing results to Shapefile') try: results.toShapefile(outputPath + '/results.shp') except: print('Base results not available to export.') try: progressValue = progressValue + progressIncrement self.updateProgressBar( progressValue, 'Writing damaged facilities to Shapefile') essentialFacilities.toShapefile( outputPath + '/damaged_facilities.shp') except: print('Damaged facilities not available to export.') try: progressValue = progressValue + progressIncrement self.updateProgressBar(progressValue, 'Writing hazard to Shapefile') if not 'hazard' in dir(): hazard = self.studyRegion.getHazardGeoDataFrame() hazard.toShapefile(outputPath + '/hazard.shp') except: print('Hazard not available to export.') except: ctypes.windll.user32.MessageBoxW( None, u"Unexpected error exporting Shapefile: " + str(sys.exc_info()[0]), u'HazPy - Message', 0) # export study region to GeoJSON if the checkbox is selected if self.exportOptions['geojson']: try: progressValue = progressValue + progressIncrement msg = 'Writing results to GeoJSON' self.updateProgressBar(progressValue, msg) try: results.toGeoJSON(outputPath + '/results.geojson') except: print('Base results not available to export.') try: progressValue = progressValue + progressIncrement self.updateProgressBar( progressValue, 'Writing damaged facilities to GeoJSON') essentialFacilities.toGeoJSON( outputPath + '/damaged_facilities.geojson') except: print('Damaged facilities not available to export.') try: progressValue = progressValue + progressIncrement self.updateProgressBar(progressValue, 'Writing hazard to GeoJSON') if not 'hazard' in dir(): hazard = self.studyRegion.getHazardGeoDataFrame() hazard.toGeoJSON(outputPath + '/hazard.geojson') except: print('Hazard not available to export.') except: ctypes.windll.user32.MessageBoxW( None, u"Unexpected error exporting GeoJSON: " + str(sys.exc_info()[0]), u'HazPy - Message', 0) # export study region to pdf if the checkbox is selected if self.exportOptions['report']: try: progressValue = progressValue + progressIncrement msg = 'Writing results to PDF (exchanging patience for maps)' self.updateProgressBar(progressValue, msg) reportTitle = self.text_reportTitle.get("1.0", 'end-1c') if len(reportTitle) > 0: self.studyRegion.report.title = reportTitle reportSubtitle = self.text_reportSubtitle.get( "1.0", 'end-1c') if len(reportSubtitle) > 0: self.studyRegion.report.subtitle = reportSubtitle self.studyRegion.report.save(outputPath + '/report_summary.pdf', build=True) except: ctypes.windll.user32.MessageBoxW( None, u"Unexpected error exporting the PDF: " + str(sys.exc_info()[0]), u'HazPy - Message', 0) # show export is complete self.updateProgressBar(100, 'Complete') print('Results available at: ' + outputPath) print('Total elapsed time: ' + str(time() - t0)) tk.messagebox.showinfo( "HazPy", "Complete - Output files can be found at: " + outputPath) self.removeWidget_progress() except: # if the export fails if 'bar_progress' in dir(self): self.removeWidget_progress() ctypes.windll.user32.MessageBoxW( None, u"Unexpected export error: " + str(sys.exc_info()[0]), u'HazPy - Message', 0) def validateRequiredFields(self): """ checks that the user has completed all required fields """ try: # create a list to store error strings - this will prompt the user to complete every error found self.selection_errors = [] # defaults all fields validated to true validated = True # validate dropdown menus # validates that a study region is selected if self.dropdown_studyRegion.winfo_ismapped(): value = self.dropdown_studyRegion.get() if len(value) > 0: self.studyRegion = StudyRegion(str(value)) else: self.selection_errors.append('Study Region') validated = False # validates that a scenario is selected or auto-assigned if 'dropdown_scenario' in dir( self) and self.dropdown_scenario.winfo_ismapped(): value = self.dropdown_scenario.get() if len(value) > 0: self.studyRegion.setScenario(value) else: self.selection_errors.append('Scenario') validated = False # validates that a hazard is selected or auto-assigned if 'dropdown_hazard' in dir( self) and self.dropdown_hazard.winfo_ismapped(): value = self.dropdown_hazard.get() if len(value) > 0: self.studyRegion.setHazard(value) else: self.selection_errors.append('Hazard') validated = False # validates that a return period is selected or auto-assigned if 'dropdown_returnPeriod' in dir( self) and self.dropdown_returnPeriod.winfo_ismapped(): value = self.dropdown_returnPeriod.get() if len(value) > 0: self.studyRegion.setReturnPeriod(value) else: self.selection_errors.append('Return Period') validated = False # validate export checkboxes self.exportOptions = {} self.exportOptions['csv'] = self.opt_csv.get() self.exportOptions['shapefile'] = self.opt_shp.get() self.exportOptions['geojson'] = self.opt_geojson.get() self.exportOptions['report'] = self.opt_report.get() # validates if the sum is greater than zero - if selected, they each checkbox will have a value of 1 exportOptionsCount = sum([x for x in self.exportOptions.values()]) if exportOptionsCount == 0: self.selection_errors.append('export checkbox') validated = False # validate output directory _outputDirectory = self.text_outputDirectory.get("1.0", 'end') _outputDirectory = _outputDirectory.replace('\n', '') if len(_outputDirectory) == 0: self.selection_errors.append('output directory') validated = False # (extra) validate only if exists - MUST be last in validation if 'opt_draftEmail' in dir(self): val = self.opt_draftEmail.get() self.exportOptions['draftEmail'] = val if val == 1: validated = True return validated except: # validation check fails validated = False ctypes.windll.user32.MessageBoxW( None, u"Unexpected export error: " + str(sys.exc_info()[0]), u'HazPy - Message', 0) def addWidget_report(self, row): """ adds the report title and report subtitle widgets """ # report title self.label_reportTitle = tk.Label(self.root, text='Report Title', font='Helvetica 10 bold', background=self.backgroundColor, fg=self.fontColor) self.label_reportTitle.grid(row=row, column=1, padx=0, pady=(20, 5), sticky=W) row += 1 # report title text input self.text_reportTitle = tk.Text( self.root, height=1, width=37, font='Helvetica 10', background=self.textEntryColor, relief='flat', highlightbackground=self.textBorderColor, highlightthickness=1, highlightcolor=self.textHighlightColor) self.text_reportTitle.grid(row=row, column=1, padx=(0, 0), pady=(0, 0), sticky=W) # report title icon self.img_reportTitle = tk.Label(self.root, image=self.img_edit, background=self.backgroundColor) self.img_reportTitle.grid(row=row, column=2, padx=(0, self.padl), pady=(0, 0), sticky=W) row += 1 # report subtitle # report subtitle label self.label_reportSubtitle = tk.Label(self.root, text='Report Subtitle', font='Helvetica 10 bold', background=self.backgroundColor, fg=self.fontColor) self.label_reportSubtitle.grid(row=row, column=1, padx=0, pady=(20, 5), sticky=W) row += 1 # report subtitle text input self.text_reportSubtitle = tk.Text( self.root, height=1, width=37, font='Helvetica 10', background=self.textEntryColor, relief='flat', highlightbackground=self.textBorderColor, highlightthickness=1, highlightcolor=self.textHighlightColor) self.text_reportSubtitle.grid(row=row, column=1, padx=(0, 0), pady=(0, 0), sticky=W) # report subtitle icon self.img_reportSubtitle = tk.Label(self.root, image=self.img_edit, background=self.backgroundColor) self.img_reportSubtitle.grid(row=row, column=2, padx=(0, self.padl), pady=(0, 0), sticky=W) def removeWidget_report(self): """ removes the report title and report subtitle widgets """ self.label_reportTitle.grid_forget() self.text_reportTitle.grid_forget() self.text_reportTitle.delete('1.0', 'end') self.img_reportTitle.grid_forget() self.label_reportSubtitle.grid_forget() self.text_reportSubtitle.grid_forget() self.text_reportSubtitle.delete('1.0', 'end') self.img_reportSubtitle.grid_forget() def handle_reportCheckbox(self): """adds and removes the report widgets based off checkbox selection""" val = self.opt_report.get() if val == 0: self.removeWidget_report() if val == 1: self.addWidget_report(self.row_report) def handle_draftEmailCheckbox(self): """handles the draft email checkbox""" val = self.opt_draftEmail.get() def addWidget_hazard(self, row): """adds the hazard dropdown widget""" # requred label self.required_hazard = tk.Label(self.root, text='*', font='Helvetica 14 bold', background=self.backgroundColor, fg=self.starColor) self.required_hazard.grid(row=row, column=0, padx=(self.padl, 0), pady=(20, 5), sticky=W) # # hazard label self.label_hazard = tk.Label(self.root, text='Hazard', font='Helvetica 10 bold', background=self.backgroundColor, fg=self.fontColor) self.label_hazard.grid(row=row, column=1, padx=0, pady=(20, 5), sticky=W) row += 1 # # hazard dropdown self.dropdown_hazard = ttk.Combobox(self.root, textvar=self.value_hazard, values=self.options_hazard, width=40, style='H.TCombobox') self.dropdown_hazard.grid(row=row, column=1, padx=(0, 0), pady=(0, 0), sticky=W) def removeWidget_hazard(self): """removes the hazard dropdown widget""" self.required_hazard.grid_forget() self.label_hazard.grid_forget() self.dropdown_hazard.grid_forget() self.dropdown_hazard.set('') def addWidget_scenario(self, row): """adds the scenario dropdown widget""" # requred label self.required_scenario = tk.Label(self.root, text='*', font='Helvetica 14 bold', background=self.backgroundColor, fg=self.starColor) self.required_scenario.grid(row=row, column=0, padx=(self.padl, 0), pady=(20, 5), sticky=W) # scenario label self.label_scenario = tk.Label(self.root, text='Scenario', font='Helvetica 10 bold', background=self.backgroundColor, fg=self.fontColor) self.label_scenario.grid(row=row, column=1, padx=0, pady=(20, 5), sticky=W) row += 1 # scenario dropdown self.dropdown_scenario = ttk.Combobox(self.root, textvar=self.value_scenario, values=self.options_scenario, width=40, style='H.TCombobox') self.dropdown_scenario.grid(row=row, column=1, padx=(0, 0), pady=(0, 0), sticky=W) def removeWidget_scenario(self): """removes the scenario dropdown widget""" self.required_scenario.grid_forget() self.label_scenario.grid_forget() self.dropdown_scenario.grid_forget() self.dropdown_scenario.set('') def addWidget_returnPeriod(self, row): """adds the return period dropdown widget""" # required label self.required_returnPeriod = tk.Label(self.root, text='*', font='Helvetica 14 bold', background=self.backgroundColor, fg=self.starColor) self.required_returnPeriod.grid(row=row, column=0, padx=(self.padl, 0), pady=(20, 5), sticky=W) # return period label self.label_returnPeriod = tk.Label(self.root, text='Return Period', font='Helvetica 10 bold', background=self.backgroundColor, fg=self.fontColor) self.label_returnPeriod.grid(row=row, column=1, padx=0, pady=(20, 5), sticky=W) row += 1 # return period dropdown self.dropdown_returnPeriod = ttk.Combobox( self.root, textvar=self.value_returnPeriod, values=self.options_returnPeriod, width=40, style='H.TCombobox') self.dropdown_returnPeriod.grid(row=row, column=1, padx=(0, 0), pady=(0, 0), sticky=W) def removeWidget_returnPeriod(self): """removes the return period dropdown widget""" self.required_returnPeriod.grid_forget() self.label_returnPeriod.grid_forget() self.dropdown_returnPeriod.grid_forget() self.dropdown_returnPeriod.set('') def addWidget_progress(self): """adds the progress bar widget""" row = self.row_progress self.bar_progress = Progressbar(mode='indeterminate') self.bar_progress.grid(row=row, column=1, pady=(0, 10), padx=50, sticky='nsew') self.root.update_idletasks() row += 1 self.label_progress = tk.Label(self.root, text='Initializing', font='Helvetica 8', background=self.backgroundColor, fg=self.foregroundColor) self.label_progress.grid(row=row, pady=(0, 10), column=1, sticky='nsew') row += 1 self.label_progress.config(text='Initializing') self.bar_progress['value'] = 0 self.root.update_idletasks() self.root.update() def removeWidget_progress(self): """removes the progress bar widget""" self.bar_progress.grid_forget() self.label_progress.grid_forget() def handle_studyRegion(self, name, index, operation): """handles widget creation and removal and initializes the study region class based off the study region dropdown selection""" try: value = self.value_studyRegion.get() # if a study region is selected if value != '': # init StudyRegion class self.studyRegion = StudyRegion(str(value)) # get lists of hazards, scenarios, and return periods self.options_hazard = self.studyRegion.getHazardsAnalyzed() self.options_scenario = self.studyRegion.getScenarios() self.options_returnPeriod = self.studyRegion.getReturnPeriods() # try to remove previous widgets if they exist try: self.removeWidget_hazard() except: pass try: self.removeWidget_scenario() except: pass try: self.removeWidget_returnPeriod() except: pass # add widgets if multiple options exist if len(self.options_hazard) > 1: self.addWidget_hazard(self.row_hazard) if len(self.options_scenario) > 1: self.addWidget_scenario(self.row_scenario) if len(self.options_returnPeriod) > 1: self.addWidget_returnPeriod(self.row_returnPeriod) # update the output directory if len(self.text_outputDirectory.get("1.0", 'end-1c')) > 0: self.text_outputDirectory.delete("1.0", 'end-1c') self.text_outputDirectory.insert( "1.0", self.outputDirectory + '/' + self.studyRegion.name) except: ctypes.windll.user32.MessageBoxW( None, u"Unable to initialize the Study Region. Please select another Study Region to continue. Error: " + str(sys.exc_info()[0]), u'HazPy - Message', 0) def handle_hazard(self, name, index, operation): """handles the selection of a hazard from the hazard widget""" value = self.value_hazard.get() # if value selected if value != '': # update study region class with value self.studyRegion.setHazard(value) print('Hazard set as ' + str(value)) # get new scenario list self.options_scenario = self.studyRegion.getScenarios() # remove previous scenario widget if exists try: self.removeWidget_scenario() except: pass # add scenario widget if more than one option exists if len(self.options_scenario) > 1: self.addWidget_scenario() def handle_scenario(self, name, index, operation): """handles the selection of a scenario from the scenario widget""" value = self.value_scenario.get() # if value selected if value != '': # update study region class with value self.studyRegion.setScenario(value) print('Scenario set as ' + str(value)) # get new return period list self.options_returnPeriod = self.studyRegion.getReturnPeriods() # remove previous return period widget if exists try: self.removeWidget_returnPeriod() except: pass # add return period widget if more than one option exists if len(self.options_returnPeriod) > 1: self.addWidget_returnPeriod() def handle_returnPeriod(self, name, index, operation): """handles the selection of a return period from the return period widget""" value = self.value_returnPeriod.get() # if value exists if value != '': # update study region class with value self.studyRegion.setReturnPeriod(value) print('Return Period set as ' + str(value)) def build_gui(self): """ builds the GUI """ try: # initialize dropdown options options_studyRegion = HazusDB().getStudyRegions() self.value_studyRegion = StringVar(name='studyRegion') self.value_studyRegion.trace('w', self.handle_studyRegion) self.options_hazard = [] self.value_hazard = StringVar(name='hazard') self.value_hazard.trace('w', self.handle_hazard) self.options_scenario = [] self.value_scenario = StringVar(name='scenario') self.value_scenario.trace(W, self.handle_scenario) self.options_returnPeriod = [] self.value_returnPeriod = StringVar(name='returnPeriod') self.value_returnPeriod.trace(W, self.handle_returnPeriod) # requred label self.required_studyRegion = tk.Label( self.root, text='*', font='Helvetica 14 bold', background=self.backgroundColor, fg=self.starColor) self.required_studyRegion.grid(row=self.row, column=0, padx=(self.padl, 0), pady=(20, 5), sticky=W) # Study Region label self.label_studyRegion = tk.Label(self.root, text='Study Region', font='Helvetica 10 bold', background=self.backgroundColor, fg=self.fontColor) self.label_studyRegion.grid(row=self.row, column=1, padx=0, pady=(20, 5), sticky=W) self.row += 1 # Study Region dropdown self.dropdown_studyRegion = ttk.Combobox( self.root, textvar=self.value_studyRegion, values=options_studyRegion, width=40, style='H.TCombobox') self.dropdown_studyRegion.grid(row=self.row, column=1, padx=(0, 0), pady=(0, 0), sticky=W) # Study Region icon self.img_scenarioName = tk.Label(self.root, image=self.img_data, background=self.backgroundColor) self.img_scenarioName.grid(row=self.row, column=2, padx=(0, self.padl), pady=(0, 0), sticky=W) self.row += 1 # requred label self.required_export = tk.Label(self.root, text='*', font='Helvetica 14 bold', background=self.backgroundColor, fg=self.starColor) self.required_export.grid(row=self.row, column=0, padx=(self.padl, 0), pady=(20, 5), sticky=W) # export label self.label_export = tk.Label(self.root, text='Export', font='Helvetica 10 bold', background=self.backgroundColor, fg=self.fontColor) self.label_export.grid(row=self.row, column=1, padx=0, pady=(20, 5), sticky=W) self.row += 1 # export options xpadl = 200 # CSV self.opt_csv = tk.IntVar(value=1) ttk.Checkbutton(self.root, text="CSV", variable=self.opt_csv, style='BW.TCheckbutton').grid(row=self.row, column=1, padx=(xpadl, 0), pady=0, sticky=W) self.row += 1 # shapefile self.opt_shp = tk.IntVar(value=1) ttk.Checkbutton(self.root, text="Shapefile", variable=self.opt_shp, style='BW.TCheckbutton').grid(row=self.row, column=1, padx=(xpadl, 0), pady=0, sticky=W) self.row += 1 # geojson self.opt_geojson = tk.IntVar(value=1) ttk.Checkbutton(self.root, text="GeoJSON", variable=self.opt_geojson, style='BW.TCheckbutton').grid(row=self.row, column=1, padx=(xpadl, 0), pady=0, sticky=W) self.row += 1 # report self.opt_report = tk.IntVar(value=1) ttk.Checkbutton(self.root, text="Report", variable=self.opt_report, style='BW.TCheckbutton', command=self.handle_reportCheckbox).grid( row=self.row, column=1, padx=(xpadl, 0), pady=0, sticky=W) self.row += 1 # (extra) draft email if self.config['extras']['draftEmail']: self.opt_draftEmail = tk.IntVar(value=1) ttk.Checkbutton(self.root, text="Draft Email", variable=self.opt_draftEmail, style='BW.TCheckbutton', command=self.handle_draftEmailCheckbox).grid( row=self.row, column=1, padx=(xpadl, 0), pady=0, sticky=W) self.row += 1 # hazard self.row_hazard = self.row self.row += 2 # scenario self.row_scenario = self.row self.row += 2 # return period self.row_returnPeriod = self.row self.row += 2 # report title self.row_report = self.row if self.opt_report.get() == 1: self.addWidget_report(self.row_report) self.row += 4 # requred label self.label_required1 = tk.Label(self.root, text='*', font='Helvetica 14 bold', background=self.backgroundColor, fg=self.starColor) self.label_required1.grid(row=self.row, column=0, padx=(self.padl, 0), pady=(20, 5), sticky=W) # output directory label self.label_outputDirectory = tk.Label( self.root, text='Output Directory', font='Helvetica 10 bold', background=self.backgroundColor, fg=self.fontColor) self.label_outputDirectory.grid(row=self.row, column=1, padx=0, pady=(10, 0), sticky=W) self.row += 1 # output directory form self.text_outputDirectory = tk.Text( self.root, height=1, width=37, font='Helvetica 10', background=self.textEntryColor, relief='flat', highlightbackground=self.textBorderColor, highlightthickness=1, highlightcolor=self.textHighlightColor) self.text_outputDirectory.grid(row=self.row, column=1, padx=(0, 0), pady=(0, 0), sticky=W) # output directory icon self.button_outputDirectory = tk.Button( self.root, text="", image=self.img_folder, command=self.browsefunc, relief='flat', background=self.backgroundColor, fg='#dfe8e8', cursor="hand2", font='Helvetica 8 bold') self.button_outputDirectory.grid(row=self.row, column=2, padx=(0, self.padl), pady=(0, 0), sticky=W) self.row += 1 # run button self.button_run = tk.Button(self.root, text='Export', width=5, command=self.run, background='#0078a9', fg='#fff', cursor="hand2", font='Helvetica 8 bold', relief='flat') self.button_run.grid(row=self.row, column=1, columnspan=1, sticky='nsew', padx=50, pady=(30, 20)) self.row += 2 # progress bar self.row_progress = self.row self.row += 1 # bind widget actions self.text_reportTitle.bind('<Tab>', self.focus_next_widget) self.text_reportSubtitle.bind('<Tab>', self.focus_next_widget) self.text_outputDirectory.bind('<Tab>', self.focus_next_widget) self.text_reportTitle.bind('<Shift-Tab>', self.focus_previous_widget) self.text_reportSubtitle.bind('<Shift-Tab>', self.focus_previous_widget) self.text_outputDirectory.bind('<Shift-Tab>', self.focus_previous_widget) except: messageBox = ctypes.windll.user32.MessageBoxW messageBox( 0, "Unable to build the app: " + str(sys.exc_info()[0]) + " | If this problem persists, contact [email protected].", "HazPy", 0x1000) def centerApp(self): try: screenWidth = self.root.winfo_screenwidth() screenHeight = self.root.winfo_screenheight() windowWidth = self.root.winfo_reqwidth() + 100 windowHeight = self.root.winfo_reqheight() + 300 positionRight = int(screenWidth / 2 - windowWidth / 2) positionDown = int(screenHeight / 2 - windowHeight / 2) self.root.geometry("+{}+{}".format(positionRight, positionDown)) except: print('unable to center the app') pass def start(self): """builds the GUI and starts the app""" self.build_gui() self.centerApp() # center application on screen self.root.lift() # bring app to front self.root.mainloop()
class MainApplication(tk.Frame): def __init__(self, parent, *args, **kwargs): tk.Frame.__init__(self, parent, *args, **kwargs) self.parent = parent self.grid(column=0, row=0, sticky=(tk.N, tk.W, tk.E, tk.S)) self.columnconfigure(0, weight=1) self.rowconfigure(0, weight=1) self.pack(pady=100, padx=100) tk.Label(self, text="Choose something to compute").grid(row=1, column=1) # variable to be used in dropdown for function selection self.tkvar = tk.StringVar(self.parent) self.tkvar.set('------') # set the default option self.popupMenu = tk.OptionMenu(self, self.tkvar, *_controller.all_functions) self.popupMenu.grid(row=2, column=1) # define a callback with write permission to self.tkvar self.tkvar.trace('w', self.on_change_dropdown) self.default_input_desc = "Enter comma separated inputs (i.e. 5, 20)." self.input_description = tk.Label(self, text=self.default_input_desc) self.input_description.grid(row=3, column=1) self.e1 = tk.Entry(self) self.e1.grid(row=4, column=1) self.compute_B = tk.Button(self, text="Compute", command=self.on_click_compute) self.compute_B.grid(row=5, column=1) self.cancel_B = tk.Button(self, text="Stop computation", command=self.on_click_cancel) self.cancel_B.grid(row=6, column=1) self.cancel_B.grid_forget() self.prog_bar = Progressbar(self, orient="horizontal", length=200, mode="indeterminate") self.prog_bar.grid(row=7, column=1) self.prog_bar.grid_forget( ) # only show progress bar during computation self.res = tk.Label(self, text="", wraplength=500, fg='blue') self.res.grid(row=8, column=1) self.res.grid_forget() # only show res label when there is a result self.img_path = None self.img = None self.img_zoom = .5 self.panel = tk.Label(self, image=self.img) self.panel.grid(row=9, column=1) mp.set_start_method('spawn') self.queue = mp.Queue() self.py_version_gte_3_7 = sys.version[0] == 3 and sys.version[1] >= 7 # on change dropdown value def on_change_dropdown(self, *args): self.img_path, args = _controller.all_functions[self.tkvar.get()][ 1:3] # [1:3] slices elements at indices 1 and 2 if self.img_path is None: self.img_path = _controller.default_doc self.img = Image.open(self.img_path) # multiply image size by zoom pixels_x, pixels_y = tuple( [int(self.img_zoom * x) for x in self.img.size]) self.img = ImageTk.PhotoImage(self.img.resize((pixels_x, pixels_y))) self.panel.configure(image=self.img) self.panel.image = self.img self.input_description.configure( text=f"{self.default_input_desc} Expected args: {', '.join(args)}") self.img_path = _controller.all_functions[self.tkvar.get()][1] self.res.grid_forget() def reset_gui(self): self.prog_bar.stop() self.prog_bar.grid_forget() self.compute_B.config(state=tk.NORMAL) self.compute_B.config(text="Compute") self.cancel_B.grid_forget() def on_click_cancel(self): self.queue.put(("interrupt", 0)) self.res.config(text="Computation cancelled", fg='red') self.res.grid(row=8, column=1) self.reset_gui() def on_click_compute(self): if self.tkvar.get() == '------': return self.res.grid_forget() self.prog_bar.grid(row=7, column=1) self.prog_bar.start() self.compute_B.config(text="Computing") self.compute_B.config(state=tk.DISABLED) self.cancel_B.grid(row=6, column=1) # TODO: instead of a progress bar, make a buffering animation # while computation is happening with an option to cancel the function unformatted_input = self.e1.get() self.function_name = self.tkvar.get() try: self.user_in, args, function = _controller.parse_input( self.function_name, unformatted_input) except TypeError: self.res.config(text=f"Expected integer inputs, please try again", fg='red') self.res.grid(row=8, column=1) return except ValueError: if self.function_name == 'solve LHCCRR': s = '''For a kth degree LHCCRR, need k base cases.\nSeparate coefficients and base cases with a semicolon, i.e. "2,3;3,4"''' else: args = unformatted_input.split(',') s = _controller.build_error_string( _controller.functions_with_int_parameters[ self.tkvar.get()], len(args)) self.res.config(text=s, fg='red') self.res.grid(row=8, column=1) self.reset_gui() return if self.function_name in _controller.functions_with_int_parameters: args = [*args] else: if self.function_name == 'solve LHCCRR' or self.function_name == 'generate cartesian product': args = [self.user_in[0], self.user_in[1]] elif self.function_name in _controller.functions_with_list_parameters: args = [self.user_in] else: args = [self.user_in[0]] self.process = mp.Process(target=_controller.run, args=(self.queue, function, args, time.time())) self.process.start() self.master.after(100, self.process_queue) def process_queue(self): try: result, t = self.queue.get(0) if not result: if self.function_name == 'solve LHCCRR': s = '''No implementation for complex roots of LHCCRR\nNo implementation for higher order solutions with repeated roots''' elif result == "interrupt": self.process.terminate() time.sleep(0.1) if self.py_version_gte_3_7: self.process.close() s = "Computation cancelled" self.res.config(fg='red') else: s = _controller.build_output_string(self.user_in, self.function_name, result, t) self.res.config(fg='blue') self.res.config(text=s) self.res.grid(row=8, column=1) self.prog_bar.stop() self.prog_bar.grid_forget() self.compute_B.config(state=tk.NORMAL) self.compute_B.config(text="Compute") self.cancel_B.grid_forget() except queue.Empty: # this comes from queue module, not from multiprocessing self.master.after(100, self.process_queue)
class App: def __init__(self, _async_loop): self.async_loop = _async_loop self.imgs = {} self.imgs_length = 0 self.img_selected = None # Build TK self.window = Tk() self.window.title = 'Aplicación Gráfica!' self.window.geometry('850x100') self.window.resizable(False, False) self.window.configure(bg=bg_color) # Build Title self.title_app = Label(text="URL a procesar", bg=bg_color, width=20, fg=font_color) self.title_app.grid(column=0, row=1, padx=10) # Build search self.search = Entry(width=40, bg=bg_color, fg=font_color) self.search.grid(column=1, row=1, pady=10, padx=5) # Build button search self.button_search = Button(text='Buscar', command=self.observe_search_button, highlightbackground=bg_color, width=10) \ .grid(column=2, row=1, columnspan=2, sticky="w") # Build listbox self.listbox = Listbox(background=bg_color, fg=font_color, selectbackground=black_color) self.listbox.grid_forget() self.listbox.bind("<<ListboxSelect>>", self.observe_select_item) # Build canvas self.canvas = Canvas(self.window, width=300, height=300, bg=bg_color, borderwidth=0) self.canvas.grid_forget() # Build label status download images self.status_download_files = Label(text="", bg=bg_color, fg=font_color) self.status_download_files.grid_forget() # Build progress bar to show progress while downloading images self.progress_bar = Progressbar(self.window, orient=HORIZONTAL, length=100, mode='determinate') self.progress_bar.grid_forget() self.window.mainloop() ''' Method to initialize flow when user click on button search ''' def initialize_flow_download(self): self.imgs = {} self.imgs_length = 0 self.listbox.delete(0, END) self.listbox.grid(column=0, row=3, columnspan=2, padx=10, sticky="nsew") self.status_download_files.grid(column=0, row=4, columnspan=4, sticky="se", pady=5) self.progress_bar.grid(column=2, row=5, columnspan=4, sticky="ew") self.canvas.grid(row=3, column=2, columnspan=2) self.img_selected = None self.title_app.config(text="Procesando url") self.window.geometry('850x450') # START SECTION OBSERVABLE DOWNLOAD URL IMAGES ''' Method to initialize async loop until complete download images ''' def _asyncio_thread(self, _imgs, observer): self.async_loop.run_until_complete( self.download_images(_imgs, observer)) async def download_images(self, _imgs, observer): downloads = [self.download_image(img) for img in _imgs] await asyncio.wait(downloads) observer.on_completed() def observable_search_button(self, url): def search_page(o, s): try: content = requests.get(url) soup = BeautifulSoup(content.text, 'html.parser') _imgs = soup.find_all('img') self.imgs_length = len(_imgs) self.status_download_files.config( text=f'Se han descargado 0 de {self.imgs_length} imagenes') self.title_app.config(text="Descargando imagenes") threading.Thread(target=self._asyncio_thread, args=( _imgs, o, )).start() except Exception as e: print(e) self.listbox.grid_forget() self.status_download_files.grid_forget() self.progress_bar.grid_forget() self.canvas.grid_forget() self.window.geometry('650x100') self.title_app.config(text="Error url") return create(search_page) async def download_image(self, img): try: async with aiohttp.ClientSession() as session: async with session.get(img['src']) as resp: img_downloaded = await resp.read() alt_img = f'{img["alt"] or "Imagen"}' alt_img_key = f'{alt_img}_{self.listbox.size()}' self.imgs[alt_img_key] = img_downloaded self.listbox.insert(self.listbox.size(), alt_img) self.status_download_files.config( text= f'Se han descargado {self.listbox.size()} de {self.imgs_length} imagenes', bg=bg_color) self.progress_bar.config(value=self.listbox.size() * 100 / self.imgs_length) except Exception as e: print(e) print(img['src'] + " No ha podido ser descargada correctamente") def download_completed(self): self.status_download_files.configure( text=f'Descarga finalizada de las {self.imgs_length} imagenes') self.title_app.config(text="Introduce nueva URL") self.progress_bar.grid_forget() def observe_search_button(self): self.initialize_flow_download() self.observable_search_button( self.search.get()).subscribe(on_completed=self.download_completed) # END SECTION OBSERVABLE DOWNLOAD URL IMAGES # START SECTION OBSERVABLE LISTBOX def observable_select_item(self, widget, index): def search_item(o, s): try: img_key = f'{widget.get(index)}_{index}' aux_image = resize_image(self.imgs[img_key], "bytes") self.img_selected = ImageTk.PhotoImage(aux_image) self.canvas.create_image(20, 20, anchor=NW, image=self.img_selected) except Exception as e: print(e) aux_image = resize_image("./assets/imgs/default.jpg", "file") self.img_selected = ImageTk.PhotoImage(aux_image) self.canvas.create_image(20, 20, anchor=NW, image=self.img_selected) o.on_completed() return create(search_item) def item_load_completed(self): print("Imagen cargada correctamente") def observe_select_item(self, event): self.observable_select_item(event.widget, event.widget.curselection()[0]) \ .subscribe(on_completed=self.item_load_completed)
class MonApp(Tk): def __init__(self, argv): super().__init__() self.iconbitmap(default='minor\logo_minor.ico') self.winfo_toplevel().title( "Minor FoodIT - MenuLink Export Data (2018 Copy@Right)") self.geometry("500x30") #You want the size of the app to be 500x500 self.resizable(0, 0) # Don't allow resizing in the x or y direction self.btn = Button(self, text='Exporting data', command=self.start) self.btn.grid(row=0, column=0) self.label = Label(self, text="") self.label.grid(row=0, column=2) self.progress = Progressbar(self, orient=HORIZONTAL, length=200, mode='indeterminate') self.argv = argv def start(self): def real_start(): self.progress.grid(row=0, column=1) self.progress.start() self.label['text'] = 'Data processing...' #time.sleep(5) main_run(self.argv) #Move to main_run self.quit() self.btn['state'] = 'disabled' threading.Thread(target=real_start).start() def main_run(argv): # log("Original file record size is "+str(dbfRec.record_count())) if menulink_ver <= 15 and aloha_ver >= 12: conn = SQLConn.createConn() # Check exist from query to file cursor = SQLConn.getEmpData(conn, site_number) for row in cursor: empQuery = DBF.Emp(row) loopOnRecord(empQuery, dbfRec) #log("hasNewRecordCreated is " + str(hasNewRecordCreated)) if hasNewRecordCreated: doWriteCreated(dbfRec) else: dbfRec.close() # log("File updated/created record size is " + str(dbfRec.record_count())) # Check file to removed openfile = filename cursor = SQLConn.getEmpData(conn, site_number) cursorID = [row[0] for row in cursor] loopOnDBF(cursorID, openfile) db = AlohaDBF.DbfData(openfile) # log("File deleted record size is " + str(db.record_count())) self.progress.stop() self.progress.grid_forget() self.label['text'] = 'Done.' self.btn['state'] = 'normal' dbfRec.showWarning( "Database file updated", "The data " + str(DBF_FILE.get(sys.argv[1:][0])) + " is updated. Please refresh data in Aloha Configuration Center to load updated" ) elif menulink_ver >= 15 and aloha_ver < 12: log("to be future") else: pass
def create(self) -> None: if not self.fields: print('No fields.') return # Calculate the length of the longest field (some fields can have less values than others). total_signs = 0 for field_iid in self.fields: total_signs = max(total_signs, len(self.fields[field_iid].data)) if total_signs == 0: print('No fields with data.') return try: sheet_width = float(self.sheet_width_var.get()) sheet_height = float(self.sheet_height_var.get()) sign_width = float(self.sign_width_var.get()) sign_height = float(self.sign_height_var.get()) layers_per_sheet = int(self.layers_per_sheet_var.get()) assert sign_width > 0, 'Sign width must be greater than 0.' assert sign_height > 0, 'Sign height must be greater than 0.' assert sheet_width >= sign_width, 'Sheet width must be greater than sign width.' assert sheet_height >= sign_height, 'Sheet height must be greater than sign height.' except ValueError: print('Invalid dimensions.') return except AssertionError as e: print(e) return # Show progress bar. progress_bar = Progressbar(self.frame) progress_bar.grid(column=0, row=5, columnspan=4, sticky='WE') # Calculate the needed values to define sheet layout. signs_per_row = int(sheet_width // sign_width) signs_per_column = int(sheet_height // sign_height) signs_per_layer = signs_per_row * signs_per_column # Ceiling division. total_layers = -int(-total_signs // signs_per_layer) if layers_per_sheet > 0: total_sheets = -int(-total_layers // layers_per_sheet) else: total_sheets = 1 print( f'Marking total of {total_signs} signs ({sign_width} x {sign_height}).' ) print( f'Sheet size of {sheet_width} x {sheet_height} fits {signs_per_row} x {signs_per_column} signs,' ) print( f'so the effective sheet size is {signs_per_row * sign_width} x {signs_per_column * sign_height}.' ) print(f'Total of {total_layers} layer(s) are needed.') if layers_per_sheet == 0: print( 'There is no limit on the maximum amount of layers per sheet,') else: print( f'There are maximum of {layers_per_sheet} layer(s) per sheet,') print(f'so total of {total_sheets} sheet(s) are needed.') # Create needed sheet objects. print('Creating sheets.') sheets = [] for _ in range(total_sheets): sheets.append(ezdxf.new(self.dxf_version.get())) # Iterate over all layers and draw their outline based on how many signs that layer will have. print('Drawing layer outlines.') for layer in range(total_layers): max_x = sign_width * signs_per_row max_y = -sign_height * signs_per_column if layer == total_layers - 1: # If last layer. signs_in_last_sheet = total_signs - layer * signs_per_layer if signs_in_last_sheet < signs_per_row: max_x = sign_width * signs_in_last_sheet max_y = sign_height * (-signs_in_last_sheet // signs_per_row) if layers_per_sheet > 0: sheet_index = layer // layers_per_sheet else: sheet_index = 0 # Draw layer outline (left and top side bounds). sheets[sheet_index].modelspace().add_lwpolyline( [(0, max_y), (0, 0), (max_x, 0)], dxfattribs={'layer': str(layer)}) # Iterate over each sign. print('Drawing marks.') for sign_index in range(total_signs): # Update progress bar value. progress_bar['value'] = (sign_index + 1) / total_signs * 100 progress_bar.update() # Calculate in which position, in which layer of which sheet the current sign should be drawn. layer = sign_index // signs_per_layer layer_position = sign_index % signs_per_layer sign_origin_x = (layer_position % signs_per_row) * sign_width sign_origin_y = -(layer_position // signs_per_row) * sign_height if layers_per_sheet > 0: sheet_index = layer // layers_per_sheet else: sheet_index = 0 sheet = sheets[sheet_index] # Draw marks (QR, Text and Hole objects). for field_iid in self.fields: try: self.fields[field_iid].draw(sign_index, sheet, layer, sign_origin_x, sign_origin_y, sign_width, sign_height) except Exception as e: print(e) progress_bar.grid_forget() return # Draw sign outline (right and bottom side bounds). sign_outline = [(sign_origin_x, sign_origin_y - sign_height), (sign_origin_x + sign_width, sign_origin_y - sign_height), (sign_origin_x + sign_width, sign_origin_y)] sheet.modelspace().add_lwpolyline(sign_outline, dxfattribs={'layer': str(layer)}) # Save sheets. # Get a output directory if there are multiple sheets to be saved, otherwise get path for the single output (.dxf) file. print('Saving.') if total_sheets > 1: if directory := tkinter.filedialog.askdirectory(): for index, sheet in enumerate(sheets): # Indicate save progress. progress_bar['value'] = (index + 1) / len(sheets) * 100 progress_bar.update() sheet.saveas(Path(directory) / f'sheet{index}.dxf')
class GUI: """ Is responsible for opening and handling graphical interface of an application """ def __init__(self, thread=4): self.root = tk.Tk() self.progress = Progressbar(self.root, orient="horizontal") self.buttons_frame = tk.Frame(self.root, bg="grey") self.labelframe = tk.LabelFrame(self.root, bg="grey", height=35, width=130, padx=10) self.label = tk.Label(self.labelframe) self.top = None self.topSettings = None self.report = "../" self.video_location = "../" self.uploaded_file = "" self.video = None self.video_name = "processed_video.mp4" self.report_name = "processed_report.txt" self.progress_percent = 0 self.thread = thread self.video_path = Path(self.video_location).joinpath(self.video_name) self.report_path = Path(self.report).joinpath(self.report_name) def run(self): self.root.geometry("1200x900") self.root.resizable(0, 0) self.root.title("Platonic") self.root.config(bg="grey") self.root.grid_rowconfigure(0, weight=1) self.root.grid_columnconfigure(0, weight=1) self.root.grid_rowconfigure(1, weight=4) self.root.grid_columnconfigure(1, weight=4) self.progress.grid_forget() self.buttons_frame.pack_propagate(0) # type: ignore self.buttons_frame.config(width=25, height=40) self.buttons_frame.grid(row=0, column=2, sticky="NESW", pady=10) currently_loaded_file_label = tk.Label( self.buttons_frame, text="Loaded file", width=32, bg="grey", font="Verdana 10 bold", ) currently_loaded_file_label.grid(row=8, column=0, pady=0, padx=0) currently_loaded_file = tk.Label( self.buttons_frame, text="None", wraplength=200, width=40, bg="grey", font="Verdana 9 bold", ) currently_loaded_file.grid(row=10, column=0, pady=10, padx=10) start_algorithm_button = tk.Button( self.buttons_frame, text="start algorithm", command=lambda: self.start_algorithm( currently_loaded_file, currently_loaded_file_label, upload_file_button, start_algorithm_button, play_uploaded_video_button, inside_player, menu_button, ), width=32, state="disabled", ) start_algorithm_button.grid(row=2, column=0, pady=10, padx=10) play_uploaded_video_button = tk.Button( self.buttons_frame, text="outside player", command=self.play_uploaded_video, width=32, state="disabled", ) play_uploaded_video_button.grid(row=4, column=0, pady=10, padx=10) inside_player = tk.Button( self.buttons_frame, text="inbuild player", command=self.inside_player, width=32, state="disabled", ) inside_player.grid(row=6, column=0, pady=10, padx=10) upload_file_button = tk.Button( self.buttons_frame, text="upload a video", command=lambda: self.upload_video( start_algorithm_button, play_uploaded_video_button, inside_player, currently_loaded_file, ), width=32, ) upload_file_button.grid(row=0, column=0, pady=10, padx=10) self.labelframe.grid(row=0, column=1, pady=10) self.label.config(bg="grey71", height=40, width=130) self.label.pack_propagate(0) # type: ignore self.label.grid(row=0, column=1, sticky="NESW") menu_button = tk.Button(self.root, text="settings", width=32, command=self.settings_window) menu_button.grid(row=1, column=2) self.root.mainloop() def refresh_paths(self): self.video_path = Path(self.video_location).joinpath(self.video_name) self.report_path = Path(self.report).joinpath(self.report_name) def play_it(self, label): for image in self.video.iter_data(): # type: ignore frame_image = ImageTk.PhotoImage(Image.fromarray(image), height=400, width=800) self.label.config(image=frame_image, width=920, height=600) self.label.image = frame_image # type: ignore def upload_video(self, process, outside, inbuilt, loaded): self.uploaded_file = filedialog.askopenfilename() if self.uploaded_file.endswith((".mp4", ".mkv")): self.video = imageio.get_reader(self.uploaded_file) process["state"] = "normal" outside["state"] = "normal" inbuilt["state"] = "normal" loaded["text"] = self.uploaded_file else: messagebox.showerror( "Bad format", "Wrong data format chosen! Select mp4 or mkv file") self.uploaded_file = "" def start_algorithm(self, label, loaded, upload, process, outside, inbuilt, settings): self.progress.grid(row=1, column=1, sticky="EW", pady=10, padx=10) master = Master( self.uploaded_file, str(self.video_path), self.thread, ) master.start() upload["state"] = "disabled" process["state"] = "disabled" outside["state"] = "disabled" inbuilt["state"] = "disabled" settings["state"] = "disabled" time.sleep(15) self.progress_percent = master.get_progress() self.refresh_progress(master) self.report_path.write_text(str(master.get_log())) self.progress["value"] = 100 self.refresh_paths() self.uploaded_file = str(self.video_path) self.video = imageio.get_reader(self.uploaded_file) upload["state"] = "normal" process["state"] = "normal" outside["state"] = "normal" inbuilt["state"] = "normal" settings["state"] = "normal" label["text"] = str(self.video_path) loaded["text"] = "Processed file" def refresh_progress(self, master): while master.is_alive(): self.progress["value"] = self.progress_percent self.root.update_idletasks() self.progress_percent = master.get_progress() time.sleep(1) def play_uploaded_video(self): if self.uploaded_file != "" and sys.platform == "win32": os.startfile(self.uploaded_file) # type: ignore elif sys.platform == "darwin" and self.uploaded_file != "": opener = "open" subprocess.call([opener, self.uploaded_file]) elif self.uploaded_file != "": opener = "xdg-open" subprocess.call([opener, self.uploaded_file]) else: messagebox.showerror("No video uploaded", "No video uploaded! Upload one to play it") def inside_player(self): thread = threading.Thread(target=self.play_it, args=(self.label, )) thread.daemon = 1 # type: ignore thread.start() def choose_raport_location(self, label): self.report = filedialog.askdirectory(parent=self.top) self.refresh_paths() label["text"] = "processed report location: " + str(self.report_path) def choose_video_location(self, label): self.video_location = filedialog.askdirectory(parent=self.top) self.refresh_paths() label["text"] = "processed video location: " + str(self.video_path) def exit_settings(self, top, video_location, report): if video_location.get() != "": self.video_name = video_location.get() + ".mp4" if report.get() != "": self.report_name = report.get() + ".txt" self.refresh_paths() self.topSettings.destroy() # type: ignore def settings_window(self): self.topSettings = Toplevel() self.topSettings.resizable(0, 0) self.topSettings.title("settings") self.topSettings.geometry("500x510") self.topSettings.config(bg="grey") where_is_video = tk.Label( self.topSettings, text="processed video location: " + str(self.video_path), width=90, bg="grey", wraplength=200, pady=15, font="Verdana 10 bold", ) where_is_video.place(x=-100, y=355) where_is_report = tk.Label( self.topSettings, text="processed report location: " + str(self.report_path), width=90, bg="grey", wraplength=200, pady=15, font="Verdana 10 bold", ) where_is_report.place(x=-100, y=260) report_label = tk.Label( self.topSettings, text="Where to store report:", bg="grey", pady=25, font="Verdana 10 bold", ) report_label.grid(row=1, column=0) report_button = tk.Button( self.topSettings, width=35, text="Choose directory", command=lambda: self.choose_raport_location(where_is_report), ) report_button.grid(row=1, column=1, padx=10, pady=5) where_report_label = tk.Label( self.topSettings, text="Report name:", bg="grey", pady=15, font="Verdana 10 bold", ) where_report_label.grid(row=3, column=0) where_report_input = tk.Entry(self.topSettings, width=35) where_report_input.insert(0, self.report_name[:len(self.report_name) - 4]) where_report_input.grid(row=3, column=1, padx=10) video_label = tk.Label( self.topSettings, text="Where to store video:", bg="grey", pady=20, font="Verdana 10 bold", ) video_label.grid(row=2, column=0) video_input = tk.Button( self.topSettings, width=35, text="Choose directory", command=lambda: self.choose_video_location(where_is_video), ) video_input.grid(row=2, column=1, padx=10, pady=5) where_video_label = tk.Label( self.topSettings, text="Video name:", bg="grey", pady=15, font="Verdana 10 bold", ) where_video_label.grid(row=4, column=0) where_video_input = tk.Entry(self.topSettings, width=35) where_video_input.insert(0, self.video_name[:len(self.video_name) - 4]) where_video_input.grid(row=4, column=1, padx=10) exit_button = tk.Button( self.topSettings, text="save", command=lambda: self.exit_settings( self.topSettings, where_video_input, where_report_input), width=400, height=35, bg="grey71", ) exit_button.place(x=15, y=455, relwidth=0.95, relheight=0.08) how_many_threads = tk.Label( self.topSettings, text="active threads: " + str(self.thread), width=20, bg="grey", pady=20, font="Verdana 10 bold", ) how_many_threads.place(x=180, y=220)
def cellPlot(): error.grid_forget() numCellDots=int(entry1.get()) print("Running cellPlot at :"+str(dir)) os.chdir(dir) newDir = dir + "\\modseq" + str(numCellDots) + "_" + str(shortTime) os.mkdir(newDir) imgs = glob.glob("*.png") im = Image.open(imgs[0]) im = im.convert('RGB') draw = ImageDraw.Draw(im) xminvalue = 0 xmaxvalue = 0 yminvalue = 0 ymaxvalue = 0 count = 0 xmls = glob.glob("*.xml") numDots = 0 #print("Plotting.....", end="", flush=True) pb = Progressbar(window, orient="horizontal", length=100, mode="indeterminate") pb.grid(column=2, row=4) for file in xmls: progress = int(100 * (xmls.index(file)) / len(xmls)) name = os.path.basename(file) currfile = os.path.abspath(file) with open(file, 'r', encoding="utf-8") as content: tree = ET.parse(content) root = tree.getroot() for oj in root.findall('object'): xmin = list(tree.iter('xmin')) for value in xmin: xminvalue = int(value.text) # print("xmin = " + str(xminvalue)) xmax = list(tree.iter('xmax')) for value in xmax: xmaxvalue = int(value.text) # print("xmax = " + str(xmaxvalue)) xmid = (xmaxvalue + xminvalue) / 2 ymin = list(tree.iter('ymin')) for value in ymin: yminvalue = int(value.text) # print("ymin = " + str(yminvalue)) ymax = list(tree.iter('ymax')) for value in ymax: ymaxvalue = int(value.text) # print("ymax = " + str(ymaxvalue)) ymid = (ymaxvalue + yminvalue) / 2 draw.point((xmid, ymid), fill=(190, 20, 20, 20)) numDots += 1 # print("new dot "+name+" num dots: "+str(numDots)) count += 1 if count % int(numCellDots) == 0: # im.show() draw.line([(0, 95), (int((count / len(xmls) * 160)), 95)], fill=220, width=4) # os.chdir(dir+"\\"+str(numCellDots)) os.chdir(newDir) im.save("part" + str(count / 100) + " " + str(numDots) + " dots.png") os.chdir(dir) del im im = Image.open(imgs[0]) im = im.convert('RGB') draw = ImageDraw.Draw(im) # count=0 # print(str(numDots)) numDots = 0 os.chdir(newDir) im.save("partLast.png") newImg = im.resize((320,200), PIL.Image.ANTIALIAS) newImg3 = ImageTk.PhotoImage(newImg) w.configure(image=newImg3) w.image = newImg3 print("DONE") pb.grid_forget() window.title("Cell Plotter GUI") dirSelect = 0 error.grid_forget()
class Gui: DARK_THEME = { 'PRIMARY': '#222', 'SECONDARY': '#333', 'TEXT': '#fff', 'SEC_TEXT': '#4d5c69' } LIGHT_THEME = { 'PRIMARY': '#fff', 'SECONDARY': '#eee', 'TEXT': '#222', 'SEC_TEXT': '#a9b5c0' } APP_NAME = 'Timefy' def __init__(self): self.THEME = self.DARK_THEME if config.DARK_THEME else self.LIGHT_THEME gui_dir = os.path.dirname(__file__) assets_dir = gui_dir + './../assets/' self.top = tkinter.Tk() self.top.title(self.APP_NAME) self.top.geometry("500x175") self.top.resizable(False, False) self.top.iconbitmap(default=assets_dir + 'favicon.ico') frame = tkinter.Frame(self.top, padx=10, pady=10, bg=self.THEME['PRIMARY']) frame.pack(fill=tkinter.BOTH, expand=True) searchImg = ImageTk.PhotoImage(Image.open(assets_dir + 'search.png').resize((20, 20), Image.ANTIALIAS)) sourceButton = tkinter.Button(frame, image=searchImg, padx=0, relief=tkinter.FLAT, command=self.__load_source, bg=self.THEME['PRIMARY']) sourceButton.image = searchImg sourceButton.grid(column=2, row=0, padx=(5, 5), pady=(5, 0)) outputButton = tkinter.Button(frame, image=searchImg, padx=0, relief=tkinter.FLAT, command=self.__load_output, bg=self.THEME['PRIMARY']) outputButton.grid(column=2, row=1, padx=(5, 5), pady=(5, 0)) sourceLabel = tkinter.Label(frame, text='Source', bg=self.THEME['PRIMARY'], fg=self.THEME['TEXT'], width=8) sourceLabel.grid(row=0, column=0) self.sourceValue = tkinter.StringVar() source = tkinter.Entry(frame, bg=self.THEME['SECONDARY'], textvariable=self.sourceValue, fg=self.THEME['TEXT'], width=60, borderwidth=5, relief=tkinter.FLAT, state='disabled', disabledbackground=self.THEME['SECONDARY'], disabledforeground=self.THEME['TEXT']) source.grid(row=0, column=1, pady=(6, 0)) outputLabel = tkinter.Label(frame, text='Output', bg=self.THEME['PRIMARY'], fg=self.THEME['TEXT'], width=8) outputLabel.grid(column=0, row=1) self.outputValue = tkinter.StringVar() output = tkinter.Entry(frame, bg=self.THEME['SECONDARY'], textvariable=self.outputValue, fg=self.THEME['TEXT'], width=60, borderwidth=5, relief=tkinter.FLAT, state='disabled', disabledbackground=self.THEME['SECONDARY'], disabledforeground=self.THEME['TEXT']) output.grid(row=1, column=1, pady=(6, 0)) generate = tkinter.Button(frame, text='GENERATE', bg='#3742fa', fg='#fff', bd=0, padx=15, pady=5, command=self.__gen) generate.grid(row=2, column=1, columnspan=2, sticky=tkinter.E, pady=(20, 0)) self.should_append = tkinter.IntVar() # append = tkinter.Checkbutton(frame, text="Append", selectcolor=self.THEME['SECONDARY'], relief=tkinter.FLAT, onvalue=1, offvalue=0, variable=self.should_append, bg=self.THEME['PRIMARY'], activebackground=self.THEME['PRIMARY'], activeforeground=self.THEME['TEXT'], fg=self.THEME['TEXT']) # append.grid(row=2, column=1, pady=(20, 0), padx=(175, 0)) reset = tkinter.Button(frame, text='RESET', bg=self.THEME['SECONDARY'], fg=self.THEME['TEXT'], padx=15, pady=5, bd=0, command=self.reset) reset.grid(row=2, column=1, pady=(20, 0), padx=(175, 0)) github = tkinter.Label(frame, text='github.com/rodchenk', bg=self.THEME['PRIMARY'], fg=self.THEME['SEC_TEXT'], pady=5) github.grid(row=2, column=0, columnspan=2, sticky=tkinter.W, pady=(20, 0), padx=10) s = Style() s.theme_use("default") s.configure("TProgressbar", thickness=5, background='#26A65B', troughrelief='flat') self.progress = Progressbar(frame, orient=tkinter.HORIZONTAL, length=465, mode='determinate', style="TProgressbar") def run(self): self.top.mainloop() def reset(self): self.outputValue.set('') self.sourceValue.set('') def __show_progress(self): self.progress.grid(row=3, column=0, columnspan=3, pady=(25, 0)) for x in range(51): self.progress['value'] = 2 * x self.top.update_idletasks() time.sleep(0.01) def __hide_progress(self): self.progress.grid_forget() def __gen(self): source, output, append = self.sourceValue.get(), self.outputValue.get(), self.should_append.get() == 1 if not source or not output: return # self.__show_progress() threading.Thread(target=self.__show_progress).start() result = self.__call_script(source, output) if result == 0: _open = messagebox.askyesno('Success', 'Report has been generated. Do you want to open it?') if _open: subprocess.Popen(output, shell=True, stdout = subprocess.PIPE) else: messagebox.showerror('Error', 'An error has occured') self.__hide_progress() def __call_script(self, source, output): cli_path = os.path.dirname(__file__) + './../main.py' command = 'python %s -s %s -o %s' % (cli_path, source, output) p = subprocess.Popen(command, shell=True, stdout = subprocess.PIPE) stdout, stderr = p.communicate() return p.returncode def __load_source(self): dname = askdirectory() self.sourceValue.set(dname) def __load_output(self): fname = asksaveasfilename(filetypes=(("CSV Files", "*.csv;"), ("All files", "*.*") )) if not fname: return if not fname.endswith('.csv'): if fname[-1:] == '.': fname = fname[:-1] fname += '.csv' self.outputValue.set(fname)
class job: def __init__(self, root): self.root = root self.depart() self.Liste_date = [] self.Liste_issues = [] self.Liste_review = [] self.Liste_comments = [] def depart(self): self.frame1 = Frame(self.root, width=600, bg='#FFFFFF') self.frame1.grid(row=0, column=0, ipady=10, ipadx=10) self.frame1.grid_columnconfigure(0, weight=2) self.vfichier1 = StringVar() self.vfichier2 = StringVar() self.vproject = StringVar() self.vfichier1.set('') self.vfichier2.set('') self.vproject.set('') self.chemin = '' self.chemin1 = '' self.button1 = Button(self.frame1, text="Import weekly reporting", command=self.set_fichier1, width=50, height=2, bg='#66B239') self.button1.grid(row=0, column=0, pady=5) self.button2 = Button(self.frame1, text='Import SSR dashboard', command=self.set_fichier2, width=50, height=2, bg='#66B239') self.button2.grid(row=2, column=0, pady=5) self.vname_g = StringVar() self.vfilter_name = StringVar() self.vremarque = StringVar() self.vremarque.set("") self.vfilter_name.set('') self.bpetit_tab = Button(self.frame1, text='Import part list', command=self.set_filter, width=50, height=2, bg='#66B239') self.bpetit_tab.grid(row=4, column=0, pady=5) self.bProject = Button(self.frame1, text='Import Hard points list', command=self.set_project, width=50, height=2, bg='#66B239') self.bProject.grid(row=3, column=0, pady=5) self.bpetit_emp = Button(self.frame1, text="Generate report", command=self.set_emplacement, width=50, height=2, bg='#66B239') self.bpetit_emp.grid(row=5, column=0, pady=5) self.lremarque = Label(self.frame1, textvariable=self.vremarque, relief=GROOVE, bg='#CAE21E', font=('arial', 10), border='2px', wraplength=550) self.progress_bar = Progressbar(self.frame1, orient='horizontal', length=286, mode='determinate') def part1(self, fichier1, fichier2, rapport_name, vproject, vfilter): self.progress_bar["maximum"] = 100 self.bpetit_emp['bg'] = '#006738' self.progress_bar.grid(row=6, column=0, pady=2) self.progress_bar["value"] = 5 root.update() # !/usr/bin/env python # coding: utf-8 path = fichier1 classeur = xlrd.open_workbook(path) self.progress_bar["value"] = 20 root.update() nom_des_feuilles = classeur.sheet_names() #feuille = classeur.sheet_by_name(nom_des_feuilles[2]) feuille = classeur.sheet_by_name("ECU Dashboard") ############################################################################################# ############################################################################################# def data_frame12(colonne1, colonne2, colonne3, colonne4, colonne5, colonne6): data = pd.DataFrame({ "Part": (colonne1), "SSR Decision Trend": (colonne2), "Update_date": (colonne3), "Issues/Concerns": (colonne4), "Review/SSR_Status": (colonne5), "Expected Action": (colonne6) }) return data dff = pd.read_excel(path, sheet_name="ECU Dashboard", skiprows=3) List_part = dff['ECU ID'] liste_SSR_Status = dff["SSR status"] Sentence = dff["Review Plans & Commitments / Action plan/ Remarks"] term = "NEWDATE" term1 = "Issues/Concerns:" term2 = "Review/SSR Status:" term3 = " " i = 0 for sentence in list(Sentence): i += 1 sentence = str(sentence).replace('\n', 'sautligne') sentence = sentence.replace('Review /SSR', 'Review/SSR') sentence = sentence.replace('Review / SSR ', 'Review/SSR') sentence = sentence.replace('Review/ SSR', 'Review/SSR') sentence = sentence.replace('Review/SSR status', 'Review/SSR Status') sentence = sentence.replace('Review/SSRstatus', 'Review/SSR Status') sentence = sentence.replace('Review/SSRStatus', 'Review/SSR Status') sentence = sentence.replace('Review/SSR Status :', 'Review/SSR Status:') sentence = sentence.replace('Issues/ Concerns', 'Issues/Concerns') sentence = sentence.replace('Issues /Concerns', 'Issues/Concerns') sentence = sentence.replace('Issues / Concerns', 'Issues/Concerns') sentence = sentence.replace('Issues/Concerns :', 'Issues/Concerns:') list2 = re.findall("\d\d-\d\d-\d{4}", sentence) for formatdate in list2: sentence = sentence.replace(formatdate + " :", formatdate + ":") try: premieredate = list2[0] list2 = [s for s in list2 if s != premieredate] for formatdate in list2: sentence = sentence.split(formatdate + ":")[0] sentence = sentence.split(formatdate + "sautligne")[0] except: 1 # on recupere le blocke le plus recent block = sentence.split("NEWDATE")[0] try: if term1 in block and term2 in block and re.search( 'Issues/Concerns:(.*)Review/SSR Status:', block).group(1) != '' and re.search( 'Review/SSR Status:(.*)', block).group(1): # on recupere la date (première occurence) self.Liste_date.append( re.findall("\d\d-\d\d-\d{4}", block)[0]) # on recupere les Issues/Concerns (première occurence) issue = block.split('Review/SSR Status:')[0] issue = re.findall('Issues/Concerns:(.*)', issue)[0] issue = issue.replace('sautlignesautligne', 'sautligne') # on rajoute les retours à la ligne try: # print(re.search('sautligne(.*)', review).group(1)) if issue[0:9] == 'sautligne': issue = issue[9::] except: issue = issue issue = issue.replace('sautligne', '\n') self.Liste_issues.append(issue) # on recupere les reviews (première occurence) review = re.search('Review/SSR Status:(.*)', block).group(1) self.List_date = re.findall("\d\d-\d\d-\d{4}", review) for k in self.List_date: review = review.split('sautligne' + k)[0] review = review.replace('sautlignesautligne', 'sautligne') # on rajoute les retours à la ligne try: # print(re.search('sautligne(.*)', review).group(1)) if review[0:9] == 'sautligne': review = review[9::] except: review = review review = review.replace('sautligne', '\n') self.Liste_review.append(review) self.Liste_comments.append(term3) # liste_comments.append(" {}".format(feuille.cell_value(i,64))) else: self.Liste_review.append(review) self.Liste_comments.append(term3) self.Liste_issues.append(issue) self.Liste_date.append(".") except: self.Liste_date.append(".") self.Liste_review.append(".") self.Liste_comments.append(".") self.Liste_issues.append(".") print(len(List_part), ' ,', len(liste_SSR_Status), ' ,', len(self.Liste_date), ' ,', len(self.Liste_issues), ' ,', len(self.Liste_review, ), ' ,', len(self.Liste_comments)) ee = data_frame12(List_part, liste_SSR_Status, self.Liste_date, self.Liste_issues, self.Liste_review, self.Liste_comments) import numpy as np ea = ee.to_numpy() import matplotlib.pyplot as plt import numpy as np import datetime # premier tableau================================================= data = pd.read_excel(fichier2, "°Cover Page", skiprows=9, index_col=1) data = data.drop(['R_KPI_MILESTONE', 'Trend'], axis=1) e1 = data.iloc[0:4, 0:1] # deuxieme tableau=============================================== data1 = pd.read_excel(fichier2, "°Cover Page", skiprows=43, index_col=2) data1 = data1.reset_index(drop=True) data1 = data1.drop(['Unnamed: 0', 'Unnamed: 1'], axis=1) e2 = data1.iloc[0:4, 0:11] self.progress_bar["value"] = 30 root.update() time.sleep(0.5) # GRAPHE ========================================================== import matplotlib.pyplot as plt plt.rcParams.update({ "pgf.texsystem": "pdflatex", "pgf.preamble": [ r"\usepackage[utf8x]{inputenc}", r"\usepackage[T1]{fontenc}", r"\usepackage{cmbright}", ] }) CWmax = e2['Unnamed: 3'][0].isocalendar()[1] x = [] for i in range(CWmax, CWmax - 10, -1): x.append('CW' + str(i)) self.progress_bar["value"] = 40 root.update() y1 = e2.loc[1] y2 = e2.loc[2] y3 = e2.loc[3] plt.figure(figsize=(10, 5)) plt.grid(True) plt.plot(x, y1, label='Coverage', lw=3) plt.plot(x, y2, label='Completness', lw=3) plt.plot(x, y3, label='Consistency', lw=3) self.progress_bar["value"] = 50 time.sleep(1) root.update() plt.title('Milestone trend') plt.xlabel('Calendar Week') plt.ylabel('Kpi (%)') plt.legend() ax = plt.gca() ax.invert_xaxis() plt.savefig("fig.png") eb = e1.to_numpy() self.progress_bar["value"] = 60 time.sleep(0.5) from openpyxl.utils.dataframe import dataframe_to_rows from openpyxl.chart import BarChart, Series, Reference path = vproject # data = pd.read_excel(path, skiprows=3, sheet_name=4) data = pd.read_excel(path, "Hard points", skiprows=3) id_list = list(data['ID']) veh_Project_list = list(data['Veh Project']) parts_list = list(data['Parts']) status_list = list(data['Status']) # Create a workbook and add a worksheet. workbook = Workbook() worksheet = workbook.active worksheet.title = 'Report.xlsx' # Add a bold format to use to highlight cells. header_formatfont = Font(bold=True, ) header_formattxt = Alignment(wrap_text=True) ## pour le petit tableau worksheet['A1'].value = 'KPI' worksheet['B1'].value = 'Completness' worksheet['C1'].value = 'Consistency' worksheet['B2'].value = 'Target = 100%' worksheet['C2'].value = 'Target = 80%' liste = ['A1', 'A2', 'B2', 'B1', 'C1', 'C2'] for cell in liste: worksheet[cell].font = header_formatfont worksheet[cell].alignment = header_formattxt # data, workbook, and worksheet are the same as in the BarChart example tab = Table(displayName="Table1", ref="A1:C3") # I list out the 4 show-xyz options here for reference style = TableStyleInfo(name="TableStyleMedium9", showFirstColumn=False, showLastColumn=False, showRowStripes=True, showColumnStripes=False) tab.tableStyleInfo = style worksheet.add_table(tab) worksheet.column_dimensions['A'].width = 20 worksheet.column_dimensions['B'].width = 20 worksheet.column_dimensions['C'].width = 20 worksheet.column_dimensions['D'].width = 70 worksheet.column_dimensions['E'].width = 70 worksheet.column_dimensions['F'].width = 40 worksheet.column_dimensions['G'].width = 40 self.progress_bar["value"] = 70 time.sleep(1) root.update() # pour le grand tableau worksheet['A25'].value = 'PART' worksheet['B25'].value = 'SSR Decision Trend' worksheet['C25'].value = 'Update_date' worksheet['D25'].value = 'Issues/Concerns' worksheet['E25'].value = 'Review/SSR_Status' worksheet['F25'].value = 'Hard points and Risks IDs' worksheet['G25'].value = 'Expected Action' liste = ['A25', 'B25', 'C25', 'D25', 'E25', 'F25', 'G25'] for cell in liste: worksheet[cell].font = header_formatfont worksheet[cell].alignment = header_formattxt # Petit tableau roww = 3 coll = 0 worksheet.cell(roww, 2).value = str(eb[1]) worksheet.cell(roww, 3).value = str(eb[2]) filename3 = vfilter wb3 = load_workbook(filename3) ws3 = wb3.worksheets[0] mr = ws3.max_row mc = ws3.max_column filter = [] for i in range(1, mr + 1): c = ws3.cell(row=i, column=1) filter.append(c.value.upper()) # Grand Tableau expenses = ea row = 26 col = 1 #expenses1 = ec col2 = 6 for aa, bb, cc, dd, ff, gg in (expenses): if str(aa).strip().upper() in filter: worksheet.cell(row, col).value = aa worksheet.cell(row, col).alignment = Alignment(wrapText=True, vertical='top') worksheet.cell(row, col + 1).value = bb worksheet.cell(row, col + 1).alignment = Alignment(wrapText=True, vertical='top') worksheet.cell(row, col + 2).value = cc worksheet.cell(row, col + 2).alignment = Alignment(vertical='top', wrapText=True) worksheet.cell(row, col + 3).value = "'" + str(dd).strip() worksheet.cell(row, col + 3).alignment = Alignment(vertical='top', wrapText=True) worksheet.cell(row, col + 4).value = "'" + str(ff).strip() worksheet.cell(row, col + 4).alignment = Alignment(vertical='top', wrapText=True) worksheet.cell(row, col + 6).value = gg #str(gg).strip() worksheet.cell(row, col + 6).alignment = Alignment(vertical='top', wrapText=True) v_hp = "" v_part = "" v_final = "" v_hp = "" v_part = "" v_final = "" for i in range(len(id_list)): v1 = str(veh_Project_list[i]).strip().upper() + "_" + str( parts_list[i]).strip().upper() if v1 != v_part: if str(aa).strip().upper() == v1.strip().upper(): if str(status_list[i]).strip().upper() == "OPEN": worksheet.cell( row, col2).value = str(id_list[i]) + '\n' worksheet.cell(row, col2).alignment = Alignment( wrapText=True, vertical='top') v_part = v1.strip() v_hp = "" v_final = id_list[i] else: if str(aa).strip().upper() == v1.strip().upper(): if str(status_list[i]).strip().upper() == "OPEN": v_hp += v_final + '\n' + id_list[i] worksheet.cell(row, col2).value = v_hp worksheet.cell(row, col2).alignment = Alignment( wrapText=True, vertical='top') v_final = " " # v_final = aaa[0] + ' , ' row += 1 piece_no_disponible = [] piece_disponible = [] self.progress_bar["value"] = 80 time.sleep(1) root.update() for aa, bb, cc, dd, ff, gg in (expenses): piece_disponible.append(str(aa).upper().strip()) for i in filter: if i not in piece_disponible: piece_no_disponible.append(i) # pour le message des piece non disponible l = '' for k in piece_no_disponible: if k != 'PART': l += ' , ' + str(k) li = 'The following parts ( ' + l + " ) are not available." if l != '': self.vremarque.set(li) self.lremarque['bg'] = '#FC4C4C' else: self.vremarque.set('Report created') self.lremarque['bg'] = '#CAE21E' #indice = len(expenses) + 25 indice = len(filter) - len(piece_no_disponible) + 25 ref = "A25:G" + str(indice) tab3 = Table(displayName="Table2", ref=ref) style = TableStyleInfo(name="TableStyleMedium9", showFirstColumn=False, showLastColumn=False, showRowStripes=True, showColumnStripes=False) tab3.tableStyleInfo = style worksheet.add_table(tab3) # Pour le graphe img = openpyxl.drawing.image.Image('fig.png') img.width = 750 img.height = 370 worksheet.add_image(img, 'A5') my_red = openpyxl.styles.colors.Color(rgb='00FF0000') my_green = openpyxl.styles.colors.Color(rgb='0000FF00') my_orange = openpyxl.styles.colors.Color(rgb='00FFA500') # Couleur colonne B for i in range(26, len(expenses) + 26): if str(worksheet.cell(i, 2).value).strip() == 'Not Passed' or str( worksheet.cell(i, 2).value).strip() == 'Not passed': worksheet.cell(i, 2).value = 'Not passed' worksheet.cell(i, 2).fill = PatternFill(patternType='solid', fgColor=my_red) if str(worksheet.cell(i, 2).value).strip() == 'Conditionally': worksheet.cell(i, 2).value = worksheet.cell(i, 2).value.strip() worksheet.cell(i, 2).fill = PatternFill(patternType='solid', fgColor=my_orange) if str(worksheet.cell(i, 2).value).strip() == 'Passed' or str( worksheet.cell(i, 2).value).strip() == 'passed': worksheet.cell(i, 2).value = 'Passed' worksheet.cell(i, 2).fill = PatternFill(patternType='solid', fgColor=my_green) """v = str(worksheet.cell(i, 2).value) if v.upper().strip() == 'NOT PASSED': worksheet.cell(i, 2).value = 'Not passed' worksheet.cell(i, 2).fill = PatternFill(patternType='solid', fgColor=my_red) if str(worksheet.cell(i, 2).value).upper().strip() == 'CONDITIONALLY': worksheet.cell(i, 2).value = worksheet.cell(i, 2).value.strip() worksheet.cell(i, 2).fill = PatternFill(patternType='solid', fgColor=my_orange) if str(worksheet.cell(i, 2).value).upper().strip() == 'PASSED': worksheet.cell(i, 2).value = 'Passed' worksheet.cell(i, 2).fill = PatternFill(patternType='solid', fgColor=my_green)""" workbook.save(rapport_name) workbook.close() self.progress_bar["value"] = 95 time.sleep(2) root.update() self.progress_bar["value"] = 100 time.sleep(2) root.update() self.progress_bar.grid_forget() root.update() def set_emplacement(self): import time self.FILETYPES = [("text files", "*.xlsx")] self.chemin1 = (askdirectory()) date_now = time.strftime('%d%m%Y') self.chemin = self.chemin1 + '/' + 'F' + date_now + '.xlsx' if self.chemin1 != '': self.create_rapport(self.chemin) def set_fichier1(self): self.vremarque.set('') self.lremarque.grid_remove() self.FILETYPES = [("text files", "*.xlsx")] self.vfichier1.set(askopenfilename(filetypes=self.FILETYPES)) if self.vfichier1.get() != '': self.button1['bg'] = '#006738' def set_fichier2(self): self.lremarque.grid_remove() self.vremarque.set('') self.FILETYPES = [("text files", "*.xlsx")] self.vfichier2.set(askopenfilename(filetypes=self.FILETYPES)) if self.vfichier2.get() != '': self.button2['bg'] = '#006738' def set_project(self): self.vremarque.set('') self.lremarque.grid_remove() self.FILETYPES = [("text files", "*.xlsx")] self.vproject.set(askopenfilename(filetypes=self.FILETYPES)) if self.vfichier1.get() != '': self.bProject['bg'] = '#006738' def set_filter(self): self.FILETYPES = [("text files", "*.xlsx")] self.vfilter_name.set(askopenfilename(filetypes=self.FILETYPES)) if self.vfilter_name.get() != '': self.bpetit_tab['bg'] = '#006738' def create_rapport(self, name_r): if self.vfichier1.get() != '' and self.vfichier1.get( ) != '' and self.chemin1 != '' and self.vfilter_name != '': self.part1(str(self.vfichier1.get()), self.vfichier2.get(), name_r, self.vproject.get(), self.vfilter_name.get()) self.button2['bg'] = '#66B239' self.button1['bg'] = '#66B239' self.bpetit_tab['bg'] = '#66B239' self.bpetit_emp['bg'] = '#66B239' self.bProject['bg'] = '#66B239' self.lremarque.grid(row=7, column=0, sticky='news') else: messagebox.showerror( 'ERROR', "Import all files and select storage location")
class buildGUI(Frame): def __init__(self, typeNeuralNet, master=None): Frame.__init__(self, master) self.master = master self.typeNeuralNet = typeNeuralNet self.init_gui() def init_gui(self): self.master.title(self.typeNeuralNet) self.pack(fill=BOTH, expand=1) #Tabs self.tabControl = ttk.Notebook(self.master) self.mainTab = Frame(self.tabControl, bg="white") self.tabControl.add(self.mainTab, text='Main') self.tabControl.pack(expand=1, fill='both') if (self.typeNeuralNet == "Classification-CNN"): self.advancedOptionsTab(self.tabControl) #Input inputLabel = Label(self.mainTab, text="Input Folder", bg="white", font=("Helvetica", 20)) inputLabel.grid(row=0, column=0) #Output outputLabel = Label(self.mainTab, text="Output Folder", bg="white", font=("Helvetica", 20)) outputLabel.grid(row=1, column=0) #Input Folder self.inputDir = filedialog.askdirectory( title="Select input directory") self.input = Label(self.mainTab, text=self.inputDir, bg="white", font=("Helvetica", 20)) self.input.grid(row=0, column=1) #Output Folder self.outputDir = filedialog.askdirectory( title="Select output directory") self.output = Label(self.mainTab, text=self.outputDir, bg="white", font=("Helvetica", 20)) self.output.grid(row=1, column=1) # Start self.startButton = Button(self.mainTab, text="Start", command=self.run, bg="white", font=("Helvetica", 20)) self.startButton.grid(row=3, column=0) #Backend self.process = bk.Backend(self.typeNeuralNet) #Progress bar self.progress = Progressbar(self.mainTab, orient=HORIZONTAL, length=500, mode='indeterminate') if (self.typeNeuralNet == "Self-classification"): # TODO: counter self.timeLeft = 10 self.paused = True self.timeLeftLabel = Label(self.mainTab, text="", width=10) self.timeLeftLabel.grid(row=1, column=1) self.countdownButton = Button(self.mainTab, text="Start", command=self.toggle) self.countdownButton.grid(row=1, column=0) # TODO: Image viewer # self.imageViewer = imageViewer.ImageViewer(self.mainTab) # self.imageView = self.imageViewer.btn # self.imageView.grid(row = 1, column = 0) # TODO: Buttons self.blurryCount = 0 self.nonBlurryCount = 0 self.blurryButton = Button(self.mainTab, text="Blurry", command=self.addBlurry) self.blurryButton.grid(row=5, column=0) self.notBlurryButton = Button(self.mainTab, text="Not Blurry", command=self.addNotBlurry) self.notBlurryButton.grid(row=5, column=1) # TODO: Dynamic display def run(self): def runInner(): self.progress.grid(row=5, column=0) self.progress.start() (good, uncertain, bad) = self.process.runModel(self.progress, self.inputDir, self.outputDir) if messagebox.askyesno( 'Process completed!', 'There are : \n-' + str(good) + " good scans \n-" + str(bad) + " bad scans \n-" + str(uncertain) + " uncertain scans \n\n" + "Do you want to go to the output directory?", icon=messagebox.INFO): webbrowser.open(self.outputDir) self.progress.grid_forget() threading.Thread(target=runInner).start() def advancedOptionsTab(self, tabControl): self.advancedOptionsTab = ttk.Frame(tabControl) tabControl.add(self.advancedOptionsTab, text="Advanced Options") tabControl.pack(expand=1, fill='both') percentageLabel = Label(self.advancedOptionsTab, text="Percentage accuracy") percentageLabel.grid(row=0, column=0) self.percentage = Entry(self.advancedOptionsTab) self.percentage.grid(row=0, column=1) def toggle(self): if self.paused: self.paused = False self.countdownButton.config(text="Reset") self.countdown() else: self.timeLeft = 10 self.blurryCount = 0 self.nonBlurryCount = 0 self.paused = True self.countdownButton.config(text='Start') def countdown(self): if self.paused: return elif self.timeLeft <= 0: self.timeLeftLabel.config(text="time's up!") else: self.timeLeftLabel.config(text="%d" % self.timeLeft) self.timeLeft = self.timeLeft - 1 self.after(1000, self.countdown) def addBlurry(self): self.blurryCount = self.blurryCount + 1 print(self.blurryCount) def addNotBlurry(self): self.nonBlurryCount = self.nonBlurryCount + 1 print(self.nonBlurryCount)
class CleanUpGui(Frame): def __init__(self, master=None): Frame.__init__(self, master=master) self.master.title("Clean up") self.grid(row=12, column=3, sticky=NSEW) self.progress = Progressbar(self, orient=HORIZONTAL, length=200, maximum=100, mode='determinate') file = open("never_delete_files.txt", "a") # Setup variables self.folder_details = None self.current_file = None self.new_path = "" # dummy, =1 if in never_delete_files.txt, otherwise =0 self.checkvar1 = IntVar() # bytes deleted counter self.bytes_counter = 0 # Setup GUI elements self.current_file_name = Label(self) self.current_file_size = Label(self) self.type_file_info = Label(self) self.never_delete_this_file = Label(self) self.bytes_counter_label = Label(self) self.rename_button = Label(self) # buttons self.delete_file_button = Button(self, text="Delete", command=self.delete_current_file) self.skip_file_button = Button(self, text="Skip", command=self.load_next_file) self.never_delete_button = Checkbutton(self, text="Never delete this file", variable=self.checkvar1, onvalue=1, offvalue=0, command=self.combined_function1) self.bytes_counter_label.configure(text="Current bytes deleted: " + str(self.bytes_counter)) self.rename_button = Button(self, text="Rename file", command=self.rename_window) self.quick_move_button = Button(self, text="Quick Move", command=self.quick_move) # Place GUI elements on Canvas self.progress.grid(row=0, column=0, columnspan=3) self.current_file_name.grid(row=1, column=0, columnspan=3, rowspan=1, sticky="W") self.current_file_size.grid(row=2, column=0, columnspan=3, rowspan=1, sticky="W") self.bytes_counter_label.grid(row=3, column=0, columnspan=3, rowspan=1, sticky="W") self.never_delete_this_file.grid(row=4, column=0, columnspan=3, rowspan=1, sticky="NESW") self.type_file_info.grid(row=5, column=0, columnspan=3, rowspan=4, sticky="NESW") self.quick_move_button.grid(row=10, column=0, columnspan=3, rowspan=1, sticky="ESW") self.delete_file_button.grid(row=11, column=0, columnspan=1, rowspan=1, sticky="ESW") self.skip_file_button.grid(row=11, column=1, columnspan=1, rowspan=1, sticky="ESW") self.rename_button.grid(row=11, column=2, columnspan=1, rowspan=1, sticky="ESW") self.never_delete_button.grid(row=12, column=0, columnspan=3, rowspan=1, sticky="W") # steps of the progress bar for each file def progress_bar(self): n = self.folder_details.n_files steps = (100 - 0.001) / n self.progress.step(steps) # to execute 2 functions with 1 button press def combined_function1(self): self.prevent_unchecking() self.never_delete() # delete files with button press def delete_current_file(self): try: # check if file is not in the "never_delete_file" i.e. box is unchecked/dummy equal to 0 if self.checkvar1.get() == 1: self.never_delete_this_file.configure(text="The file" + self.current_file.path + " cannot be deleted") else: # if not in the .txt file then delete, load next file and count the bytes deleted if self.current_file: file_size = getsize( join(self.folder_details.path, self.current_file.path)) self.bytes_counter += file_size self.bytes_counter_label.configure( text="current bytes deleted: " + str(self.bytes_counter)) remove( join(self.folder_details.path, self.current_file.path)) # load the next file self.load_next_file() except FileNotFoundError: # if file not found e.g. because deleted manually after program started print("no file to delete") self.load_next_file() # load next file def load_next_file(self): if self.folder_details: next_file = self.folder_details.get_next_file() if next_file: # load next file, check if it can be deleted, disable/enable checkbox, move progress bar self.current_file = FileDetails(self, self.folder_details, next_file) self.check_not_delete_list() self.prevent_unchecking() self.progress_bar() else: self.current_file = FileDetails(self, self.folder_details, "") self.check_not_delete_list() self.prevent_unchecking() self.progress.grid_forget() self.current_file.display_details() # write absolute path to txt file, to never deleted a file with that exact absolute path def never_delete(self): path = join(self.folder_details.path, self.current_file.path) file = open("never_delete_files.txt", "a") file.write(path + "\n") # check if file can be deleted, check the checkbox if not/uncheck if it can def check_not_delete_list(self): ndfile = open("never_delete_files.txt", "r") ndfiles = ndfile.read().splitlines() path = join(self.folder_details.path, self.current_file.path) if path in ndfiles: self.checkvar1.set(1) else: self.checkvar1.set(0) # check if file can be deleted, if not disable checkbox def prevent_unchecking(self): if self.checkvar1.get() == 1: self.never_delete_button.config(state=DISABLED) else: self.never_delete_button.config(state=NORMAL) # rename a file with user input + if file is in never_deleted_file add the new path to the text file def rename_file(self): try: path = join(self.folder_details.path, self.current_file.path) new_name = join(self.folder_details.path, self.entry.get()) os.rename(path, new_name) if self.checkvar1.get() == 1: path = join(self.folder_details.path, self.entry.get()) file = open("never_delete_files.txt", "a") file.write(path + "\n") self.root.destroy() self.load_next_file() except OSError: # if file name not allowed raise error print("file name not allowed") # open new canvas, ask for user input to rename, execute function rename_file if button pressed def rename_window(self): self.root = Tk() self.root.title("Rename File") new_window = Canvas(self.root, width=200, height=100) self.entry = Entry(self.root) self.entry.insert(0, str(self.current_file.path)) new_window.create_window(100, 35, window=self.entry) label = Label( self.root, text= "Type your new file name here:\n\n Include the extension in the new file name!" ) b = Button(self.root, text="rename", width=10, command=self.rename_file) label.pack() new_window.pack() b.place(x=65, y=110) # disable buttons when went through all files, to prevent any errors from occurring def disable_buttons(self): self.delete_file_button["state"] = DISABLED self.rename_button["state"] = DISABLED self.never_delete_button["state"] = DISABLED self.skip_file_button["state"] = DISABLED self.quick_move_button["state"] = DISABLED # Move file to selected directory, raise error if no directory selected to or file doesnt exist anymore def quick_move(self): try: if self.new_path == "": self.new_path = filedialog.askdirectory() shutil.move(join(self.folder_details.path, self.current_file.path), self.new_path) self.load_next_file() except FileNotFoundError: print("no directory selected to move the file to") def delete_path(self): pass # startup # select directory and 'start' the program, raise error if no directory selected def select_folder(self): try: folder_path = filedialog.askdirectory() self.folder_details = FolderDetails(folder_path) self.load_next_file() self.check_not_delete_list() self.prevent_unchecking() except AttributeError: print("no folder selected") raise SystemExit
class App: def __init__(self, master): master.minsize(width=350, height=200) master.maxsize(width=350, height=200) master.configure(background='LightSalmon2') master.title('ShellCracker 1.0') # Menubar menu_bar = Menu(master) file_menu = Menu(menu_bar, tearoff=0) file_menu.add_command(label="Exit", accelerator="Alt + F4", command=self.turn_off) view_menu = Menu(menu_bar, tearoff=0) about_menu = Menu(menu_bar, tearoff=0) about_menu.add_command(label="About") about_menu.add_command(label="Help") menu_bar.add_cascade(label='File', menu=file_menu) menu_bar.add_cascade(label='View', menu=view_menu) menu_bar.add_cascade(label='About', menu=about_menu) master.config(menu=menu_bar) # File chooser button search_img = PhotoImage(file="images/Search-Folder-icon.png") search_img = search_img.subsample(5) self.btn_search = Button(master, text="Select File", command=self.process_file) self.btn_search.config(image=search_img, width="240", height="80", border=2, cursor='hand2', bg='lightblue') self.btn_search.grid(row=0, column=1, sticky='e' + 'w', padx=50, pady=20) self.btn_search.image = search_img # Progressbar self.progress = Progressbar(master, orient=HORIZONTAL, length=245, mode='indeterminate') def process_file(self): def progress(): self.progress.grid(row=1, column=1, sticky='e', padx=50) self.progress.start() time.sleep(5) self.progress.stop() self.progress.grid_forget() self.btn_search['state'] = 'normal' file = tkinter.filedialog.askopenfilename(filetypes=[("MS Excel", "*.xlsx")]) if file: p = FileProcessor(file) p.process() self.btn_search['state'] = 'disabled' threading.Thread(target=progress).start() @staticmethod def turn_off(): root.destroy()
class GUI(Tk): def __init__(self): Tk.__init__(self) self.user_frame = Frame() self.back_button = Button(self.user_frame, text="Back", command=self.back_to_home_gui) self.segmentation_button = Button(self.user_frame, text="Segmentation", command=self.segmentation_gui, height=2, width=10) self.analysis_button = Button(self.user_frame, text="Analysis", command=self.analysis_gui, height=2, width=10) self.progress = Progressbar(self.user_frame, orient=HORIZONTAL, length=200, mode='indeterminate') self.progress_label = Label(self.user_frame) # output folder self.output_path = StringVar("") self.output_label = Label(self.user_frame, text="please select " "output path") self.output_input = Entry(self.user_frame, textvariable=self.output_path, width=40) self.select_output = Button(self.user_frame, text=" ", command=self.select_output_folder) # original image self.file_path = StringVar("") self.file_label = Label(self.user_frame, text="please select the CT " "scan") self.file_input = Entry(self.user_frame, textvariable=self.file_path, width=40) self.select_file = Button( self.user_frame, text=" ", command=lambda: self.select_nifti_file(self.file_path)) # seeds self.seeds_path = StringVar("") self.seeds_label = Label(self.user_frame, text="please select the " "marking") self.seeds_input = Entry(self.user_frame, textvariable=self.seeds_path, width=40) self.select_seeds = Button( self.user_frame, text=" ", command=lambda: self.select_nifti_file(self.seeds_path)) # run buttons self.segmentation_run = Button(self.user_frame, text="Run " "Segmentation", command=self.run_segmentation) self.analysis_run = Button(self.user_frame, text="Run Analysis", command=self.run_analysis) self.default_background = self.output_input.cget("background") self.scaphoid = None self.radius = None self.initilize_gui() def __del__(self): del self.user_frame del self.back_button del self.segmentation_button del self.analysis_button del self.progress del self.progress_label del self.output_path del self.output_label del self.output_input del self.select_output del self.file_path del self.file_label del self.file_input del self.select_file del self.seeds_path del self.seeds_label del self.seeds_input del self.select_seeds del self.segmentation_run del self.analysis_run del self.default_background del self.scaphoid del self.radius def select_output_folder(self): """Select an output folder""" path = filedialog.askdirectory() self.output_path.set(path) self.output_input.config(background=self.default_background) del path def select_nifti_file(self, var): """Select a nifti file""" input_path = filedialog.askopenfilename() var.set(input_path) self.user_frame.grid_slaves( int(str(var)[-1]) + 1, 1)[0].config(background=self.default_background) del input_path def back_to_home_gui(self): """forgets the other gui and reload the home gui""" self.forget_non_home_gui() self.seeds_path.set("") self.initilize_gui() def initilize_gui(self): """Initial GUI""" self.title("Scaphoid Fracture Segmentation and analysis") self.user_frame.grid() self.segmentation_button.grid(row=0, column=0, padx=(100, 50), pady=(30, 30)) self.analysis_button.grid(row=0, column=1, padx=(50, 100), pady=(30, 30)) def segmentation_gui(self): """Initial GUI of the segmentation""" self.segmentation_button.grid_forget() self.analysis_button.grid_forget() self.back_button.grid(row=0, pady=(2, 2)) self.title("Scaphoid Fracture Segmentation") self.seeds_label.config(text="please select the marking") self.output_label.grid(row=1, column=0) self.output_input.grid(row=1, column=1) self.select_output.grid(row=1, column=2) self.file_label.grid(row=2, column=0) self.file_input.grid(row=2, column=1) self.select_file.grid(row=2, column=2) self.seeds_label.grid(row=3, column=0) self.seeds_input.grid(row=3, column=1) self.select_seeds.grid(row=3, column=2) self.segmentation_run.grid(row=4, columnspan=3, sticky=N + S + E + W) def analysis_gui(self): """Initial the analysis GUI""" self.segmentation_button.grid_forget() self.analysis_button.grid_forget() self.back_button.grid(row=0, pady=(2, 2)) self.title("Scaphoid Fracture analysis") self.seeds_label.config(text="please select the segmentation") self.output_label.grid(row=1, column=0) self.output_input.grid(row=1, column=1) self.select_output.grid(row=1, column=2) self.file_label.grid(row=2, column=0) self.file_input.grid(row=2, column=1) self.select_file.grid(row=2, column=2) self.seeds_label.grid(row=3, column=0) self.seeds_input.grid(row=3, column=1) self.select_seeds.grid(row=3, column=2) self.analysis_run.grid(row=4, columnspan=3, sticky=N + S + E + W) def forget_non_home_gui(self): """Forgets the grid of segmentation GUI""" collect() self.back_button.grid_forget() self.output_label.grid_forget() self.output_input.grid_forget() self.select_output.grid_forget() self.file_label.grid_forget() self.file_input.grid_forget() self.select_file.grid_forget() self.seeds_label.grid_forget() self.seeds_input.grid_forget() self.select_seeds.grid_forget() self.segmentation_run.grid_forget() self.analysis_run.grid_forget() def validate_data(self): """This function make sure that the data the user selected is valid""" valid = True if not exists(self.output_path.get()): valid = False self.output_input.config(background="tomato") file_path = self.file_path.get() seeds_path = self.seeds_path.get() if not (file_path.endswith(".nii.gz") and exists(file_path)): valid = False self.file_input.config(background="tomato") if not (seeds_path.endswith(".nii.gz") and exists(seeds_path)): valid = False self.seeds_input.config(background="tomato") return valid def run_segmentation(self): """Run the segmentation algorithm while updating the progressbar""" def threaded_prog(): self.progress_label.grid(row=5, column=0) self.progress.grid(row=5, column=1, columnspan=2) self.progress.start() self.progress_label.config(text="Running Segmentation") self.segmentation_process() self.progress.stop() self.progress_label.grid_forget() self.progress.grid_forget() self.back_to_home_gui() if self.validate_data(): Thread(target=threaded_prog).start() else: messagebox.showinfo("Error with the input", "Error with the input") def segmentation_process(self): """Creates the segmentation of the scaphoid and the fracture""" self.progress_label.config(text="Getting seeds") scaphoid_seeds, fracture_seeds = generate_scaphoid_seeds( self.seeds_path.get()) self.progress_label.config(text="Isolating The Scaphoid") self.scaphoid = Scaphoid(self.file_path.get(), scaphoid_seeds, fracture_seeds, 6) self.scaphoid.region_growing_from_input(SCAPHOID_COLOR) self.progress_label.config(text="Isolating The Fracture") self.scaphoid.segment_fracture_region_growing_mean( FRACTURE_COLOR, SCAPHOID_COLOR) self.progress_label.config(text="Saving Files") save_scaphoid_segmentations(self.scaphoid, self.output_path.get()) self.progress_label.config(text="Finishing") self.scaphoid = None del scaphoid_seeds, fracture_seeds messagebox.showinfo("Process Finished Successfully", "Process Finished Successfully") def run_analysis(self): """runs the analysis algorithm while updating the progress bar""" def threaded_prog(): self.progress_label.grid(row=5, column=0) self.progress.grid(row=5, column=1, columnspan=2) self.progress.start() self.progress_label.config(text="Running Analysis") self.analysis_process() self.progress.stop() self.progress_label.grid_forget() self.progress.grid_forget() self.back_to_home_gui() if self.validate_data(): Thread(target=threaded_prog).start() else: messagebox.showinfo("Error with the input", "Error with the input") def analysis_process(self): """The main analysis process""" self.progress_label.config(text="Getting the fracture") self.scaphoid = Scaphoid(self.file_path.get(), [], [], 1) self.scaphoid.load_bone_fracture(self.seeds_path.get()) self.scaphoid.load_fracture_from_bone_fracture() self.progress_label.config(text="Getting seeds") radius_seeds, capitate_seg = generate_analysis_seeds( self.seeds_path.get()) self.progress_label.config(text="Isolating The Radius") self.radius = Radius(self.file_path.get(), radius_seeds, 6) self.radius.region_growing_from_input(RADIUS_COLOR) self.progress_label.config(text="Getting PCA from radius") pca = self.radius.extract_PCA_components() self.progress_label.config(text="Dividing the bone") self.scaphoid.divide_bone_into_quarters(pca) self.progress_label.config(text="Dividing the fracture") self.scaphoid.divide_fracture_into_quarters(pca) self.progress_label.config(text="Getting geometric information") geo_features = self.scaphoid.get_geometric_features() geo_features["Angle between Radius and Capitate"] = \ str(create_direction_vector_for_2_points_cloud( capitate_seg, pca[0])) self.progress_label.config(text="Saving Files") save_analysis_segmentation(self.scaphoid, self.output_path.get()) file_name = str( abspath(self.scaphoid.get_original_path()).split("\\")[-1].split( ".")[0]) save_geometric_features(geo_features, self.output_path.get(), file_name) self.progress_label.config(text="Finishing") self.scaphoid = None self.radius = None del pca, geo_features messagebox.showinfo("Process Finished Successfully", "Process Finished Successfully")
class AppTracker(Frame): def __init__(self, parent): Frame.__init__(self, parent) # widgets self._status_label = Label(parent, anchor="w", font=("Gisha", 8), text="", background="#d9d9d9", foreground="#3f3f3f") self._status_label.grid(sticky="NEWS", row=1, rowspan=1, column=0, columnspan=3, ipady=1) self._progress_bar = Progressbar(parent, maximum=40, mode='determinate', orient="horizontal") self._loading_bar = Progressbar(parent, maximum=40, mode='indeterminate', orient="horizontal") # self._preset_button = Button(parent, border=0, font=("Gisha", 8), text="Change preset file..") # self._preset_button.grid(sticky="EW", row=1, rowspan=1, column=2, columnspan=1) @property def loading_bar(self): return self._loading_bar @property def progress_bar(self): return self._progress_bar @property def status_label(self): return self._status_label # @property # def preset_button(self): # return self._preset_button def show_loading_bar(self): self._loading_bar.grid(sticky="EW", row=1, rowspan=1, column=2, columnspan=1) self._loading_bar.update_idletasks() def hide_loading_bar(self): self._loading_bar.stop() self._loading_bar.grid_forget() self._loading_bar.update_idletasks() def show_progress_bar(self): self._progress_bar.grid(sticky="EW", row=1, rowspan=1, column=2, columnspan=1) self._progress_bar.update_idletasks() def hide_progress_bar(self): self._progress_bar.grid_forget() self._progress_bar.update_idletasks() def update_status_label(self, text): self._status_label.configure(text=text) self._status_label.update_idletasks() def update_progress_bar(self, value): self._progress_bar['value'] = value self._progress_bar.update_idletasks() def update_loading_bar(self, value): self._loading_bar.step(value) self._loading_bar.update_idletasks()
class ScanDialog(Toplevel): def __init__(self, root, path, fileList): Toplevel.__init__(self, root) self.wm_title("Importing Directory...") self.scanner = DirectoryScanner(path, fileList) # string variables self.percent = StringVar() self.timeRemaining = StringVar() self.itemsRemaining = StringVar() # create gui elements self.percLabel = Label(self, textvariable=self.percent) self.timeLabel = Label(self, textvariable=self.timeRemaining) self.itemLabel = Label(self, textvariable=self.itemsRemaining) self.progress = Progressbar(self, orient="horizontal", length=300, mode='indeterminate') self.cancelBtn = Button(self, text="Cancel", width=10, command=self.cancel) # build gui self.timeLabel.grid(row=2, column=0, padx=5, pady=5, sticky="w") self.progress.grid(row=1, column=0, padx=5, pady=5, sticky="ew") self.cancelBtn.grid(row=4, column=0, padx=5, pady=5) self.resizable(False, False) self.grab_set() self.transient() self.scanner.start() self.progress.start() self.timeRemaining.set("Searching for files...") self.after(0, self.search) # cancel scan def cancel(self): self.scanner.stop() self.destroy() # waits for file search to complete, # then prepares gui for scan def search(self): if self.scanner.is_alive(): # if search has completed if self.scanner.status == "scanning": self.resizable(True, True) self.percLabel.grid(row=0, column=0, padx=5, pady=5, sticky="w") self.itemLabel.grid(row=3, column=0, padx=5, pady=5, sticky="w") self.progress.grid_forget() self.progress = Progressbar(self, orient="horizontal", length=300, mode='determinate') self.progress.grid(row=1, column=0, padx=5, pady=5, sticky="ew") self.resizable(False, False) self.after(0, self.scan) else: self.after(50, self.search) else: self.destroy() # updates gui during scan def scan(self): if self.scanner.is_alive(): self.percent.set(str(self.scanner.percent) + "% complete") self.progress["value"] = self.scanner.percent self.timeRemaining.set("Time remaining: " + self.scanner.timeRemaining) self.itemsRemaining.set("Items remaining: " + str(self.scanner.itemsRemaining)) self.after(50, self.scan) else: self.destroy()