def getView(self, window): view = Frame(window) Label(view, text=self.question).pack() if (self.screentype == "Scale"): var = DoubleVar() slider = Scale(view, from_=0, to=100, orient=HORIZONTAL, variable=var, command=self.updateButtonText) slider.pack() self.btn = Button( master=view, text="Your Answer = " + str(slider.get()), command=lambda *args: self.check(str(slider.get()), view)) self.btn.pack() elif (self.screentype == "Radio"): var = StringVar() Radiobutton( view, text=self.answers[0], value="A", variable=var, command=lambda *args: self.check(var.get(), view)).pack() Radiobutton( view, text=self.answers[1], value="B", variable=var, command=lambda *args: self.check(var.get(), view)).pack() Radiobutton( view, text=self.answers[2], value="C", variable=var, command=lambda *args: self.check(var.get(), view)).pack() Radiobutton( view, text=self.answers[3], value="D", variable=var, command=lambda *args: self.check(var.get(), view)).pack() var.set(None) else: Button(view, text=self.answers[0], command=lambda *args: self.check("A", view)).pack() Button(view, text=self.answers[1], command=lambda *args: self.check("B", view)).pack() Button(view, text=self.answers[2], command=lambda *args: self.check("C", view)).pack() Button(view, text=self.answers[3], command=lambda *args: self.check("D", view)).pack() return view
def VentanaFourierLineal (ventana): """ Ventana en la que el usuario define los parámetros para el cálculo. Parámetros de la función: ------------------------ ventana: Variable que cierra una ventana ya abierta. Salida de la función: --------------------- Interfaz gráfica con la que el usuario elije un método de simulación. """ ventana.destroy () ventanaFourLineal = Tk () ventanaFourLineal.minsize (1300,600) ventanaFourLineal.config (bg='White') barraLadoX = Scale(ventanaFourLineal, from_=7, to=20, tickinterval=13, length=400, bg = 'White', resolution=1, showvalue=True, orient='horizontal', label="Tamaño del Lado (Lx)", cursor = "hand1") barraLadoX.set(10) tamañoLadoX = barraLadoX.get() barraLadoX.place (relx=0.3, rely=0.35, anchor=CENTER) barraTérminosN = Scale(ventanaFourLineal, from_=2, to=20, tickinterval=18,length=400, bg = 'White', resolution=1, showvalue=True, orient='horizontal', label="Número de Términos N", cursor = "hand1") barraTérminosN.set(10) númeroTérminosN = barraTérminosN.get() barraTérminosN.place (relx=0.7, rely=0.35, anchor=CENTER) barraLadoY = Scale(ventanaFourLineal, from_=7, to=20, tickinterval=13, length=400, bg = 'White', resolution=1, showvalue=True, orient='horizontal', label="Tamaño del Lado (Ly)", cursor = "hand1") barraLadoY.set(10) tamañoLadoY = barraLadoY.get() barraLadoY.place (relx=0.3, rely=0.55, anchor=CENTER) barraTérminosM = Scale(ventanaFourLineal, from_=2, to=20, tickinterval=18,length=400, bg = 'White', resolution=1, showvalue=True, orient='horizontal', label="Número de Términos M", cursor = "hand1") barraTérminosM.set(10) númeroTérminosM = barraTérminosM.get() barraTérminosM.place (relx=0.7, rely=0.55, anchor=CENTER) etiquetaParámetros = Label (ventanaFourLineal, text = ('Defina los parámetros iniciales: ')) etiquetaParámetros.config (bg = 'white', font = ('Verdana', 12)) etiquetaParámetros.place (relx=0.1225, rely=0.2, anchor=CENTER) boton3D = Button(ventanaFourLineal, text='Abrir Gráfica 3D', command = lambda: AbrirGrafica3D (tamañoLadoX, 0, númeroTérminosN, tamañoLadoY, 0, númeroTérminosM, 0)) boton3D.place (relx=0.42, rely=0.7, anchor=CENTER) botonLatInt = Button(ventanaFourLineal, text='Abrir Grafica de Intensidad', command = lambda: AbrirGraficaLateralIntensidad (tamañoLadoX, 0, númeroTérminosN, tamañoLadoY, 0, númeroTérminosM, 0)) botonLatInt.place (relx=0.6, rely=0.7, anchor=CENTER) botonRegresarPrincipal = Button(ventanaFourLineal, text='Regresar', command = lambda: VentanaFourierPrincipal (ventanaFourLineal)) botonRegresarPrincipal.place (relx=0.835, rely=0.85, anchor=CENTER) ventanaFourLineal.title ("Cálculo de la ecuación de difusión de calor") ventanaFourLineal.mainloop()
class ColorPickerDialog(Dialog): """ """ SCALE_MIN = 0 SCALE_MAX = 255 def __init__(self, callback, callback_args=None, validation_check=None): super().__init__("Pick a color", callback, callback_args, validation_check) def _create_widgets(self): super()._create_widgets() self.swatch_label = Label(self, text=(" " * 10) + ("\n" * 7)) self.r_scale = Scale(self, orient=HORIZONTAL, from_=self.SCALE_MIN, to=self.SCALE_MAX) self.g_scale = Scale(self, orient=HORIZONTAL, from_=self.SCALE_MIN, to=self.SCALE_MAX) self.b_scale = Scale(self, orient=HORIZONTAL, from_=self.SCALE_MIN, to=self.SCALE_MAX) self._update_swatch() def _arrange_widgets(self): self.swatch_label.grid(row=0, column=0, rowspan=3) self.r_scale.grid(row=0, column=1) self.g_scale.grid(row=1, column=1) self.b_scale.grid(row=2, column=1) self.cancel_button.grid(row=3, column=0) self.confirm_button.grid(row=3, column=1) def _bind_actions(self): super()._bind_actions() self.r_scale["command"] = self._update_swatch self.g_scale["command"] = self._update_swatch self.b_scale["command"] = self._update_swatch def _get_data(self): """ Return the hex format string built from the three scales. """ rgb = map(lambda x: hex(x)[2:], (self.r_scale.get(), self.g_scale.get(), self.b_scale.get())) return "#{:0>2}{:0>2}{:0>2}".format(*rgb) def _update_swatch(self, *args): """ Update the color of the swatch label to the current selection. """ self.swatch_label["background"] = self._get_data()
class ClipboardTyper(Tk): def __init__(self): Tk.__init__(self) # Initialize window properties self.title('Clipboard Typer') # Checkbutton for Type Racer text processing self.__cbIsTypeRacerVar = IntVar() cbIsTypeRacer = Checkbutton(self, text="isTypeRacer", variable=self.__cbIsTypeRacerVar) cbIsTypeRacer.grid(row=0, column=0, sticky=W) # Checkbutton for typing everything except the last character self.__cbLeaveLastChar = IntVar() cbLeaveLastChar = Checkbutton(self, text="leaveLastChar", variable=self.__cbLeaveLastChar) cbLeaveLastChar.grid(row=1, column=0, sticky=W) # Typing delay label typing_delay_label = Label(self, text="Typing delay (ms)") typing_delay_label.grid(row=2, column=0) # Typing delay scale self.__typing_delay_scale = Scale(self, from_=1, to=1000, orient=HORIZONTAL) self.__typing_delay_scale.grid(row=2, column=1) # Start delay label start_delay_label = Label(self, text="Start delay (ms)") start_delay_label.grid(row=3, column=0) # Start delay scale self.__start_delay_scale = Scale(self, from_=0, to=10000, orient=HORIZONTAL) self.__start_delay_scale.grid(row=3, column=1) # Main button button = Button(self, text="Type Clipboard Image", bg="pale green", command=self.__on_button_press) button.grid(row=4, column=0, columnspan=2, sticky=EW) def __on_button_press(self): Utils.type_from_clipboard(isTypeRacer=self.__cbIsTypeRacerVar.get(), leaveLastChar=self.__cbLeaveLastChar.get(), typingDelay=self.__typing_delay_scale.get(), startDelay=self.__start_delay_scale.get())
class DPIChanger(): def __init__(self, winTitle, xSize, ySize, *args): self.window = tk.Tk() if args: self.window.configure(bg=args) self.window.geometry(f'{xSize}x{ySize}') self.window.title(winTitle) self.window.iconbitmap("ImageDPI.ico") self.window.resizable(False, False) self.chooseImageButton = Button(text="Choose Image", bd=3, command=self.chooseImageFunc) self.chooseImageButton.place(x=23, y=20) self.chooseSaveTo = Button(text="Choose folder to save to", bd=3, command=self.chooseSaveFunc) self.chooseSaveTo.place(x=150, y=20) self.dpiScale = Scale(from_=5000, to=0) self.dpiScale.place(x=0, y=70) self.dpiScaleTwo = Scale(from_=5000, to=0) self.dpiScaleTwo.place(x=40, y=70) self.newImageName = Label(text="Enter new image name", font=("Courier", 12)) self.newImageName.place(x=110, y=70) self.newImageEntry = Entry(bd=3) self.newImageEntry.place(x=110, y=100) self.changeDPIBtn = Button(text="Submit", bd=3, command=self.changeDPI) self.changeDPIBtn.place(x=110, y=145) self.window.mainloop() def chooseImageFunc(self): self.getImage = filedialog.askopenfilename() messagebox.showinfo("Image ", self.getImage) self.getImageExtension = self.getImage.rsplit(".", 1) self.imageExtension = self.getImageExtension[1] def chooseSaveFunc(self): self.savedFolder = filedialog.askdirectory() messagebox.showinfo("Folder", self.savedFolder) def changeDPI(self): try: self.scaleNum = self.dpiScale.get() self.scaleNumTwo = self.dpiScaleTwo.get() self.theNewImage = PILImage.open(self.getImage) self.theNewImage.save(self.savedFolder + "/" + self.newImageEntry.get() + "." + self.imageExtension, dpi=(self.scaleNum, self.scaleNumTwo)) messagebox.showinfo( "Saved", self.savedFolder + "/" + self.newImageEntry.get() + "." + self.imageExtension) except: messagebox.showwarning("Error", "Something went wrong")
class SineGUI: def __init__(self, master): self.master = master master.title("Sine Tone") self.sin = SineGenerator() self.freq_label = Label(master, text="Frequency:") self.freq_label.pack() self.freq_scale = Scale(master, from_=50, to=5000, orient=HORIZONTAL) self.freq_scale.set(440) self.freq_scale.pack() self.volume_label = Label(master, text="Volume:") self.volume_label.pack() self.volume_scale = Scale(master, from_=0, to=1, resolution=0.1, orient=HORIZONTAL) self.volume_scale.set(0.5) self.volume_scale.pack() self.play_button = Button(master, text="Play", command=self.play) self.play_button.pack() f = self.sin.plot_sine(440, volume=0.5) self.canvas = FigureCanvasTkAgg(f, master=self.master) self.canvas.draw() self.canvas.get_tk_widget().pack() self.close_button = Button(master, text="Close", command=master.quit) self.close_button.pack() def play(self): freq = float(self.freq_scale.get()) vol = float(self.volume_scale.get()) self.sin.play_sine_tone(freq, volume=vol) self.add_plot() def add_plot(self): freq = float(self.freq_scale.get()) vol = float(self.volume_scale.get()) f = self.sin.plot_sine(freq, volume=vol) self.canvas.get_tk_widget().pack_forget() self.canvas = FigureCanvasTkAgg(f, master=self.master) self.canvas.draw() self.canvas.get_tk_widget().pack()
class TkDistanceSensor(TkDevice): def __init__(self, root, x, y, name, trigger_pin, echo_pin, min_distance=0, max_distance=50): super().__init__(root, x, y, name) self._echo_pin = Device.pin_factory.pin(echo_pin) self._trigger_pin = Device.pin_factory.pin(trigger_pin, pin_class=PreciseMockTriggerPin, echo_pin=self._echo_pin, echo_time=0.004) self._echo_pin._bounce = 0 self._trigger_pin._bounce = 0 self._set_image_for_state("distance_sensor.png", "normal", (86, 50)) self._create_main_widget(Label, "normal") self._scale = Scale(root, from_=min_distance, to=max_distance, orient=HORIZONTAL, command=self._scale_changed, sliderlength=20, length=150, highlightthickness=0, background="white") self._scale.place(x=x + 100, y=y) self._scale.set(round((min_distance + max_distance) / 2)) self._scale_changed(self._scale.get()) def _scale_changed(self, value): speed_of_sound = 343.26 # m/s distance = float(value) / 100 # cm -> m self._trigger_pin.echo_time = distance * 2 / speed_of_sound
class LabeledVerticalScale(Frame): """ LabeledVerticalScale - Supporting Frame of vertical slider with labels """ def __init__(self, parent, text="", value=0.0, slider_bind_func=None): Frame.__init__(self, parent) self.main_bg = parent['bg'] self.config(bg=self.main_bg) self.slider_events = ["<ButtonRelease-1>", "<ButtonRelease-3>"] self.label = Label(self, text=text) self.label.grid(row=0, column=0, padx=5, pady=3, sticky='s') self.slider = Scale(self, from_=1, to=0, orient=VERTICAL, resolution=0.01, length=200, width=18) self.slider.grid(row=1, column=0, padx=5, pady=5, sticky='n') if slider_bind_func is not None: for event in self.slider_events: self.slider.bind(event, slider_bind_func) self.slider.set(value) self.label.config(bg=self.slider['bg']) def get(self): return self.slider.get()
class TkLightSensor(TkDevice): def __init__(self, root, x, y, name, pin): super().__init__(root, x, y, name) self._pin = Device.pin_factory.pin(pin, pin_class=PreciseMockChargingPin) self._scale = Scale(root, from_=0, to=90, showvalue=0, orient=VERTICAL, command=self._scale_changed, sliderlength=20, length=150, highlightthickness=0, background="white") self._scale.place(x=x + 90, y=y) self._scale.set(30) self._scale_changed(self._scale.get()) self._set_image_for_state("light_sensor.png", "normal", (75, 150)) self._create_main_widget(Label, "normal") def _scale_changed(self, value): self._pin.charge_time = float(value) / 10000
def __init__( self, parent, data, stepname, statement, number_labels="(1=Strongly Disagree, 2=Disagree, 3=Neutral, 4=Agree, 5=Strongly Agree)" ): super().__init__(parent, data, stepname) self.statement = statement lbl1 = Label(self, text=self.statement) lbl1.pack(side="top", fill="x") lbl2 = Label(self, text=number_labels) lbl2.pack() likertscale = Scale(self, from_=1, to=5, length=200, tickinterval=1, orient=HORIZONTAL, command=self.updateValue) likertscale.set(3) likertscale.pack() self.data[self.stepname]["statement"] = self.statement self.data[self.stepname]["likert_score"] = likertscale.get()
class MainDisplay: def __init__(self, master): self.master = master master.title("Plastic Classifier") self.path = os.path.dirname(os.path.abspath(__file__)) + '/object-detection.jpg' img = Image.open(self.path) img = img.resize((1280,720)) photo = ImageTk.PhotoImage(img) self.image = Label(master, image=photo) self.image.image = photo self.image.pack(side="top") self.confidenceSlider = Scale(master, from_=0, to=1, orient=HORIZONTAL, tickinterval=0.1, resolution=0.01, length=580, label='Confidence') self.confidenceSlider.set(0.5) self.confidenceSlider.pack(side='left') self.nonMaximaSlider = Scale(master, from_=0, to=1, orient=HORIZONTAL, tickinterval=0.1, resolution=0.01, length=580, label='NMS') self.nonMaximaSlider.set(0.3) self.nonMaximaSlider.pack(side='right') self.changePic = Button(master, text="Change Picture", command=self.changePhoto) self.changePic.pack(side="top", pady=5, fill=X, padx=5) self.updatePic = Button(master, text="Update", command=self.updatePhoto) self.updatePic.pack(side="top", pady=5, fill=X, padx=5) def changePhoto(self): self.path = filedialog.askopenfilename(initialdir=os.path.dirname(os.path.abspath(__file__)), title="Select Photo", filetypes = (('jpeg files','*.jpg'),('all files','*.*'))) img = Image.open(self.path) img = img.resize((1280,720)) photo = ImageTk.PhotoImage(img) self.image.configure(image=photo) self.image.image = photo if debug == True: print("updated") def updatePhoto(self): path = self.path confidence = self.confidenceSlider.get() nms = self.nonMaximaSlider.get() predictor = plasticClassifier(confidence, nms, path) predictor.label_image() path = "object-detection.jpg" img = Image.open(path) img = img.resize((1280,720)) photo = ImageTk.PhotoImage(img) self.image.configure(image=photo) self.image.image = photo if debug == True: print('Image predicted')
def Ventana1Temp (ventana): """ Ventana en la que el usuario elige la orientación de los spines y la temperatura específica con la que realizar la simulación. Parámetros de la función: ------------------------ ventana: Variable que cierra una ventana ya abierta. Salida de la función --------------------- Interfaz gráfica con la que el usuario define los parámetros de la simulación. """ # Función para cerrar una ventana definida. ventana.destroy () # Parametros iniciales para la ventana gráfica. ventana1 = Tk () ventana1.minsize (800, 750) ventana1.config (bg='White') # Etiquetas que indican al usuario lo que debe seleccionar. etiqueta1 = Label (ventana1, text = ('Seleccione la temperatura ' "\n" r"a analizar" )) etiqueta1.config (bg = 'white', font = ('Verdana', 15)) etiqueta1.place (relx=0.5, rely=0.2, anchor=CENTER) etiqueta2 = Label (ventana1, text = ('Seleccione la orientación ' "\n" r"inicial de los Spines" )) etiqueta2.config (bg = 'white', font = ('Verdana', 15)) etiqueta2.place (relx=0.5, rely=0.45, anchor=CENTER) # Se define el slider para la temperatura con la que realizar los cálculos. barraTemp = Scale(ventana1, from_=0.1, to=5, tickinterval=4.9, length=400, bg = 'White', resolution=0.1, showvalue=True, orient='horizontal', label="Temperatura", cursor = "hand1") barraTemp.set(1) barraTemp.place (relx=0.5, rely=0.325, anchor=CENTER) # Obtiene los valores dados por el slider en la ventana. temperatura = barraTemp.get() # Se definen los diferentes botones. botonArriba = Button(ventana1, text='Hacia arriba', command = lambda: EjecutarUnaTemperatura(1, temperatura), cursor = 'hand1') botonArriba.place (relx=0.25, rely=0.575, anchor=CENTER) botonAbajo = Button(ventana1, text='Hacia abajo', command = lambda: EjecutarUnaTemperatura(-1, temperatura), cursor = 'hand1') botonAbajo.place (relx=0.5, rely=0.575, anchor=CENTER) botonAleatorio = Button(ventana1, text='Spines aleatorios', command = lambda: EjecutarUnaTemperatura(0, temperatura), cursor = 'hand1') botonAleatorio.place (relx=0.75, rely=0.575, anchor=CENTER) botonRegresar = Button(ventana1, text='Regresar', command = lambda: VentanaPrincipal(ventana1), cursor = 'hand1') botonRegresar.place (relx=0.775, rely=0.85, anchor=CENTER) # Se configura el título de la ventana y se ejecuta. ventana1.title ("Cálculo de R para un Sistema Estocástico con base a una sola temperatura") ventana1.mainloop()
class Slider(ScheduleMixin, DestroyMixin, EnableMixin, FocusMixin, DisplayMixin, ReprMixin): def __init__(self, master, start=0, end=100, horizontal=True, command=None, grid=None, align=None): # If you specify a command to the slider, it must take one argument as it will be given # the slider's current value # Description of this object (for friendly error messages) self.description = "[Slider] object from " + str(start) + " to " + str( end) # Set the direction orient = HORIZONTAL if horizontal else VERTICAL # Create a tk Scale object within this object self.tk = Scale(master.tk, from_=start, to=end, orient=orient, command=command) # Pack this object try: utils.auto_pack(self, master, grid, align) except AttributeError: utils.error_format( self.description + "\n" + "Could not add to interface - check first argument is [App] or [Box]" ) # PROPERTIES # ---------------- # Get/set the value @property def value(self): return (self.tk.get()) @value.setter def value(self, value): self.tk.set(value) # METHODS # ---------------- # Calls the given function when the slider value is changed def add_command(self, command): self.tk.config(command=command)
class View(Frame): def __init__(self, master, controller, label, width, minimum, maximum, current, *args, **kwargs): super(View, self).__init__(master, *args, **kwargs) self._controller = controller self._create_label(label, width) self._create_spinbox(minimum, maximum) self._create_scale(minimum, maximum) def w_label(self): return self._label def w_spinbox(self): return self._spinbox def w_scale(self): return self._scale def _create_label(self, label, width): self._label = LabelTtk(self, text=label) if width: self._label.config(width=width) self._label.pack(side='left', anchor='s') def _create_spinbox(self, minimum, maximum): self._spinbox = Spinbox(self, from_=minimum, to=maximum) self._spinbox['command'] = lambda: \ self._controller.set_current(int(self._spinbox.get())) self._spinbox.bind('<Return>', lambda e: \ self._controller.set_current(self._spinbox.get())) self._spinbox.pack(side="left", anchor="s") def _create_scale(self, minimum, maximum): self._scale = Scale(self, orient="horizontal", from_=minimum, to=maximum) self._scale['command'] = lambda e: \ self._controller.set_current(self._scale.get()) self._scale.pack(side="left", fill="x", expand=True, anchor="s")
def main(): window = Tk() # window.iconbitmap('Nik.ico') window.title('Селезнев Никита, ФИИТ-401') window.resizable(width=False, height=False) color1 = 'PaleGoldenrod' color2 = 'lightyellow' frame = Frame(window, bg=color1) frame.pack() Label(frame, text="Лабораторная работа №2.\n14 вариант.", justify=CENTER, font=("Helvetica", 12), bd=10, bg=color1).pack() Label(frame, text="""f(x) = y + Lx(1-x) + 2L + 2, L = 3.3,\ty0 = 0 Решение численными методами 1) Эйлера (явный) 2) Эйлера (с пересчётом) 3) Рунге-Кутта 4) Прогонка а также точное решение.""", justify=LEFT, font=("Helvetica", 12), bd=10, bg=color2).pack() Label(frame, text="\nВыберите количество точек:", justify=CENTER, font=("Helvetica", 12), bd=0, bg=color1).pack() w = Scale(frame, from_=5, to=500, resolution=1, length=300, bg=color1, borderwidth=0, relief=GROOVE, orient=HORIZONTAL, highlightthickness=0) w.pack() Label(frame, text='\n', bg=color1).pack() Button(frame, text="Нарисовать график", font=("Helvetica", 12), bg=color2, command=lambda: draw_all(int(w.get()))).pack() window.mainloop()
class Visual(Frame): '''Class that takes a world as argument and present it graphically on a tkinter canvas.''' def __init__(self): '''Sets up a simulation GUI in tkinter. ''' Frame.__init__(self) self.master.title("The Schelling Segregation Model in Python") self.master.wm_resizable(0, 0) self.grid() self.movement_possible = True # --------------------------------------- # # --------- FRAMES FOR GUI -------------- # # --------------------------------------- # # The pane for user values self._entryPane = Frame(self, borderwidth=5, relief='sunken') self._entryPane.grid(row=0, column=0, sticky='n') # The buttons pane self._buttonPane = Frame(self, borderwidth=5) self._buttonPane.grid(row=1, column=0, sticky='n') # A temp pane where graph is located, just for cosmetic reasons width, height = 425, 350 self._graph = Canvas(self, width=width, height=height, background="black") self._graph.configure(relief='sunken', border=2) self._graph.grid(row=3, column=0) # The pane where the canvas is located self._animationPane = Frame(self, borderwidth=5, relief='sunken') self._animationPane.grid(row=0, column=1, rowspan=4, pady=10, sticky="n") # --------------------------------------- # # --------- FILLING THE FRAMES ---------- # # --------------------------------------- # self._canvas() # Create graphics canvas self._entry() # Create entry widgets self._buttons() # Create button widgets def _plot_setup(self, time): '''Method for crudely annotating the graph window.''' time = time # Main plot width, height = 425, 350 y0 = -time / 10 self._graph = Canvas(self, width=width, height=height, background="black", borderwidth=5) self._graph.grid(row=3, column=0) self.trans = Plotcoords(width, height, y0, -0.2, time, 1.3) x, y = self.trans.screen(time // 2, 1.2) x1, y1 = self.trans.screen(time // 2, 1.13) self._graph.create_text(x, y, text="% Happy", fill="yellow", font="bold 12") self._graph.create_text(x1, y1, text="% Unhappy", fill="blue", font="bold 12") # Line x-axis x, y = self.trans.screen((-5 * (time / 100)), -0.05) x1, y = self.trans.screen(time, -0.05) self._graph.create_line(x, y, x1, y, fill="white", width=1.5) # Text x-axis x_text, y_text = self.trans.screen(time / 2, -0.15) self._graph.create_text(x_text, y_text, text="Time", fill="white", font="bold 12") # Liney-axis x, y = self.trans.screen((-0.5 * (time / 100)), -0.05) x, y1 = self.trans.screen((-5 * (time / 100)), 1) self._graph.create_line(x, y, x, y1, fill="white", width=1.5) def _entry(self): '''Method for creating widgets for collecting user input.''' # N (no of turtles) dim = 30 * 30 self._N_label = Label(self._entryPane, anchor='w', justify='left', text="N:", relief='raised', width=12, height=1, font="italic 20") self._N_label.grid(row=0, column=1, ipady=14) self._N = Scale(self._entryPane, from_=1, to=dim - 50, resolution=1, bd=3, relief='sunken', orient='horizontal', length=235, tickinterval=849) self._N.set(400) self._N.grid(row=0, column=2) # Ticks (lenght of simulation) self._Ticks_label = Label(self._entryPane, anchor='w', justify='left', text="Time:", relief='raised', width=12, height=1, font="bold 20") self._Ticks_label.grid(row=1, column=1, ipady=14) self._Ticks = Scale(self._entryPane, from_=10, to=1000, resolution=1, bd=3, relief='sunken', orient='horizontal', length=235, tickinterval=990) self._Ticks.set(500) self._Ticks.grid(row=1, column=2) # % similar wanted self._Similar_label = Label(self._entryPane, anchor='w', justify='left', text="Similar wanted:", relief='raised', width=12, height=1, font="bold 20") self._Similar_label.grid(row=2, column=1, ipady=14) self._Similar = Scale(self._entryPane, from_=0.0, to=1.0, resolution=0.01, bd=3, relief='sunken', orient='horizontal', length=235, tickinterval=1) self._Similar.set(0.76) self._Similar.grid(row=2, column=2) def _buttons(self): '''Method for creating button widgets for setting up, running and plotting results from simulation.''' width = 7 height = 1 # The 'Setup' button self._setupButton = Button(self._buttonPane, text="Setup", command=self._setup, width=width, height=height, font="bold 30", relief='raised', borderwidth=5) self._setupButton.grid(row=0, column=0) # The 'Go' button self._goButton = Button(self._buttonPane, text="Go", command=self._go, width=width, height=height, font="bold 30", relief='raised', borderwidth=5) self._goButton.grid(row=0, column=1) # The 'Quit' button self._quitButton = Button(self._buttonPane, text="Quit", command=self._quit, width=width, height=height, font="bold 30", relief='raised', borderwidth=5) self._quitButton.grid(row=1, column=0, columnspan=2) def _canvas(self): '''Creates the canvas on which everything happens.''' # The tick counter information self._Tick_counter = Label(self._animationPane, anchor='w', justify='left', text="Time:", width=5, font="bold 20") self._Tick_counter.grid(row=0, column=0, sticky="e") self._Tick_counter1 = Label(self._animationPane, justify='center', text="", relief='raised', width=5, font="bold 20") self._Tick_counter1.grid(row=0, column=1, sticky='w') self.canvas_w, self.canvas_h = 750, 750 self.canvas = Canvas(self._animationPane, width=self.canvas_w, height=self.canvas_h, background="black") self.canvas.grid(row=1, column=0, columnspan=2) def _setup(self): '''Method for 'Setup' button.''' ## Clearing the canvas and reset the go button self.canvas.delete('all') self._goButton['relief'] = 'raised' self.N = int(self._N.get()) self.Ticks = int(self._Ticks.get()) self.similar = float(self._Similar.get()) self.data = [] self.tick_counter = 0 self._Tick_counter1['text'] = str(self.tick_counter) self._plot_setup(self.Ticks) self.grid_size = 30 self.world = World(750, 750, self.grid_size) self.create_turtles() self.neighbouring_turtles() self.draw_turtles() def _go(self): '''Method for the 'Go' button, i.e. running the simulation.''' self._goButton['relief'] = 'sunken' if self.tick_counter <= self.Ticks: self._Tick_counter1['text'] = str(self.tick_counter) self.canvas.update() self._graph.update() self._graph.after(0) # Data collection turtles_unhappy = self.check_satisfaction() prop_happy, prop_unhappy = self.calc_prop_happy(self.tick_counter) self.data_collection(self.tick_counter, prop_happy, prop_unhappy) if self.tick_counter >= 1: # HAPPY values (%) x0 = self.tick_counter - 1 x1 = self.tick_counter # Collecting values from stoblue data y0 = self.data[self.tick_counter - 1][1] y1 = self.data[self.tick_counter][1] # Transforming to tkinter x1, y1 = self.trans.screen(x1, y1) x0, y0 = self.trans.screen(x0, y0) self._graph.create_line(x0, y0, x1, y1, fill="yellow", width=1.3, tag="happy") # Draw "happy lines # UNHAPPY values (%) x0 = self.tick_counter - 1 x1 = self.tick_counter # Collecting values from stored data y0 = self.data[self.tick_counter - 1][2] y1 = self.data[self.tick_counter][2] # Transforming to tkinter x1, y1 = self.trans.screen(x1, y1) x0, y0 = self.trans.screen(x0, y0) self._graph.create_line(x0, y0, x1, y1, fill="blue", width=1.1, tag="unhappy") # Draw unhappy lines if prop_happy < 1: self.turtle_move(turtles_unhappy) self.update_neighbours() self.tick_counter += 1 self.canvas.after(0, self._go()) self._goButton['relief'] = 'raised' def _quit(self): '''Method for the 'Quit' button.''' self.master.destroy() # ------------------------------------------------------ # # ---------- FUNCTIONS CALLED AT EACH TICK ------------- # # ------------------------------------------------------ # def turtle_move(self, unhappy_turtles): '''Moves all the unhappy turtles (randomly).''' while unhappy_turtles: i = random.randint(0, len(unhappy_turtles) - 1) turtle = unhappy_turtles.pop(i) turtle.move(self) def update_neighbours(self): '''Updates the turtles neigbour attributes. Called after all turtles have moved.''' for turtle in self.turtles: turtle.update_neighbours() def check_satisfaction(self): '''Checks to see if turtles are happy or not. Returns a list of unhappy turtles, i.e. turtles that should move. Called before the move method.''' for turtle in self.turtles: turtle.is_happy() unhappy_turtles = [] for element in self.turtles: if not element.happy: unhappy_turtles.append(element) return unhappy_turtles def calc_prop_happy(self, i): '''Calculates the proportion of happy turtles.''' happy = 0 unhappy = 0 for turtle in self.turtles: if turtle.happy: happy += 1 else: unhappy += 1 prop_happy = happy / len(self.turtles) prop_unhappy = unhappy / len(self.turtles) return prop_happy, prop_unhappy def data_collection(self, i, prop_happy, prop_unhappy): '''Method for collecting data at each tick.''' self.data.append((i, prop_happy, prop_unhappy)) # ------------------------------------------------------ # # ---------- INITIALISATION FUNCTIONS ------------------ # # ------------------------------------------------------ # def create_turtles(self): '''Method for creating a new list of turtles. Upon creation they are registered in the World object.''' if self.N <= self.grid_size * self.grid_size: counter = 0 self.turtles = [] while counter < self.N: s = "S" + str(counter) if counter <= int(self.N / 2): color = "yellow" else: color = "blue" x = random.randint(0, self.grid_size - 1) y = random.randint(0, self.grid_size - 1) if not self.world.patch_list[x][y]: new_turtle = Schelling(world=self.world, x=x, y=y, s=s, color=color, similar_wanted=self.similar) self.world.register(new_turtle) counter += 1 self.turtles.append(new_turtle) else: print("Number of turtles exceeds world!") def draw_turtles(self): '''Method for drawing turtles on canvas. Calls each turtle's own method for drawing.''' for turtle in self.turtles: turtle.draw(self.canvas) def neighbouring_turtles(self): '''Method for updating turtles' neighbours. Calls on each turtle's own method for updating neighbours.''' for turtle in self.turtles: turtle.get_neighbouring_patches()
class Simulator: def __init__(self): # MQTT Client self.client = mqtt.Client(client_id="simulator") self.client.connect("localhost", port=1883) # Window settings self.window = Tk() self.window.title(cnst.WINDOW_TITLE) self.window.geometry( str(cnst.WINDOW_WIDTH) + 'x' + str(cnst.WINDOW_HEIGHT)) # Temperature slider self.temp_lbl = Label(self.window, text="Temperature") self.temp_lbl.pack(anchor=CENTER) self.temp_var = DoubleVar(value=cnst.DEFAULT_TEMP) self.slider_temperature = Scale(self.window, variable=self.temp_var, from_=cnst.MIN_TEMP, to_=cnst.MAX_TEMP, resolution=-1, orient=HORIZONTAL) self.slider_temperature.pack(anchor=CENTER) # API Temperature slider self.api_temp_lbl = Label(self.window, text="API Temperature") self.api_temp_lbl.pack(anchor=CENTER) self.api_temp_var = DoubleVar(value=cnst.DEFAULT_TEMP) self.slider_api_temperature = Scale(self.window, variable=self.api_temp_var, from_=cnst.MIN_TEMP, to_=cnst.MAX_TEMP, resolution=-1, orient=HORIZONTAL) self.slider_api_temperature.pack(anchor=CENTER) # API Min temperature slider self.api_min_temp_lbl = Label(self.window, text="API Min Temperature") self.api_min_temp_lbl.pack(anchor=CENTER) self.api_min_temp_var = DoubleVar(value=cnst.DEFAULT_TEMP) self.slider_api_min_temperature = Scale(self.window, variable=self.api_min_temp_var, from_=cnst.MIN_TEMP, to_=cnst.MAX_TEMP, resolution=-1, orient=HORIZONTAL) self.slider_api_min_temperature.pack(anchor=CENTER) # API Max temperature slider self.api_max_temp_lbl = Label(self.window, text="API Max Temperature") self.api_max_temp_lbl.pack(anchor=CENTER) self.api_max_temp_var = DoubleVar(value=cnst.DEFAULT_TEMP) self.slider_api_max_temperature = Scale(self.window, variable=self.api_max_temp_var, from_=cnst.MIN_TEMP, to_=cnst.MAX_TEMP, resolution=-1, orient=HORIZONTAL) self.slider_api_max_temperature.pack(anchor=CENTER) # API Feels temperature slider self.api_feels_temp_lbl = Label(self.window, text="API Feels Temperature") self.api_feels_temp_lbl.pack(anchor=CENTER) self.api_feels_temp_var = DoubleVar(value=cnst.DEFAULT_TEMP) self.slider_api_feels_temperature = Scale( self.window, variable=self.api_feels_temp_var, from_=cnst.MIN_TEMP, to_=cnst.MAX_TEMP, resolution=-1, orient=HORIZONTAL) self.slider_api_feels_temperature.pack(anchor=CENTER) # API Humidity slider self.api_humidity_lbl = Label(self.window, text="API Humidity") self.api_humidity_lbl.pack(anchor=CENTER) self.api_humidity_var = DoubleVar(value=cnst.DEFAULT_HUMIDITY) self.slider_api_humidity = Scale(self.window, variable=self.api_humidity_var, from_=cnst.MIN_HUMIDITY, to_=cnst.MAX_HUMIDITY, resolution=-1, orient=HORIZONTAL) self.slider_api_humidity.pack(anchor=CENTER) # Luminosity slider self.luminosity_lbl = Label(self.window, text="Luminosity") self.luminosity_lbl.pack(anchor=CENTER) self.luminosity_var = DoubleVar(value=cnst.DEFAULT_LUMINOSITY) self.slider_luminosity = Scale(self.window, variable=self.luminosity_var, from_=cnst.MIN_LUMINOSITY, to_=cnst.MAX_LUMINOSITY, resolution=-1, orient=HORIZONTAL) self.slider_luminosity.pack(anchor=CENTER) # Humidity slider self.humidity_lbl = Label(self.window, text="Humidity") self.humidity_lbl.pack(anchor=CENTER) self.humidity_var = DoubleVar(value=cnst.DEFAULT_HUMIDITY) self.slider_humidity = Scale(self.window, variable=self.humidity_var, from_=cnst.MIN_HUMIDITY, to_=cnst.MAX_HUMIDITY, resolution=-1, orient=HORIZONTAL) self.slider_humidity.pack(anchor=CENTER) # Noise slider self.noise_lbl = Label(self.window, text="Noise") self.noise_lbl.pack(anchor=CENTER) self.noise_var = DoubleVar(value=cnst.DEFAULT_NOISE) self.slider_noise = Scale(self.window, variable=self.noise_var, from_=cnst.MIN_NOISE, to_=cnst.MAX_NOISE, resolution=-1, orient=HORIZONTAL) self.slider_noise.pack(anchor=CENTER) # Air Quality slider self.airquality_lbl = Label(self.window, text="AirQuality") self.airquality_lbl.pack(anchor=CENTER) self.airquality_var = DoubleVar(value=cnst.DEFAULT_AIRQUALITY) self.slider_airquality = Scale(self.window, variable=self.airquality_var, from_=cnst.MIN_AIRQUALITY, to_=cnst.MAX_AIRQUALITY, resolution=-1, orient=HORIZONTAL) self.slider_airquality.pack(anchor=CENTER) # Button to publish the data self.submit_btn = Button(self.window, text="Simulate", command=self.publish) self.submit_btn.pack(anchor=CENTER) def publish(self): self.client.publish(topic="temperature", payload=self.slider_temperature.get(), qos=1) self.client.publish(topic="weather_temp", payload=self.slider_api_temperature.get(), qos=1) self.client.publish(topic="weather_temp_min", payload=self.slider_api_min_temperature.get(), qos=1) self.client.publish(topic="weather_temp_max", payload=self.slider_api_max_temperature.get(), qos=1) self.client.publish(topic="weather_temp_feels", payload=self.slider_api_feels_temperature.get(), qos=1) self.client.publish(topic="weather_humidity", payload=self.slider_api_humidity.get(), qos=1) self.client.publish(topic="luminosity", payload=self.slider_luminosity.get(), qos=1) self.client.publish(topic="humidity", payload=self.slider_humidity.get(), qos=1) self.client.publish(topic="noise", payload=self.slider_noise.get(), qos=1) self.client.publish(topic="airquality", payload=self.slider_airquality.get(), qos=1) self.client.loop() def loop(self): self.window.mainloop()
slider_frame.grid(row=2, column=1) gain_label = Label(slider_frame, text='gain', font=('monospace')) gain_label.grid(row=1, column=0) reverb_label = Label(slider_frame, text='reverb', font=('monospace')) reverb_label.grid(row=1, column=1) chorus_label = Label(slider_frame, text='chorus', font=('monospace')) chorus_label.grid(row=1, column=2) #gain slider gain_slider = Scale(slider_frame, from_=10, to=0, width=50, length=250, command=lambda x: gain_command_change( gain_slider.get(), client_connection)) gain_slider.set(2) gain_slider.grid(row=0, column=0) #reverb slider rev_slider = Scale( slider_frame, from_=30, to=0, width=50, length=250, command=lambda x: rev_slider_change(rev_slider.get(), client_connection)) rev_slider.set(0) rev_slider.grid(row=0, column=1) chorus_slider = Scale(slider_frame,
class OfflineVisualiser(Visualiser): """A VTK-powered offline visualiser which runs in its own thread. In addition to the functions provided by the standard visualiser, the following additional functions are provided: precache_height_quantities() - Precache all the vtkpoints structures for any dynamic height based quantities to render. """ def __init__(self, source, frameDelay=100, frameStep=1): """The source parameter is assumed to be a NetCDF sww file. The frameDelay parameter is the number of milliseconds waited between frames. """ Visualiser.__init__(self, source) self.frameNumber = 0 fin = NetCDFFile(self.source, 'r') self.maxFrameNumber = fin.variables['time'].shape[0] - 1 fin.close() #self.frameNumberTkVariable = StringVar() #self.frameNumberTkVariable.set('Frame - %05g'%self.framNumber) self.frameDelay = frameDelay self.xmin = None self.xmax = None self.ymin = None self.ymax = None self.zmin = None self.zmax = None self.frameStep = frameStep self.vtk_heightQuantityCache = [] for i in range(self.maxFrameNumber + 1): # maxFrameNumber is zero indexed. self.vtk_heightQuantityCache.append({}) self.paused = False self.movie = False def setup_grid(self): fin = NetCDFFile(self.source, 'r') self.vtk_cells = vtkCellArray() N_tri = fin.variables['volumes'].shape[0] for v in range(N_tri): self.vtk_cells.InsertNextCell(3) for i in range(3): self.vtk_cells.InsertCellPoint(fin.variables['volumes'][v][i]) fin.close() def update_height_quantity(self, quantityName, dynamic=True): polydata = self.vtk_polyData[quantityName] = vtkPolyData() if dynamic is True: #print ' - Frame',self.frameNumber,'of',self.maxFrameNumber if quantityName not in self.vtk_heightQuantityCache[ self.frameNumber]: self.vtk_heightQuantityCache[self.frameNumber][quantityName]\ = self.read_height_quantity(quantityName, True, self.frameNumber) polydata.SetPoints( self.vtk_heightQuantityCache[self.frameNumber][quantityName]) else: polydata.SetPoints(self.read_height_quantity(quantityName, False)) polydata.SetPolys(self.vtk_cells) def get_3d_bounds(self): return [ self.xmin, self.xmax, self.ymin, self.ymax, self.zmin, self.zmax ] def read_height_quantity(self, quantityName, dynamic=True, frameNumber=0): """Read in a height based quantity from the NetCDF source file and return a vtkPoints object. frameNumber is ignored if dynamic is false.""" fin = NetCDFFile(self.source, 'r') points = vtkPoints() if dynamic is True: N_vert = fin.variables[quantityName].shape[1] else: N_vert = len(fin.variables[quantityName]) x = num.ravel(num.array(fin.variables['x'], num.float)) y = num.ravel(num.array(fin.variables['y'], num.float)) if dynamic is True: q = num.array(fin.variables[quantityName][frameNumber], num.float) else: q = num.ravel(num.array(fin.variables[quantityName], num.float)) q *= self.height_zScales[quantityName] q += self.height_offset[quantityName] for v in range(N_vert): points.InsertNextPoint(x[v], y[v], q[v]) if self.xmin is None or self.xmin > x[v]: self.xmin = x[v] if self.xmax is None or self.xmax < x[v]: self.xmax = x[v] if self.ymin is None or self.ymin > y[v]: self.ymin = y[v] if self.ymax is None or self.ymax < y[v]: self.ymax = y[v] if self.zmin is None or self.zmin > q[v]: self.zmin = q[v] if self.zmax is None or self.zmax < q[v]: self.zmax = q[v] fin.close() return points def precache_height_quantities(self): """Precache any height-based quantities. Call before rendering beigns.""" for q in self.height_quantities: if self.height_dynamic[q] is True: print('Precaching %s' % q) for i in range(self.maxFrameNumber + 1): # maxFrameNumber is zero-indexed print(' - Frame %d of %d' % (i, self.maxFrameNumber)) self.vtk_heightQuantityCache[i][q]\ = self.read_height_quantity(q, True, i) def build_quantity_dict(self): quantities = {} fin = NetCDFFile(self.source, 'r') for q in [ n for n in list(fin.variables.keys()) if n != 'x' and n != 'y' and n != 'z' and n != 'time' and n != 'volumes' ]: if len(fin.variables[q].shape) == 1: # Not a time-varying quantity quantities[q] = num.ravel( num.array(fin.variables[q], num.float)) else: # Time-varying, get the current timestep data quantities[q] = num.array(fin.variables[q][self.frameNumber], num.float) fin.close() return quantities def setup_gui(self): Visualiser.setup_gui(self) self.tk_quit.grid(row=0, column=0, sticky=W + E) self.tk_movie_toggle = Button(self.tk_controlFrame, text="Movie off", command=self.movie_toggle) self.tk_movie_toggle.grid(row=0, column=6, sticky=W + E) self.tk_restart = Button(self.tk_controlFrame, text="<<<", command=self.restart, width=5) self.tk_restart.grid(row=1, column=0, sticky=W + E) self.tk_back10 = Button(self.tk_controlFrame, text="<<", command=self.back10, width=5) self.tk_back10.grid(row=1, column=1, sticky=W + E) self.tk_back = Button(self.tk_controlFrame, text="<", command=self.back, width=5) self.tk_back.grid(row=1, column=2, sticky=W + E) self.tk_pauseResume = Button(self.tk_controlFrame, text="Pause", command=self.pauseResume, width=15) self.tk_pauseResume.grid(row=1, column=3, sticky=W + E) self.tk_forward = Button(self.tk_controlFrame, text=">", command=self.forward, width=5) self.tk_forward.grid(row=1, column=4, sticky=W + E) self.tk_forward10 = Button(self.tk_controlFrame, text=">>", command=self.forward10, width=5) self.tk_forward10.grid(row=1, column=5, sticky=W + E) self.tk_forwardEnd = Button(self.tk_controlFrame, text=">>>", command=self.forwardEnd, width=5) self.tk_forwardEnd.grid(row=1, column=6, sticky=W + E) self.tk_frameNumber = Label(self.tk_controlFrame, text='Frame') self.tk_frameNumber.grid(row=2, column=0, sticky=W + E) self.tk_gotoFrame = Scale(self.tk_controlFrame, from_=0, to=self.maxFrameNumber, orient=HORIZONTAL) self.tk_gotoFrame.grid(row=2, column=1, columnspan=2, sticky=W + E) self.tk_stepLabel = Label(self.tk_controlFrame, text='Step') self.tk_stepLabel.grid(row=2, column=4, sticky=W + E) self.tk_frameStep = Scale(self.tk_controlFrame, from_=0, to=self.maxFrameNumber, orient=HORIZONTAL) self.tk_frameStep.grid(row=2, column=5, columnspan=2, sticky=W + E) # Make the buttons stretch to fill all available space for i in range(7): self.tk_controlFrame.grid_columnconfigure(i, weight=1) def run(self): self.alter_tkroot(Tk.after, (self.frameDelay, self.animateForward)) Visualiser.run(self) def restart(self): self.frameNumber = 0 self.redraw_quantities() self.update_labels() self.pause() if self.movie: self.save_image() def forwardEnd(self): self.frameNumber = self.maxFrameNumber self.redraw_quantities() self.update_labels() self.pause() def movie_toggle(self): if self.movie == True: self.movie = False self.tk_movie_toggle.config(text='Movie off') else: self.movie = True self.tk_movie_toggle.config(text='Movie on ') def save_image(self): from vtk import vtkJPEGWriter, vtkJPEGWriter, vtkPNGWriter from vtk import vtkPNMWriter, vtkWindowToImageFilter from os import path sourcebase, _ = path.splitext(self.source) fname = sourcebase + '%05g.png' % self.frameNumber #print fname extmap = { '.jpg': vtkJPEGWriter, '.jpeg': vtkJPEGWriter, '.png': vtkPNGWriter, '.pnm': vtkPNMWriter, } basename, ext = path.splitext(fname) try: Writer = extmap[ext.lower()] except KeyError: error_msg("Don't know how to handle %s files" % ext, parent=self) return renWin = self.vtk_renderer.GetRenderWindow() w2i = vtkWindowToImageFilter() writer = Writer() w2i.SetInput(renWin) w2i.Update() writer.SetInput(w2i.GetOutput()) writer.SetFileName(fname) renWin.Render() writer.Write() def back10(self): if self.frameNumber - 10 >= 0: self.frameNumber -= 10 else: self.frameNumber = 0 self.redraw_quantities() self.update_labels() self.pause() def back(self): if self.frameNumber > 0: self.frameNumber -= 1 self.redraw_quantities() self.update_labels() self.pause() def pauseResume(self): if self.paused is True: self.resume() else: self.pause() def pause(self): self.paused = True self.tk_pauseResume.config(text="Resume") def resume(self): self.paused = False self.tk_pauseResume.config(text="Pause") self.frameNumber = self.tk_gotoFrame.get() self.frameStep = self.tk_frameStep.get() self.tk_root.after(self.frameDelay, self.animateForward) def forward(self): if self.frameNumber < self.maxFrameNumber: self.frameNumber += 1 self.redraw_quantities() self.update_labels() self.pause() def forward_step(self): if self.frameNumber + self.frameStep <= self.maxFrameNumber: self.frameNumber += self.frameStep self.redraw_quantities() self.update_labels() else: self.frameNumber = self.maxFrameNumber self.redraw_quantities() self.update_labels() self.pause() if self.movie: self.save_image() def forward10(self): if self.frameNumber + 10 <= self.maxFrameNumber: self.frameNumber += 10 else: self.frameNumber = self.maxFrameNumber self.redraw_quantities() self.update_labels() self.pause() def animateForward(self): if self.paused is not True: self.forward_step() self.tk_root.after(self.frameDelay, self.animateForward) def update_labels(self): #self.tk_frameNumber.config(text='%05g of %05g'%(self.frameNumber,self.maxFrameNumber)) self.tk_gotoFrame.set(self.frameNumber) self.tk_frameStep.set(self.frameStep) def shutdown(self): #self.pause() self.tk_root.withdraw() self.tk_root.destroy()
class TelloUI(object): """ Wrapper class to enable the GUI. """ def __init__(self, tello): """ Initializes all the element of the GUI, supported by Tkinter :param tello: class interacts with the Tello drone. """ self.tello = tello # videostream device self.thread = None # thread of the Tkinter mainloop self.stopEvent = None # control variables self.distance = 0.1 # default distance for 'move' cmd self.degree = 30 # default degree for 'cw' or 'ccw' cmd # if the flag is TRUE,the auto-takeoff thread will stop waiting # for the response from tello self.quit_waiting_flag = False # initialize the root window and image panel self.root = tki.Tk() self.panel = None # create buttons self.btn_landing = tki.Button(self.root, text='Open Command Panel', relief='raised', command=self.openCmdWindow) self.btn_landing.pack(side='bottom', fill='both', expand='yes', padx=10, pady=5) # start a thread that constantly pools the video sensor for # the most recently read frame self.stopEvent = threading.Event() # set a callback to handle when the window is closed self.root.wm_title('TELLO Controller') self.root.wm_protocol('WM_DELETE_WINDOW', self.on_close) # the sending_command will send command to tello every 5 seconds self.sending_command_thread = threading.Thread( target=self._sendingCommand) def _sendingCommand(self): """ Starts a while loop that sends 'command' to tello every 5 second. :return: None """ while True: self.tello.send_command('command') time.sleep(5) def _setQuitWaitingFlag(self): """ Set the variable as TRUE; it will stop computer waiting for response from tello. :return: None """ self.quit_waiting_flag = True def openCmdWindow(self): """ Open the cmd window and initial all the button and text. :return: None """ panel = Toplevel(self.root) panel.wm_title('Command Panel') # create text input entry text0 = tki.Label( panel, text= 'This Controller map keyboard inputs to Tello control commands\n' 'Adjust the trackbar to reset distance and degree parameter', font='Helvetica 10 bold') text0.pack(side='top') text1 = tki.Label( panel, text='W - Move Tello Up\t\t\tArrow Up - Move Tello Forward\n' 'S - Move Tello Down\t\t\tArrow Down - Move Tello Backward\n' 'A - Rotate Tello Counter-Clockwise\tArrow Left - Move Tello Left\n' 'D - Rotate Tello Clockwise\t\tArrow Right - Move Tello Right', justify='left') text1.pack(side='top') self.btn_landing = tki.Button(panel, text='Land', relief='raised', command=self.telloLanding) self.btn_landing.pack(side='bottom', fill='both', expand='yes', padx=10, pady=5) self.btn_takeoff = tki.Button(panel, text='Takeoff', relief='raised', command=self.telloTakeOff) self.btn_takeoff.pack(side='bottom', fill='both', expand='yes', padx=10, pady=5) # binding arrow keys to drone control self.tmp_f = tki.Frame(panel, width=100, height=2) self.tmp_f.bind('<KeyPress-w>', self.on_keypress_w) self.tmp_f.bind('<KeyPress-s>', self.on_keypress_s) self.tmp_f.bind('<KeyPress-a>', self.on_keypress_a) self.tmp_f.bind('<KeyPress-d>', self.on_keypress_d) self.tmp_f.bind('<KeyPress-Up>', self.on_keypress_up) self.tmp_f.bind('<KeyPress-Down>', self.on_keypress_down) self.tmp_f.bind('<KeyPress-Left>', self.on_keypress_left) self.tmp_f.bind('<KeyPress-Right>', self.on_keypress_right) self.tmp_f.pack(side='bottom') self.tmp_f.focus_set() self.btn_landing = tki.Button(panel, text='Flip', relief='raised', command=self.openFlipWindow) self.btn_landing.pack(side='bottom', fill='both', expand='yes', padx=10, pady=5) self.distance_bar = Scale(panel, from_=0.02, to=5, tickinterval=0.01, digits=3, label='Distance(m)', resolution=0.01) self.distance_bar.set(0.2) self.distance_bar.pack(side='left') self.btn_distance = tki.Button( panel, text='Reset Distance', relief='raised', command=self.updateDistancebar, ) self.btn_distance.pack(side='left', fill='both', expand='yes', padx=10, pady=5) self.degree_bar = Scale(panel, from_=1, to=360, tickinterval=10, label='Degree') self.degree_bar.set(30) self.degree_bar.pack(side='right') self.btn_distance = tki.Button(panel, text='Reset Degree', relief='raised', command=self.updateDegreebar) self.btn_distance.pack(side='right', fill='both', expand='yes', padx=10, pady=5) def openFlipWindow(self): """ Open the flip window and initial all the button and text. :return: None """ panel = Toplevel(self.root) panel.wm_title('Gesture Recognition') self.btn_flipl = tki.Button(panel, text='Flip Left', relief='raised', command=self.telloFlip_l) self.btn_flipl.pack(side='bottom', fill='both', expand='yes', padx=10, pady=5) self.btn_flipr = tki.Button(panel, text='Flip Right', relief='raised', command=self.telloFlip_r) self.btn_flipr.pack(side='bottom', fill='both', expand='yes', padx=10, pady=5) self.btn_flipf = tki.Button(panel, text='Flip Forward', relief='raised', command=self.telloFlip_f) self.btn_flipf.pack(side='bottom', fill='both', expand='yes', padx=10, pady=5) self.btn_flipb = tki.Button(panel, text='Flip Backward', relief='raised', command=self.telloFlip_b) self.btn_flipb.pack(side='bottom', fill='both', expand='yes', padx=10, pady=5) def telloTakeOff(self): return self.tello.takeoff() def telloLanding(self): return self.tello.land() def telloFlip_l(self): return self.tello.flip('l') def telloFlip_r(self): return self.tello.flip('r') def telloFlip_f(self): return self.tello.flip('f') def telloFlip_b(self): return self.tello.flip('b') def telloCW(self, degree): return self.tello.rotate_cw(degree) def telloCCW(self, degree): return self.tello.rotate_ccw(degree) def telloMoveForward(self, distance): return self.tello.move_forward(distance) def telloMoveBackward(self, distance): return self.tello.move_backward(distance) def telloMoveLeft(self, distance): return self.tello.move_left(distance) def telloMoveRight(self, distance): return self.tello.move_right(distance) def telloUp(self, dist): return self.tello.move_up(dist) def telloDown(self, dist): return self.tello.move_down(dist) def updateDistancebar(self): self.distance = self.distance_bar.get() print(f'reset distance to {self.distance:.1f}') def updateDegreebar(self): self.degree = self.degree_bar.get() print(f'reset distance to {self.degree}') def on_keypress_w(self, event): print(f'up {self.distance} m') self.telloUp(self.distance) def on_keypress_s(self, event): print(f'down {self.distance} m') self.telloDown(self.distance) def on_keypress_a(self, event): print(f'ccw {self.degree} degree') self.tello.rotate_ccw(self.degree) def on_keypress_d(self, event): print(f'cw {self.degree} m') self.tello.rotate_cw(self.degree) def on_keypress_up(self, event): print(f'forward {self.distance} m') self.telloMoveForward(self.distance) def on_keypress_down(self, event): print(f'backward {self.distance} m') self.telloMoveBackward(self.distance) def on_keypress_left(self, event): print(f'left {self.distance} m') self.telloMoveLeft(self.distance) def on_keypress_right(self, event): print(f'right {self.distance} m') self.telloMoveRight(self.distance) def on_close(self): """ Sets the stop event, cleanup the camera, and allow the rest of the quit process to continue. :return: None """ print('[INFO] closing...') self.stopEvent.set() del self.tello self.root.quit()
class Slider(WidgetMixin, ScheduleMixin, DestroyMixin, EnableMixin, FocusMixin, DisplayMixin, ColorMixin, ReprMixin): def __init__(self, master, start=0, end=100, horizontal=True, command=None, grid=None, align=None): # If you specify a command to the slider, it must take one argument as it will be given # the slider's current value self._master = master self._grid = grid self._align = align self._visible = True # Description of this object (for friendly error messages) self.description = "[Slider] object from " + str(start) + " to " + str( end) # Set the direction orient = HORIZONTAL if horizontal else VERTICAL # Create a tk Scale object within this object self.tk = Scale(master.tk, from_=start, to=end, orient=orient, command=self._command_callback) self.update_command(command) # Pack this object try: utils.auto_pack(self, master, grid, align) except AttributeError: utils.error_format( self.description + "\n" + "Could not add to interface - check first argument is [App] or [Box]" ) # PROPERTIES # ---------------- # Get/set the value @property def value(self): return (self.tk.get()) @value.setter def value(self, value): self.tk.set(value) # METHODS # ---------------- # Calls the given function when the slider value is changed def _command_callback(self, value): if self._command: args_expected = utils.no_args_expected(self._command) if args_expected == 0: self._command() elif args_expected == 1: self._command(value) else: utils.error_format( "Slider command function must accept either 0 or 1 arguments.\nThe current command has {} arguments." .format(args_expected)) def update_command(self, command): if command is None: self._command = lambda: None else: self._command = command # DEPRECATED # ------------------------------------------- def add_command(self, command): self.update_command(command) utils.deprecated( "Slider add_command() is deprecated - renamed to update_command()")
class TelloUI: """Wrapper class to enable the GUI.""" def __init__(self, tello, outputpath): """ Initial all the element of the GUI,support by Tkinter :param tello: class interacts with the Tello drone. Raises: RuntimeError: If the Tello rejects the attempt to enter command mode. """ self.tello = tello # videostream device self.outputPath = outputpath # the path that save pictures created by clicking the takeSnapshot button self.frame = None # frame read from h264decoder and used for pose recognition self.thread = None # thread of the Tkinter mainloop self.stopEvent = None # control variables self.distance = 0.1 # default distance for 'move' cmd self.degree = 30 # default degree for 'cw' or 'ccw' cmd # if the flag is TRUE,the auto-takeoff thread will stop waiting for the response from tello self.quit_waiting_flag = False # initialize the root window and image panel self.root = tki.Tk() self.panel = None # create buttons self.btn_snapshot = tki.Button(self.root, text="Snapshot!", command=self.takeSnapshot) self.btn_snapshot.pack(side="bottom", fill="both", expand="yes", padx=10, pady=5) self.btn_pause = tki.Button(self.root, text="Pause", relief="raised", command=self.pauseVideo) self.btn_pause.pack(side="bottom", fill="both", expand="yes", padx=10, pady=5) self.btn_landing = tki.Button(self.root, text="Open Command Panel", relief="raised", command=self.openCmdWindow) self.btn_landing.pack(side="bottom", fill="both", expand="yes", padx=10, pady=5) # start a thread that constantly pools the video sensor for # the most recently read frame self.stopEvent = threading.Event() self.thread = threading.Thread(target=self.videoLoop, args=()) self.thread.start() # set a callback to handle when the window is closed self.root.wm_title("TELLO Controller") self.root.wm_protocol("WM_DELETE_WINDOW", self.onClose) # the sending_command will send command to tello every 5 seconds self.sending_command_thread = threading.Thread( target=self._sendingCommand) def videoLoop(self): """ The mainloop thread of Tkinter Raises: RuntimeError: To get around a RunTime error that Tkinter throws due to threading. """ try: # start the thread that get GUI image and drwa skeleton time.sleep(0.5) self.sending_command_thread.start() while not self.stopEvent.is_set(): system = platform.system() # read the frame for GUI show self.frame = self.tello.read() if self.frame is None or self.frame.size == 0: continue # transfer the format from frame to image image = Image.fromarray(self.frame) # we found compatibility problem between Tkinter,PIL and Macos,and it will # sometimes result the very long preriod of the "ImageTk.PhotoImage" function, # so for Macos,we start a new thread to execute the _updateGUIImage function. if system == "Windows" or system == "Linux": self._updateGUIImage(image) else: thread_tmp = threading.Thread(target=self._updateGUIImage, args=(image, )) thread_tmp.start() time.sleep(0.03) except RuntimeError as e: print("[INFO] caught a RuntimeError") def _updateGUIImage(self, image): """ Main operation to initial the object of image,and update the GUI panel """ image = ImageTk.PhotoImage(image) # if the panel none ,we need to initial it if self.panel is None: self.panel = tki.Label(image=image) self.panel.image = image self.panel.pack(side="left", padx=10, pady=10) # otherwise, simply update the panel else: self.panel.configure(image=image) self.panel.image = image def _sendingCommand(self): """ start a while loop that sends 'command' to tello every 5 second """ while True: self.tello.send_command('command') time.sleep(5) def _setQuitWaitingFlag(self): """ set the variable as TRUE,it will stop computer waiting for response from tello """ self.quit_waiting_flag = True def openCmdWindow(self): """ open the cmd window and initial all the button and text """ panel = Toplevel(self.root) panel.wm_title("Command Panel") # create text input entry text0 = tki.Label( panel, text= 'This Controller map keyboard inputs to Tello control commands\n' 'Adjust the trackbar to reset distance and degree parameter', font='Helvetica 10 bold') text0.pack(side='top') text1 = tki.Label( panel, text='W - Move Tello Up\t\t\tArrow Up - Move Tello Forward\n' 'S - Move Tello Down\t\t\tArrow Down - Move Tello Backward\n' 'A - Rotate Tello Counter-Clockwise\tArrow Left - Move Tello Left\n' 'D - Rotate Tello Clockwise\t\tArrow Right - Move Tello Right', justify="left") text1.pack(side="top") self.btn_landing = tki.Button(panel, text="Land", relief="raised", command=self.telloLanding) self.btn_landing.pack(side="bottom", fill="both", expand="yes", padx=10, pady=5) self.btn_takeoff = tki.Button(panel, text="Takeoff", relief="raised", command=self.telloTakeOff) self.btn_takeoff.pack(side="bottom", fill="both", expand="yes", padx=10, pady=5) # binding arrow keys to drone control self.tmp_f = tki.Frame(panel, width=100, height=2) self.tmp_f.bind('<KeyPress-w>', self.on_keypress_w) self.tmp_f.bind('<KeyPress-s>', self.on_keypress_s) self.tmp_f.bind('<KeyPress-a>', self.on_keypress_a) self.tmp_f.bind('<KeyPress-d>', self.on_keypress_d) self.tmp_f.bind('<KeyPress-Up>', self.on_keypress_up) self.tmp_f.bind('<KeyPress-Down>', self.on_keypress_down) self.tmp_f.bind('<KeyPress-Left>', self.on_keypress_left) self.tmp_f.bind('<KeyPress-Right>', self.on_keypress_right) self.tmp_f.pack(side="bottom") self.tmp_f.focus_set() self.btn_landing = tki.Button(panel, text="Flip", relief="raised", command=self.openFlipWindow) self.btn_landing.pack(side="bottom", fill="both", expand="yes", padx=10, pady=5) self.distance_bar = Scale(panel, from_=0.02, to=5, tickinterval=0.01, digits=3, label='Distance(m)', resolution=0.01) self.distance_bar.set(0.2) self.distance_bar.pack(side="left") self.btn_distance = tki.Button( panel, text="Reset Distance", relief="raised", command=self.updateDistancebar, ) self.btn_distance.pack(side="left", fill="both", expand="yes", padx=10, pady=5) self.degree_bar = Scale(panel, from_=1, to=360, tickinterval=10, label='Degree') self.degree_bar.set(30) self.degree_bar.pack(side="right") self.btn_distance = tki.Button(panel, text="Reset Degree", relief="raised", command=self.updateDegreebar) self.btn_distance.pack(side="right", fill="both", expand="yes", padx=10, pady=5) def openFlipWindow(self): """ open the flip window and initial all the button and text """ panel = Toplevel(self.root) panel.wm_title("Gesture Recognition") self.btn_flipl = tki.Button(panel, text="Flip Left", relief="raised", command=self.telloFlip_l) self.btn_flipl.pack(side="bottom", fill="both", expand="yes", padx=10, pady=5) self.btn_flipr = tki.Button(panel, text="Flip Right", relief="raised", command=self.telloFlip_r) self.btn_flipr.pack(side="bottom", fill="both", expand="yes", padx=10, pady=5) self.btn_flipf = tki.Button(panel, text="Flip Forward", relief="raised", command=self.telloFlip_f) self.btn_flipf.pack(side="bottom", fill="both", expand="yes", padx=10, pady=5) self.btn_flipb = tki.Button(panel, text="Flip Backward", relief="raised", command=self.telloFlip_b) self.btn_flipb.pack(side="bottom", fill="both", expand="yes", padx=10, pady=5) def takeSnapshot(self): """ save the current frame of the video as a jpg file and put it into outputpath """ # grab the current timestamp and use it to construct the filename ts = datetime.datetime.now() filename = "{}.jpg".format(ts.strftime("%Y-%m-%d_%H-%M-%S")) p = os.path.sep.join((self.outputPath, filename)) # save the file cv2.imwrite(p, cv2.cvtColor(self.frame, cv2.COLOR_RGB2BGR)) print("[INFO] saved {}".format(filename)) def pauseVideo(self): """ Toggle the freeze/unfreze of video """ if self.btn_pause.config('relief')[-1] == 'sunken': self.btn_pause.config(relief="raised") self.tello.video_freeze(False) else: self.btn_pause.config(relief="sunken") self.tello.video_freeze(True) def telloTakeOff(self): return self.tello.takeoff() def telloLanding(self): return self.tello.land() def telloFlip_l(self): return self.tello.flip('l') def telloFlip_r(self): return self.tello.flip('r') def telloFlip_f(self): return self.tello.flip('f') def telloFlip_b(self): return self.tello.flip('b') def telloCW(self, degree): return self.tello.rotate_cw(degree) def telloCCW(self, degree): return self.tello.rotate_ccw(degree) def telloMoveForward(self, distance): return self.tello.move_forward(distance) def telloMoveBackward(self, distance): return self.tello.move_backward(distance) def telloMoveLeft(self, distance): return self.tello.move_left(distance) def telloMoveRight(self, distance): return self.tello.move_right(distance) def telloUp(self, dist): return self.tello.move_up(dist) def telloDown(self, dist): return self.tello.move_down(dist) def updateTrackBar(self): self.my_tello_hand.setThr(self.hand_thr_bar.get()) def updateDistancebar(self): self.distance = self.distance_bar.get() print 'reset distance to %.1f' % self.distance def updateDegreebar(self): self.degree = self.degree_bar.get() print 'reset distance to %d' % self.degree def on_keypress_w(self, event): print "up %d m" % self.distance self.telloUp(self.distance) def on_keypress_s(self, event): print "down %d m" % self.distance self.telloDown(self.distance) def on_keypress_a(self, event): print "ccw %d degree" % self.degree self.tello.rotate_ccw(self.degree) def on_keypress_d(self, event): print "cw %d m" % self.degree self.tello.rotate_cw(self.degree) def on_keypress_up(self, event): print "forward %d m" % self.distance self.telloMoveForward(self.distance) def on_keypress_down(self, event): print "backward %d m" % self.distance self.telloMoveBackward(self.distance) def on_keypress_left(self, event): print "left %d m" % self.distance self.telloMoveLeft(self.distance) def on_keypress_right(self, event): print "right %d m" % self.distance self.telloMoveRight(self.distance) def on_keypress_enter(self, event): if self.frame is not None: self.registerFace() self.tmp_f.focus_set() def onClose(self): """ set the stop event, cleanup the camera, and allow the rest of the quit process to continue """ print("[INFO] closing...") self.stopEvent.set() del self.tello self.root.quit()
class GUI(): def __init__(self): self.root = ThemedTk(theme="radiance") INIT_WIDTH, INIT_HEIGHT = self.root.winfo_screenwidth( ), self.root.winfo_screenheight() boldStyle = ttk.Style() boldStyle.configure("Bold.TButton", font=('Sans', '12', 'bold')) #icon_loc = os.path.join(os.getcwd(),ICON_NAME) #img = ImageTk.PhotoImage(master = self.root, file=icon_loc) #self.root.wm_iconbitmap(img) #self.root.ttk.call('wm', 'iconphoto', self.root._w, img) self.root.title("Form Labeller") self.root.maxsize(INIT_WIDTH, INIT_HEIGHT) self.supported_formats = SUPPORTED_FORMATS self.left_frame = Frame(self.root, width=BUTTON_WIDTH) self.top_frame1 = Frame(self.left_frame, width=BUTTON_WIDTH, height=int(INIT_HEIGHT / 2)) self.top_frame = Frame(self.left_frame, width=BUTTON_WIDTH, height=INIT_HEIGHT - int(INIT_HEIGHT / 2)) self.bottom_frame = Frame(self.root, width=INIT_WIDTH - BUTTON_WIDTH) self.load_image_directory_button = Button(self.top_frame1, text='Open Folder', command=self.load_directory, width=int(BUTTON_WIDTH), style="Bold.TButton") self.load_image_directory_button.grid(row=OPEN_FOLDER_ROW, columnspan=2, sticky=tk.W + tk.E) self.prev_img_button = Button(self.top_frame1, text='← Prev', command=self.previous_img, state=tk.DISABLED, width=int(BUTTON_WIDTH / 2), style="Bold.TButton") self.prev_img_button.grid(row=PREV_ROW, column=0, sticky=tk.W + tk.E) self.next_img_button = Button(self.top_frame1, text='Next → ', command=self.next_img, width=int(BUTTON_WIDTH / 2), style="Bold.TButton") self.next_img_button.grid(row=NEXT_COL, column=1, sticky=tk.W + tk.E) self.save_image_button = Button(self.top_frame1, text='Save ', command=self.saver, width=int(BUTTON_WIDTH), style="Bold.TButton") self.save_image_button.grid(row=SAVE_ROW, columnspan=2, sticky=tk.W + tk.E) self.delete_poly_button = Button(self.top_frame, text='Delete Selected', command=self.delete_selected, width=int(BUTTON_WIDTH), style="Bold.TButton") self.delete_poly_button.grid(row=DEL_SELECTED_ROW, columnspan=2, sticky=tk.W + tk.E) self.type_choices = TYPE_CHOICES self.variable = StringVar(self.top_frame) self.variable.set(self.type_choices[0]) self.type_options = OptionMenu(self.top_frame, self.variable, *self.type_choices, style="Bold.TButton") self.type_options.config(width=int(BUTTON_WIDTH / 2)) self.type_options.grid(row=DROP_DOWN_ROW, column=0) self.save_type_button = Button(self.top_frame, text='Save Type', command=self.save_type, width=int(BUTTON_WIDTH / 2), style="Bold.TButton") self.save_type_button.grid(row=SAVE_TYPE_ROW, column=1, sticky=tk.W + tk.E) self.deselect_all_button = Button(self.top_frame, text='Deselect All', command=self.deselect_all, width=BUTTON_WIDTH, style="Bold.TButton") self.deselect_all_button.grid(row=DESELECT_ALL_ROW, columnspan=2, sticky=tk.W + tk.E) self.select_all_button = Button(self.top_frame, text='Select All', command=self.select_all, width=BUTTON_WIDTH, style="Bold.TButton") self.select_all_button.grid(row=SELECT_ALL_ROW, columnspan=2, sticky=tk.W + tk.E) self.draw_poly_button = Button(self.top_frame, text='Draw Poly', command=self.draw_poly_func, width=BUTTON_WIDTH, style="Bold.TButton") self.draw_poly_button.grid(row=DRAW_POLY_ROW, columnspan=2, sticky=tk.W + tk.E) self.draw_rect_button = Button(self.top_frame, text='Draw Rectangle', command=self.draw_rect_func, width=BUTTON_WIDTH, style="Bold.TButton") self.draw_rect_button.grid(row=DRAW_RECT_ROW, columnspan=2, sticky=tk.W + tk.E) self.delete_all_button = Button(self.top_frame, text='Delete All', command=self.delete_all, width=BUTTON_WIDTH, style="Bold.TButton") self.save_poly_button = Button(self.top_frame, text='Save Poly', command=self.save_drawing, width=int(BUTTON_WIDTH / 2), style="Bold.TButton") self.discard_poly_button = Button(self.top_frame, text='Discard Poly', command=self.discard_drawing, width=int(BUTTON_WIDTH / 2), style="Bold.TButton") self.save_rect_button = Button(self.top_frame, text='Save Rect', command=self.save_drawing, width=int(BUTTON_WIDTH / 2), style="Bold.TButton") self.discard_rect_button = Button(self.top_frame, text='Discard Rect', command=self.discard_drawing, width=int(BUTTON_WIDTH / 2), style="Bold.TButton") self.show_type_button = Button(self.top_frame, text='Show Type', command=self.show_type, width=int(BUTTON_WIDTH / 2), style="Bold.TButton") self.show_type_button.grid(row=SHOW_TYPE_ROW, column=0, columnspan=1, sticky=tk.W + tk.E) self.hide_type_button = Button(self.top_frame, text='Hide Type', command=self.hide_type, width=int(BUTTON_WIDTH / 2), style="Bold.TButton") self.hide_type_button.grid(row=HIDE_TYPE_ROW, columnspan=1, column=1, sticky=tk.W + tk.E) self.make_tight_button = Button(self.top_frame, text='Make Tight', command=self.make_tight, width=int(BUTTON_WIDTH / 2), style="Bold.TButton") self.make_tight_button.grid(row=MAKE_TIGHT_ROW, columnspan=2, column=0, sticky=tk.W + tk.E) self.threshold_scale = Scale(self.top_frame, from_=0, to=255, orient=HORIZONTAL, width=int(BUTTON_WIDTH / 2), label="Binary Threshold") self.threshold_scale.set(128) self.threshold_scale.grid(row=THRESHOLD_ROW, columnspan=2, column=0, sticky=tk.W + tk.E) self.tight_save_button = Button(self.top_frame, text='Accept Tight', command=self.save_tight) self.tight_discard_button = Button(self.top_frame, text='Discard Tight', command=self.discard_tight) self.canvas = Canvas(self.bottom_frame, width=INIT_WIDTH - BUTTON_WIDTH, height=INIT_HEIGHT, borderwidth=1) self.image_name = None #self.image_path = os.path.join('imgs','img1.jpg') self.image_dir = None self.images_in_dir = None self.curr_idx = None self.img_cnv = None #self.img_cnv = ImageOnCanvas(self.root,self.canvas,self.image_path) self.drawing_obj = None self.tight_box_obj = None self.left_frame.pack(side=tk.LEFT) self.top_frame1.pack(side=tk.TOP) self.top_frame.pack(side=tk.BOTTOM) self.bottom_frame.pack(side=tk.LEFT) self.canvas.pack() self.hide_buttons() self.load_image_directory_button.config(state="normal") def save_tight(self): self.tight_box_obj.save_tight_box() self.tight_save_button.grid_forget() self.tight_discard_button.grid_forget() self.make_tight_button.grid(row=MAKE_TIGHT_ROW, columnspan=2, sticky=tk.W + tk.E) self.show_buttons() self.tight_box_obj = None def discard_tight(self): self.tight_box_obj.discard_tight_box() self.tight_save_button.grid_forget() self.tight_discard_button.grid_forget() self.make_tight_button.grid(row=MAKE_TIGHT_ROW, columnspan=2, sticky=tk.W + tk.E) self.show_buttons() self.tight_box_obj = None def show_type(self): for poly in self.img_cnv.polygons: if poly.select_poly: poly.show_type() def hide_type(self): for poly in self.img_cnv.polygons: poly.unshow_type() def hide_buttons(self): self.load_image_directory_button.config(state=tk.DISABLED) self.save_image_button.config(state=tk.DISABLED) self.delete_poly_button.config(state=tk.DISABLED) self.save_type_button.config(state=tk.DISABLED) self.deselect_all_button.config(state=tk.DISABLED) self.select_all_button.config(state=tk.DISABLED) self.delete_all_button.config(state=tk.DISABLED) self.show_type_button.config(state=tk.DISABLED) self.hide_type_button.config(state=tk.DISABLED) self.make_tight_button.config(state=tk.DISABLED) def show_buttons(self): self.load_image_directory_button.config(state="normal") self.save_image_button.config(state="normal") self.delete_poly_button.config(state="normal") self.save_type_button.config(state="normal") self.deselect_all_button.config(state="normal") self.select_all_button.config(state="normal") self.delete_all_button.config(state="normal") self.show_type_button.config(state="normal") self.hide_type_button.config(state="normal") self.draw_poly_button.config(state="normal") self.draw_rect_button.config(state="normal") self.make_tight_button.config(state="normal") def select_all(self): for poly in self.img_cnv.polygons: poly.select_polygon() def deselect_all(self): self.hide_type() for poly in self.img_cnv.polygons: poly.deselect_poly() def delete_all(self): result = messagebox.askyesno("Confirm Delete All", "Delete All Annotations?") if not result: return self.select_all() self.delete_selected() #self.img_cnv.polygons_mutex.acquire() #for poly in self.img_cnv.polygons: # poly.delete_self() #self.img_cnv.polygons_mutex.release() def save_type(self): selected_option = self.variable.get() self.img_cnv.polygons_mutex.acquire() for poly in self.img_cnv.polygons: if poly.select_poly == True: if selected_option == "None": poly.poly_type = None else: poly.poly_type = selected_option #poly.unshow_type() #poly.show_type() self.img_cnv.polygons_mutex.release() self.variable.set(self.type_choices[0]) #self.deselect_all() def load_new_img(self): self.canvas.delete('all') self.img_cnv = None path = os.path.join(self.image_dir, self.image_name) self.img_cnv = ImageOnCanvas(self.root, self.canvas, path) logger("LOADED: " + self.img_cnv.image_path) def load_directory(self): while True: selection = filedialog.askdirectory() if selection == () or selection == '': return self.root.directory = selection self.image_dir = self.root.directory file_names = os.listdir(self.image_dir) self.images_in_dir = [] self.curr_idx = None self.image_name = None for name in file_names: if name.split('.')[-1] in self.supported_formats: self.images_in_dir.append(name) if len(self.images_in_dir) == 0: self.pop_up("No supported images in the selected directory") else: break self.show_buttons() self.next_img() def pop_up(self, text): top = Toplevel() top.title("ERROR") msg = Message(top, text=text) msg.pack() button = Button(top, text="Dismiss", command=top.destroy) button.pack() def next_img(self): if self.curr_idx == None: self.curr_idx = -1 self.curr_idx = self.curr_idx + 1 if self.curr_idx >= len(self.images_in_dir): self.pop_up("Done with Images in this directory") self.curr_idx = self.curr_idx - 1 return if self.curr_idx > 0: self.prev_img_button.config(state="normal") self.image_name = self.images_in_dir[self.curr_idx] self.load_new_img() self.root.title("Form Labeller - " + self.image_name + "(" + str(self.curr_idx + 1) + "/" + str(len(self.images_in_dir)) + ")") def previous_img(self): if self.curr_idx == 1: self.curr_idx = -1 self.prev_img_button.config(state=tk.DISABLED) else: self.curr_idx = self.curr_idx - 2 self.next_img() def delete_selected(self): to_be_deleted = [] for i, poly in enumerate(self.img_cnv.polygons): if poly.select_poly == True: poly.delete_self() to_be_deleted.append(i) j = 0 for idx in to_be_deleted: self.img_cnv.polygons.pop(idx - j) self.img_cnv.bbs.pop(idx - j) self.img_cnv.poly_type.pop(idx - j) j = j + 1 def start_gui(self): self.root.mainloop() def saver(self): logger("Saving: " + self.img_cnv.image_path) self.save_image_button.config(state=tk.DISABLED) self.img_cnv.save_json(self.root.directory) self.save_image_button.config(state="normal") def draw_poly_func(self): self.deselect_all() self.img_cnv.drawing_polygon = True self.draw_poly_button.grid_forget() self.save_poly_button.grid(row=DRAW_POLY_ROW, column=0, sticky=tk.W + tk.E) self.discard_poly_button.grid(row=DRAW_POLY_ROW, column=1, sticky=tk.W + tk.E) self.hide_buttons() self.draw_rect_button.config(state=tk.DISABLED) self.drawing_obj = DrawPoly(self.bottom_frame, self.canvas, self.img_cnv, RADIUS) def draw_rect_func(self): self.deselect_all() self.img_cnv.drawing_polygon = True self.draw_rect_button.grid_forget() self.save_rect_button.grid(row=DRAW_RECT_ROW, column=0, sticky=tk.W + tk.E) self.discard_rect_button.grid(row=DRAW_RECT_ROW, column=1, sticky=tk.W + tk.E) self.hide_buttons() self.draw_poly_button.config(state=tk.DISABLED) self.drawing_obj = DrawRect(self.bottom_frame, self.canvas, self.img_cnv, RADIUS) def save_drawing(self): self.show_buttons() self.img_cnv.drawing_polygon = False new_poly_pts = self.drawing_obj.pt_coords print("Trying to save polygon with pts:", str(new_poly_pts)) for pt in self.drawing_obj.points: self.canvas.delete(pt) if self.img_cnv.scale_factor != None: for i in range(len(new_poly_pts)): for j in range(2): new_poly_pts[i][ j] = new_poly_pts[i][j] / self.img_cnv.scale_factor self.img_cnv.add_poly(new_poly_pts) #self.img_cnv.bbs.append(new_poly_pts) #self.img_cnv.draw_bbs([self.img_cnv.bbs[-1]]) #debug (1, str(type(self.drawing_obj))) if isinstance(self.drawing_obj, DrawRect): self.save_rect_button.grid_forget() self.discard_rect_button.grid_forget() self.draw_rect_button.grid(row=DRAW_RECT_ROW, columnspan=2, sticky=tk.W + tk.E) elif isinstance(self.drawing_obj, DrawPoly): self.save_poly_button.grid_forget() self.discard_poly_button.grid_forget() self.draw_poly_button.grid(row=DRAW_POLY_ROW, columnspan=2, sticky=tk.W + tk.E) self.drawing_obj.delete_self() self.drawing_obj = None def discard_drawing(self): self.show_buttons() self.img_cnv.drawing_polygon = False #for pt in self.drawing_obj.points: # self.canvas.delete(pt) self.drawing_obj.delete_self() if isinstance(self.drawing_obj, DrawRect): self.save_rect_button.grid_forget() self.discard_rect_button.grid_forget() self.draw_rect_button.grid(row=DRAW_RECT_ROW, columnspan=2, sticky=tk.W + tk.E) elif isinstance(self.drawing_obj, DrawPoly): self.save_poly_button.grid_forget() self.discard_poly_button.grid_forget() self.draw_poly_button.grid(row=DRAW_POLY_ROW, columnspan=2, sticky=tk.W + tk.E) self.drawing_obj = None def make_tight(self): self.hide_buttons() self.tight_box_obj = TightBox(self.root, self.img_cnv, self.threshold_scale.get()) self.tight_box_obj.tight_box() self.make_tight_button.grid_forget() self.tight_save_button.grid(row=MAKE_TIGHT_ROW, column=0, columnspan=1, sticky=tk.W + tk.E) self.tight_discard_button.grid(row=MAKE_TIGHT_ROW, column=1, columnspan=1, sticky=tk.W + tk.E)
class ChoixEcole: def __init__(self): # Initialise l'application change le titre et la positionne self.root = Tk() self.root.title("ChoixEcole") """Ouvre la base de donnees""" basededonne = filedialog.askopenfilename(title="Ouvrir un fichier", filetypes=[("db file", ".db") ]) model.connec(basededonne) self.root.resizable(False, False) self.entry_ecole = tkscrolled.ScrolledText( self.root, width=40, height=10, ) menubar = Menu(self.root) self.root.config(menu=menubar) menufichier = Menu(menubar, tearoff=0) menubar.add_cascade(label="Fichier", menu=menufichier) menufichier.add_command(label="Enregistrer ", command=self.save_file) menufichier.add_command(label="Enregistrer sous", command=self.save_file_as) self.filename = () self.button = [] self.ecolesselect = {} ######################################################################## # NOTES # ######################################################################## # On considre les notes entrées par l'utilisateur (sous forme de # "StringVar"). À chaque modification d'une de ces variables, on met # tout à jour. self.notes_vars = { "maths": StringVar(self.root), "physique": StringVar(self.root), "si": StringVar(self.root), "informatique": StringVar(self.root), "anglais": StringVar(self.root), "francais": StringVar(self.root), } for var in self.notes_vars.values(): var.trace("w", self.update) # self.notes représente soit une erreur de saisie des notes (avec None) # soit un dictionnaire "matière -> note(float)". self.notes = None self.nom = {"nom": StringVar(self.root)} ######################################################################## # CHOIX # ######################################################################## # On crée un dictonnaire modifié a chaque clique sur la ListeBox. self.choix = { "regions": None, "specialites": None, "alternance": None, "concours": None, "annee": None, } self.varsbuttons = { "specialites": IntVar(self.root), "regions": IntVar(self.root), "concours": IntVar(self.root), "alternance": IntVar(self.root), "annee": IntVar(self.root), "ecole": IntVar(self.root), } ######################################################################## # RENDU FORMULAIRE NOTES # ######################################################################## self.scale = Scale( self.root, orient="horizontal", from_=0, to=100, resolution=1, tickinterval=25, length=100, label="Augmentation %", command=self.update, ) Label(self.root, text="Maths").grid(row=2, column=1) Entry(self.root, textvariable=self.notes_vars["maths"]).grid(row=3, column=1) Label(self.root, text="Physique").grid(row=4, column=1) Entry(self.root, textvariable=self.notes_vars["physique"]).grid(row=5, column=1) Label(self.root, text="Si").grid(row=6, column=1) Entry(self.root, textvariable=self.notes_vars["si"]).grid(row=7, column=1) Label(self.root, text="Informatique").grid(row=8, column=1) Entry(self.root, textvariable=self.notes_vars["informatique"]).grid(row=9, column=1) Label(self.root, text="Anglais").grid(row=10, column=1) Entry(self.root, textvariable=self.notes_vars["anglais"]).grid(row=11, column=1) Label(self.root, text=" Francais").grid(row=12, column=1) Entry(self.root, textvariable=self.notes_vars["francais"]).grid(row=13, column=1) Label(self.root, text="Nom").grid(row=5, column=31) Entry(self.root, textvariable=self.nom["nom"]).grid(row=6, column=31) ######################################################################## # RENDU FORMULAIRE choix # ######################################################################## self.specialites = Listbox(self.root, selectmode="multiple", exportselection=0, width=20, height=10) Label(self.root, text="Specialite").grid(row=0, column=6) self.specialites = Listbox(self.root, selectmode="multiple", exportselection=0, width=20, height=10) Label(self.root, text="Specialite").grid(row=0, column=6) self.regions = Listbox(self.root, selectmode="multiple", exportselection=0, width=20, height=10) Label(self.root, text="Region").grid(row=0, column=7) self.alternance = Listbox(self.root, exportselection=0, width=6, height=3) Label(self.root, text="Alternance").grid(row=11, column=6) self.concours = Listbox(self.root, selectmode="multiple", exportselection=0, width=20, height=10) Label(self.root, text="Admission").grid(row=0, column=9) self.annee = Listbox(self.root, exportselection=0, width=6, height=3) Label(self.root, text="Année").grid(row=11, column=7) self.specialites.grid(row=2, column=6, rowspan=10, padx=10) self.regions.grid(row=2, column=7, rowspan=10, padx=10) self.alternance.grid(row=13, column=6, rowspan=10, padx=10) self.concours.grid(row=2, column=9, rowspan=10, padx=10) self.annee.grid(row=13, column=7, rowspan=10, padx=10) ######################################################################## # Insertion des Bouton Peu importe # ######################################################################## Checkbutton( self.root, variable=self.varsbuttons["specialites"], text="Peu importe", command=self.update, ).grid(row=1, column=6) Checkbutton( self.root, variable=self.varsbuttons["regions"], text="Peu importe", command=self.update, ).grid(row=1, column=7) Checkbutton( self.root, variable=self.varsbuttons["alternance"], text="Peu importe", command=self.update, ).grid(row=12, column=6) Checkbutton( self.root, variable=self.varsbuttons["concours"], text="Peu importe", command=self.update, ).grid(row=1, column=9) Button(self.root, text="Plus d'information", command=self.information, width=15).grid(row=2, column=31) Button(self.root, text="Note", command=self.recuperernote, width=15).grid(row=3, column=31) Button(self.root, text="Prix", command=self.calculprix, width=15).grid(row=2, column=32) ######################################################################## # Insertion des données # ######################################################################## for specialite in model.renvoie_specialites(): self.specialites.insert("end", specialite) for region in model.renvoie_regions(): self.regions.insert("end", region) for alternance in ["Oui", "Non"]: self.alternance.insert("end", alternance) for concours in model.renvoie_admission(): self.concours.insert("end", concours) for annee in ["3/2", "5/2"]: self.annee.insert("end", annee) ######################################################################## # On bind les ListBox # ######################################################################## self.entry_ecole.grid(row=2, column=20, rowspan=10) self.scale.grid(row=0, column=1, rowspan=2) self.specialites.bind("<<ListboxSelect>>", self.update) self.regions.bind("<<ListboxSelect>>", self.update) self.alternance.bind("<<ListboxSelect>>", self.update) self.concours.bind("<<ListboxSelect>>", self.update) self.annee.bind("<<ListboxSelect>>", self.update) self.update() self.root.mainloop() def valide_maj_notes(self): ######################################################################## # NOTES # ######################################################################## # On récupere la note entrée et on la vérifie try: notes = {} for nom_matiere, note_var in self.notes_vars.items(): note_float = float(note_var.get()) if note_float > 20 or note_float < 0: raise ValueError() else: if len(note_var.get()) in (2, 1): pass elif note_var.get()[2] == "." and len(note_var.get()) < 6: pass elif note_var.get()[1] == "." and len(note_var.get()) < 5: pass else: raise ValueError note_float = note_float + (self.scale.get() * note_float) / 100 if note_float >= 20: notes[nom_matiere] = 20 else: notes[nom_matiere] = note_float notes["modelisation"] = (notes["maths"] + notes["si"]) / 2 self.notes = notes except ValueError: # Une erreur est survenue lors de la conversion des notes self.notes = None def maj_choix(self): ######################################################################## # NOTES # ######################################################################## # On récupere l'index de la spécialite et le texte coché pour les autres variables # Et en fonction de certains cas on dit que self.choix=None self.choix = { "specialites": model.renvoie_idspe( self.specialites.get(i) for i in self.specialites.curselection()), "regions": tuple(self.regions.get(i) for i in self.regions.curselection()), "concours": tuple(self.concours.get(i) for i in self.concours.curselection()), "alternance": tuple( self.alternance.get(i) for i in self.alternance.curselection()), "annee": tuple(self.annee.get(i) for i in self.annee.curselection()), } for cle in self.varsbuttons: if self.varsbuttons[cle].get() == 1: eval('self.' + cle + '.selection_clear(0, "end")') for cle in self.choix: if not self.choix[cle] or self.varsbuttons[cle].get() == 1: self.choix[cle] = None def update(self, *inutile): self.valide_maj_notes() self.maj_choix() self.construit_ecoles() self.affichage() def construit_ecoles(self): """On récupere les écoles disponibles dans la bdd et on les stocke """ self.ecolesselect = {} if self.notes != None: for j, ecoles in enumerate(model.filtre(self.choix, self.notes)): self.ecolesselect[j] = { "var": IntVar(self.root), "id": ecoles[0], "nom": ecoles[1], "admission": ecoles[2], "region": ecoles[3], "Alternance": ecoles[4], "Acronyme": ecoles[5], "Spe": ecoles[6], } def information(self): ######################################################################## # Information # ######################################################################## # Renvoie les spécialite offerte par l'école en fonction du choix de l'utilisateur window = Toplevel(self.root) window.resizable(False, False) window.geometry("700x150") vsb = Scrollbar(window, orient="vertical") vsb.grid(row=0, column=1, sticky="ns") hsb = Scrollbar(window, orient="horizontal") hsb.grid(row=1, column=0, sticky="ew") ca = Canvas(window, yscrollcommand=vsb.set, xscrollcommand=hsb.set) ca.grid(row=0, column=0, sticky="news") vsb.config(command=ca.yview) hsb.config(command=ca.xview) window.grid_rowconfigure(0, weight=1) window.grid_columnconfigure(0, weight=1) fr = Frame(ca) i = 1 for a in ["Nom", "Admission", "Region", "Alternance", "Specialite"]: Label(fr, text=a).grid(row=0, column=i) i += 2 if self.choix["specialites"] == None: ListeSpe = list(self.specialites.get(0, "end")) else: ListeSpe = [ self.specialites.get(i) for i in self.specialites.curselection() ] if self.choix["alternance"] == None: alternance = ["Oui", "Non"] else: alternance = [self.choix["alternance"][0]] ligne = 1 for ecole in self.ecolesselect.values(): if ecole["var"].get() == 1: for ecolesinfo in self.ecolesselect.values(): if (ecole["nom"] == ecolesinfo["nom"] and ecolesinfo["Alternance"] in alternance and ecolesinfo["Spe"] in ListeSpe): i = 1 for texte in [ ecolesinfo["nom"], ecolesinfo["admission"], ecolesinfo["region"], ecolesinfo["Alternance"], ecolesinfo["Spe"] ]: a = Entry(fr, width=60) a.insert(0, texte) a.grid(row=ligne, column=i) i += 2 a.config(state="disabled") ligne += 1 ca.create_window(0, 0, window=fr) fr.update_idletasks() ca.config(scrollregion=ca.bbox("all")) def calculprix(self): ecoles = [] for ecole in self.ecolesselect.values(): if ecole["var"].get() == 1: ecoles.append(ecole["admission"]) prixboursier = str(model.prix_ecole(ecoles, "Boursier")) prixnonboursier = str(model.prix_ecole(ecoles, "NonBoursier")) Label(self.root, text="Prix Boursier \n" + prixboursier).grid(row=3, column=32) Label(self.root, text="Prix Non Boursier\n" + prixnonboursier).grid(row=4, column=32) def convertpdf(self, spacing=2): """Converti en PDF """ pdf = FPDF() pdf.add_page() pdf.set_font("Arial", size=12) data = [["Nom", "Résultat"]] admission, listeecoles = self.returntext() data += [[listeecoles[i], admission[i]] for i in range(len(admission))] col_width = pdf.w / 2.5 row_height = pdf.font_size for row in data: for item in row: pdf.cell(col_width, row_height * spacing, txt=item, border=1) pdf.ln(row_height * spacing) pdf.output(self.filename) def returntext(self): """Affiche le nom de l'école et a cote Refuse ou admis""" ecoleamoi = list( set([ ecoles[5] for ecoles in model.filtre( {choix: None for choix in self.choix}, self.notes) ])) listeecoles = list( set([ ecoles[5] for ecoles in model.filtre( {choix: None for choix in self.choix}, {Note: 20 for Note in self.notes}, ) ])) admission = ["Admis"] * len(listeecoles) for i in range(len(listeecoles)): if listeecoles[i] not in ecoleamoi: admission[i] = "Refuse" return admission, listeecoles def save_file(self, whatever=None): if self.filename == (): self.save_file_as() self.convertpdf() def save_file_as(self, whatever=None): self.filename = filedialog.asksaveasfilename(defaultextension=".pdf", filetypes=[ ("PDF", "*.pdf"), ]) self.convertpdf() def affichage(self): """Affiche les écoles auquel on est admissible """ for i in self.button: i.destroy() self.entry_ecole.configure(state="normal") self.entry_ecole.delete(0.7, "end") if self.notes: textverification = [] for ecole in self.ecolesselect.values(): if ecole["Acronyme"] not in textverification: check = Checkbutton(text=ecole["Acronyme"], variable=ecole["var"]) self.entry_ecole.window_create(0.7, window=check) self.entry_ecole.insert(0.7, "\n") self.button.append(check) textverification.append(ecole["Acronyme"]) else: self.entry_ecole.insert(0.7, "Erreur lors de la saisie des notes.") self.entry_ecole.configure(state="disabled") def recuperernote(self): nom = self.nom["nom"].get() noteeleve = model.moyenneel(nom) self.notes_vars["si"].set(noteeleve[0]) self.notes_vars["maths"].set(noteeleve[1]) self.notes_vars["physique"].set(noteeleve[2]) self.notes_vars["informatique"].set(noteeleve[3]) self.notes_vars["francais"].set(noteeleve[4]) self.notes_vars["anglais"].set(noteeleve[5])
class AdjustFrame(Toplevel): def __init__(self, master=None): Toplevel.__init__(self, master=master) self.brightness_value = 0 self.previous_brightness_value = 0 self.original_image = self.master.processed_image self.processing_image = self.master.processed_image self.brightness_label = Label(self, text="Brightness") self.brightness_scale = Scale(self, from_=0, to_=2, length=250, resolution=0.1, orient=HORIZONTAL) self.r_label = Label(self, text="R") self.r_scale = Scale(self, from_=-100, to_=100, length=250, resolution=1, orient=HORIZONTAL) self.g_label = Label(self, text="G") self.g_scale = Scale(self, from_=-100, to_=100, length=250, resolution=1, orient=HORIZONTAL) self.b_label = Label(self, text="B") self.b_scale = Scale(self, from_=-100, to_=100, length=250, resolution=1, orient=HORIZONTAL) self.apply_button = Button(self, text="Apply") self.preview_button = Button(self, text="Preview") self.cancel_button = Button(self, text="Cancel") self.brightness_scale.set(1) self.apply_button.bind("<ButtonRelease>", self.apply_button_released) self.preview_button.bind("<ButtonRelease>", self.show_button_released) self.cancel_button.bind("<ButtonRelease>", self.cancel_button_released) self.brightness_label.pack() self.brightness_scale.pack() self.r_label.pack() self.r_scale.pack() self.g_label.pack() self.g_scale.pack() self.b_label.pack() self.b_scale.pack() self.cancel_button.pack(side=RIGHT) self.preview_button.pack(side=RIGHT) self.apply_button.pack() def apply_button_released(self, event): self.master.processed_image = self.processing_image self.close() def show_button_released(self, event): self.processing_image = cv2.convertScaleAbs( self.original_image, alpha=self.brightness_scale.get()) b, g, r = cv2.split(self.processing_image) for b_value in b: cv2.add(b_value, self.b_scale.get(), b_value) for g_value in g: cv2.add(g_value, self.g_scale.get(), g_value) for r_value in r: cv2.add(r_value, self.r_scale.get(), r_value) self.processing_image = cv2.merge((b, g, r)) self.show_image(self.processing_image) def cancel_button_released(self, event): self.close() def show_image(self, img=None): self.master.image_viewer.show_image(img=img) def close(self): self.show_image() self.destroy()
class Report(Frame): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.root = self.winfo_toplevel() self.root.title(" ".join((APPNAME, VERSION, "| Report"))) self.root.resizable(0, 0) self.items = None headers = ('Page', 'Rank', 'PageRank Value', 'Incoming') self.t = Scale(self, from_=0, to=1, label='n-th iteration', bd=1, width=7, orient='horizontal', command=self.__set_t) self.t.pack(fill='x') self.label = Label(self, anchor='e') self.label.pack(fill='x') self.tree = Treeview(self, columns=headers, show="headings", height=REPORT_HEIGHT) self.tree.column(0, anchor='center', width=55) self.tree.column(1, anchor='center', width=55) self.tree.column(2, width=175) self.tree.column(3, anchor='center', width=55) self.scroll = Scrollbar(self, command=self.tree.yview) self.scroll.pack(side='right', fill='y') self.tree.config(yscrollcommand=self.scroll.set) for col in headers: self.tree.heading(col, text=col.title()) self.root.master.focus_force() self.root.bind('<Key>', self.__keys) def __keys(self, event): if event.char == 'i': self.t.set(self.t.get() - 1) elif event.char == 'I': self.t.set(0) elif event.char == 'o': self.t.set(self.t.get() + 1) elif event.char == 'O': self.t.set(self.pagerank[1]) def __set_t(self, t=None): self.render(self.pagerank, self.edge_counts, self.d, self.e, t=int(t)) def render(self, pagerank, edge_counts, d, e, t=None): self.d, self.e = d, e self.edge_counts = edge_counts self.pagerank = pagerank if t is not None: pr = pagerank[0][t] else: self.t.config(command=None) self.t.config(to=self.pagerank[1]) self.t.set(self.pagerank[1]) self.t.config(command=self.__set_t) pr = pagerank[0][-1] label_text = '# of ranks:{0:>3} # of iterations:{1:>3}'.format( len(set(pr.values())), self.pagerank[1]) self.label.config(text=label_text) in_map = {k: 0 for k in pr.keys()} # incoming edges by nodes for (tail, head), n in edge_counts.items(): if tail is not head: in_map[head] += n get_rank = lambda k: sorted(pr.values())[::-1].index(pr[k]) + 1 data = tuple( (k, get_rank(k), pr[k], in_map[k]) for k in sorted(pr.keys())) if self.items: self.tree.delete(*self.items) self.items = [ self.tree.insert('', 'end', values=line) for line in data ] self.tree.pack(side='left', fill='y') #self.root.master.focus_force() def destroy(self): super().destroy() self.root.master.r_win = False self.root.master.windowsmenu.entryconfig(0, label='[ ] Report window') self.root.destroy()
class AuxMode(Frame): def __init__(self, root, parent): Frame.__init__(self, root, borderwidth=2, relief='groove', height=10) settings = parent.settings('aux_mode') self.parent = parent lbl_power = Label(self, text='Power:') lbl_power.grid(row=0, column=0, pady=2) self.cmb_power = ttk.Combobox(self, value=['Off', 'On']) self.cmb_power.grid(row=0, column=1, pady=2) self.cmb_power.set(settings['power']) self.cmb_power['state'] = 'readonly' self.cmb_power.bind('<<ComboboxSelected>>', self.set_power) lbl_aux_pin = Label(self, text='AUX pin:') lbl_aux_pin.grid(row=1, column=0, pady=2) self.cmb_aux_pin = ttk.Combobox(self, values=['AUX', 'CS']) self.cmb_aux_pin.grid(row=1, column=1, pady=2) self.cmb_aux_pin['state'] = 'readonly' self.cmb_aux_pin.set(settings['aux_pin']) self.cmb_aux_pin.bind('<<ComboboxSelected>>', self.select_aux_pin) lbl_aux = Label(self, text='AUX mode:') lbl_aux.grid(row=2, column=0, pady=2) self.cmb_aux_mode = ttk.Combobox( self, values=['Input', 'Output', 'Servo', 'PWM']) self.cmb_aux_mode.grid(row=2, column=1, pady=2) self.cmb_aux_mode['state'] = 'readonly' self.cmb_aux_mode.set(settings['mode']) self.cmb_aux_mode.bind('<<ComboboxSelected>>', self.select_aux_mode) self.aux_servo = Scale(self, from_=0, to=180, orient='horizontal') self.aux_servo.set(settings['servo']) self.aux_servo.bind('<ButtonRelease-1>', self.select_aux_mode) self.aux_pin_state = IntVar() self.aux_pin_state.set(settings['aux_state']) self.aux_pin_state.trace_add('write', self.select_aux_mode) self.aux_high = Radiobutton(self, text='HIGH', value=1, variable=self.aux_pin_state) self.aux_low = Radiobutton(self, text='LOW', value=0, variable=self.aux_pin_state) self.aux_pwm_lbl = Label(self, text='Frequency (KHz):') self.aux_pwm_freq = Entry(self) self.aux_pwm_freq.insert(0, settings['pwm_freq']) self.aux_pwm_freq.bind('<KeyRelease>', self.select_aux_mode) self.aux_pwm_duty_lbl = Label(self, text='Duty cycle (%):') self.aux_pwm_duty = Scale(self, from_=0, to=99, orient='horizontal') self.aux_pwm_duty.set(settings['pwm_duty']) self.aux_pwm_duty.bind('<ButtonRelease-1>', self.select_aux_mode) def __call__(self): return { 'power': self.cmb_power.get(), 'mode': self.cmb_aux_mode.get(), 'aux_state': self.aux_pin_state.get(), 'aux_pin': self.cmb_aux_pin.get(), 'servo': self.aux_servo.get(), 'pwm_freq': self.aux_pwm_freq.get(), 'pwm_duty': self.aux_pwm_duty.get() } def select_aux_mode(self, e=None, a=None, b=None): for i, widget in enumerate(self.winfo_children()): if i > 5: widget.grid_forget() mode = self.cmb_aux_mode.get() # if self.parent.console.mode == 'HiZ': return if mode == 'Input': self.parent.console.aux('Input') if mode == 'Output': self.aux_high.grid(row=3, column=1) self.aux_low.grid(row=4, column=1) self.parent.console.aux('Output', self.aux_pin_state.get()) if mode == 'Servo': self.aux_servo.grid(row=3, column=1) self.parent.console.servo(self.aux_servo.get()) if mode == 'PWM': self.aux_pwm_lbl.grid(row=3, column=0) self.aux_pwm_freq.grid(row=3, column=1) self.aux_pwm_duty_lbl.grid(row=4, column=0) self.aux_pwm_duty.grid(row=4, column=1) self.parent.console.pwm(self.aux_pwm_freq.get(), self.aux_pwm_duty.get()) if mode == 'CS': self.parent.console.cs() self.parent.settings('aux_mode', self()) def select_aux_pin(self, e=None): self.parent.console.aux_pin(self.cmb_aux_pin.get()) def set_power(self, e=None): self.parent.console.power(self.cmb_power.get()) self.parent.settings('aux_mode', self()) def disable(self): self.cmb_power['state'] = 'disabled' self.cmb_aux_mode['state'] = 'disabled' self.aux_high['state'] = 'disabled' self.aux_low['state'] = 'disabled' self.aux_servo['state'] = 'disabled' self.aux_pwm_freq['state'] = 'disabled' self.aux_pwm_duty['state'] = 'disabled' def enable(self): self.cmb_power['state'] = 'readonly' self.cmb_aux_mode['state'] = 'readonly' self.aux_high['state'] = 'normal' self.aux_low['state'] = 'normal' self.aux_servo['state'] = 'normal' self.aux_pwm_freq['state'] = 'normal' self.aux_pwm_duty['state'] = 'normal'
class ScytheConfigEditor(): def __init__(self): global CURRENTCONFIG global MAXCONFIG global CF_MODE self.confighandler = ConfigHandler() self.confighandler.backupConf() tmpconfig= configparser.ConfigParser() self.confighandler.backupConfTo(tmpconfig) top = tk.Toplevel() top.title("Set configuration") nb = ttk.Notebook(top) b_config_ok = tk.Button(top, text="OK", command=top.destroy) b_config_ok.bind('<ButtonRelease-1>',self.onSetConfigOK) b_config_apply = tk.Button(top, text="Apply", command=self.onSetConfigApply) b_config_cancel = tk.Button(top, text="Cancel", command=top.destroy) b_config_cancel.bind('<ButtonRelease-1>',self.onSetConfigCancel()) fr_paths = tk.Frame(nb,width=200, height=100) fr_penalties = tk.Frame(nb,width=200, height=100) fr_mode = ttk.Frame(nb,width=200, height=100) fr_cleanup = ttk.Frame(nb,width=200, height=100) fr_run = ttk.Frame(nb,width=200, height=100) fr_algorithm = ttk.Frame(nb,width=200, height=100) fr_fastaheader = ttk.Frame(nb,width=200, height=100) #######labels######################## self.txt_sec=[] self.txt_subsec={} for section in MAXCONFIG.sections(): #print( "["+section +"]\n") self.txt_sec.append(section) for opt in MAXCONFIG.options(section): try: self.txt_subsec[section].append(opt) except KeyError as e: self.txt_subsec[section]=[opt] lab_sec=[] lab_subsec={} dd_subsec={} self.var_subsec={} for t in self.txt_sec: lab_sec.append(tk.Label(fr_paths,text = t)) for t in self.txt_subsec: #print(t,self.txt_subsec[t]) for u in self.txt_subsec[t]: if t == CF_MODE: fr = fr_mode elif t == CF_PATHS: fr = fr_paths elif t == CF_CLEANUP: fr = fr_cleanup elif t == CF_RUN: fr = fr_run elif t == CF_PENALTIES: fr = fr_penalties elif t == CF_ALGORITHM: fr = fr_algorithm elif t == CF_FASTAHEADER: fr = fr_fastaheader #print("fastaheader_fr") ################################ else: sys.stderr.write("No such section:",t) try: lab_subsec[t].append(tk.Label(fr,text = u)) self.var_subsec[t].append(tk.StringVar(fr)) if u in OPTIONS: dd_subsec[t].append(OptionMenu(fr,self.var_subsec[t][-1],*OPTIONS[u])) else: dd_subsec[t].append("") except KeyError as e: try: lab_subsec[t]=[tk.Label(fr,text = u)] self.var_subsec[t]=[tk.StringVar(fr)] if u in OPTIONS: dd_subsec[t] = [OptionMenu(fr,self.var_subsec[t][-1],*OPTIONS[u])] else: dd_subsec[t] = [""] except KeyError as e: sys.stderr.write(str(e)) dd_subsec[t].append("") for t in lab_subsec: r=0 c=0 for i in lab_subsec[t]: #print(i.cget("text")) i.grid(row=r,column=c, sticky=tk.E) r+=1 #print(r,i.cget("text")) for t in dd_subsec: c=1 r=0 for i in dd_subsec[t]: #print(i) if i is not "": i.grid(row=r,column=c,sticky=tk.N) r+=1 #print(r) ###################################### self.st_submat = tk.StringVar() self.st_fasta_header_delimiter = tk.StringVar() self.st_fasta_header_part = tk.StringVar() #cpu_count starts at 0 for one cpu self.sc_config_numthreads = Scale(fr_run, from_=1, to=multiprocessing.cpu_count(), orient=tk.HORIZONTAL) self.sc_config_numthreads.grid(row=0, column=1, sticky=tk.E) en_config_gapopen=tk.Entry(fr_penalties, textvariable=self.var_subsec[CF_PENALTIES][0]) en_config_gapextend=tk.Entry(fr_penalties,textvariable=self.var_subsec[CF_PENALTIES][1] ) self.en_config_fasta_header_delimiter= tk.Entry(fr_fastaheader,textvariable=self.st_fasta_header_delimiter,width=6 ) self.en_config_fasta_header_part= tk.Entry(fr_fastaheader,textvariable=self.st_fasta_header_part ,width=6 ) self.om_config_submat=tk.OptionMenu(fr_penalties, self.st_submat, *["EBLOSUM62","EDNAFULL"]) self.om_config_submat.grid(row=2,column=1 ) en_config_gapopen.grid(row=0, column=1) en_config_gapextend.grid(row=1, column=1) self.en_config_fasta_header_delimiter.grid(row=0, column=1) self.en_config_fasta_header_part.grid(row=1,column=1) nb.add(fr_penalties, text=CF_PENALTIES) nb.add(fr_cleanup, text=CF_CLEANUP) nb.add(fr_run, text=CF_RUN) nb.add(fr_algorithm, text=CF_ALGORITHM) nb.add(fr_fastaheader, text=CF_FASTAHEADER) nb.grid() b_config_cancel.grid(row=1, column=0, sticky=tk.E,padx=115) b_config_apply.grid(row=1, column=0, sticky=tk.E,padx=50) b_config_ok.grid(row=1, column=0, sticky=tk.E) self.setFieldsFromConfig() def onSetConfigApply(self): self.setConfigFromFields() def onSetConfigOK(self,event): self.setConfigFromFields() def onSetConfigCancel(self): self.confighandler.restoreConf() #print("RESTORED-->CURRENTCONF set") #print("Config CANCEL") def setConfigFromFields(self): tempconf = configparser.ConfigParser() self.confighandler.backupConfTo(tempconf) #get all values from fields #penalties tempconf.set(CF_PENALTIES,CF_PENALTIES_gap_open_cost,self.var_subsec[CF_PENALTIES][0].get() ) tempconf.set(CF_PENALTIES, CF_PENALTIES_gap_extend_cost,self.var_subsec[CF_PENALTIES][1].get()) tempconf.set(CF_PENALTIES, CF_PENALTIES_substitution_matrix,self.st_submat.get()) tempconf.set(CF_ALGORITHM, CF_ALGORITHM_use_global_max,self.var_subsec[CF_ALGORITHM][0].get()) tempconf.set(CF_ALGORITHM, CF_ALGORITHM_use_default,self.var_subsec[CF_ALGORITHM ][1].get()) tempconf.set(CF_ALGORITHM, CF_ALGORITHM_use_global_sum,self.var_subsec[CF_ALGORITHM][2].get()) tempconf.set(CF_RUN, CF_RUN_num_CPU,str(self.sc_config_numthreads.get())) #CLEANUP tempconf.set(CF_CLEANUP, CF_CLEANUP_clean_up_directories, self.var_subsec[CF_CLEANUP][0].get()) #Fasta header tempconf.set(CF_FASTAHEADER, CF_FASTAHEADER_delimiter, self.var_subsec[CF_FASTAHEADER][0].get()) tempconf.set(CF_FASTAHEADER, CF_FASTAHEADER_part, self.var_subsec[CF_FASTAHEADER][1].get()) tempconf.set(CF_FASTAHEADER, CF_FASTAHEADER_part,self.st_fasta_header_part.get()) tempconf.set(CF_FASTAHEADER, CF_FASTAHEADER_delimiter,self.st_fasta_header_delimiter.get()) self.confighandler.setCurrentConf(tempconf) def setFieldsFromConfig(self): #penalties self.var_subsec[CF_PENALTIES][0].set(CURRENTCONFIG.get(CF_PENALTIES,self.txt_subsec[CF_PENALTIES][0])) self.var_subsec[CF_PENALTIES][1].set(CURRENTCONFIG.get(CF_PENALTIES,self.txt_subsec[CF_PENALTIES][1])) self.st_submat.set(CURRENTCONFIG.get(CF_PENALTIES, CF_PENALTIES_substitution_matrix)) #output #cleanup self.var_subsec[CF_CLEANUP][0].set(CURRENTCONFIG.get(CF_CLEANUP,self.txt_subsec[CF_CLEANUP][0])) #run #slider #algo self.var_subsec[CF_ALGORITHM][0].set(CURRENTCONFIG.get(CF_ALGORITHM,self.txt_subsec[CF_ALGORITHM][0])) self.var_subsec[CF_ALGORITHM][1].set(CURRENTCONFIG.get(CF_ALGORITHM,self.txt_subsec[CF_ALGORITHM][1])) self.var_subsec[CF_ALGORITHM][2].set(CURRENTCONFIG.get(CF_ALGORITHM,self.txt_subsec[CF_ALGORITHM][2])) self.var_subsec[CF_FASTAHEADER][0].set(CURRENTCONFIG.get(CF_FASTAHEADER,self.txt_subsec[CF_FASTAHEADER][0])) self.var_subsec[CF_FASTAHEADER][1].set(CURRENTCONFIG.get(CF_FASTAHEADER,self.txt_subsec[CF_FASTAHEADER][1])) self.st_fasta_header_part.set(CURRENTCONFIG.get(CF_FASTAHEADER, CF_FASTAHEADER_part)) self.st_fasta_header_delimiter.set(CURRENTCONFIG.get(CF_FASTAHEADER, CF_FASTAHEADER_delimiter))
class HsvGui(tk.Frame): def __init__(self, master=None,): tk.Frame.__init__(self, master) self.root = master self.Webcam = G2.Webcamera() self.baseImage = self.Webcam.save_image(persist=False) self.baseImage = cv2.cvtColor(numpy.array(self.baseImage), cv2.COLOR_RGB2BGR) self.createWidgets() self.OnValueChange = event.Event() self.title = "Webcam" cv2.startWindowThread() cv2.namedWindow(self.title, cv2.WINDOW_NORMAL) cv2.imshow(self.title, self.baseImage) self.Funkify() def createWidgets(self): Label(self.root, text="Value:").grid(row=0, sticky=W) Label(self.root, text="H:").grid(row=1, sticky=W) Label(self.root, text="S:").grid(row=2, sticky=W) Label(self.root, text="V:").grid(row=3, sticky=W) Label(self.root, text="S:").grid(row=4, sticky=W) Label(self.root, text="V:").grid(row=5, sticky=W) Label(self.root, text="H:").grid(row=6, sticky=W) self.valueLabel = Label(self.root, text="000-000-000 to 000-000-000") self.valueLabel.grid(row=0, column=1, sticky=W) self.Hvalue = Scale(self.root, from_=0, to=255, orient=HORIZONTAL, command=self.__sliderCallback) self.Hvalue.grid(row=1, column=1) self.Hvalue.set(0) self.Svalue = Scale(self.root, from_=0, to=255, orient=HORIZONTAL, command=self.__sliderCallback) self.Svalue.grid( row=2, column=1) self.Svalue.set(90) self.Vvalue = Scale(self.root, from_=0, to=255, orient=HORIZONTAL, command=self.__sliderCallback) self.Vvalue.grid( row=3, column=1) self.Vvalue.set(0) self.HvalueMax = Scale(self.root, from_=0, to=255, orient=HORIZONTAL, command=self.__sliderCallback) self.HvalueMax.grid(row=4, column=1) self.HvalueMax.set(255) self.SvalueMax = Scale(self.root, from_=0, to=255, orient=HORIZONTAL, command=self.__sliderCallback) self.SvalueMax.grid(row=5, column=1) self.SvalueMax.set(255) self.VvalueMax = Scale(self.root, from_=0, to=255, orient=HORIZONTAL, command=self.__sliderCallback) self.VvalueMax.grid(row=6, column=1) self.VvalueMax.set(120) self.Go = tk.Button(self.root, text="Go!", fg="Green", command=self.Funkify) self.Go.grid(row=7, column=0) self.QUIT = tk.Button(self.root, text="QUIT", fg="red", command=self.root.destroy) self.QUIT.grid(row=7, column=1) def Funkify(self): H = int(self.Hvalue.get()) S = int(self.Svalue.get()) V = int(self.Vvalue.get()) lower = [H, S, V] Hmax = int(self.HvalueMax.get()) Smax = int(self.SvalueMax.get()) Vmax = int(self.VvalueMax.get()) upper= [Hmax, Smax, Vmax] #self.valueLabel['text'] = '{0}-{1}-{2} to {3}-{4}-{5}'.format(H, S, V, Hmax, Smax, Vmax) output, a = self.Webcam.funkyfy(colorrange=(lower, upper)) cv2.imshow(self.title, numpy.hstack([output, a])) def __sliderCallback(self, args): print('Sliding!!')
class Visual(Frame): '''Class that takes a world as argument and present it graphically on a tkinter canvas.''' def __init__(self): ''' Sets up a simulation GUI in tkinter. ''' Frame.__init__(self) self.master.title("The Schelling Segregation Model in Python") self.master.wm_resizable(0, 0) self.grid() self.movement_possible = True # --------------------------------------- # # --------- FRAMES FOR GUI -------------- # # --------------------------------------- # # The pane for user values self._entryPane = Frame(self, borderwidth=5, relief='sunken') self._entryPane.grid(row=0, column=0, sticky='n') # The buttons pane self._buttonPane = Frame(self, borderwidth=5) self._buttonPane.grid(row=1, column=0, sticky='n') # A temp pane where graph is located, just for cosmetic reasons width, height = 425, 350 self._graph = Canvas(self, width=width, height=height, background="black") self._graph.configure(relief='sunken', border=2) self._graph.grid(row=3, column=0) # The pane where the canvas is located self._animationPane = Frame(self, borderwidth=5, relief='sunken') self._animationPane.grid(row=0, column=1, rowspan=4, pady=10, sticky="n") # --------------------------------------- # # --------- FILLING THE FRAMES ---------- # # --------------------------------------- # self._canvas() # Create graphics canvas self._entry() # Create entry widgets self._buttons() # Create button widgets def _plot_setup(self, time): '''Method for crudely annotating the graph window.''' time = time # Main plot width, height = 425, 350 y0 = -time/10 self._graph = Canvas(self, width=width, height=height, background="black", borderwidth=5) self._graph.grid(row=3, column=0) self.trans = Plotcoords(width, height, y0, -0.2, time, 1.3) x, y = self.trans.screen(time // 2, 1.2) x1, y1 = self.trans.screen(time // 2, 1.13) self._graph.create_text(x, y, text="% Happy", fill="green", font="bold 12") self._graph.create_text(x1, y1, text="% Unhappy", fill="red", font="bold 12") # Line x-axis x, y = self.trans.screen((-5 * (time / 100)), -0.05) x1, y = self.trans.screen(time, -0.05) self._graph.create_line(x, y, x1, y, fill="white", width=1.5) # Text x-axis x_text, y_text = self.trans.screen(time / 2, -0.15) self._graph.create_text(x_text, y_text, text="Time", fill="white", font="bold 12") # Line y-axis x, y = self.trans.screen((-0.5 * (time / 100)), -0.05) x, y1 = self.trans.screen((-5 * (time / 100)), 1) self._graph.create_line(x, y, x, y1, fill="white", width=1.5) def _entry(self): '''Method for creating widgets for collecting user input.''' # N (no of turtles) dim = 30*30 self.fill_label = Label(self._entryPane, anchor='w', justify='left', text='Fill', relief='raised', width=12, height=1, font='italic 20') self.fill_label.grid(row=0, column=1, ipady=14) self.fill = Scale(self._entryPane, from_=0, to=1, resolution=0.01, bd=3, relief='sunken', orient='horizontal', length=235, tickinterval=20) self.fill.grid(row=0, column=2) self.fill.set(0.8) self._N_label = Label(self._entryPane, anchor='w', justify='left', text="N:", relief='raised', width=12, height=1, font="italic 20") self._N_label.grid(row=1, column=1, ipady=14) self._N = Scale(self._entryPane, from_=0, to=100, resolution=1, bd=3, relief='sunken', orient='horizontal', length=235, tickinterval=20) self._N.set(30) self._N.grid(row=1, column=2) # Ticks (length of simulation) self._Ticks_label = Label(self._entryPane, anchor='w', justify='left', text="Time:", relief='raised', width=12, height=1, font="bold 20") self._Ticks_label.grid(row=2, column=1, ipady=14) self._Ticks = Scale(self._entryPane, from_=10, to=1000, resolution=1, bd=3, relief='sunken', orient='horizontal', length=235, tickinterval=990) self._Ticks.set(500) self._Ticks.grid(row=2, column=2) # % similar wanted self._Similar_label = Label(self._entryPane, anchor='w', justify='left', text="Similar wanted:", relief='raised', width=12, height=1, font="bold 20") self._Similar_label.grid(row=3, column=1, ipady=14) self._Similar = Scale(self._entryPane, from_=0.0, to=1.0, resolution=0.01, bd=3, relief='sunken', orient='horizontal', length=235, tickinterval=0.5) self._Similar.set(0.76) self._Similar.grid(row=3, column=2) # Delay between steps self._delay_label = Label(self._entryPane, anchor='w', justify='left', text="Delay (s):", relief='raised', width=12, height=1, font="bold 20") self._delay_label.grid(row=4, column=1, ipady=14) self._delay = Scale(self._entryPane, from_=0.0, to=1.0, resolution=0.01, bd=3, relief='sunken', orient='horizontal', length=235, tickinterval=0.5) self._delay.set(0.15) self._delay.grid(row=4, column=2) def _buttons(self): '''Method for creating button widgets for setting up, running and plotting results from simulation.''' width = 7 height = 1 # The 'Setup' button self._setupButton = Button(self._buttonPane, text="Setup", command=self._setup, width=width, height=height, font="bold 30", relief='raised', borderwidth=5) self._setupButton.grid(row=0, column=0) # The 'Go' button self._goButton = Button(self._buttonPane, text="Go", command=self._go, width=width, height=height, font="bold 30", relief='raised', borderwidth=5) self._goButton.grid(row=0, column=1) # The 'Quit' button self._quitButton = Button(self._buttonPane, text="Quit", command=self._quit, width=width, height=height, font="bold 30", relief='raised', borderwidth=5) self._quitButton.grid(row=1, column=0, columnspan=2) def _canvas(self): '''Creates the canvas on which everything happens.''' # The tick counter information self._Tick_counter = Label(self._animationPane, anchor='w', justify='left', text="Time:", width=5, font="bold 20") self._Tick_counter.grid(row=0, column=0, sticky="e") self._Tick_counter1 = Label(self._animationPane, justify='center', text="", relief='raised', width=5, font="bold 20") self._Tick_counter1.grid(row=0, column=1, sticky='w') self.canvas_w, self.canvas_h = 750, 750 self.canvas = Canvas(self._animationPane, width=self.canvas_w, height=self.canvas_h, background="black") self.canvas.grid(row=1, column=0, columnspan=2) def _setup(self): '''Method for 'Setup' button.''' # Clearing the canvas and reset the go button self.canvas.delete('all') self._goButton['relief'] = 'raised' self.N = int(self._N.get()) self.Ticks = int(self._Ticks.get()) self.similar = float(self._Similar.get()) self.data = [] self.tick_counter = 0 self._Tick_counter1['text'] = str(self.tick_counter) self._plot_setup(self.Ticks) self.grid_size = self.N self.world = World(750, 750, self.grid_size) self.create_turtles() self.neighbouring_turtles() self.draw_turtles() def _go(self): '''Method for the 'Go' button, i.e. running the simulation.''' self._goButton['relief'] = 'sunken' if self.tick_counter <= self.Ticks: self._Tick_counter1['text'] = str(self.tick_counter) self.canvas.update() self._graph.update() self._graph.after(0) # Data collection turtles_unhappy = self.check_satisfaction() prop_happy, prop_unhappy = self.calc_prop_happy(self.tick_counter) self.data_collection(self.tick_counter, prop_happy, prop_unhappy) if self.tick_counter >= 1: # HAPPY values (%) x0 = self.tick_counter-1 x1 = self.tick_counter # Collecting values from stored data y0 = self.data[self.tick_counter-1][1] y1 = self.data[self.tick_counter][1] # Transforming to tkinter x1, y1 = self.trans.screen(x1, y1) x0, y0 = self.trans.screen(x0, y0) self._graph.create_line(x0, y0, x1, y1, fill="green", width=1.3, tag="happy") # Draw "happy lines # UNHAPPY values (%) x0 = self.tick_counter-1 x1 = self.tick_counter # Collecting values from stored data y0 = self.data[self.tick_counter-1][2] y1 = self.data[self.tick_counter][2] # Transforming to tkinter x1, y1 = self.trans.screen(x1, y1) x0, y0 = self.trans.screen(x0, y0) self._graph.create_line(x0, y0, x1, y1, fill="red", width=1.1, tag="unhappy") # Draw unhappy lines if prop_happy < 1: self.turtle_move(turtles_unhappy) time.sleep(self._delay.get()) self.update_neighbours() self.tick_counter += 1 self.canvas.after(0, self._go()) self._goButton['relief'] = 'raised' def _quit(self): '''Method for the 'Quit' button.''' self.master.destroy() # ------------------------------------------------------ # # ---------- FUNCTIONS CALLED AT EACH TICK ------------- # # ------------------------------------------------------ # def turtle_move(self, unhappy_turtles): '''Moves all the unhappy turtles (randomly).''' while unhappy_turtles: i = random.randint(0, len(unhappy_turtles)-1) turtle = unhappy_turtles.pop(i) turtle.move(self) def update_neighbours(self): '''Updates the turtles neigbour attributes. Called after all turtles have moved.''' for turtle in self.turtles: turtle.update_neighbours() def check_satisfaction(self): '''Checks to see if turtles are happy or not. Returns a list of unhappy turtles, i.e. turtles that should move. Called before the move method.''' for turtle in self.turtles: turtle.is_happy() unhappy_turtles = [] for element in self.turtles: if not element.happy: unhappy_turtles.append(element) return unhappy_turtles def calc_prop_happy(self, i): '''Calculates the proportion of happy turtles.''' happy = 0 unhappy = 0 for turtle in self.turtles: if turtle.happy: happy += 1 else: unhappy += 1 prop_happy = happy/len(self.turtles) prop_unhappy = unhappy/len(self.turtles) return prop_happy, prop_unhappy def data_collection(self, i, prop_happy, prop_unhappy): '''Method for collecting data at each tick.''' self.data.append((i, prop_happy, prop_unhappy)) # ------------------------------------------------------ # # ---------- INITIALISATION FUNCTIONS ------------------ # # ------------------------------------------------------ # def create_turtles(self): '''Method for creating a new list of turtles. Upon creation they are registered in the World object.''' if self.N*self.N <= self.grid_size*self.grid_size: counter = 0 self.turtles = [] while counter < self.N * self.N * self.fill.get(): s = "S"+str(counter) if counter <= int(self.N * self.N * self.fill.get() / 2): color = "green" else: color = "red" x = random.randint(0, self.grid_size-1) y = random.randint(0, self.grid_size-1) if not self.world.patch_list[x][y]: new_turtle = Schelling(world=self.world, x=x, y=y, s=s, color=color, similar_wanted=self.similar) self.world.register(new_turtle) counter += 1 self.turtles.append(new_turtle) else: print("Number of turtles exceeds world!") def draw_turtles(self): '''Method for drawing turtles on canvas. Calls each turtle's own method for drawing.''' for turtle in self.turtles: turtle.draw(self.canvas) def neighbouring_turtles(self): '''Method for updating turtles' neighbours. Calls on each turtle's own method for updating neighbours.''' for turtle in self.turtles: turtle.get_neighbouring_patches()
class ipGUI: def __init__(self, master): self.master = master self.master.minsize(width=800, height=600) menu = Menu(self.master) master.config(menu=menu) # ***** Main Menu ***** # *** file menu *** fileMenu = Menu(menu) menu.add_cascade(label='File', menu=fileMenu) fileMenu.add_command(label="Open", command=self.openImage) fileMenu.add_command(label="Load Blur Kernel", command=self.loadKernel) fileMenu.add_command(label="Save", command=self.saveImage) fileMenu.add_command(label="Exit", command=master.destroy) # *** edit menu *** editMenu = Menu(menu) menu.add_cascade(label='Space', menu=editMenu) editMenu.add_command(label="Histogram Equalization", command=self.histWrap) editMenu.add_command(label="Gamma Correction", command=self.gammaCorWrap) editMenu.add_command(label="Log Transform", command=self.logTranWrap) editMenu.add_command(label="Sharpen", command=self.sharpWrap) editMenu.add_command(label="Cartoonify", command=self.cartoonifyWrap) # *** blur menu *** blurMenu = Menu(editMenu) editMenu.add_cascade(label='Blur', menu=blurMenu) blurMenu.add_command(label="Box", command=self.boxBlurWrap) blurMenu.add_command(label="Gaussian", command=self.gaussianBlurWrap) blurMenu.add_command(label="Median", command=self.medianBlurWrap) # *** frequency filtering *** freqMenu = Menu(menu) menu.add_cascade(label='Frequency', menu=freqMenu) freqMenu.add_command(label="DFT", command=self.dftWrap) freqMenu.add_command(label="Load Mask", command=self.freqMaskWrap) # *** Mask Menu *** maskMenu = Menu(freqMenu) freqMenu.add_cascade(label='Create Mask', menu=maskMenu) maskMenu.add_command(label='Low Pass', command=self.lpmWrap) maskMenu.add_command(label='High Pass', command=self.hpmWrap) maskMenu.add_command(label='Band Pass', command=self.bppmWrap) maskMenu.add_command(label='Band Stop', command=self.bspmWrap) # *** frequency filtering *** restorationMenu = Menu(menu) menu.add_cascade(label='Restoration', menu=restorationMenu) restorationMenu.add_command(label="Full Inverse", command=self.fullInverseWrap) restorationMenu.add_command(label="Radially Limited Inverse", command=self.truncatedInverseWrap) restorationMenu.add_command(label="Approximate Weiner", command=self.approximateWeinerWrap) restorationMenu.add_command(label="Constrained LS", command=self.contrainedLSWrap) # ***** Toolbar ***** toolbar = Frame(master, bg="grey") undoButton = Button(toolbar, text="Undo", command=self.undoFunc) undoButton.pack(side=LEFT) origButton = Button(toolbar, text="Original", command=self.origFunc) origButton.pack(side=LEFT) toolbar.pack(side=TOP, fill=X) # ***** Image Display Area ***** self.frame = Frame(self.master) self.frame.pack() self.panel = Label(self.frame) self.panel.pack(padx=10, pady=10) self.img = None self.origImg = None self.prevImg = None # ***** Gamma Controls ***** self.gammaFrame = Frame(self.master) self.gammaSlider = Scale(self.gammaFrame, from_=0.1, to=2, orient=HORIZONTAL, resolution=0.1) self.gammaSlider.pack(side=TOP) self.gammaExitButton = Button(self.gammaFrame, text="Exit", command=self.gammaFrame.pack_forget) self.gammaExitButton.pack(side=TOP) # ***** Box Blur Controls ***** self.boxFrame = Frame(self.master) self.boxSlider = Scale(self.boxFrame, from_=1, to=5, orient=HORIZONTAL) self.boxSlider.pack(side=TOP) self.boxExitButton = Button(self.boxFrame, text="Exit", command=self.boxFrame.pack_forget) self.boxExitButton.pack(side=TOP) # ***** Truncated Inverse Controls ***** self.truncatedInverseFrame = Frame(self.master) self.truncatedInverseSlider = Scale(self.truncatedInverseFrame, from_=-3, to=2, orient=HORIZONTAL, resolution=0.1) self.truncatedInverseSlider.pack(side=TOP) self.truncatedInverseExitButton = Button( self.truncatedInverseFrame, text="Exit", command=self.truncatedInverseFrame.pack_forget) self.truncatedInverseExitButton.pack(side=TOP) # ***** Weiner Controls ***** self.weinerFrame = Frame(self.master) self.weinerSlider = Scale(self.weinerFrame, from_=-3, to=2, orient=HORIZONTAL, resolution=0.1) self.weinerSlider.pack(side=TOP) self.weinerExitButton = Button(self.weinerFrame, text="Exit", command=self.weinerFrame.pack_forget) self.weinerExitButton.pack(side=TOP) # ***** CLS Controls ***** self.clsFrame = Frame(self.master) self.clsSlider = Scale(self.clsFrame, from_=-3, to=2, orient=HORIZONTAL, resolution=0.1) self.clsSlider.pack(side=TOP) self.clsExitButton = Button(self.clsFrame, text="Exit", command=self.clsFrame.pack_forget) self.clsExitButton.pack(side=TOP) # ***** DFT Display Area ****** self.dftFrame = Frame(self.master) self.magPanel = Label(self.dftFrame) self.magPanel.pack(padx=10, pady=10, side=TOP) self.freqPanel = Label(self.dftFrame) self.freqPanel.pack(padx=10, pady=10, side=TOP) self.dftExitButton = Button( self.dftFrame, text="Exit", command=lambda: self.displayImg(np.array(self.img))) self.dftExitButton.pack(side=TOP, fill=X) # ***** Low Pass Mask Creation ***** self.lpmFrame = Frame(self.master) self.lpmPanel = Label(self.lpmFrame) self.lpmPanel.pack(padx=10, pady=10, side=TOP) self.lpmSubButton = Button(self.lpmFrame, text="submit") self.lpmSubButton.pack(side=TOP) self.lpmExitButton = Button( self.lpmFrame, text="Exit", command=lambda: self.displayImg(np.array(self.img))) self.lpmExitButton.pack(side=TOP) self.lpmSlider = Scale(self.lpmFrame, from_=1, to=2, orient=HORIZONTAL, resolution=1) # ***** High Pass Mask Creation ***** self.hpmFrame = Frame(self.master) self.hpmPanel = Label(self.hpmFrame) self.hpmPanel.pack(padx=10, pady=10, side=TOP) self.hpmSubButton = Button(self.hpmFrame, text="submit") self.hpmSubButton.pack(side=TOP) self.hpmExitButton = Button( self.hpmFrame, text="Exit", command=lambda: self.displayImg(np.array(self.img))) self.hpmExitButton.pack(side=TOP) self.hpmSlider = Scale(self.hpmFrame, from_=1, to=2, orient=HORIZONTAL, resolution=1) # ***** Band Pass Mask Creation ***** self.bppmFrame = Frame(self.master) self.bppmPanel = Label(self.bppmFrame) self.bppmPanel.pack(padx=10, pady=10, side=TOP) self.bppmSubButton = Button(self.bppmFrame, text="submit") self.bppmSubButton.pack(side=TOP) self.bppmExitButton = Button( self.bppmFrame, text="Exit", command=lambda: self.displayImg(np.array(self.img))) self.bppmExitButton.pack(side=TOP) self.bppmSliderLow = Scale(self.bppmFrame, from_=1, to=2, orient=HORIZONTAL, resolution=1) self.bppmSliderHigh = Scale(self.bppmFrame, from_=1, to=2, orient=HORIZONTAL, resolution=1) # ***** Band Pass Mask Creation ***** self.bspmFrame = Frame(self.master) self.bspmPanel = Label(self.bspmFrame) self.bspmPanel.pack(padx=10, pady=10, side=TOP) self.bspmSubButton = Button(self.bspmFrame, text="submit") self.bspmSubButton.pack(side=TOP) self.bspmExitButton = Button( self.bspmFrame, text="exit", command=lambda: self.displayImg(np.array(self.img))) self.bspmExitButton.pack(side=TOP) self.bspmSliderLow = Scale(self.bspmFrame, from_=1, to=2, orient=HORIZONTAL, resolution=1) self.bspmSliderHigh = Scale(self.bspmFrame, from_=1, to=2, orient=HORIZONTAL, resolution=1) def displayImg(self, img): # input image in RGB self.frame.pack() self.dftFrame.pack_forget() self.lpmFrame.pack_forget() self.hpmFrame.pack_forget() self.bppmFrame.pack_forget() self.bspmFrame.pack_forget() self.img = Image.fromarray(img) imgtk = ImageTk.PhotoImage(self.img) self.panel.configure(image=imgtk) self.panel.image = imgtk def openImage(self): # can change the image path = filedialog.askopenfilename() if len(path) > 0: imgRead = cv2.imread(path) if imgRead is not None: imgRead = cv2.cvtColor(imgRead, cv2.COLOR_BGR2RGB) self.origImg = Image.fromarray(imgRead) self.prevImg = Image.fromarray(imgRead) self.displayImg(imgRead) else: raise ValueError("Not a valid image") else: raise ValueError("Not a valid path") def loadKernel(self): path = filedialog.askopenfilename() if len(path) > 0: self.filter_kernel = np.mean(cv2.imread(path), axis=-1) self.filter_kernel = self.filter_kernel / np.sum( self.filter_kernel) else: raise ValueError("Not a valid path") def saveImage(self): if self.img is not None: toSave = filedialog.asksaveasfilename() self.img.save(toSave) else: messagebox.showerror(title="Save Error", message="No image to be saved!") def histWrap(self): img = np.array(self.img) self.prevImg = self.img imgNew = image_utils.histEqlFunc(img) self.displayImg(imgNew) # Gamma Correction def gammaCallback(self, event, img): gamma = self.gammaSlider.get() self.prevImg = self.img imgNew = image_utils.gammaCorFunc(img, 255.0 / (255.0**gamma), gamma) self.displayImg(imgNew) def truncatedInverseCallback(self, event, img): th = 10**self.truncatedInverseSlider.get() imgNew = self.truncatedInverseFilter(th) self.displayImg(imgNew) def weinerCallback(self, event, img): gamma = 10**self.weinerSlider.get() imgNew = self.weinerFilter(gamma) self.displayImg(imgNew) def clsCallback(self, event, img): K = 10**self.clsSlider.get() imgNew = self.clsFilter(K) self.displayImg(imgNew) def gammaCorWrap(self): img = np.array(self.img) self.gammaFrame.pack() self.gammaSlider.set(1.0) self.gammaSlider.bind( "<ButtonRelease-1>", lambda event, img=img: self.gammaCallback(event, img)) def logTranWrap(self): img = np.array(self.img) self.prevImg = self.img imgNew = image_utils.logTranFunc(img, 255.0 / np.log10(256)) self.displayImg(imgNew) def sharpWrap(self): # Sharpen Wrapper img = np.array(self.img) self.prevImg = self.img imgNew = image_utils.sharpFunc(img) self.displayImg(imgNew) def boxBlurWrap(self): # Box Blur Wrapper img = np.array(self.img) self.prevImg = self.img self.boxFrame.pack() self.boxSlider.set(1) self.boxSlider.bind("<ButtonRelease-1>", lambda event, img=img: self.displayImg( image_utils.boxBlurFunc( event, img, 2 * self.boxSlider.get() + 1))) def gaussianBlurWrap(self): # Gaussian Blur Wrapper img = np.array(self.img) self.prevImg = self.img imgNew = image_utils.gaussianBlurFunc(img) self.displayImg(imgNew) def medianBlurWrap(self): # Median Blur Wrapper img = np.array(self.img) self.prevImg = self.img imgNew = image_utils.medianBlurFunc(img) self.displayImg(imgNew) def cartoonifyWrap(self): img = np.array(self.img) self.prevImg = self.img imgNew = image_utils.cartoonifyFunc(img) self.displayImg(imgNew) def undoFunc(self): self.img = self.prevImg self.displayImg(np.array(self.img)) def origFunc(self): self.prevImg = self.img self.img = self.origImg self.displayImg(np.array(self.img)) def displayDFT(self, x_fft): m, n = x_fft.shape[:] self.frame.pack_forget() self.dftFrame.pack() x_mag = np.log10(np.absolute(x_fft)) * 255 / np.log10(m * n * 255) x_mag = Image.fromarray(x_mag) x_mag = x_mag.resize((min(256, m), min(int(256 * n / m), n)), Image.ANTIALIAS) x_mag = ImageTk.PhotoImage(x_mag) x_freq = (np.angle(x_fft) % 360) * 255 / 360 x_freq = Image.fromarray(x_freq) x_freq = x_freq.resize((min(256, m), min(int(256 * n / m), n)), Image.ANTIALIAS) x_freq = ImageTk.PhotoImage(x_freq) self.magPanel.configure(image=x_mag) self.magPanel.image = x_mag self.freqPanel.configure(image=x_freq) self.freqPanel.image = x_freq def dftWrap(self): img = np.array(self.img) x = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) x_outp_img = fft.fft2d_img(x) self.displayDFT(x_outp_img) def freqMaskWrap(self): m, n = np.array(self.img).shape[:2] lm, ln = np.log2(m), np.log2(m) dm, dn = int(2**np.ceil(lm)) + 1, int(2**np.ceil(ln)) + 1 messagebox.showinfo( "Mask Size", "Mask Size should be (" + str(dm) + "," + str(dn) + ")") path = filedialog.askopenfilename() if len(path) > 0: maskRead = cv2.imread(path, 0) if (maskRead.shape != (dm, dn)): messagebox.showerror( title="Shape Error", message="Shape of mask and image don't match") else: self.prevImg = self.img self.display(image_utils.freqMask(np.array(self.img), maskRead)) else: raise ValueError("Not a valid path") def maskWrap(self): img = np.array(self.img) x = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) x_outp_img = fft.fft2d_img(x) x_mag = image_utils.xMagCreate(x_outp_img) return x_outp_img, x_mag def maskFinal(self, x_outp_img): self.prevImg = self.img img = np.array(self.img) img = cv2.cvtColor(img, cv2.COLOR_RGB2HSV) m = len(img) res = fft.ifft2d_img(x_outp_img) res = np.array(res * 255 / np.max(res), dtype=np.uint8) res = np.array([[[img[i][j][0], img[i][j][1], res[i][j]] for j in range(m)] for i in range(m)]) res = cv2.cvtColor(res, cv2.COLOR_HSV2RGB) self.displayImg(res) def lpmCallBack(self, event, slider, x_outp_img): m = len(x_outp_img) m2 = int((m - 1) / 2) r = slider.get() x_outp_copy = np.copy(x_outp_img) nCircle = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(m)] for i in range(m)]) nCircle = np.where(nCircle > r**2) x_outp_copy[nCircle] = 1 x_mag = image_utils.xMagCreate(x_outp_copy) self.lpmPanel.configure(image=x_mag) self.lpmPanel.image = x_mag def lpmFinal(self, x_outp_img): mx = len(x_outp_img) m2 = int((mx - 1) / 2) r = self.lpmSlider.get() nCircle = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(mx)] for i in range(mx)]) nCircle = np.where(nCircle > r**2) x_outp_img[nCircle] = 0 self.maskFinal(x_outp_img) def lpmWrap(self): x_outp_img, x_mag = self.maskWrap() m = len(x_outp_img) self.lpmPanel.configure(image=x_mag) self.lpmPanel.image = x_mag self.lpmSlider.configure(to=int(np.ceil(m / 2))) self.lpmSlider.set(1) self.lpmSlider.pack(side=TOP) self.lpmSlider.bind( "<ButtonRelease-1>", lambda event, slider=self.lpmSlider, x_outp_img=x_outp_img: self. lpmCallBack(event, slider, x_outp_img)) self.lpmSubButton.configure( command=lambda x_outp_img=x_outp_img: self.lpmFinal(x_outp_img)) self.dftFrame.pack_forget() self.frame.pack_forget() self.hpmFrame.pack_forget() self.bppmFrame.pack_forget() self.bspmFrame.pack_forget() self.lpmFrame.pack() def hpmCallBack(self, event, slider, x_outp_img): mx = len(x_outp_img) m2 = int((mx - 1) / 2) r = slider.get() x_outp_copy = np.copy(x_outp_img) circle = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(mx)] for i in range(mx)]) circle = np.where(circle <= r**2) x_outp_copy[circle] = 1 x_mag = image_utils.xMagCreate(x_outp_copy) self.hpmPanel.configure(image=x_mag) self.hpmPanel.image = x_mag def hpmFinal(self, x_outp_img): mx = len(x_outp_img) m2 = int((mx - 1) / 2) r = self.hpmSlider.get() circle = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(mx)] for i in range(mx)]) circle = np.where(circle <= r**2) x_outp_img[circle] = 0 self.maskFinal(x_outp_img) def hpmWrap(self): x_outp_img, x_mag = self.maskWrap() m = len(x_outp_img) self.hpmPanel.configure(image=x_mag) self.hpmPanel.image = x_mag self.hpmSlider.configure(to=m // 2) self.hpmSlider.set(1) self.hpmSlider.pack(side=TOP) self.hpmSlider.bind( "<ButtonRelease-1>", lambda event, slider=self.hpmSlider, x_outp_img=x_outp_img: self. hpmCallBack(event, slider, x_outp_img)) self.hpmSubButton.configure( command=lambda x_outp_img=x_outp_img: self.hpmFinal(x_outp_img)) self.dftFrame.pack_forget() self.frame.pack_forget() self.lpmFrame.pack_forget() self.bppmFrame.pack_forget() self.bspmFrame.pack_forget() self.hpmFrame.pack() def bppmCallBack(self, event, x_outp_img): mx = len(x_outp_img) m2 = int((mx - 1) / 2) r1 = self.bppmSliderLow.get() r2 = self.bppmSliderHigh.get() assert (r1 <= r2) self.bppmSliderLow.configure(to=r2) self.bppmSliderHigh.configure(from_=r1) x_outp_copy = np.copy(x_outp_img) allVals = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(mx)] for i in range(mx)]) nullVals = np.where(allVals < r1**2) x_outp_copy[nullVals] = 1 nullVals = np.where(allVals > r2**2) x_outp_copy[nullVals] = 1 x_mag = image_utils.xMagCreate(x_outp_copy) self.bppmPanel.configure(image=x_mag) self.bppmPanel.image = x_mag def bppmFinal(self, x_outp_img): mx = len(x_outp_img) m2 = int((mx - 1) / 2) r1 = self.bppmSliderLow.get() r2 = self.bppmSliderHigh.get() allVals = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(mx)] for i in range(mx)]) nullVals = np.where(allVals < r1**2) x_outp_img[nullVals] = 0 nullVals = np.where(allVals > r2**2) x_outp_img[nullVals] = 0 self.maskFinal(x_outp_img) def bppmWrap(self): x_outp_img, x_mag = self.maskWrap() m = len(x_outp_img) self.bppmPanel.configure(image=x_mag) self.bppmPanel.image = x_mag self.bppmSliderHigh.configure(from_=1) self.bppmSliderHigh.configure(to=m // 2) self.bppmSliderHigh.set(m // 2) self.bppmSliderHigh.pack(side=TOP) self.bppmSliderHigh.bind("<ButtonRelease-1>", lambda event, x_outp_img=x_outp_img: self. bppmCallBack(event, x_outp_img)) self.bppmSliderLow.configure(from_=1) self.bppmSliderLow.configure(to=m // 2) self.bppmSliderLow.set(1) self.bppmSliderLow.pack(side=TOP) self.bppmSliderLow.bind("<ButtonRelease-1>", lambda event, x_outp_img=x_outp_img: self. bppmCallBack(event, x_outp_img)) self.bppmSubButton.configure( command=lambda x_outp_img=x_outp_img: self.bppmFinal(x_outp_img)) self.dftFrame.pack_forget() self.frame.pack_forget() self.lpmFrame.pack_forget() self.hpmFrame.pack_forget() self.bspmFrame.pack_forget() self.bppmFrame.pack() def bspmCallBack(self, event, x_outp_img): mx = len(x_outp_img) m2 = int((mx - 1) / 2) r1 = self.bspmSliderLow.get() r2 = self.bspmSliderHigh.get() assert (r1 <= r2) self.bspmSliderLow.configure(to=r2) self.bspmSliderHigh.configure(from_=r1) x_outp_copy = np.copy(x_outp_img) allVals = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(mx)] for i in range(mx)]) nullVals = np.where((allVals - r1**2) * (allVals - r2**2) < 0) x_outp_copy[nullVals] = 1 x_mag = image_utils.xMagCreate(x_outp_copy) self.bspmPanel.configure(image=x_mag) self.bspmPanel.image = x_mag def bspmFinal(self, x_outp_img): mx = len(x_outp_img) m2 = int((mx - 1) / 2) r1 = self.bspmSliderLow.get() r2 = self.bspmSliderHigh.get() allVals = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(mx)] for i in range(mx)]) nullVals = np.where((allVals - r1**2) * (allVals - r2**2) < 0) x_outp_img[nullVals] = 0 self.maskFinal(x_outp_img) def bspmWrap(self): x_outp_img, x_mag = self.maskWrap() m = len(x_outp_img) self.bspmPanel.configure(image=x_mag) self.bspmPanel.image = x_mag self.bspmSliderHigh.configure(from_=1) self.bspmSliderHigh.configure(to=m // 2) self.bspmSliderHigh.set(m // 2) self.bspmSliderHigh.pack(side=TOP) self.bspmSliderHigh.bind("<ButtonRelease-1>", lambda event, x_outp_img=x_outp_img: self. bspmCallBack(event, x_outp_img)) self.bspmSliderLow.configure(from_=1) self.bspmSliderLow.configure(to=m // 2) self.bspmSliderLow.set(1) self.bspmSliderLow.pack(side=TOP) self.bspmSliderLow.bind("<ButtonRelease-1>", lambda event, x_outp_img=x_outp_img: self. bspmCallBack(event, x_outp_img)) self.bspmSubButton.configure( command=lambda x_outp_img=x_outp_img: self.bspmFinal(x_outp_img)) self.dftFrame.pack_forget() self.frame.pack_forget() self.lpmFrame.pack_forget() self.hpmFrame.pack_forget() self.bppmFrame.pack_forget() self.bspmFrame.pack() def fullInverseWrap(self): img = np.array(self.img) self.prevImg = self.img imgNew = filtering.inverseFilter2D(img, self.filter_kernel) self.displayImg(imgNew) def truncatedInverseWrap(self): img = np.array(self.img) self.prevImg = self.img self.truncatedInverseFilter = filtering.getTruncatedInverseFilter2D( img, self.filter_kernel) self.truncatedInverseFrame.pack() self.truncatedInverseSlider.set(1.0) self.truncatedInverseSlider.bind( "<ButtonRelease-1>", lambda event, img=img: self.truncatedInverseCallback(event, img)) def approximateWeinerWrap(self): img = np.array(self.img) self.prevImg = self.img self.weinerFilter = filtering.getApproximateWeinerFilter2D( img, self.filter_kernel) self.weinerFrame.pack() self.weinerSlider.set(1.0) self.weinerSlider.bind( "<ButtonRelease-1>", lambda event, img=img: self.weinerCallback(event, img)) def contrainedLSWrap(self): # TODO: implement img = np.array(self.img) self.prevImg = self.img self.clsFilter = filtering.getConstrainedLSFilter2D( img, self.filter_kernel) self.clsFrame.pack() self.clsSlider.set(1.0) self.clsSlider.bind( "<ButtonRelease-1>", lambda event, img=img: self.clsCallback(event, img))
class TelloUI: """Wrapper class to enable the GUI.""" def __init__(self, tello, outputpath): """ Initial all the element of the GUI,support by Tkinter :param tello: class interacts with the Tello drone. Raises: RuntimeError: If the Tello rejects the attempt to enter command mode. """ self.tello = tello # videostream device self.outputPath = outputpath # the path that save pictures created by clicking the takeSnapshot button self.frame = None # frame read from h264decoder and used for pose recognition self.thread = None # thread of the Tkinter mainloop self.stopEvent = None # control variables self.distance = 0.1 # default distance for 'move' cmd self.degree = 30 # default degree for 'cw' or 'ccw' cmd # if the pose recognition mode is opened self.pose_mode = False # if the flag is TRUE,the auto-takeoff thread will stop waiting for the response from tello self.quit_waiting_flag = False # if the flag is TRUE,the pose recognition skeleton will be drawn on the GUI picture self.draw_skeleton_flag = False # pose recognition self.my_tello_pose = Tello_Pose() # record the coordinates of the nodes in the pose recognition skeleton self.points = [] #list of all the possible connections between skeleton nodes self.POSE_PAIRS = [[0, 1], [1, 2], [2, 3], [3, 4], [1, 5], [5, 6], [6, 7], [1, 14], [14, 8], [8, 9], [9, 10], [14, 11], [11, 12], [12, 13]] # initialize the root window and image panel self.root = tki.Tk() self.panel = None # self.panel_for_pose_handle_show = None # create buttons self.btn_snapshot = tki.Button(self.root, text="Snapshot!", command=self.takeSnapshot) self.btn_snapshot.pack(side="bottom", fill="both", expand="yes", padx=10, pady=5) self.btn_pose = tki.Button(self.root, text="Pose Recognition Status: Off", command=self.setPoseMode) self.btn_pose.pack(side="bottom", fill="both", expand="yes", padx=10, pady=5) self.btn_pause = tki.Button(self.root, text="Pause", relief="raised", command=self.pauseVideo) self.btn_pause.pack(side="bottom", fill="both", expand="yes", padx=10, pady=5) self.btn_landing = tki.Button(self.root, text="Open Command Panel", relief="raised", command=self.openCmdWindow) self.btn_landing.pack(side="bottom", fill="both", expand="yes", padx=10, pady=5) # start a thread that constantly pools the video sensor for # the most recently read frame self.stopEvent = threading.Event() self.thread = threading.Thread(target=self.videoLoop, args=()) self.thread.start() # set a callback to handle when the window is closed self.root.wm_title("TELLO Controller") self.root.wm_protocol("WM_DELETE_WINDOW", self.onClose) # the auto-takeoff thread will start if the 'takeoff' button on command window is clicked self.auto_takeoff_thread = threading.Thread(target=self._autoTakeoff) # the sending_command will send command to tello every 5 seconds self.sending_command_thread = threading.Thread( target=self._sendingCommand) self.get_GUI_Image_thread = threading.Thread(target=self._getGUIImage) def videoLoop(self): """ The mainloop thread of Tkinter Raises: RuntimeError: To get around a RunTime error that Tkinter throws due to threading. """ try: # start the thread that get GUI image and drwa skeleton time.sleep(0.5) self.get_GUI_Image_thread.start() while not self.stopEvent.is_set(): # read the frame for pose recognition self.frame = self.tello.read() if self.frame is None or self.frame.size == 0: continue # smoothing filter self.frame = cv2.bilateralFilter(self.frame, 5, 50, 100) cmd = '' self.points.append(None) # process pose-recognition if self.pose_mode: cmd, self.draw_skeleton_flag, self.points = self.my_tello_pose.detect( self.frame) # process command - map your motion to whatever Tello movement you want! if cmd == 'moveback': self.telloMoveBackward(0.50) elif cmd == 'moveforward': self.telloMoveForward(0.50) elif cmd == 'land': self.telloLanding() except RuntimeError as e: print("[INFO] caught a RuntimeError") def _getGUIImage(self): """ Main operation to read frames from h264decoder and draw skeleton on frames if the pose mode is opened """ # read the system of your computer system = platform.system() while not self.stopEvent.is_set(): # read the frame for GUI show frame = self.tello.read() if frame is None or frame.size == 0: continue if self.pose_mode: # Draw the detected skeleton points for i in range(15): if self.draw_skeleton_flag == True: cv2.circle(frame, self.points[i], 8, (0, 255, 255), thickness=-1, lineType=cv2.FILLED) cv2.putText(frame, "{}".format(i), self.points[i], cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2, lineType=cv2.LINE_AA) # Draw Skeleton for pair in self.POSE_PAIRS: partA = pair[0] partB = pair[1] if self.points[partA] and self.points[partB]: cv2.line(frame, self.points[partA], self.points[partB], (0, 255, 255), 2) cv2.circle(frame, self.points[partA], 8, (0, 0, 255), thickness=-1, lineType=cv2.FILLED) # transfer the format from frame to image image = Image.fromarray(frame) # we found compatibility problem between Tkinter,PIL and Macos,and it will # sometimes result the very long preriod of the "ImageTk.PhotoImage" function, # so for Macos,we start a new thread to execute the _updateGUIImage function. if system == "Windows" or system == "Linux": self._updateGUIImage(image) else: thread_tmp = threading.Thread(target=self._updateGUIImage, args=(image, )) thread_tmp.start() time.sleep(0.03) def _updateGUIImage(self, image): """ Main operation to initial the object of image,and update the GUI panel """ image = ImageTk.PhotoImage(image) # if the panel none ,we need to initial it if self.panel is None: self.panel = tki.Label(image=image) self.panel.image = image self.panel.pack(side="left", padx=10, pady=10) # otherwise, simply update the panel else: self.panel.configure(image=image) self.panel.image = image def _autoTakeoff(self): """ Firstly,it will waiting for the response that will be sent by Tello if Tello finish the takeoff command.If computer doesn't receive the response,it may be because tello doesn't takeoff normally,or because the UDP pack of response is lost.So in order to confirm the reason,computer will send 'height?'command to get several real-time height datas and get a average value.If the height is in normal range,tello will execute the moveup command.Otherwise,tello will land. Finally,the sending-command thread will start. """ response = None height_tmp = 0 # temp variable to content value of height height_val = 0 # average value of height cnt = 0 # effective number of height reading timeout = 6 # max waiting time of tello's response timer = threading.Timer(timeout, self._setQuitWaitingFlag) timer.start() # waiting for the response from tello while response != 'ok': if self.quit_waiting_flag is True: break response = self.tello.get_response() print("ack:%s" % response) timer.cancel() # receive the correct response if response == 'ok': self.tello.move_up(0.5) # calculate the height of tello else: for i in range(0, 50): height_tmp = self.tello.get_height() try: height_val = height_val + height_tmp cnt = cnt + 1 print(height_tmp, cnt) except: height_val = height_val height_val = height_val / cnt # if the height value is in normal range if height_val == 9 or height_val == 10 or height_val == 11: self.tello.move_up(0.5) else: self.tello.land() # start the sendingCmd thread self.sending_command_thread.start() def _sendingCommand(self): """ start a while loop that sends 'command' to tello every 5 second """ while True: self.tello.send_command('command') time.sleep(5) def _setQuitWaitingFlag(self): """ set the variable as TRUE,it will stop computer waiting for response from tello """ self.quit_waiting_flag = True def openCmdWindow(self): """ open the cmd window and initial all the button and text """ panel = Toplevel(self.root) panel.wm_title("Command Panel") # create text input entry text0 = tki.Label( panel, text= 'This Controller map keyboard inputs to Tello control commands\n' 'Adjust the trackbar to reset distance and degree parameter', font='Helvetica 10 bold') text0.pack(side='top') text1 = tki.Label( panel, text='W - Move Tello Up\t\t\tArrow Up - Move Tello Forward\n' 'S - Move Tello Down\t\t\tArrow Down - Move Tello Backward\n' 'A - Rotate Tello Counter-Clockwise\tArrow Left - Move Tello Left\n' 'D - Rotate Tello Clockwise\t\tArrow Right - Move Tello Right', justify="left") text1.pack(side="top") self.btn_landing = tki.Button(panel, text="Land", relief="raised", command=self.telloLanding) self.btn_landing.pack(side="bottom", fill="both", expand="yes", padx=10, pady=5) self.btn_takeoff = tki.Button(panel, text="Takeoff", relief="raised", command=self.telloTakeOff) self.btn_takeoff.pack(side="bottom", fill="both", expand="yes", padx=10, pady=5) # binding arrow keys to drone control self.tmp_f = tki.Frame(panel, width=100, height=2) self.tmp_f.bind('<KeyPress-w>', self.on_keypress_w) self.tmp_f.bind('<KeyPress-s>', self.on_keypress_s) self.tmp_f.bind('<KeyPress-a>', self.on_keypress_a) self.tmp_f.bind('<KeyPress-d>', self.on_keypress_d) self.tmp_f.bind('<KeyPress-Up>', self.on_keypress_up) self.tmp_f.bind('<KeyPress-Down>', self.on_keypress_down) self.tmp_f.bind('<KeyPress-Left>', self.on_keypress_left) self.tmp_f.bind('<KeyPress-Right>', self.on_keypress_right) self.tmp_f.pack(side="bottom") self.tmp_f.focus_set() self.btn_landing = tki.Button(panel, text="Flip", relief="raised", command=self.openFlipWindow) self.btn_landing.pack(side="bottom", fill="both", expand="yes", padx=10, pady=5) self.distance_bar = Scale(panel, from_=0.02, to=5, tickinterval=0.01, digits=3, label='Distance(m)', resolution=0.01) self.distance_bar.set(0.2) self.distance_bar.pack(side="left") self.btn_distance = tki.Button( panel, text="Reset Distance", relief="raised", command=self.updateDistancebar, ) self.btn_distance.pack(side="left", fill="both", expand="yes", padx=10, pady=5) self.degree_bar = Scale(panel, from_=1, to=360, tickinterval=10, label='Degree') self.degree_bar.set(30) self.degree_bar.pack(side="right") self.btn_distance = tki.Button(panel, text="Reset Degree", relief="raised", command=self.updateDegreebar) self.btn_distance.pack(side="right", fill="both", expand="yes", padx=10, pady=5) def openFlipWindow(self): """ open the flip window and initial all the button and text """ panel = Toplevel(self.root) panel.wm_title("Gesture Recognition") self.btn_flipl = tki.Button(panel, text="Flip Left", relief="raised", command=self.telloFlip_l) self.btn_flipl.pack(side="bottom", fill="both", expand="yes", padx=10, pady=5) self.btn_flipr = tki.Button(panel, text="Flip Right", relief="raised", command=self.telloFlip_r) self.btn_flipr.pack(side="bottom", fill="both", expand="yes", padx=10, pady=5) self.btn_flipf = tki.Button(panel, text="Flip Forward", relief="raised", command=self.telloFlip_f) self.btn_flipf.pack(side="bottom", fill="both", expand="yes", padx=10, pady=5) self.btn_flipb = tki.Button(panel, text="Flip Backward", relief="raised", command=self.telloFlip_b) self.btn_flipb.pack(side="bottom", fill="both", expand="yes", padx=10, pady=5) def takeSnapshot(self): """ save the current frame of the video as a jpg file and put it into outputpath """ # grab the current timestamp and use it to construct the filename ts = datetime.datetime.now() filename = "{}.jpg".format(ts.strftime("%Y-%m-%d_%H-%M-%S")) p = os.path.sep.join((self.outputPath, filename)) # save the file cv2.imwrite(p, cv2.cvtColor(self.frame, cv2.COLOR_RGB2BGR)) print(("[INFO] saved {}".format(filename))) def setPoseMode(self): """ Toggle the open/close of pose recognition mode """ if self.pose_mode is False: self.pose_mode = True self.btn_pose.config(text='Pose Recognition Status: On') else: self.pose_mode = False self.btn_pose.config(text='Pose Recognition Status: Off') def pauseVideo(self): """ Toggle the freeze/unfreze of video """ if self.btn_pause.config('relief')[-1] == 'sunken': self.btn_pause.config(relief="raised") self.tello.video_freeze(False) else: self.btn_pause.config(relief="sunken") self.tello.video_freeze(True) def telloTakeOff(self): """ send the takeoff command to tello,and wait for the first response, if get the 'error'response,remind the "battery low" warning.Otherwise, start the auto-takeoff thread """ takeoff_response = None self.tello.takeoff() time.sleep(0.2) takeoff_response = self.tello.get_response() if takeoff_response != 'error': self.auto_takeoff_thread.start() else: print("battery low,please repalce with a new one") def telloLanding(self): return self.tello.land() def telloFlip_l(self): return self.tello.flip('l') def telloFlip_r(self): return self.tello.flip('r') def telloFlip_f(self): return self.tello.flip('f') def telloFlip_b(self): return self.tello.flip('b') def telloCW(self, degree): return self.tello.rotate_cw(degree) def telloCCW(self, degree): return self.tello.rotate_ccw(degree) def telloMoveForward(self, distance): return self.tello.move_forward(distance) def telloMoveBackward(self, distance): return self.tello.move_backward(distance) def telloMoveLeft(self, distance): return self.tello.move_left(distance) def telloMoveRight(self, distance): return self.tello.move_right(distance) def telloUp(self, dist): return self.tello.move_up(dist) def telloDown(self, dist): return self.tello.move_down(dist) def updateTrackBar(self): self.my_tello_hand.setThr(self.hand_thr_bar.get()) def updateDistancebar(self): self.distance = self.distance_bar.get() print('reset distance to %.1f' % self.distance) def updateDegreebar(self): self.degree = self.degree_bar.get() print('reset distance to %d' % self.degree) def on_keypress_w(self, event): print("up %d m" % self.distance) self.telloUp(self.distance) def on_keypress_s(self, event): print("down %d m" % self.distance) self.telloDown(self.distance) def on_keypress_a(self, event): print("ccw %d degree" % self.degree) self.tello.rotate_ccw(self.degree) def on_keypress_d(self, event): print("cw %d m" % self.degree) self.tello.rotate_cw(self.degree) def on_keypress_up(self, event): print("forward %d m" % self.distance) self.telloMoveForward(self.distance) def on_keypress_down(self, event): print("backward %d m" % self.distance) self.telloMoveBackward(self.distance) def on_keypress_left(self, event): print("left %d m" % self.distance) self.telloMoveLeft(self.distance) def on_keypress_right(self, event): print("right %d m" % self.distance) self.telloMoveRight(self.distance) def on_keypress_enter(self, event): if self.frame is not None: self.registerFace() self.tmp_f.focus_set() def onClose(self): """ set the stop event, cleanup the camera, and allow the rest of the quit process to continue """ print("[INFO] closing...") self.stopEvent.set() del self.tello self.root.quit()
class vedoGUI(Frame): def __init__(self, parent): Frame.__init__(self, parent, bg="white") self.parent = parent self.filenames = [] self.noshare = BooleanVar() self.flat = BooleanVar() self.xspacing = StringVar() self.yspacing = StringVar() self.zspacing = StringVar() self.background_grad = BooleanVar() self.initUI() def initUI(self): self.parent.title("vedo") self.style = Style() self.style.theme_use("clam") self.pack(fill=BOTH, expand=True) ############import Button(self, text="Import Files", command=self._importCMD, width=15).place(x=115, y=17) ############meshes Frame(root, height=1, width=398, bg="grey").place(x=1, y=60) Label(self, text="Meshes", fg="white", bg="green", font=("Courier 11 bold")).place(x=20, y=65) # color Label(self, text="Color:", bg="white").place(x=30, y=98) colvalues = ('by scalar', 'gold', 'red', 'green', 'blue', 'coral', 'plum', 'tomato') self.colorCB = Combobox(self, state="readonly", values=colvalues, width=10) self.colorCB.current(0) self.colorCB.place(x=100, y=98) # mode modvalues = ('surface', 'surf. & edges', 'wireframe', 'point cloud') self.surfmodeCB = Combobox(self, state="readonly", values=modvalues, width=14) self.surfmodeCB.current(0) self.surfmodeCB.place(x=205, y=98) # alpha Label(self, text="Alpha:", bg="white").place(x=30, y=145) self.alphaCB = Scale( self, from_=0, to=1, resolution=0.02, bg="white", length=220, orient="horizontal", ) self.alphaCB.set(1.0) self.alphaCB.place(x=100, y=125) # lighting Label(self, text="Lighting:", bg="white").place(x=30, y=180) lightvalues = ('default', 'metallic', 'plastic', 'shiny', 'glossy') self.lightCB = Combobox(self, state="readonly", values=lightvalues, width=10) self.lightCB.current(0) self.lightCB.place(x=100, y=180) # shading phong or flat self.flatCB = Checkbutton(self, text="flat shading", var=self.flat, bg="white") #self.flatCB.select() self.flatCB.place(x=210, y=180) # rendering arrangement Label(self, text="Arrange as:", bg="white").place(x=30, y=220) schemevalues = ('superpose (default)', 'mesh browser', 'n sync-ed renderers') self.schememodeCB = Combobox(self, state="readonly", values=schemevalues, width=20) self.schememodeCB.current(0) self.schememodeCB.place(x=160, y=220) # share cam self.noshareCB = Checkbutton(self, text="independent cameras", variable=self.noshare, bg="white") self.noshareCB.place(x=160, y=245) ############volumes Frame(root, height=1, width=398, bg="grey").place(x=1, y=275) Label(self, text="Volumes", fg="white", bg="blue", font=("Courier 11 bold")).place(x=20, y=280) # mode Label(self, text="Rendering mode:", bg="white").place(x=30, y=310) modevalues = ( "isosurface (default)", "composite", "maximum proj", "lego", "slicer", "slicer2d", ) self.modeCB = Combobox(self, state="readonly", values=modevalues, width=20) self.modeCB.current(0) self.modeCB.place(x=160, y=310) Label(self, text="Spacing factors:", bg="white").place(x=30, y=335) self.xspacingCB = Entry(self, textvariable=self.xspacing, width=3) self.xspacing.set('1.0') self.xspacingCB.place(x=160, y=335) self.yspacingCB = Entry(self, textvariable=self.yspacing, width=3) self.yspacing.set('1.0') self.yspacingCB.place(x=210, y=335) self.zspacingCB = Entry(self, textvariable=self.zspacing, width=3) self.zspacing.set('1.0') self.zspacingCB.place(x=260, y=335) ############## options Frame(root, height=1, width=398, bg="grey").place(x=1, y=370) Label(self, text="Options", fg='white', bg="brown", font=("Courier 11 bold")).place(x=20, y=375) # backgr color Label(self, text="Background color:", bg="white").place(x=30, y=405) bgcolvalues = ("white", "lightyellow", "azure", "blackboard", "black") self.bgcolorCB = Combobox(self, state="readonly", values=bgcolvalues, width=9) self.bgcolorCB.current(3) self.bgcolorCB.place(x=160, y=405) # backgr color gradient self.backgroundGradCB = Checkbutton(self, text="gradient", variable=self.background_grad, bg="white") self.backgroundGradCB.place(x=255, y=405) ################ render button Frame(root, height=1, width=398, bg="grey").place(x=1, y=437) Button(self, text="Render", command=self._run, width=15).place(x=115, y=454) def _importCMD(self): ftypes = [ ("All files", "*"), ("VTK files", "*.vtk"), ("VTK files", "*.vtp"), ("VTK files", "*.vts"), ("VTK files", "*.vtu"), ("Surface Mesh", "*.ply"), ("Surface Mesh", "*.obj"), ("Surface Mesh", "*.stl"), ("Surface Mesh", "*.off"), ("Surface Mesh", "*.facet"), ("Volume files", "*.tif"), ("Volume files", "*.slc"), ("Volume files", "*.vti"), ("Volume files", "*.mhd"), ("Volume files", "*.nrrd"), ("Volume files", "*.nii"), ("Volume files", "*.dem"), ("Picture files", "*.png"), ("Picture files", "*.jpg"), ("Picture files", "*.bmp"), ("Picture files", "*.gif"), ("Picture files", "*.jpeg"), ("Geojson files", "*.geojson"), ("DOLFIN files", "*.xml.gz"), ("DOLFIN files", "*.xml"), ("DOLFIN files", "*.xdmf"), ("Neutral mesh", "*.neu*"), ("GMESH", "*.gmsh"), ("Point Cloud", "*.pcd"), ("3DS", "*.3ds"), ("Numpy scene file", "*.npy"), ("Numpy scene file", "*.npz"), ] self.filenames = tkFileDialog.askopenfilenames(parent=root, filetypes=ftypes) args.files = list(self.filenames) def _run(self): tips() args.files = list(self.filenames) if self.colorCB.get() == "by scalar": args.color = None else: if self.colorCB.get() == 'red': args.color = 'crimson' elif self.colorCB.get() == 'green': args.color = 'limegreen' elif self.colorCB.get() == 'blue': args.color = 'darkcyan' else: args.color = self.colorCB.get() args.alpha = self.alphaCB.get() args.wireframe = False args.showedges = False args.point_size = 0 if self.surfmodeCB.get() == 'point cloud': args.point_size = 2 elif self.surfmodeCB.get() == 'wireframe': args.wireframe = True elif self.surfmodeCB.get() == 'surf. & edges': args.showedges = True else: pass # normal surface mode args.lighting = self.lightCB.get() args.flat = self.flat.get() args.no_camera_share = self.noshare.get() args.background = self.bgcolorCB.get() args.background_grad = None if self.background_grad.get(): b = getColor(args.background) args.background_grad = (b[0] / 1.8, b[1] / 1.8, b[2] / 1.8) args.multirenderer_mode = False args.scrolling_mode = False if self.schememodeCB.get() == "n sync-ed renderers": args.multirenderer_mode = True elif self.schememodeCB.get() == "mesh browser": args.scrolling_mode = True args.ray_cast_mode = False args.lego = False args.slicer = False args.slicer2d = False args.lego = False args.mode = 0 if self.modeCB.get() == "composite": args.ray_cast_mode = True args.mode = 0 elif self.modeCB.get() == "maximum proj": args.ray_cast_mode = True args.mode = 1 elif self.modeCB.get() == "slicer": args.slicer = True elif self.modeCB.get() == "slicer2d": args.slicer2d = True elif self.modeCB.get() == "lego": args.lego = True args.x_spacing = 1 args.y_spacing = 1 args.z_spacing = 1 if self.xspacing.get() != '1.0': args.x_spacing = float(self.xspacing.get()) if self.yspacing.get() != '1.0': args.y_spacing = float(self.yspacing.get()) if self.zspacing.get() != '1.0': args.z_spacing = float(self.zspacing.get()) draw_scene(args) if os.name == "nt": exit() if settings.plotter_instance: settings.plotter_instance.close()
def __init__(self, parent, data, stepname): super().__init__(parent, data, stepname) lbl1 = Label( self, text= 'Click on each scale at the point that best indicates your experience of the task' ) lbl1.grid(row=1, column=1) lbl2 = Label(self, text="(1=extremely low,5=extremely high)") lbl2.grid(row=2, column=1) ########################### lbl3 = Label( self, text= 'Mental demand: How much mental and perceptual activity was required?' ) lbl3.grid(row=3, column=1) mentalscale = Scale(self, from_=1, to=10, length=200, tickinterval=1, orient=HORIZONTAL, command=self.updatemental) mentalscale.set(5) mentalscale.grid(row=3, column=2) self.data[self.stepname]["mental demand weight"] = mentalscale.get() ########### lbl4 = Label( self, text='Physical demand: How much physical activity was required?') lbl4.grid(row=4, column=1) physicalscale = Scale(self, from_=1, to=10, length=200, tickinterval=1, orient=HORIZONTAL, command=self.updatephysical) physicalscale.set(5) physicalscale.grid(row=4, column=2) self.data[ self.stepname]["physical demand weight"] = physicalscale.get() ########### ########### lbl5 = Label( self, text= 'Temporal demand: How much time pressure did you feel due to the rate of pace at which the tasks or task elements occurred?' ) lbl5.grid(row=5, column=1) temporalscale = Scale(self, from_=1, to=10, length=200, tickinterval=1, orient=HORIZONTAL, command=self.updatetemporal) temporalscale.set(5) temporalscale.grid(row=5, column=2) self.data[ self.stepname]["temporal demand weight"] = temporalscale.get() ########### ########### lbl6 = Label( self, text= 'Performance: How successful do you think you were in accomplishing the goals?' ) lbl6.grid(row=6, column=1) perforscale = Scale(self, from_=1, to=10, length=200, tickinterval=1, orient=HORIZONTAL, command=self.updateperformance) perforscale.set(5) perforscale.grid(row=6, column=2) self.data[self.stepname]["performance weight"] = perforscale.get() ########### ########### lbl7 = Label( self, text= 'Effort: How hard did you have to work (mentally and physically) to accomplish your level of performance?' ) lbl7.grid(row=7, column=1) effortscale = Scale(self, from_=1, to=10, length=200, tickinterval=1, orient=HORIZONTAL, command=self.updateeffort) effortscale.set(5) effortscale.grid(row=7, column=2) self.data[self.stepname]["effort weight"] = effortscale.get() ########### ########### lbl8 = Label( self, text= 'Frustration: How insecure, discouraged, irritated, stressed,and annoyed were you?' ) lbl8.grid(row=8, column=1) frustrationscale = Scale(self, from_=1, to=10, length=200, tickinterval=1, orient=HORIZONTAL, command=self.updatefrustration) frustrationscale.set(5) frustrationscale.grid(row=8, column=2) self.data[self.stepname]["frustration weight"] = frustrationscale.get() ########### self.data[self.stepname]["choose mental times"] = 0 self.data[self.stepname]["choose physical times"] = 0 self.data[self.stepname]["choose temporal times"] = 0 self.data[self.stepname]["choose performance times"] = 0 self.data[self.stepname]["choose effort times"] = 0 self.data[self.stepname]["choose frustration times"] = 0
class Fenetre(Tk): def __init__(self): Tk.__init__(self) self.tilt_val_init = 110 self.pan_val_init = 75 self.pan_min = 0 self.pan_max = 105 self.tilt_min = 35 self.tilt_max = 135 self.pas = 5 # Full Screen largeur, hauteur = self.winfo_screenwidth(), self.winfo_screenheight() self.overrideredirect(0) self.geometry("%dx%d" % (largeur, hauteur)) # TILT self.tilt_bar = Scale(self, from_=self.tilt_min, to=self.tilt_max, length=250, label='Tilt', sliderlength=20, orient=HORIZONTAL, command=self.update_tilt) self.tilt_bar.set((self.tilt_max + self.tilt_min) // 2) self.tilt_bar.grid(row=1, column=2) self.tilt_angle = StringVar() self.tilt_val = self.tilt_bar.get() # PAN self.pan_bar = Scale(self, from_=self.pan_min, to=self.pan_max, length=250, label='Pan', sliderlength=20, orient=HORIZONTAL, command=self.update_pan) self.pan_bar.set((self.pan_max + self.pan_min) // 2) self.pan_bar.grid(row=2, column=2) self.pan_angle = StringVar() self.pan_val = self.pan_bar.get() # PS3 Controller self.bind("<a>", self.pan_plus) self.bind("<d>", self.pan_moins) self.bind("<s>", self.tilt_plus) self.bind("<w>", self.tilt_moins) self.bind("<p>", self.lean_left) self.bind("<m>", self.lean_right) self.bind("<q>", self.initialiser_positon) self.bind("<j>", self.forward) self.bind("<u>", self.reverse) self.bind("<h>", self.left) self.bind("<k>", self.right) self.bind("<i>", self.break_motor) self.bind("<Button-2>", self.alarm) self.bind("<Button-3>", self.beep) # Motor self.gear = 0 self.speed_init = 5 self.speed = self.speed_init self.leds = [led_1, led_2, led_3] self.bind("<e>", self.shift_down) self.bind("<r>", self.shift_up) self.pwm = gpio.PWM(enable_pin, 50) # 50 is the frequency # Infos self.pas_label = Label(self, text=str(self.pas)) self.pas_label.grid(row=3) self.buzzer_state = 0 #--------Buzzer-------- def beep(self, event, time=100): self.buzzer_on() self.after(time, self.buzzer_off) def buzzer_on(self): gpio.output(buzzer, gpio.HIGH) self.buzzer_state = 1 def buzzer_off(self): gpio.output(buzzer, gpio.LOW) self.buzzer_state = 0 def alarm(self, event): if self.buzzer_state == 0: gpio.output(buzzer, gpio.HIGH) self.buzzer_state = 1 else: gpio.output(buzzer, gpio.LOW) self.buzzer_state = 0 #-------Camera------- #-------Motor------- def shift_up(self, event): if self.gear != 3: self.gear += 1 gpio.output(self.leds[self.gear - 1], gpio.HIGH) else: self.beep(event, time=70) if self.gear == 0: self.speed = self.speed_init elif self.gear == 1: self.speed = 33 elif self.gear == 2: self.speed = 66 elif self.gear == 3: self.speed = 100 def shift_down(self, event): if self.gear != 0: gpio.output(self.leds[self.gear - 1], gpio.LOW) self.gear -= 1 if self.gear == 0: self.speed = self.speed_init elif self.gear == 1: self.speed = 33 elif self.gear == 2: self.speed = 66 elif self.gear == 3: self.speed = 100 def forward(self, event): self.go("forward") def reverse(self, event): self.go("reverse") def right(self, event): self.go("right") def left(self, event): self.go("left") def lean_left(self, event): self.go('lean left') def lean_right(self, event): self.go('lean right') def break_motor(self, event): self.go("stop") def go(self, direction): gpio_reset_motor() if direction == "forward": print("forward") gpio.output(right_forward, gpio.HIGH) gpio.output(left_forward, gpio.HIGH) elif direction == "reverse": print("reverse") gpio.output(right_reverse, gpio.HIGH) gpio.output(left_reverse, gpio.HIGH) elif direction == "right": print("right") gpio.output(left_reverse, gpio.HIGH) gpio.output(right_forward, gpio.HIGH) elif direction == "left": print("left") gpio.output(right_reverse, gpio.HIGH) gpio.output(left_forward, gpio.HIGH) elif direction == 'lean left': gpio.output(left_reverse, gpio.HIGH) elif direction == 'lean right': gpio.output(right_reverse, gpio.HIGH) elif direction == 'stop': self.pwm.stop() self.pwm = gpio.PWM(enable_pin, 50) # 50 is the frequency else: pass self.pwm.start(self.speed) # a "speed" of 50, sends power exactly every second cycle #time.sleep(1) #direction = input('Enter next direction') #-------Servos------- def tilt_plus(self, event): if verif_angle(self.tilt_val + self.pas, self.tilt_min, self.tilt_max): self.tilt_val += self.pas self.tilt_bar.set(self.tilt_val) def tilt_moins(self, event): if verif_angle(self.tilt_val - self.pas, self.tilt_min, self.tilt_max): self.tilt_val -= self.pas self.tilt_bar.set(self.tilt_val) def pan_plus(self, event): if verif_angle(self.pan_val + self.pas, self.pan_min, self.pan_max): self.pan_val += self.pas self.pan_bar.set(self.pan_val) def pan_moins(self, event): if verif_angle(self.pan_val - self.pas, self.pan_min, self.pan_max): self.pan_val -= self.pas * 2 self.pan_bar.set(self.pan_val) def pas_plus(self, event): if self.pas + 1 < 21: self.pas += 1 self.update_window() def pas_moins(self, event): if self.pas - 1 > 0: self.pas -= 1 self.update_window() def update_tilt(self, x): if x == 0: pass set_servo(int(x), 0) self.tilt_val = int(x) def update_pan(self, x): if x == 0: pass set_servo(int(x), 1) self.pan_val = int(x) def update_window(self): self.pas_label['text'] = str(self.pas) def initialiser_positon(self, event): self.tilt_bar.set(self.tilt_val_init) self.pan_bar.set(self.pan_val_init)