def __init__(self, parent, buttondefs): '''Initialization method.''' Frame.__init__(self, parent) for title, handler in buttondefs: new_button = Button(self, text=title) cmd = lambda callback=handler, button=new_button: callback(button) new_button.configure(command=cmd) new_button.pack(side=LEFT, padx=5, pady=5)
class AddManually(Frame): def __init__(self, parent, controller): Frame.__init__(self, parent) self.controller = controller self.place(relx=0.0, rely=0.0, relheight=0.62, relwidth=0.72) self.configure(relief=GROOVE) self.configure(borderwidth="2") self.configure(relief=GROOVE) self.configure(width=125) self.label_top = Label(self) self.label_top.place(relx=0.4, rely=0.03, height=21, width=112) self.label_top.configure(text="Add items manually") self.name = Entry(self, fg='grey') self.name.place(relx=0.05, rely=0.31, relheight=0.08, relwidth=0.29) self.name.insert(0, "Input name here") self.name.bind('<Button-1>', lambda event: greytext(self.name)) self.link = Entry(self, fg='grey') self.link.place(relx=0.65, rely=0.31, relheight=0.08, relwidth=0.29) self.link.insert(0, "Input link here") self.link.bind('<Button-1>', lambda event: greytext(self.link)) self.add_btn = Button(self, command=self.send_data) self.add_btn.place(relx=0.42, rely=0.44, height=34, width=100) self.add_btn.configure(text="Add item") self.back = Button(self, command=lambda: controller.show_frame('Main')) self.back.place(relx=0.42, rely=0.64, height=34, width=100) self.back.configure(text="Go back") name_label = Label(self) name_label.place(relx=0.05, rely=0.22, height=21, width=38) name_label.configure(text="Name") link_label = Label(self) link_label.place(relx=0.65, rely=0.22, height=21, width=28) link_label.configure(text="Link") def send_data(self): if self.link.cget('fg') == 'grey' or self.name.cget('fg') == 'grey': return link = self.link.get() if link.strip() != '': name = self.name.get() self.controller.add_item(link, name) print("Item added")
def show(self): self.__menu = Frame(self.__window) self.__menu.configure(padx=10, pady=20) self.__menu.pack(fill=BOTH, expand=True) line1 = Frame(self.__menu) line1.pack(fill=X) self.__name = StringVar() self.__name.set("my_game_at_"+strftime("%H:%M")+"-"+strftime("%d.%m.%Y")) name_input = Entry(line1) name_input.configure(textvariable=self.__name) name_input.pack(fill=X) line2 = Frame(self.__menu) line2.pack(fill=X, pady=20) save_btn = Button(line2) save_btn.configure(text="Save Game", command=self.save) save_btn.pack(fill=X)
def _build_canvas(self): canvas = tk.Canvas(self, bg='white', height=HEIGHT * UNIT, width=WIDTH * UNIT) # buttons iteration_button = Button(self, text="Evaluate", command=self.evaluate_policy) iteration_button.configure(width=10, activebackground="#33B5E5") canvas.create_window(WIDTH * UNIT * 0.13, HEIGHT * UNIT + 10, window=iteration_button) policy_button = Button(self, text="Improve", command=self.improve_policy) policy_button.configure(width=10, activebackground="#33B5E5") canvas.create_window(WIDTH * UNIT * 0.37, HEIGHT * UNIT + 10, window=policy_button) policy_button = Button(self, text="move", command=self.move_by_policy) policy_button.configure(width=10, activebackground="#33B5E5") canvas.create_window(WIDTH * UNIT * 0.62, HEIGHT * UNIT + 10, window=policy_button) policy_button = Button(self, text="reset", command=self.reset) policy_button.configure(width=10, activebackground="#33B5E5") canvas.create_window(WIDTH * UNIT * 0.87, HEIGHT * UNIT + 10, window=policy_button) # create grids for col in range(0, WIDTH * UNIT, UNIT): # 0~400 by 80 x0, y0, x1, y1 = col, 0, col, HEIGHT * UNIT canvas.create_line(x0, y0, x1, y1) for row in range(0, HEIGHT * UNIT, UNIT): # 0~400 by 80 x0, y0, x1, y1 = 0, row, HEIGHT * UNIT, row canvas.create_line(x0, y0, x1, y1) # add img to canvas self.rectangle = canvas.create_image(50, 50, image=self.shapes[0]) canvas.create_image(250, 150, image=self.shapes[1]) canvas.create_image(150, 250, image=self.shapes[1]) canvas.create_image(250, 250, image=self.shapes[2]) # pack all canvas.pack() return canvas
def init(self, config): _user, _passw, _jpgfile, _microfilm, _workdir, _hold_imgs = config self.root = Tk() self.folder_path = StringVar() self.user = StringVar() self.passw = StringVar() self.url = StringVar() self.jpgfile = StringVar() self.hold_imgs = IntVar() self.continuar = BooleanVar() self.folder_path.set(_workdir) self.user.set(_user) self.passw.set(_passw) self.url.set(_microfilm) self.jpgfile.set(_jpgfile) self.hold_imgs.set(_hold_imgs) #self.root.grid_columnconfigure(0, weight=1) self.root.geometry("800x260") self.root.title("Familysearch - Descargar Microfilme y Extraer texto") self.root.grid_columnconfigure((1, 1), weight=1) LabelUser = Label(self.root, text="Usuario Familysearch", padx="10") LabelPass = Label(self.root, text="Clave Family Search", padx="10") LabelJpg = Label(self.root, text="Archivo por defecto del navegador ", padx="10") LabelUrl = Label(self.root, text="URL del Microfim", padx="10") EntryUser = Entry(self.root, textvariable=self.user) #EntryUser.insert(0, _user) EntryPass = Entry(self.root, show="*", textvariable=self.passw) EntryJpg = Entry(self.root, textvariable=self.jpgfile) EntryUrl = Entry(self.root, textvariable=self.url) EntryPath = Entry(self.root, textvariable=self.folder_path) LabelUser.grid(row=3, column=0, pady=(10, 0), sticky="e") EntryUser.grid(row=3, column=1, sticky="w", padx="10", pady=(10, 0)) LabelPass.grid(row=4, column=0, pady=(10, 0), sticky="e") EntryPass.grid(row=4, column=1, sticky="w", padx="10", pady=(10, 0)) LabelJpg.grid(row=5, column=0, pady=(10, 0), sticky="e") EntryJpg.grid(row=5, column=1, sticky="w", padx="10", pady=(10, 0)) LabelUrl.grid(row=6, column=0, pady=(10, 0), sticky="e") EntryUrl.grid(row=6, column=1, sticky="ew", padx="10", pady=(10, 0)) btn_path = Button(text="Directorio destino", command=self.browse_button) btn_path.grid(row=7, column=0, pady=(10, 0), sticky="e") EntryPath.grid(row=7, column=1, sticky="ew", padx="10", pady=(10, 0)) Check_hold_imgs = Checkbutton( self.root, onvalue=1, offvalue=0, text="Mantener las imágenes del Microfilm descargadas", variable=self.hold_imgs) Check_hold_imgs.grid(row=8, columnspan="2", sticky="ew", padx="10", pady=(10, 0)) BtnDown = Button(self.root) BtnDown.grid(row=9, column=0, pady=10) BtnDown.configure(text='Descargar y extraer (HTR)', command=self.print_content) BtnQuit = Button(self.root) BtnQuit.grid(row=9, column=1, pady=10) BtnQuit.configure(text='Cerrar', command=self.quit) self.root.mainloop()
class App(Tk): def __init__(self): Tk.__init__(self) self.label = Label(self, text="Programme en pause.") self.label.pack() self.play_button = Button(self, text="commencer les screenshots", command=self.play) self.play_button.pack(side="left", padx=2, pady=2) self.stop_button = Button(self, text="arrêter les screenshots", command=self.stop) self.stop_button.pack(side="left", padx=2, pady=2) self._thread, self._pause, self._stop = None, False, True def action(self): print("Lancement du programme !") compteurtemps = 0 numeroimage = 0 strnumeroimage = str(numeroimage) tempsattentescreenshot = 5 screen1 = pyautogui.screenshot() screen1 = cv2.cvtColor(np.array(screen1), cv2.COLOR_RGB2BGR) pathtot = folderCreation.jaimeleschevres() print(pathtot) photodirection = pathtot + "image" + strnumeroimage + ".png" cv2.imwrite(photodirection, screen1) sleep(tempsattentescreenshot) #boucle infinie______________________________________________________________________________________________ while True: #__ je tente de comparer 2 images screen0 = screen1 screen1 = pyautogui.screenshot() screen1 = cv2.cvtColor(np.array(screen1), cv2.COLOR_RGB2BGR) #screen0 = cv2.imread(photodirection) image1 = screen0.shape image2 = screen1.shape nbrdepixels1 = image1[0] * image1[1] nbrdepixels2 = image2[0] * image2[1] def testpixels(): if nbrdepixels2 != nbrdepixels1: print( "la comparaison ne peut pas fonctinner les image n'ont pas le même size" ) testpixels() if screen0.shape == screen1.shape: print("les images font la même taille") difference = cv2.subtract(screen0, screen1) b, g, r = cv2.split(difference) nonZero = abs(cv2.countNonZero(b)) + abs( cv2.countNonZero(g)) + abs(cv2.countNonZero(r)) nonZero = nonZero / 3 print(nonZero) pourcentage = (nbrdepixels1 - nonZero) / nbrdepixels1 * 100 print(pourcentage, " pourcent de similarité") #comparaison photo actuelle et dernière photo enregistrée__________________________ derniereimage = cv2.imread(photodirection) difference = cv2.subtract(derniereimage, screen1) b, g, r = cv2.split(difference) nonZero = abs(cv2.countNonZero(b)) + abs( cv2.countNonZero(g)) + abs(cv2.countNonZero(r)) nonZero = nonZero / 3 print(nonZero, "le deuxième nonZero") if nonZero == 0: print("les images sont les mêmes.") pourcentage1 = (nbrdepixels1 - nonZero) / nbrdepixels1 * 100 print(pourcentage1, " pourcent de similarité") #__________________________________________________________________________________ compteurtemps += 1 # définir le nom de l'image à enregistrer if pourcentage < 92 or pourcentage1 < 92: compteurtemps = 0 print("tes sensé la créer là") while os.path.exists(photodirection): numeroimage += 1 strnumeroimage = str(numeroimage) photodirection = pathtot + "image" + strnumeroimage + ".png" if numeroimage > 100: print("problème image") break photodirection = pathtot + "image" + strnumeroimage + ".png" cv2.imwrite(photodirection, screen1) if compteurtemps >= 48: numeroimage += 1 strnumeroimage = str(numeroimage) photodirection = pathtot + "image" + strnumeroimage + ".png" cv2.imwrite(photodirection, screen1) sleep(tempsattentescreenshot) if self._stop: self.label["text"] = "arrêté" break while self._pause: sleep(0.1) self.label["text"] = "en cours d'acquisition" sleep(0.1) self.play_button["text"] = "screenshots en cours" def play(self): if self._thread is None: self._stop = False self._thread = Thread(target=self.action) self._thread.start() self._pause = False # self.play_button.configure(text="Pause", command=self.pause) def pause(self): self._pause = True self.play_button.configure(text="Play", command=self.play) def stop(self): if self._thread is not None: self._thread, self._pause, self._stop = None, False, True self.play_button.configure(text="commencer les screenshots", command=self.play)
class Calendar(Frame): """This class represents a date-picker. Inherits from the Tkinter Frame Class. Object of this class is designed either to work independently or to serve as date-picker component within DateTimePicker. Responsible for providing framework for date selection operations including following: - navigation between months either via UI(navigation buttons) or via keyboard(arrow-left and arrow-right keys) - displaying calendar of the month currently navigated to - making possible selection of date TBD: storing and providing up-to-date information regarding the selected date. """ # class variables today_date = date.today( ) # WILL BE NECESSARY TO UPDATE WHEN COMPUTER DATE CHANGES AT MIDNIGHT #datetime.date.today() month_names_lst = list(month_name) #calendar.month_name bgcolor = 'snow2' month_year_font = '"Tempus Sans ITC" 10' shiftbtn_font = 'Arial 8 bold' shift_back_text = '<' # '\u23EA' # to watch here: https://unicode-search.net/unicode-namesearch.pl?term=ARROW shift_forward_text = '>' # '\u23E9' def __init__(self, container, padx_param=0, pady_param=0): """ctor""" super().__init__(container) # control variable for 'MonthName yyyy' value self.month_year_ctrlvar = StringVar() self.month_year_ctrlvar.set( __class__.today_date.strftime("%B %Y") ) # initial value is 'CurrentMonth CurrentYear' e.g.'July 2019' self.create_widgets(container, padx_param, pady_param) self.lbl_month_year.focus_set() ### # enabling navigation between months using arrow-left and arrow-right keys self.shiftback_funcid = self.lbl_month_year.bind( '<Left>', self.action_shift_month_back) self.shiftfwd_funcid = self.lbl_month_year.bind( '<Right>', self.action_shift_month_forward) # initialization - displaying calendar of the current month of the year self.month_dispatcher = MonthDispatcher(self.frm_display, __class__.today_date.year, __class__.today_date.month) def create_widgets(self, container, padx_val, pady_val): """This method defines UI of the date picker""" self.frm_main_calendar = Frame(container) self.frm_main_calendar.grid(row=0, ipady=5, padx=padx_val, pady=pady_val) #self.frm_main_calendar.grid_propagate(False) self.frm_month_year = Frame(self.frm_main_calendar, bg=__class__.bgcolor) self.frm_month_year.grid(row=0, padx=10, pady=10) self.btn_shift_back = Button(self.frm_month_year, command=self.action_shift_month_back, width=1, text=__class__.shift_back_text, font=__class__.shiftbtn_font, bd=0, bg=__class__.bgcolor) self.btn_shift_back.grid(row=0, column=0) self.lbl_month_year = Label(self.frm_month_year, width=17, textvariable=self.month_year_ctrlvar, font=__class__.month_year_font, bg=__class__.bgcolor) self.lbl_month_year.grid(row=0, column=1) self.btn_shift_forward = Button( self.frm_month_year, command=self.action_shift_month_forward, width=1, text=__class__.shift_forward_text, font=__class__.shiftbtn_font, bd=0, bg=__class__.bgcolor) self.btn_shift_forward.grid(row=0, column=2) self.frm_display = Frame( self.frm_main_calendar ) # place holder for calendar of the month navigated to self.frm_display.grid(row=1, padx=10) def action_shift_month_back( self, event=None): # event=None, day_to_select=None: for the future use """This method is a callback for mouse click on shift-month-back button / for hitting arrow-left keyboard key It is responsible for performing navigation to preceding month including following: - calculation and displaying values of the target month and year - making decision whether to block further navigation back - invoking generation of the target month calendar """ # enabling navigation forward because moving one step back ensures it is possible to go at least one step forward self.btn_shift_forward.configure( state=NORMAL) # enabling the shift-month-forward button self.shiftfwd_funcid = self.lbl_month_year.bind( '<Right>', self.action_shift_month_forward ) # binding a callback for the arrow-right keyboard key # retrieving values of the currently displayed month and year displayed_month, displayed_year = self.month_year_ctrlvar.get().split( ' ') displayed_year = int(displayed_year) month_index = __class__.month_names_lst.index(displayed_month) # calculation of the target month and year; in case minimum valid month is reached, blocking further navigation back month_index -= 1 if displayed_year == MINYEAR and month_index == date.min.month: # year:1, month: 1 (January) #datetime.MINYEAR datetime.date.min.month self.btn_shift_back.configure( state=DISABLED) # disabling the shift-month-back button self.lbl_month_year.unbind( '<Left>', self.shiftback_funcid ) # unbinding a callback for the arrow-left keyboard key elif month_index == 0: month_index = 12 displayed_year -= 1 # updating control variable that stores <MonthName yyyy> value - new value being immediately reflected in UI self.month_year_ctrlvar.set( f'{__class__.month_names_lst[month_index]} {displayed_year}') # creating calendar of the target month self.month_dispatcher.arrange_month(displayed_year, month_index) def action_shift_month_forward( self, event=None): # event=None, day_to_select=None: for future use """This method is a callback for mouse click on shift-month-forward button / for hitting arrow-right keyboard key It is responsible for performing navigation to succeeding month including following: - calculation and displaying values of the target month and year - making decision whether to block further navigation forward - invoking generation of the target month calendar """ # enabling navigation back because moving one step forward ensures it is possible to go at least one step back self.btn_shift_back.configure( state=NORMAL) # enabling the shift-month-back button self.shiftback_funcid = self.lbl_month_year.bind( '<Left>', self.action_shift_month_back ) # binding a callback for the arrow-left keyboard key # retrieving values of the currently displayed month and year displayed_month, displayed_year = self.month_year_ctrlvar.get().split( ' ') displayed_year = int(displayed_year) month_index = __class__.month_names_lst.index(displayed_month) # calculation of the target month and year; in case maximum valid month is reached, blocking further navigation forward month_index += 1 if displayed_year == MAXYEAR and month_index == date.max.month: # year:9999, month: 12 (December) #datetime.MAXYEAR datetime.date.max.month self.btn_shift_forward.configure( state=DISABLED) # disabling the shift-month-forward button self.lbl_month_year.unbind( '<Right>', self.shiftfwd_funcid ) # unbinding a callback for the arrow-right keyboard key elif month_index == 13: month_index = 1 displayed_year += 1 # updating control variable that stores <MonthName yyyy> value - new value being immediately reflected in UI self.month_year_ctrlvar.set( f'{__class__.month_names_lst[month_index]} {displayed_year}') # creating calendar of the target month self.month_dispatcher.arrange_month(displayed_year, month_index)
class Board: def __init__(self, top=None, session=None, num=None): top.geometry("1000x700+200+50") top.title("Game Board") top.configure(background="gray") global color, wall color = ['red', 'blue', 'green', 'yellow'] wall = [0 for i in range(num)] self.turn = 0 def music(): winsound.PlaySound('Vay-Behalash.wav', winsound.SND_ALIAS | winsound.SND_ASYNC) self.status = Label(top, text=" Turn Player %s" % color[self.turn]) self.status.place(relx=0.85, rely=0.10, height=50, width=120) ''' make places for pawns ''' self.matrix = [[0 for i in range(9)] for j in range(9)] self.Button = [[0 for i in range(9)] for j in range(9)] # main buttons i = 0 j = 0 x = 0.10 y = 0.03 while i < 9: while j < 9: self.Button[i][j] = Button(top) self.Button[i][j].place(relx=x, rely=y, height=50, width=50) self.Button[i][j].bind("<Button-1>", lambda a=None, f=i, g=j: self.move(session, f, g, num)) self.Button[i][j].configure(background="gray88") self.matrix[i][j] = "gray88" j += 1 x += 0.08 j = 0 x = 0.10 y += 0.11 i += 1 ''' make players color ''' if num == 4: self.Button[4][0].configure(background="yellow") self.Button[4][8].configure(background="green") self.matrix[4][0] = "yellow" self.matrix[4][8] = "green" self.Button[0][4].configure(background="red") self.Button[8][4].configure(background="blue") self.matrix[0][4] = "red" self.matrix[8][4] = "blue" ''' make horizontal walls''' self.h_wall = [[0 for z in range(9)] for w in range(8)] i = 0 j = 0 x = 0.10 y = 0.11 while i < 8: while j < 9: self.h_wall[i][j] = Button(top) self.h_wall[i][j].place(relx=x, rely=y, height=15, width=50) self.h_wall[i][j].configure(background="white") j += 1 x += 0.08 j = 0 x = 0.10 y += 0.11 i += 1 ''' make vertical walls''' self.v_wall = [[0 for z in range(8)] for w in range(9)] i = 0 j = 0 x = 0.16 y = 0.03 while i < 9: while j < 8: self.v_wall[i][j] = Button(top) self.v_wall[i][j].place(relx=x, rely=y, height=50, width=15) self.v_wall[i][j].configure(background="white") j += 1 x += 0.08 j = 0 x = 0.16 y += 0.11 i += 1 ''' make center buttons of walls''' self.c_wall = [[0 for z in range(8)] for w in range(8)] i = 0 j = 0 x = 0.16 y = 0.11 while i < 8: while j < 8: self.c_wall[i][j] = Button(top) self.c_wall[i][j].place(relx=x, rely=y, height=15, width=15) self.c_wall[i][j].bind("<Button-1>", lambda f=None, a=i, b=j: self.decied(self.h_wall[a][b], self.h_wall[a][b + 1], self.v_wall[a][b], self.v_wall[a + 1][b], num)) self.c_wall[i][j].configure(background="white") j += 1 x += 0.08 j = 0 x = 0.16 y += 0.11 i += 1 self.Hayede = Button(top, command=music) self.Hayede.place(relx=0.80, rely=0.88, height=75, width=75) self.Hayede.configure(text="Play Hayede", background="#d9d9d9") def move(self, session, i, j, num): # info = json.dumps(self.matrix) # t = requests.get(address.url['move'], data=info) # print(t.content) for a in range(9): for b in range(9): if self.Button[a][b]['bg'] == color[self.turn]: f = a g = b break else: continue break des = self.Button[i][j] home = self.Button[f][g] if f == i and (g == j + 1 or g == j - 1): if g == j + 1: # *** move to left *** if self.v_wall[i][j]['bg'] != 'black': if des['bg'] == 'gray88': des['bg'] = color[self.turn] home['bg'] = 'gray88' self.turn += 1 else: tkinter.messagebox.showerror('Error', 'Pay attention to other Player pawns') else: tkinter.messagebox.showerror('Error', "Pay attention to walls") else: # *** move to right *** if self.v_wall[f][g]['bg'] != 'black': if des['bg'] == 'gray88': des['bg'] = color[self.turn] home['bg'] = 'gray88' self.turn += 1 else: tkinter.messagebox.showerror('Error', 'Pay attention to other Player pawns') else: tkinter.messagebox.showerror('Error', "Pay attention to walls") elif g == j and (f == i + 1 or f == i - 1): if f == i + 1: # *** move to up *** if self.h_wall[i][j]['bg'] != 'black': if des['bg'] == 'gray88': des['bg'] = color[self.turn] home['bg'] = 'gray88' self.turn += 1 else: tkinter.messagebox.showerror('Error', 'Pay attention to other Player pawns') else: tkinter.messagebox.showerror('Error', "Pay attention to walls ") else: # *** move to down *** if self.h_wall[f][g]['bg'] != 'black': if des['bg'] == 'gray88': des['bg'] = color[self.turn] home['bg'] = 'gray88' self.turn += 1 else: tkinter.messagebox.showerror('Error', 'Pay attention to other Player pawns') else: tkinter.messagebox.showerror('Error', "Pay attention to walls") else: tkinter.messagebox.showerror('Error', 'Choose correct location') if self.turn == num: self.turn = 0 self.status['text'] = "turn Player %s" % color[self.turn] self.win(num) def decied(self, a, b, c, d, num): if wall[self.turn] == 20 / num: tkinter.messagebox.showerror('Error', ' You don\'t have any wall ') return False answer = tkinter.messagebox.askyesnocancel('Which side ?', 'Do you want Horizontal wall?(yes)\n \tVertical(no)') if str(answer) == 'True': if a['bg'] == 'black' or b['bg'] == 'black': tkinter.messagebox.showerror('Error', 'You cannot choose this location') else: a.configure(bg="black") b.configure(bg="black") wall[self.turn] += 1 self.turn += 1 if str(answer) == 'False': if c['bg'] == 'black' or d['bg'] == 'black': tkinter.messagebox.showerror('Error', 'You cannot choose this location') else: c.configure(bg="black") d.configure(bg="black") wall[self.turn] += 1 self.turn += 1 if self.turn == num: self.turn = 0 self.status['text'] = "turn Player %s" % color[self.turn] def win(self, num): for m in range(9): if self.Button[8][m]['bg'] == 'red': tkinter.messagebox.showinfo(" Game was finish ", " Congratulation Player Red\n You Win ") root.destroy() return False for m in range(9): if self.Button[0][m]['bg'] == 'blue': tkinter.messagebox.showinfo(" Game was finish ", " Congratulation Player Blue\n You Win ") root.destroy() return False if num == 4: for m in range(9): if self.Button[m][0]['bg'] == 'green': tkinter.messagebox.showinfo(" Game was finish ", " Congratulation Player Green\n You Win ") root.destroy() return False for m in range(9): if self.Button[m][8]['bg'] == 'yellow': tkinter.messagebox.showinfo(" Game was finish ", " Congratulation Player Yellow\n You Win ") root.destroy() return False
class GuessingGame: def __init__(self, master): self.master = master master.title("Guessing Game") self.secret_number = random.randint(1, 100) self.guess = None self.num_guesses = 0 self.message = "Guess a number from 1 to 100" self.label_text = StringVar() self.label_text.set(self.message) self.label = Label(master, textvariable=self.label_text) vcmd = master.register(self.validate) # we have to wrap the command self.entry = Entry(master, validate="key", validatecommand=(vcmd, '%P')) self.guess_button = Button(master, text="Guess", command=self.guess_number) self.reset_button = Button(master, text="Play again", command=self.reset, state=DISABLED) self.label.grid(row=0, column=0, columnspan=2, sticky=W+E) self.entry.grid(row=1, column=0, columnspan=2, sticky=W+E) self.guess_button.grid(row=2, column=0) self.reset_button.grid(row=2, column=1) def validate(self, new_text): if not new_text: # the field is being cleared self.guess = None return True try: guess = int(new_text) if 1 <= guess <= 100: self.guess = guess return True else: return False except ValueError: return False def guess_number(self): self.num_guesses += 1 if self.guess is None: self.message = "Guess a number from 1 to 100" elif self.guess == self.secret_number: suffix = '' if self.num_guesses == 1 else 'es' self.message = "Congratulations! You guessed the number after %d guess%s." % (self.num_guesses, suffix) self.guess_button.configure(state=DISABLED) self.reset_button.configure(state=NORMAL) elif self.guess < self.secret_number: self.message = "Too low! Guess again!" else: self.message = "Too high! Guess again!" self.label_text.set(self.message) def reset(self): self.entry.delete(0, END) self.secret_number = random.randint(1, 100) self.guess = 0 self.num_guesses = 0 self.message = "Guess a number from 1 to 100" self.label_text.set(self.message) self.guess_button.configure(state=NORMAL) self.reset_button.configure(state=DISABLED)
position_track.set(temp - 1) update_value(temp - 1) label_first_name = Label(window, text = 'First Name:', justify = 'right', padx = 5) entry_first_name = Entry(window, textvariable = first_name) label_last_name = Label(window, text = 'Last Name:', justify = 'right', padx = 5) entry_last_name = Entry(window, textvariable = last_name) label_email = Label(window, text = 'Email Address:', justify = 'right', padx = 5) entry_email = Entry(window, textvariable = email) button_first = Button(window, text = 'First', command = first_value) button_last = Button(window, text = 'Last', command = last_value) button_prev = Button(window, text = 'Prev', command = prev_value) button_next = Button(window, text = 'Next', command = next_value) button_quit = Button(window, text = 'Quit') button_quit.configure(command=window.destroy) labels = [label_first_name, label_last_name, label_email] entries = [entry_first_name, entry_last_name, entry_email] buttons = [button_first, button_last, button_prev, button_next, button_last, button_quit] for i in range(3): labels[i].grid(row = i, column = 0, sticky = 'W') entries[i].grid(row = i, column = 1, columnspan = 6) for j in range(6): buttons[j].grid(row = 3, column = j, sticky = 'E') window.mainloop()
class Placer(AppShell): # Override class variables here appname = 'Placer Panel' frameWidth = 625 frameHeight = 215 usecommandarea = 0 usestatusarea = 0 def __init__(self, parent = None, **kw): INITOPT = Pmw.INITOPT optiondefs = ( ('title', self.appname, None), ('nodePath', SEditor.camera, None), ) self.defineoptions(kw, optiondefs) # Call superclass initialization function AppShell.__init__(self) self.initialiseoptions(Placer) # Accept the message from sceneEditor to update the information about the target nodePath self.accept('placerUpdate', self.updatePlacer) def appInit(self): # Initialize state self.tempCS = SEditor.group.attachNewNode('placerTempCS') self.orbitFromCS = SEditor.group.attachNewNode( 'placerOrbitFromCS') self.orbitToCS = SEditor.group.attachNewNode('placerOrbitToCS') self.refCS = self.tempCS # Dictionary keeping track of all node paths manipulated so far self.nodePathDict = {} self.nodePathDict['camera'] = SEditor.camera self.nodePathDict['widget'] = SEditor.widget self.nodePathNames = ['camera', 'widget', 'selected'] self.refNodePathDict = {} self.refNodePathDict['parent'] = self['nodePath'].getParent() self.refNodePathDict['render'] = render self.refNodePathDict['camera'] = SEditor.camera self.refNodePathDict['widget'] = SEditor.widget self.refNodePathNames = ['parent', 'self', 'render', 'camera', 'widget', 'selected'] # Initial state self.initPos = Vec3(0) self.initHpr = Vec3(0) self.initScale = Vec3(1) self.deltaHpr = Vec3(0) # Offset for orbital mode self.posOffset = Vec3(0) # Set up event hooks self.undoEvents = [('DIRECT_undo', self.undoHook), ('DIRECT_pushUndo', self.pushUndoHook), ('DIRECT_undoListEmpty', self.undoListEmptyHook), ('DIRECT_redo', self.redoHook), ('DIRECT_pushRedo', self.pushRedoHook), ('DIRECT_redoListEmpty', self.redoListEmptyHook)] for event, method in self.undoEvents: self.accept(event, method) # Init movement mode self.movementMode = 'Relative To:' def createInterface(self): # The interior of the toplevel panel interior = self.interior() interior['relief'] = tkinter.FLAT # Add placer commands to menubar self.menuBar.addmenu('Placer', 'Placer Panel Operations') self.menuBar.addmenuitem('Placer', 'command', 'Zero Node Path', label = 'Zero All', command = self.zeroAll) self.menuBar.addmenuitem('Placer', 'command', 'Reset Node Path', label = 'Reset All', command = self.resetAll) self.menuBar.addmenuitem('Placer', 'command', 'Print Node Path Info', label = 'Print Info', command = self.printNodePathInfo) self.menuBar.addmenuitem( 'Placer', 'command', 'Toggle widget visability', label = 'Toggle Widget Vis', command = SEditor.toggleWidgetVis) self.menuBar.addmenuitem( 'Placer', 'command', 'Toggle widget manipulation mode', label = 'Toggle Widget Mode', command = SEditor.manipulationControl.toggleObjectHandlesMode) # Get a handle to the menu frame menuFrame = self.menuFrame self.nodePathMenu = Pmw.ComboBox( menuFrame, labelpos = tkinter.W, label_text = 'Node Path:', entry_width = 20, selectioncommand = self.selectNodePathNamed, scrolledlist_items = self.nodePathNames) self.nodePathMenu.selectitem('selected') self.nodePathMenuEntry = ( self.nodePathMenu.component('entryfield_entry')) self.nodePathMenuBG = ( self.nodePathMenuEntry.configure('background')[3]) self.nodePathMenu.pack(side = 'left', fill = 'x', expand = 1) self.bind(self.nodePathMenu, 'Select node path to manipulate') modeMenu = Pmw.OptionMenu(menuFrame, items = ('Relative To:', 'Orbit:'), initialitem = 'Relative To:', command = self.setMovementMode, menubutton_width = 8) modeMenu.pack(side = 'left', expand = 0) self.bind(modeMenu, 'Select manipulation mode') self.refNodePathMenu = Pmw.ComboBox( menuFrame, entry_width = 16, selectioncommand = self.selectRefNodePathNamed, scrolledlist_items = self.refNodePathNames) self.refNodePathMenu.selectitem('parent') self.refNodePathMenuEntry = ( self.refNodePathMenu.component('entryfield_entry')) self.refNodePathMenu.pack(side = 'left', fill = 'x', expand = 1) self.bind(self.refNodePathMenu, 'Select relative node path') self.undoButton = Button(menuFrame, text = 'Undo', command = SEditor.undo) if SEditor.undoList: self.undoButton['state'] = 'normal' else: self.undoButton['state'] = 'disabled' self.undoButton.pack(side = 'left', expand = 0) self.bind(self.undoButton, 'Undo last operation') self.redoButton = Button(menuFrame, text = 'Redo', command = SEditor.redo) if SEditor.redoList: self.redoButton['state'] = 'normal' else: self.redoButton['state'] = 'disabled' self.redoButton.pack(side = 'left', expand = 0) self.bind(self.redoButton, 'Redo last operation') # Create and pack the Pos Controls posGroup = Pmw.Group(interior, tag_pyclass = Menubutton, tag_text = 'Position', tag_font=('MSSansSerif', 14), tag_activebackground = '#909090', ring_relief = tkinter.RIDGE) posMenubutton = posGroup.component('tag') self.bind(posMenubutton, 'Position menu operations') posMenu = Menu(posMenubutton, tearoff = 0) posMenu.add_command(label = 'Set to zero', command = self.zeroPos) posMenu.add_command(label = 'Reset initial', command = self.resetPos) posMenubutton['menu'] = posMenu posGroup.pack(side='left', fill = 'both', expand = 1) posInterior = posGroup.interior() # Create the dials self.posX = self.createcomponent('posX', (), None, Floater, (posInterior,), text = 'X', relief = tkinter.FLAT, value = 0.0, label_foreground = 'Red') self.posX['commandData'] = ['x'] self.posX['preCallback'] = self.xformStart self.posX['postCallback'] = self.xformStop self.posX['callbackData'] = ['x'] self.posX.pack(expand=1,fill='both') self.posY = self.createcomponent('posY', (), None, Floater, (posInterior,), text = 'Y', relief = tkinter.FLAT, value = 0.0, label_foreground = '#00A000') self.posY['commandData'] = ['y'] self.posY['preCallback'] = self.xformStart self.posY['postCallback'] = self.xformStop self.posY['callbackData'] = ['y'] self.posY.pack(expand=1,fill='both') self.posZ = self.createcomponent('posZ', (), None, Floater, (posInterior,), text = 'Z', relief = tkinter.FLAT, value = 0.0, label_foreground = 'Blue') self.posZ['commandData'] = ['z'] self.posZ['preCallback'] = self.xformStart self.posZ['postCallback'] = self.xformStop self.posZ['callbackData'] = ['z'] self.posZ.pack(expand=1,fill='both') # Create and pack the Hpr Controls hprGroup = Pmw.Group(interior, tag_pyclass = Menubutton, tag_text = 'Orientation', tag_font=('MSSansSerif', 14), tag_activebackground = '#909090', ring_relief = tkinter.RIDGE) hprMenubutton = hprGroup.component('tag') self.bind(hprMenubutton, 'Orientation menu operations') hprMenu = Menu(hprMenubutton, tearoff = 0) hprMenu.add_command(label = 'Set to zero', command = self.zeroHpr) hprMenu.add_command(label = 'Reset initial', command = self.resetHpr) hprMenubutton['menu'] = hprMenu hprGroup.pack(side='left',fill = 'both', expand = 1) hprInterior = hprGroup.interior() # Create the dials self.hprH = self.createcomponent('hprH', (), None, AngleDial, (hprInterior,), style = 'mini', text = 'H', value = 0.0, relief = tkinter.FLAT, label_foreground = 'blue') self.hprH['commandData'] = ['h'] self.hprH['preCallback'] = self.xformStart self.hprH['postCallback'] = self.xformStop self.hprH['callbackData'] = ['h'] self.hprH.pack(expand=1,fill='both') self.hprP = self.createcomponent('hprP', (), None, AngleDial, (hprInterior,), style = 'mini', text = 'P', value = 0.0, relief = tkinter.FLAT, label_foreground = 'red') self.hprP['commandData'] = ['p'] self.hprP['preCallback'] = self.xformStart self.hprP['postCallback'] = self.xformStop self.hprP['callbackData'] = ['p'] self.hprP.pack(expand=1,fill='both') self.hprR = self.createcomponent('hprR', (), None, AngleDial, (hprInterior,), style = 'mini', text = 'R', value = 0.0, relief = tkinter.FLAT, label_foreground = '#00A000') self.hprR['commandData'] = ['r'] self.hprR['preCallback'] = self.xformStart self.hprR['postCallback'] = self.xformStop self.hprR['callbackData'] = ['r'] self.hprR.pack(expand=1,fill='both') # Create and pack the Scale Controls # The available scaling modes self.scalingMode = StringVar() self.scalingMode.set('Scale Uniform') # The scaling widgets scaleGroup = Pmw.Group(interior, tag_text = 'Scale Uniform', tag_pyclass = Menubutton, tag_font=('MSSansSerif', 14), tag_activebackground = '#909090', ring_relief = tkinter.RIDGE) self.scaleMenubutton = scaleGroup.component('tag') self.bind(self.scaleMenubutton, 'Scale menu operations') self.scaleMenubutton['textvariable'] = self.scalingMode # Scaling menu scaleMenu = Menu(self.scaleMenubutton, tearoff = 0) scaleMenu.add_command(label = 'Set to unity', command = self.unitScale) scaleMenu.add_command(label = 'Reset initial', command = self.resetScale) scaleMenu.add_radiobutton(label = 'Scale Free', variable = self.scalingMode) scaleMenu.add_radiobutton(label = 'Scale Uniform', variable = self.scalingMode) scaleMenu.add_radiobutton(label = 'Scale Proportional', variable = self.scalingMode) self.scaleMenubutton['menu'] = scaleMenu # Pack group widgets scaleGroup.pack(side='left',fill = 'both', expand = 1) scaleInterior = scaleGroup.interior() # Create the dials self.scaleX = self.createcomponent('scaleX', (), None, Floater, (scaleInterior,), text = 'X Scale', relief = tkinter.FLAT, min = 0.0001, value = 1.0, resetValue = 1.0, label_foreground = 'Red') self.scaleX['commandData'] = ['sx'] self.scaleX['callbackData'] = ['sx'] self.scaleX['preCallback'] = self.xformStart self.scaleX['postCallback'] = self.xformStop self.scaleX.pack(expand=1,fill='both') self.scaleY = self.createcomponent('scaleY', (), None, Floater, (scaleInterior,), text = 'Y Scale', relief = tkinter.FLAT, min = 0.0001, value = 1.0, resetValue = 1.0, label_foreground = '#00A000') self.scaleY['commandData'] = ['sy'] self.scaleY['callbackData'] = ['sy'] self.scaleY['preCallback'] = self.xformStart self.scaleY['postCallback'] = self.xformStop self.scaleY.pack(expand=1,fill='both') self.scaleZ = self.createcomponent('scaleZ', (), None, Floater, (scaleInterior,), text = 'Z Scale', relief = tkinter.FLAT, min = 0.0001, value = 1.0, resetValue = 1.0, label_foreground = 'Blue') self.scaleZ['commandData'] = ['sz'] self.scaleZ['callbackData'] = ['sz'] self.scaleZ['preCallback'] = self.xformStart self.scaleZ['postCallback'] = self.xformStop self.scaleZ.pack(expand=1,fill='both') # Make sure appropriate labels are showing self.setMovementMode('Relative To:') # Set up placer for inital node path self.selectNodePathNamed('init') self.selectRefNodePathNamed('parent') # Update place to reflect initial state self.updatePlacer() # Now that you're done setting up, attach commands self.posX['command'] = self.xform self.posY['command'] = self.xform self.posZ['command'] = self.xform self.hprH['command'] = self.xform self.hprP['command'] = self.xform self.hprR['command'] = self.xform self.scaleX['command'] = self.xform self.scaleY['command'] = self.xform self.scaleZ['command'] = self.xform ### WIDGET OPERATIONS ### def setMovementMode(self, movementMode): # Set prefix namePrefix = '' self.movementMode = movementMode if (movementMode == 'Relative To:'): namePrefix = 'Relative ' elif (movementMode == 'Orbit:'): namePrefix = 'Orbit ' # Update pos widgets self.posX['text'] = namePrefix + 'X' self.posY['text'] = namePrefix + 'Y' self.posZ['text'] = namePrefix + 'Z' # Update hpr widgets if (movementMode == 'Orbit:'): namePrefix = 'Orbit delta ' self.hprH['text'] = namePrefix + 'H' self.hprP['text'] = namePrefix + 'P' self.hprR['text'] = namePrefix + 'R' # Update temp cs and initialize widgets self.updatePlacer() def setScalingMode(self): if self['nodePath']: scale = self['nodePath'].getScale() if ((scale[0] != scale[1]) or (scale[0] != scale[2]) or (scale[1] != scale[2])): self.scalingMode.set('Scale Free') def selectNodePathNamed(self, name): nodePath = None if name == 'init': nodePath = self['nodePath'] # Add Combo box entry for the initial node path self.addNodePath(nodePath) elif name == 'selected': nodePath = SEditor.selected.last # Add Combo box entry for this selected object self.addNodePath(nodePath) else: nodePath = self.nodePathDict.get(name, None) if (nodePath == None): # See if this evaluates into a node path try: nodePath = eval(name) if isinstance(nodePath, NodePath): self.addNodePath(nodePath) else: # Good eval but not a node path, give up nodePath = None except: # Bogus eval nodePath = None # Clear bogus entry from listbox listbox = self.nodePathMenu.component('scrolledlist') listbox.setlist(self.nodePathNames) else: if name == 'widget': # Record relationship between selected nodes and widget SEditor.selected.getWrtAll() # Update active node path self.setActiveNodePath(nodePath) def setActiveNodePath(self, nodePath): self['nodePath'] = nodePath if self['nodePath']: self.nodePathMenuEntry.configure( background = self.nodePathMenuBG) # Check to see if node path and ref node path are the same if ((self.refCS != None) and (self.refCS.get_key() == self['nodePath'].get_key())): # Yes they are, use temp CS as ref # This calls updatePlacer self.setReferenceNodePath(self.tempCS) # update listbox accordingly self.refNodePathMenu.selectitem('parent') else: # Record initial value and initialize the widgets self.updatePlacer() # Record initial position self.updateResetValues(self['nodePath']) # Set scaling mode based on node path's current scale self.setScalingMode() else: # Flash entry self.nodePathMenuEntry.configure(background = 'Pink') def selectRefNodePathNamed(self, name): nodePath = None if name == 'self': nodePath = self.tempCS elif name == 'selected': nodePath = SEditor.selected.last # Add Combo box entry for this selected object self.addRefNodePath(nodePath) elif name == 'parent': nodePath = self['nodePath'].getParent() else: nodePath = self.refNodePathDict.get(name, None) if (nodePath == None): # See if this evaluates into a node path try: nodePath = eval(name) if isinstance(nodePath, NodePath): self.addRefNodePath(nodePath) else: # Good eval but not a node path, give up nodePath = None except: # Bogus eval nodePath = None # Clear bogus entry from listbox listbox = self.refNodePathMenu.component('scrolledlist') listbox.setlist(self.refNodePathNames) # Check to see if node path and ref node path are the same if (nodePath != None) and (nodePath.get_key() == self['nodePath'].get_key()): # Yes they are, use temp CS and update listbox accordingly nodePath = self.tempCS self.refNodePathMenu.selectitem('parent') # Update ref node path self.setReferenceNodePath(nodePath) def setReferenceNodePath(self, nodePath): self.refCS = nodePath if self.refCS: self.refNodePathMenuEntry.configure( background = self.nodePathMenuBG) # Update placer to reflect new state self.updatePlacer() else: # Flash entry self.refNodePathMenuEntry.configure(background = 'Pink') def addNodePath(self, nodePath): self.addNodePathToDict(nodePath, self.nodePathNames, self.nodePathMenu, self.nodePathDict) def addRefNodePath(self, nodePath): self.addNodePathToDict(nodePath, self.refNodePathNames, self.refNodePathMenu, self.refNodePathDict) def addNodePathToDict(self, nodePath, names, menu, dict): if not nodePath: return # Get node path's name name = nodePath.getName() if name in ['parent', 'render', 'camera']: dictName = name else: # Generate a unique name for the dict dictName = name + '-' + repr(nodePath.get_key()) if dictName not in dict: # Update combo box to include new item names.append(dictName) listbox = menu.component('scrolledlist') listbox.setlist(names) # Add new item to dictionary dict[dictName] = nodePath menu.selectitem(dictName) def updatePlacer(self): pos = Vec3(0) hpr = Vec3(0) scale = Vec3(1) np = self['nodePath'] if (np != None) and isinstance(np, NodePath): # Update temp CS self.updateAuxiliaryCoordinateSystems() # Update widgets if self.movementMode == 'Orbit:': pos.assign(self.posOffset) hpr.assign(ZERO_VEC) scale.assign(np.getScale()) elif self.refCS: pos.assign(np.getPos(self.refCS)) hpr.assign(np.getHpr(self.refCS)) scale.assign(np.getScale()) self.updatePosWidgets(pos) self.updateHprWidgets(hpr) self.updateScaleWidgets(scale) def updateAuxiliaryCoordinateSystems(self): # Temp CS self.tempCS.setPosHpr(self['nodePath'], 0,0,0,0,0,0) # Orbit CS # At reference self.orbitFromCS.setPos(self.refCS, 0,0,0) # But aligned with target self.orbitFromCS.setHpr(self['nodePath'], 0,0,0) # Also update to CS self.orbitToCS.setPosHpr(self.orbitFromCS, 0,0,0,0,0,0) # Get offset from origin self.posOffset.assign(self['nodePath'].getPos(self.orbitFromCS)) ### NODE PATH TRANSFORMATION OPERATIONS ### def xform(self, value, axis): if axis in ['sx', 'sy', 'sz']: self.xformScale(value,axis) elif self.movementMode == 'Relative To:': self.xformRelative(value, axis) elif self.movementMode == 'Orbit:': self.xformOrbit(value, axis) if self.nodePathMenu.get() == 'widget': if SEditor.manipulationControl.fSetCoa: # Update coa based on current widget position SEditor.selected.last.mCoa2Dnp.assign( SEditor.widget.getMat(SEditor.selected.last)) else: # Move the objects with the widget SEditor.selected.moveWrtWidgetAll() def xformStart(self, data): # Record undo point self.pushUndo() # If moving widget kill follow task and update wrts if self.nodePathMenu.get() == 'widget': taskMgr.remove('followSelectedNodePath') # Record relationship between selected nodes and widget SEditor.selected.getWrtAll() # Record initial state self.deltaHpr = self['nodePath'].getHpr(self.refCS) # Update placer to reflect new state self.updatePlacer() def xformStop(self, data): # Throw event to signal manipulation done # Send nodepath as a list messenger.send('DIRECT_manipulateObjectCleanup', [[self['nodePath']]]) # Update placer to reflect new state self.updatePlacer() # If moving widget restart follow task if self.nodePathMenu.get() == 'widget': # Restart followSelectedNodePath task SEditor.manipulationControl.spawnFollowSelectedNodePathTask() def xformRelative(self, value, axis): nodePath = self['nodePath'] if (nodePath != None) and (self.refCS != None): if axis == 'x': nodePath.setX(self.refCS, value) elif axis == 'y': nodePath.setY(self.refCS, value) elif axis == 'z': nodePath.setZ(self.refCS, value) else: if axis == 'h': self.deltaHpr.setX(value) elif axis == 'p': self.deltaHpr.setY(value) elif axis == 'r': self.deltaHpr.setZ(value) # Put node path at new hpr nodePath.setHpr(self.refCS, self.deltaHpr) def xformOrbit(self, value, axis): nodePath = self['nodePath'] if ((nodePath != None) and (self.refCS != None) and (self.orbitFromCS != None) and (self.orbitToCS != None)): if axis == 'x': self.posOffset.setX(value) elif axis == 'y': self.posOffset.setY(value) elif axis == 'z': self.posOffset.setZ(value) elif axis == 'h': self.orbitToCS.setH(self.orbitFromCS, value) elif axis == 'p': self.orbitToCS.setP(self.orbitFromCS, value) elif axis == 'r': self.orbitToCS.setR(self.orbitFromCS, value) nodePath.setPosHpr(self.orbitToCS, self.posOffset, ZERO_VEC) def xformScale(self, value, axis): if self['nodePath']: mode = self.scalingMode.get() scale = self['nodePath'].getScale() if mode == 'Scale Free': if axis == 'sx': scale.setX(value) elif axis == 'sy': scale.setY(value) elif axis == 'sz': scale.setZ(value) elif mode == 'Scale Uniform': scale.set(value,value,value) elif mode == 'Scale Proportional': if axis == 'sx': sf = value/scale[0] elif axis == 'sy': sf = value/scale[1] elif axis == 'sz': sf = value/scale[2] scale = scale * sf self['nodePath'].setScale(scale) def updatePosWidgets(self, pos): self.posX.set(pos[0]) self.posY.set(pos[1]) self.posZ.set(pos[2]) def updateHprWidgets(self, hpr): self.hprH.set(hpr[0]) self.hprP.set(hpr[1]) self.hprR.set(hpr[2]) def updateScaleWidgets(self, scale): self.scaleX.set(scale[0]) self.scaleY.set(scale[1]) self.scaleZ.set(scale[2]) def zeroAll(self): self.xformStart(None) self.updatePosWidgets(ZERO_VEC) self.updateHprWidgets(ZERO_VEC) self.updateScaleWidgets(UNIT_VEC) self.xformStop(None) def zeroPos(self): self.xformStart(None) self.updatePosWidgets(ZERO_VEC) self.xformStop(None) def zeroHpr(self): self.xformStart(None) self.updateHprWidgets(ZERO_VEC) self.xformStop(None) def unitScale(self): self.xformStart(None) self.updateScaleWidgets(UNIT_VEC) self.xformStop(None) def updateResetValues(self, nodePath): self.initPos.assign(nodePath.getPos()) self.posX['resetValue'] = self.initPos[0] self.posY['resetValue'] = self.initPos[1] self.posZ['resetValue'] = self.initPos[2] self.initHpr.assign(nodePath.getHpr()) self.hprH['resetValue'] = self.initHpr[0] self.hprP['resetValue'] = self.initHpr[1] self.hprR['resetValue'] = self.initHpr[2] self.initScale.assign(nodePath.getScale()) self.scaleX['resetValue'] = self.initScale[0] self.scaleY['resetValue'] = self.initScale[1] self.scaleZ['resetValue'] = self.initScale[2] def resetAll(self): if self['nodePath']: self.xformStart(None) self['nodePath'].setPosHprScale( self.initPos, self.initHpr, self.initScale) self.xformStop(None) def resetPos(self): if self['nodePath']: self.xformStart(None) self['nodePath'].setPos(self.initPos) self.xformStop(None) def resetHpr(self): if self['nodePath']: self.xformStart(None) self['nodePath'].setHpr(self.initHpr) self.xformStop(None) def resetScale(self): if self['nodePath']: self.xformStart(None) self['nodePath'].setScale(self.initScale) self.xformStop(None) def pushUndo(self, fResetRedo = 1): SEditor.pushUndo([self['nodePath']]) def undoHook(self, nodePathList = []): # Reflect new changes self.updatePlacer() def pushUndoHook(self): # Make sure button is reactivated self.undoButton.configure(state = 'normal') def undoListEmptyHook(self): # Make sure button is deactivated self.undoButton.configure(state = 'disabled') def pushRedo(self): SEditor.pushRedo([self['nodePath']]) def redoHook(self, nodePathList = []): # Reflect new changes self.updatePlacer() def pushRedoHook(self): # Make sure button is reactivated self.redoButton.configure(state = 'normal') def redoListEmptyHook(self): # Make sure button is deactivated self.redoButton.configure(state = 'disabled') def printNodePathInfo(self): np = self['nodePath'] if np: name = np.getName() pos = np.getPos() hpr = np.getHpr() scale = np.getScale() posString = '%.2f, %.2f, %.2f' % (pos[0], pos[1], pos[2]) hprString = '%.2f, %.2f, %.2f' % (hpr[0], hpr[1], hpr[2]) scaleString = '%.2f, %.2f, %.2f' % (scale[0], scale[1], scale[2]) print('NodePath: %s' % name) print('Pos: %s' % posString) print('Hpr: %s' % hprString) print('Scale: %s' % scaleString) print(('%s.setPosHprScale(%s, %s, %s)' % (name, posString, hprString, scaleString))) def onDestroy(self, event): # Remove hooks for event, method in self.undoEvents: self.ignore(event) self.tempCS.removeNode() self.orbitFromCS.removeNode() self.orbitToCS.removeNode() # send out a message to let sceneEditor know that placer panel has been closed. # Also, stop accepting the updata message from sceneEditor messenger.send('Placer_close') self.ignore('placerUpdate')
class Placer(AppShell): # Override class variables here appname = 'Placer Panel' frameWidth = 625 frameHeight = 215 usecommandarea = 0 usestatusarea = 0 def __init__(self, parent=None, **kw): INITOPT = Pmw.INITOPT optiondefs = ( ('title', self.appname, None), ('nodePath', SEditor.camera, None), ) self.defineoptions(kw, optiondefs) # Call superclass initialization function AppShell.__init__(self) self.initialiseoptions(Placer) # Accept the message from sceneEditor to update the information about the target nodePath self.accept('placerUpdate', self.updatePlacer) def appInit(self): # Initialize state self.tempCS = SEditor.group.attachNewNode('placerTempCS') self.orbitFromCS = SEditor.group.attachNewNode('placerOrbitFromCS') self.orbitToCS = SEditor.group.attachNewNode('placerOrbitToCS') self.refCS = self.tempCS # Dictionary keeping track of all node paths manipulated so far self.nodePathDict = {} self.nodePathDict['camera'] = SEditor.camera self.nodePathDict['widget'] = SEditor.widget self.nodePathNames = ['camera', 'widget', 'selected'] self.refNodePathDict = {} self.refNodePathDict['parent'] = self['nodePath'].getParent() self.refNodePathDict['render'] = render self.refNodePathDict['camera'] = SEditor.camera self.refNodePathDict['widget'] = SEditor.widget self.refNodePathNames = [ 'parent', 'self', 'render', 'camera', 'widget', 'selected' ] # Initial state self.initPos = Vec3(0) self.initHpr = Vec3(0) self.initScale = Vec3(1) self.deltaHpr = Vec3(0) # Offset for orbital mode self.posOffset = Vec3(0) # Set up event hooks self.undoEvents = [('DIRECT_undo', self.undoHook), ('DIRECT_pushUndo', self.pushUndoHook), ('DIRECT_undoListEmpty', self.undoListEmptyHook), ('DIRECT_redo', self.redoHook), ('DIRECT_pushRedo', self.pushRedoHook), ('DIRECT_redoListEmpty', self.redoListEmptyHook)] for event, method in self.undoEvents: self.accept(event, method) # Init movement mode self.movementMode = 'Relative To:' def createInterface(self): # The interior of the toplevel panel interior = self.interior() interior['relief'] = tkinter.FLAT # Add placer commands to menubar self.menuBar.addmenu('Placer', 'Placer Panel Operations') self.menuBar.addmenuitem('Placer', 'command', 'Zero Node Path', label='Zero All', command=self.zeroAll) self.menuBar.addmenuitem('Placer', 'command', 'Reset Node Path', label='Reset All', command=self.resetAll) self.menuBar.addmenuitem('Placer', 'command', 'Print Node Path Info', label='Print Info', command=self.printNodePathInfo) self.menuBar.addmenuitem('Placer', 'command', 'Toggle widget visability', label='Toggle Widget Vis', command=SEditor.toggleWidgetVis) self.menuBar.addmenuitem( 'Placer', 'command', 'Toggle widget manipulation mode', label='Toggle Widget Mode', command=SEditor.manipulationControl.toggleObjectHandlesMode) # Get a handle to the menu frame menuFrame = self.menuFrame self.nodePathMenu = Pmw.ComboBox( menuFrame, labelpos=tkinter.W, label_text='Node Path:', entry_width=20, selectioncommand=self.selectNodePathNamed, scrolledlist_items=self.nodePathNames) self.nodePathMenu.selectitem('selected') self.nodePathMenuEntry = ( self.nodePathMenu.component('entryfield_entry')) self.nodePathMenuBG = ( self.nodePathMenuEntry.configure('background')[3]) self.nodePathMenu.pack(side='left', fill='x', expand=1) self.bind(self.nodePathMenu, 'Select node path to manipulate') modeMenu = Pmw.OptionMenu(menuFrame, items=('Relative To:', 'Orbit:'), initialitem='Relative To:', command=self.setMovementMode, menubutton_width=8) modeMenu.pack(side='left', expand=0) self.bind(modeMenu, 'Select manipulation mode') self.refNodePathMenu = Pmw.ComboBox( menuFrame, entry_width=16, selectioncommand=self.selectRefNodePathNamed, scrolledlist_items=self.refNodePathNames) self.refNodePathMenu.selectitem('parent') self.refNodePathMenuEntry = ( self.refNodePathMenu.component('entryfield_entry')) self.refNodePathMenu.pack(side='left', fill='x', expand=1) self.bind(self.refNodePathMenu, 'Select relative node path') self.undoButton = Button(menuFrame, text='Undo', command=SEditor.undo) if SEditor.undoList: self.undoButton['state'] = 'normal' else: self.undoButton['state'] = 'disabled' self.undoButton.pack(side='left', expand=0) self.bind(self.undoButton, 'Undo last operation') self.redoButton = Button(menuFrame, text='Redo', command=SEditor.redo) if SEditor.redoList: self.redoButton['state'] = 'normal' else: self.redoButton['state'] = 'disabled' self.redoButton.pack(side='left', expand=0) self.bind(self.redoButton, 'Redo last operation') # Create and pack the Pos Controls posGroup = Pmw.Group(interior, tag_pyclass=Menubutton, tag_text='Position', tag_font=('MSSansSerif', 14), tag_activebackground='#909090', ring_relief=tkinter.RIDGE) posMenubutton = posGroup.component('tag') self.bind(posMenubutton, 'Position menu operations') posMenu = Menu(posMenubutton, tearoff=0) posMenu.add_command(label='Set to zero', command=self.zeroPos) posMenu.add_command(label='Reset initial', command=self.resetPos) posMenubutton['menu'] = posMenu posGroup.pack(side='left', fill='both', expand=1) posInterior = posGroup.interior() # Create the dials self.posX = self.createcomponent('posX', (), None, Floater, (posInterior, ), text='X', relief=tkinter.FLAT, value=0.0, label_foreground='Red') self.posX['commandData'] = ['x'] self.posX['preCallback'] = self.xformStart self.posX['postCallback'] = self.xformStop self.posX['callbackData'] = ['x'] self.posX.pack(expand=1, fill='both') self.posY = self.createcomponent('posY', (), None, Floater, (posInterior, ), text='Y', relief=tkinter.FLAT, value=0.0, label_foreground='#00A000') self.posY['commandData'] = ['y'] self.posY['preCallback'] = self.xformStart self.posY['postCallback'] = self.xformStop self.posY['callbackData'] = ['y'] self.posY.pack(expand=1, fill='both') self.posZ = self.createcomponent('posZ', (), None, Floater, (posInterior, ), text='Z', relief=tkinter.FLAT, value=0.0, label_foreground='Blue') self.posZ['commandData'] = ['z'] self.posZ['preCallback'] = self.xformStart self.posZ['postCallback'] = self.xformStop self.posZ['callbackData'] = ['z'] self.posZ.pack(expand=1, fill='both') # Create and pack the Hpr Controls hprGroup = Pmw.Group(interior, tag_pyclass=Menubutton, tag_text='Orientation', tag_font=('MSSansSerif', 14), tag_activebackground='#909090', ring_relief=tkinter.RIDGE) hprMenubutton = hprGroup.component('tag') self.bind(hprMenubutton, 'Orientation menu operations') hprMenu = Menu(hprMenubutton, tearoff=0) hprMenu.add_command(label='Set to zero', command=self.zeroHpr) hprMenu.add_command(label='Reset initial', command=self.resetHpr) hprMenubutton['menu'] = hprMenu hprGroup.pack(side='left', fill='both', expand=1) hprInterior = hprGroup.interior() # Create the dials self.hprH = self.createcomponent('hprH', (), None, AngleDial, (hprInterior, ), style='mini', text='H', value=0.0, relief=tkinter.FLAT, label_foreground='blue') self.hprH['commandData'] = ['h'] self.hprH['preCallback'] = self.xformStart self.hprH['postCallback'] = self.xformStop self.hprH['callbackData'] = ['h'] self.hprH.pack(expand=1, fill='both') self.hprP = self.createcomponent('hprP', (), None, AngleDial, (hprInterior, ), style='mini', text='P', value=0.0, relief=tkinter.FLAT, label_foreground='red') self.hprP['commandData'] = ['p'] self.hprP['preCallback'] = self.xformStart self.hprP['postCallback'] = self.xformStop self.hprP['callbackData'] = ['p'] self.hprP.pack(expand=1, fill='both') self.hprR = self.createcomponent('hprR', (), None, AngleDial, (hprInterior, ), style='mini', text='R', value=0.0, relief=tkinter.FLAT, label_foreground='#00A000') self.hprR['commandData'] = ['r'] self.hprR['preCallback'] = self.xformStart self.hprR['postCallback'] = self.xformStop self.hprR['callbackData'] = ['r'] self.hprR.pack(expand=1, fill='both') # Create and pack the Scale Controls # The available scaling modes self.scalingMode = StringVar() self.scalingMode.set('Scale Uniform') # The scaling widgets scaleGroup = Pmw.Group(interior, tag_text='Scale Uniform', tag_pyclass=Menubutton, tag_font=('MSSansSerif', 14), tag_activebackground='#909090', ring_relief=tkinter.RIDGE) self.scaleMenubutton = scaleGroup.component('tag') self.bind(self.scaleMenubutton, 'Scale menu operations') self.scaleMenubutton['textvariable'] = self.scalingMode # Scaling menu scaleMenu = Menu(self.scaleMenubutton, tearoff=0) scaleMenu.add_command(label='Set to unity', command=self.unitScale) scaleMenu.add_command(label='Reset initial', command=self.resetScale) scaleMenu.add_radiobutton(label='Scale Free', variable=self.scalingMode) scaleMenu.add_radiobutton(label='Scale Uniform', variable=self.scalingMode) scaleMenu.add_radiobutton(label='Scale Proportional', variable=self.scalingMode) self.scaleMenubutton['menu'] = scaleMenu # Pack group widgets scaleGroup.pack(side='left', fill='both', expand=1) scaleInterior = scaleGroup.interior() # Create the dials self.scaleX = self.createcomponent('scaleX', (), None, Floater, (scaleInterior, ), text='X Scale', relief=tkinter.FLAT, min=0.0001, value=1.0, resetValue=1.0, label_foreground='Red') self.scaleX['commandData'] = ['sx'] self.scaleX['callbackData'] = ['sx'] self.scaleX['preCallback'] = self.xformStart self.scaleX['postCallback'] = self.xformStop self.scaleX.pack(expand=1, fill='both') self.scaleY = self.createcomponent('scaleY', (), None, Floater, (scaleInterior, ), text='Y Scale', relief=tkinter.FLAT, min=0.0001, value=1.0, resetValue=1.0, label_foreground='#00A000') self.scaleY['commandData'] = ['sy'] self.scaleY['callbackData'] = ['sy'] self.scaleY['preCallback'] = self.xformStart self.scaleY['postCallback'] = self.xformStop self.scaleY.pack(expand=1, fill='both') self.scaleZ = self.createcomponent('scaleZ', (), None, Floater, (scaleInterior, ), text='Z Scale', relief=tkinter.FLAT, min=0.0001, value=1.0, resetValue=1.0, label_foreground='Blue') self.scaleZ['commandData'] = ['sz'] self.scaleZ['callbackData'] = ['sz'] self.scaleZ['preCallback'] = self.xformStart self.scaleZ['postCallback'] = self.xformStop self.scaleZ.pack(expand=1, fill='both') # Make sure appropriate labels are showing self.setMovementMode('Relative To:') # Set up placer for inital node path self.selectNodePathNamed('init') self.selectRefNodePathNamed('parent') # Update place to reflect initial state self.updatePlacer() # Now that you're done setting up, attach commands self.posX['command'] = self.xform self.posY['command'] = self.xform self.posZ['command'] = self.xform self.hprH['command'] = self.xform self.hprP['command'] = self.xform self.hprR['command'] = self.xform self.scaleX['command'] = self.xform self.scaleY['command'] = self.xform self.scaleZ['command'] = self.xform ### WIDGET OPERATIONS ### def setMovementMode(self, movementMode): # Set prefix namePrefix = '' self.movementMode = movementMode if (movementMode == 'Relative To:'): namePrefix = 'Relative ' elif (movementMode == 'Orbit:'): namePrefix = 'Orbit ' # Update pos widgets self.posX['text'] = namePrefix + 'X' self.posY['text'] = namePrefix + 'Y' self.posZ['text'] = namePrefix + 'Z' # Update hpr widgets if (movementMode == 'Orbit:'): namePrefix = 'Orbit delta ' self.hprH['text'] = namePrefix + 'H' self.hprP['text'] = namePrefix + 'P' self.hprR['text'] = namePrefix + 'R' # Update temp cs and initialize widgets self.updatePlacer() def setScalingMode(self): if self['nodePath']: scale = self['nodePath'].getScale() if ((scale[0] != scale[1]) or (scale[0] != scale[2]) or (scale[1] != scale[2])): self.scalingMode.set('Scale Free') def selectNodePathNamed(self, name): nodePath = None if name == 'init': nodePath = self['nodePath'] # Add Combo box entry for the initial node path self.addNodePath(nodePath) elif name == 'selected': nodePath = SEditor.selected.last # Add Combo box entry for this selected object self.addNodePath(nodePath) else: nodePath = self.nodePathDict.get(name, None) if (nodePath == None): # See if this evaluates into a node path try: nodePath = eval(name) if isinstance(nodePath, NodePath): self.addNodePath(nodePath) else: # Good eval but not a node path, give up nodePath = None except: # Bogus eval nodePath = None # Clear bogus entry from listbox listbox = self.nodePathMenu.component('scrolledlist') listbox.setlist(self.nodePathNames) else: if name == 'widget': # Record relationship between selected nodes and widget SEditor.selected.getWrtAll() # Update active node path self.setActiveNodePath(nodePath) def setActiveNodePath(self, nodePath): self['nodePath'] = nodePath if self['nodePath']: self.nodePathMenuEntry.configure(background=self.nodePathMenuBG) # Check to see if node path and ref node path are the same if ((self.refCS != None) and (self.refCS.get_key() == self['nodePath'].get_key())): # Yes they are, use temp CS as ref # This calls updatePlacer self.setReferenceNodePath(self.tempCS) # update listbox accordingly self.refNodePathMenu.selectitem('parent') else: # Record initial value and initialize the widgets self.updatePlacer() # Record initial position self.updateResetValues(self['nodePath']) # Set scaling mode based on node path's current scale self.setScalingMode() else: # Flash entry self.nodePathMenuEntry.configure(background='Pink') def selectRefNodePathNamed(self, name): nodePath = None if name == 'self': nodePath = self.tempCS elif name == 'selected': nodePath = SEditor.selected.last # Add Combo box entry for this selected object self.addRefNodePath(nodePath) elif name == 'parent': nodePath = self['nodePath'].getParent() else: nodePath = self.refNodePathDict.get(name, None) if (nodePath == None): # See if this evaluates into a node path try: nodePath = eval(name) if isinstance(nodePath, NodePath): self.addRefNodePath(nodePath) else: # Good eval but not a node path, give up nodePath = None except: # Bogus eval nodePath = None # Clear bogus entry from listbox listbox = self.refNodePathMenu.component('scrolledlist') listbox.setlist(self.refNodePathNames) # Check to see if node path and ref node path are the same if (nodePath != None) and (nodePath.get_key() == self['nodePath'].get_key()): # Yes they are, use temp CS and update listbox accordingly nodePath = self.tempCS self.refNodePathMenu.selectitem('parent') # Update ref node path self.setReferenceNodePath(nodePath) def setReferenceNodePath(self, nodePath): self.refCS = nodePath if self.refCS: self.refNodePathMenuEntry.configure(background=self.nodePathMenuBG) # Update placer to reflect new state self.updatePlacer() else: # Flash entry self.refNodePathMenuEntry.configure(background='Pink') def addNodePath(self, nodePath): self.addNodePathToDict(nodePath, self.nodePathNames, self.nodePathMenu, self.nodePathDict) def addRefNodePath(self, nodePath): self.addNodePathToDict(nodePath, self.refNodePathNames, self.refNodePathMenu, self.refNodePathDict) def addNodePathToDict(self, nodePath, names, menu, dict): if not nodePath: return # Get node path's name name = nodePath.getName() if name in ['parent', 'render', 'camera']: dictName = name else: # Generate a unique name for the dict dictName = name + '-' + repr(nodePath.get_key()) if dictName not in dict: # Update combo box to include new item names.append(dictName) listbox = menu.component('scrolledlist') listbox.setlist(names) # Add new item to dictionary dict[dictName] = nodePath menu.selectitem(dictName) def updatePlacer(self): pos = Vec3(0) hpr = Vec3(0) scale = Vec3(1) np = self['nodePath'] if (np != None) and isinstance(np, NodePath): # Update temp CS self.updateAuxiliaryCoordinateSystems() # Update widgets if self.movementMode == 'Orbit:': pos.assign(self.posOffset) hpr.assign(ZERO_VEC) scale.assign(np.getScale()) elif self.refCS: pos.assign(np.getPos(self.refCS)) hpr.assign(np.getHpr(self.refCS)) scale.assign(np.getScale()) self.updatePosWidgets(pos) self.updateHprWidgets(hpr) self.updateScaleWidgets(scale) def updateAuxiliaryCoordinateSystems(self): # Temp CS self.tempCS.setPosHpr(self['nodePath'], 0, 0, 0, 0, 0, 0) # Orbit CS # At reference self.orbitFromCS.setPos(self.refCS, 0, 0, 0) # But aligned with target self.orbitFromCS.setHpr(self['nodePath'], 0, 0, 0) # Also update to CS self.orbitToCS.setPosHpr(self.orbitFromCS, 0, 0, 0, 0, 0, 0) # Get offset from origin self.posOffset.assign(self['nodePath'].getPos(self.orbitFromCS)) ### NODE PATH TRANSFORMATION OPERATIONS ### def xform(self, value, axis): if axis in ['sx', 'sy', 'sz']: self.xformScale(value, axis) elif self.movementMode == 'Relative To:': self.xformRelative(value, axis) elif self.movementMode == 'Orbit:': self.xformOrbit(value, axis) if self.nodePathMenu.get() == 'widget': if SEditor.manipulationControl.fSetCoa: # Update coa based on current widget position SEditor.selected.last.mCoa2Dnp.assign( SEditor.widget.getMat(SEditor.selected.last)) else: # Move the objects with the widget SEditor.selected.moveWrtWidgetAll() def xformStart(self, data): # Record undo point self.pushUndo() # If moving widget kill follow task and update wrts if self.nodePathMenu.get() == 'widget': taskMgr.remove('followSelectedNodePath') # Record relationship between selected nodes and widget SEditor.selected.getWrtAll() # Record initial state self.deltaHpr = self['nodePath'].getHpr(self.refCS) # Update placer to reflect new state self.updatePlacer() def xformStop(self, data): # Throw event to signal manipulation done # Send nodepath as a list messenger.send('DIRECT_manipulateObjectCleanup', [[self['nodePath']]]) # Update placer to reflect new state self.updatePlacer() # If moving widget restart follow task if self.nodePathMenu.get() == 'widget': # Restart followSelectedNodePath task SEditor.manipulationControl.spawnFollowSelectedNodePathTask() def xformRelative(self, value, axis): nodePath = self['nodePath'] if (nodePath != None) and (self.refCS != None): if axis == 'x': nodePath.setX(self.refCS, value) elif axis == 'y': nodePath.setY(self.refCS, value) elif axis == 'z': nodePath.setZ(self.refCS, value) else: if axis == 'h': self.deltaHpr.setX(value) elif axis == 'p': self.deltaHpr.setY(value) elif axis == 'r': self.deltaHpr.setZ(value) # Put node path at new hpr nodePath.setHpr(self.refCS, self.deltaHpr) def xformOrbit(self, value, axis): nodePath = self['nodePath'] if ((nodePath != None) and (self.refCS != None) and (self.orbitFromCS != None) and (self.orbitToCS != None)): if axis == 'x': self.posOffset.setX(value) elif axis == 'y': self.posOffset.setY(value) elif axis == 'z': self.posOffset.setZ(value) elif axis == 'h': self.orbitToCS.setH(self.orbitFromCS, value) elif axis == 'p': self.orbitToCS.setP(self.orbitFromCS, value) elif axis == 'r': self.orbitToCS.setR(self.orbitFromCS, value) nodePath.setPosHpr(self.orbitToCS, self.posOffset, ZERO_VEC) def xformScale(self, value, axis): if self['nodePath']: mode = self.scalingMode.get() scale = self['nodePath'].getScale() if mode == 'Scale Free': if axis == 'sx': scale.setX(value) elif axis == 'sy': scale.setY(value) elif axis == 'sz': scale.setZ(value) elif mode == 'Scale Uniform': scale.set(value, value, value) elif mode == 'Scale Proportional': if axis == 'sx': sf = value / scale[0] elif axis == 'sy': sf = value / scale[1] elif axis == 'sz': sf = value / scale[2] scale = scale * sf self['nodePath'].setScale(scale) def updatePosWidgets(self, pos): self.posX.set(pos[0]) self.posY.set(pos[1]) self.posZ.set(pos[2]) def updateHprWidgets(self, hpr): self.hprH.set(hpr[0]) self.hprP.set(hpr[1]) self.hprR.set(hpr[2]) def updateScaleWidgets(self, scale): self.scaleX.set(scale[0]) self.scaleY.set(scale[1]) self.scaleZ.set(scale[2]) def zeroAll(self): self.xformStart(None) self.updatePosWidgets(ZERO_VEC) self.updateHprWidgets(ZERO_VEC) self.updateScaleWidgets(UNIT_VEC) self.xformStop(None) def zeroPos(self): self.xformStart(None) self.updatePosWidgets(ZERO_VEC) self.xformStop(None) def zeroHpr(self): self.xformStart(None) self.updateHprWidgets(ZERO_VEC) self.xformStop(None) def unitScale(self): self.xformStart(None) self.updateScaleWidgets(UNIT_VEC) self.xformStop(None) def updateResetValues(self, nodePath): self.initPos.assign(nodePath.getPos()) self.posX['resetValue'] = self.initPos[0] self.posY['resetValue'] = self.initPos[1] self.posZ['resetValue'] = self.initPos[2] self.initHpr.assign(nodePath.getHpr()) self.hprH['resetValue'] = self.initHpr[0] self.hprP['resetValue'] = self.initHpr[1] self.hprR['resetValue'] = self.initHpr[2] self.initScale.assign(nodePath.getScale()) self.scaleX['resetValue'] = self.initScale[0] self.scaleY['resetValue'] = self.initScale[1] self.scaleZ['resetValue'] = self.initScale[2] def resetAll(self): if self['nodePath']: self.xformStart(None) self['nodePath'].setPosHprScale(self.initPos, self.initHpr, self.initScale) self.xformStop(None) def resetPos(self): if self['nodePath']: self.xformStart(None) self['nodePath'].setPos(self.initPos) self.xformStop(None) def resetHpr(self): if self['nodePath']: self.xformStart(None) self['nodePath'].setHpr(self.initHpr) self.xformStop(None) def resetScale(self): if self['nodePath']: self.xformStart(None) self['nodePath'].setScale(self.initScale) self.xformStop(None) def pushUndo(self, fResetRedo=1): SEditor.pushUndo([self['nodePath']]) def undoHook(self, nodePathList=[]): # Reflect new changes self.updatePlacer() def pushUndoHook(self): # Make sure button is reactivated self.undoButton.configure(state='normal') def undoListEmptyHook(self): # Make sure button is deactivated self.undoButton.configure(state='disabled') def pushRedo(self): SEditor.pushRedo([self['nodePath']]) def redoHook(self, nodePathList=[]): # Reflect new changes self.updatePlacer() def pushRedoHook(self): # Make sure button is reactivated self.redoButton.configure(state='normal') def redoListEmptyHook(self): # Make sure button is deactivated self.redoButton.configure(state='disabled') def printNodePathInfo(self): np = self['nodePath'] if np: name = np.getName() pos = np.getPos() hpr = np.getHpr() scale = np.getScale() posString = '%.2f, %.2f, %.2f' % (pos[0], pos[1], pos[2]) hprString = '%.2f, %.2f, %.2f' % (hpr[0], hpr[1], hpr[2]) scaleString = '%.2f, %.2f, %.2f' % (scale[0], scale[1], scale[2]) print('NodePath: %s' % name) print('Pos: %s' % posString) print('Hpr: %s' % hprString) print('Scale: %s' % scaleString) print(('%s.setPosHprScale(%s, %s, %s)' % (name, posString, hprString, scaleString))) def onDestroy(self, event): # Remove hooks for event, method in self.undoEvents: self.ignore(event) self.tempCS.removeNode() self.orbitFromCS.removeNode() self.orbitToCS.removeNode() # send out a message to let sceneEditor know that placer panel has been closed. # Also, stop accepting the updata message from sceneEditor messenger.send('Placer_close') self.ignore('placerUpdate')
class Game(Move): # Classe gérant tout ce qui concerne le jeu pure telle que les hitboxs, le score, les conditions de victoire et de # défaite. # Cette classe comporte 7 méthodes, init comme dans toutes nos classes où l'on apelle les différentes méthodes des # classes précédentes dont nous avons besoin et où nous récupérons toues les variables nécessaire gâce aux propriétés # d'héridié des classes. # Les 6 autres méthodes sont décrites à l'aide d'un commentaire sous chacunes d'entre elles. def __init__(self, hi, dx, dy, t): Move.__init__(self, hi, dx, dy, t) Move.moveAliens(self) Move.moveSpaceships(self) Move.moveBulet2(self) Move.moveBulet(self) Move.moveBuletAliens(self) self.lives = 3 self.scoring = 0 def hitBox(self): # Cette méthode gère les collisions entre les différents éléments du Canvas. # Pour ce faire, elle vérifie que les coordonées des éléments censés intéragir entre concordent, si c'est le cas, # les deux éléments sont détruits sur le canvas et dans leurs listes respectives. # Afin de vérifier constemment si des éléments rentrenet en collisions, cette fonction s'apelle de maniére # récursive grâce à la méthode tkinter .after() # La méthode cesse sa récursivité lorsque le compteur self.cLoose passe à 1. Le compteur peut changer d'état lorsque # les aliens arrivent au niveau du vaisseau ou lorsque le nombre de vies tombe à 0. if self.cLoose == 1: self.Defeat() return -1 else: if self.canevas.coords(self.bulletsShips[-1])[1] < 0: self.canevas.delete(self.bulletsShips[-1]) self.bulletsShips.pop(-1) for line in self.Aliens: for alien in line: if self.canevas.coords(self.bulletsShips[-1])[1] < self.canevas.coords(alien)[3] and self.canevas.coords(self.bulletsShips[-1])[3] > self.canevas.coords(alien)[1] and self.canevas.coords(self.bulletsShips[-1])[0] < self.canevas.coords(alien)[2] and self.canevas.coords(self.bulletsShips[-1])[2] > self.canevas.coords(alien)[0]: line.remove(alien) if len(line) == 0: del self.Aliens[self.Aliens.index(line)] self.Aliens2.remove(alien) self.canevas.delete(alien) self.scoring = self.scoring + 100 self.Scoring() self.canevas.delete(self.bulletsShips[-1]) self.bulletsShips.pop(-1) if len(self.Aliens2) == self.aliensNumber/2: self.dx = 1.5*self.dx if len(self.Aliens2) == 0: self.Win() for bullet in self.bulletsAlien: if self.canevas.coords(bullet)[3] > self.canevas.coords(self.spaceships)[1] and self.canevas.coords(bullet)[1] < self.canevas.coords(self.spaceships)[3] and self.canevas.coords(bullet)[0] < self.canevas.coords(self.spaceships)[2] and self.canevas.coords(bullet)[2] > self.canevas.coords(self.spaceships)[0]: self.lives -= 1 self.printLives = "vie restantes: ", str(self.lives) if self.lives == 0: self.Scoring self.Defeat() self.labelLives.configure (text = "".join(self.printLives)) self.canevas.delete(self.bulletsAlien[-1]) self.bulletsAlien.pop(-1) if len(self.Barricades) != 0: for barricade in self.Barricades: if self.canevas.coords(self.bulletsShips[-1])[1] < self.canevas.coords(barricade)[3] and self.canevas.coords(self.bulletsShips[-1])[3] > self.canevas.coords(barricade)[1] and self.canevas.coords(self.bulletsShips[-1])[0] < self.canevas.coords(barricade)[2] and self.canevas.coords(self.bulletsShips[-1])[2] > self.canevas.coords(barricade)[0]: if self.canevas.itemcget(barricade, "fill") == "red": self.canevas.delete(barricade) self.Barricades.remove(barricade) self.canevas.delete(self.bulletsShips[-1]) self.bulletsShips.pop(-1) break self.canevas.itemconfigure(barricade, fill = "red") self.canevas.delete(self.bulletsShips[-1]) self.bulletsShips.pop(-1) if self.canevas.coords(self.bulletsAlien[-1])[3] > self.canevas.coords(barricade)[1] and self.canevas.coords(self.bulletsAlien[-1])[1] < self.canevas.coords(barricade)[3] and self.canevas.coords(self.bulletsAlien[-1])[0] < self.canevas.coords(barricade)[2] and self.canevas.coords(self.bulletsAlien[-1])[2] > self.canevas.coords(barricade)[0]: self.canevas.delete(barricade) self.Barricades.remove(barricade) self.canevas.delete(self.bulletsAlien[-1]) self.bulletsAlien.pop(-1) self.w.after(self.t, self.hitBox) def Scoring(self): # Cette méthode sert à afficher le score en cours de partie. # Le score est stocké dans la variables self.scoring. Elle est initialisée à 0 dans l'init de la classe Game et # augmente de 100 à chaque fois qu'un alien est détruit. # La méthode est appelée à chaque fois qu'un alien est détruit (ligne 67), lorsque l'utilisateur tombe à court de # vies (ligne 83) et lorsqu'on relance la partie(ligne 164). self.printScore = "score :", str(self.scoring) self.score.configure(text = "".join(self.printScore)) def Defeat(self): # Cette méthode est utilisée pour afficher le texte en cas de défaites dans un Label créé au moment de l'appel de # la méthode et pour détruire le vaiseau et pour arrêter # le jeu. # Pour ce faire on donne la valeure 1 au compteur self.stop, or lorsque ce compteur est 1, toutes les méthodes # qui faisaient bouger les différents éléments du jeu retourne -1 et donc arrêtent leur récursivité. # Elle est appelée lorsque l'utilisateur tombe à court de vie (ligne 84) et lorsqu'un des aliens arrive à la même # ordonnée que le vaisseau(classe Move ligne 46 + classe Game ligne 56). defeatTxt = "Oh niiooon, vous avez perdu. Votre score est de: ", str(self.scoring) self.canevas.delete(self.spaceships) # Destruction du vaisseau self.labelDefeat = Label(self.w, text = "".join(defeatTxt), fg = 'black') self.labelDefeat.grid(row = 1, column = 0) self.labelDefeat.configure(font = 20) self.stop = 1 self.cLoose = 1 # Compteur utilisée dans la méthode reload afin de détruire le bon label en fonction de si le joueur a gagnè ou perdu. self.buttonReload["command"] = self.Reload def Win(self): # Tout comme la méthode defeat cette méthode arrête le jeu en donnant au compteur self.stop la valeure 1. À la # différence de la méthode Defeat, la méthode Win affiche un texte de victoire au lieu d'un texte de défaite # dans un Label créé au moment de l'appel de la méthode. # Cette méthode est appelée lorsque la longeur la liste contenant les aliens self.Aliens2 est nul (ligne 75). winTxt = "Wouhouuu, vous avez obtenu le score maximal: ", str(self.scoring) self.labelWin = Label(self.w, text = "".join(winTxt), fg = 'black') self.labelWin.grid(row = 1, column = 0) self.labelWin.configure(font = 20) self.stop = 1 self.buttonReload["command"] = self.Reload def Reload(self): # Cette méthode n'est pas encore totalement fonctionnel, elle a pour but de préparer une nouvelle partie lorsque # l'utilisateur vient d'en terminer une (pas encore de système de niveaux) # Pour ce faire elle nettoie le canvas puis recrée les différents éléments tel que les aliens ou les barricades. # Elle crée ensuite un bouton qui lorsqu'on appuie dessus apelle la méthode reMove qui n'est pas non plus fini. # Cette méthode est appelé lorsque l'utilisateur appuie sur le boutton self.buttonReload. self.canevas.delete(all) self.scoring = 0 self.Scoring() self.lives = 3 self.printLives = "vie restantes: ", str(self.lives) if self.cLoose == 1: # Conditions obligatoires pour pas que le programme cherche à détuire un Label innexistant self.labelDefeat.destroy() else: self.labelWin.destroy() self.photo = PhotoImage(file="jean-pierre.gif") self.item = self.canevas.create_image(600, 500, image = self.photo, tags = "D") self.labelHelp = Label(self.w, text = "Etes vous prêt à jouer?", fg = 'black') self.labelHelp.grid(row = 1, column = 0, sticky = "n") self.labelHelp.configure(font = 20) self.cLoose = 0 self.stop = 0 Draw.drawAliens(self) (self.Barricades1, self.Barricades2, self.Barricades3) = Draw.drawBarricades(self) self.Barricades = self.Barricades1 + self.Barricades2 + self.Barricades3 Draw.drawSpaceships(self) self.buttonYes = Button(self.w, text = "oui", command = self.reMove) self.buttonYes.grid(row = 1, column = 0) self.buttonYes.configure(font = 20) def reMove(self): # Cette méthode est en court de finition. # Lorsqu'elle est appelée, elle détruit le boutton servant à confirmer que le joueur est prêt à commencer une # nouvelle partie et le Label self.LabelHelp # La méthode n'est cepandante pas fonctionnel car lors de son appel, les aliens ne ce déplacent pas et tirent # deux fois plus de balles que ce qu'ils devraient tirer normalement. self.buttonYes["command"] = "" self.buttonYes.destroy() self.labelHelp.destroy() self.hitBox() Move.moveAliens(self) Move.moveSpaceships(self) Move.moveBulet2(self) Move.moveBulet(self) Move.moveBuletAliens(self) Draw.createBuletsAliens(self)
class ExerciseFrame(Frame): def __init__(self, master, subject, font_name): super().__init__(master) self.master = master self.subject = subject self.pack(fill=BOTH, expand=1) # 自身Frame最大化 # counting 显示信息 # self._answer_times = 0 # 做过几次 self._answer_times_variable = StringVar() # 做过几次变量 # self._correct_times = 0 # 答对过几次 self._correct_variable = StringVar() # 答对次数变量 self._rate_variable = StringVar() # 答对率变量 # self._weight = 0.0 # 题目权重 self._weight_variable = StringVar() # 权重变量 self._info_variable = StringVar() # self._answer_string = '' # 答案 self._answer_variable = StringVar() # 答案变量 self._answer_variable.set(ANSWER_PSEUDO) # 字体 self._my_font = Font(family=font_name, size=14) self._my_small_font = Font(family=font_name, size=12) self._my_bold_font = Font(family=font_name, size=14, weight='bold') self._my_big_font = Font(family=font_name, size=28, weight='bold') self._init_stem() self._init_counting() self._init_input() def _init_stem(self): # 题干&解析按钮 self._stem_button = Button(self, text='题干', font=self._my_small_font, width=8, height=1, relief='flat', command=self._show_stem) self._stem_button.place(x=15, y=5, anchor='nw') self._ana_button = Button(self, text='解析', font=self._my_small_font, width=8, height=1, relief='flat', command=self._show_ana) # self._ana_button.place(x=100, y=5, anchor='nw') self._canvas_stem = Canvas(self) self._canvas_stem.config(width=900, height=400, bg='white', relief='flat') self._canvas_ana = Canvas(self) self._canvas_ana.config(width=900, height=400, bg='white', relief='flat') self._show_stem() def _init_counting(self): self._counting_frame = LabelFrame(self, text="统计", font=self._my_bold_font, padx=5, pady=5, width=250, height=416) self._label_times = Label(self._counting_frame, text="答题次数:", font=self._my_font, width=8, anchor="e") self._label_correct = Label(self._counting_frame, text="答对次数:", font=self._my_font, width=8, anchor="e") self._lable_rate = Label(self._counting_frame, text="答 对 率:", font=self._my_font, width=8, anchor="e") self._lable_weight = Label(self._counting_frame, text="权 值:", font=self._my_font, width=8, anchor="e") self._value_times = Label(self._counting_frame, textvariable=self._answer_times_variable, font=self._my_font, wraplength=80, justify="left") self._value_correct = Label(self._counting_frame, textvariable=self._correct_variable, font=self._my_font, wraplength=80, justify="left") self._value_rate = Label(self._counting_frame, textvariable=self._rate_variable, font=self._my_font, wraplength=80, justify="left") self._value_weight = Label(self._counting_frame, textvariable=self._weight_variable, font=self._my_font, wraplength=80, justify="left") self._label_info = Label(self._counting_frame, textvariable=self._info_variable, font=self._my_big_font, wraplength=180, justify="right", fg='blue') self._counting_frame.place(x=935, y=30, anchor='nw') self._label_times.place(x=5, y=5, anchor='nw') self._value_times.place(x=125, y=5, anchor='nw') self._label_correct.place(x=5, y=35, anchor='nw') self._value_correct.place(x=125, y=35, anchor='nw') self._lable_rate.place(x=5, y=65, anchor='nw') self._value_rate.place(x=125, y=65, anchor='nw') self._lable_weight.place(x=5, y=95, anchor='nw') self._value_weight.place(x=125, y=95, anchor='nw') self._label_info.place(x=70, y=300, anchor='nw') def _init_input(self): self._input_frame = LabelFrame(self, text="答题区域", font=self._my_bold_font, padx=5, pady=5, width=1170, height=138) self._input_frame.place(x=15, y=450, anchor='nw') self._button_check = Button(self._input_frame, text="提交答案", command=self._check, font=self._my_font, width=16) self._button_check.place(x=930, y=2, anchor='nw') self._label_answer = Label(self._input_frame, textvariable=self._answer_variable, font=self._my_font, fg='black') self._label_answer.place(x=10, y=55, anchor='nw') self._button_next = Button(self._input_frame, text="下一道题", command=self._next, font=self._my_font, width=16) self._button_next.bind("<Return>", self._next) # 解决回车问题 self._button_return = Button(self._input_frame, text="回主界面", command=self._return, font=self._my_font, width=16) self._button_return.bind("<Return>", self._return) # 解决回车问题 def set_exercise(self, e, seq, total): global photo_stem, photo_ana self.exercise = e self.seq = seq self.total = total string_info = "%d/%d" % (self.seq, self.total) self._info_variable.set(string_info) self._answer_times_variable.set(self.exercise.answer_times) self._correct_variable.set(self.exercise.correct_times) rate_value = round(self.exercise.get_correct_rate() * 100, 2) self._rate_variable.set(str(rate_value) + '%') self._weight_variable.set(round(self.exercise.weight, 2)) if STYLE.IMG_FILE == self.exercise.d_style and \ len(self.exercise.stem) > 0: pic_stem_file_name = SCRIPT_PATH + "/../raw/" + \ Subject.get_string(self.subject) + '/' + \ str(self.exercise.id) + "-stem.png" image_stem = Image.open(pic_stem_file_name) photo_stem = ImageTk.PhotoImage(image_stem) self._canvas_stem.create_image(5, 5, anchor=NW, image=photo_stem) if STYLE.TEXT_IN_DB == self.exercise.d_style and \ len(self.exercise.stem) > 0: self._canvas_stem.create_text((10, 5), text=self.exercise.stem, font=self._my_font, anchor='nw', width=860) if STYLE.IMG_FILE == self.exercise.e_style and \ len(self.exercise.explain) > 0: pic_ana_file_name = SCRIPT_PATH + "/../raw/" + \ Subject.get_string(self.subject) + '/' + \ str(self.exercise.id) + "-ana.png" image_ana = Image.open(pic_ana_file_name) photo_ana = ImageTk.PhotoImage(image_ana) self._canvas_ana.create_image(5, 5, anchor=NW, image=photo_ana) if STYLE.TEXT_IN_DB == self.exercise.e_style and \ len(self.exercise.explain) > 0: self._canvas_ana.create_text((10, 5), text=self.exercise.explain, font=self._my_font, anchor='nw', width=860) def _check(self, is_correct=False): print("ExerciseFrame _check, is_correct=", is_correct) self._answer_times_variable.set(self.exercise.answer_times) self._correct_variable.set(self.exercise.correct_times) rate_value = round(self.exercise.get_correct_rate() * 100, 2) self._rate_variable.set(str(rate_value) + '%') self._weight_variable.set(round(self.exercise.weight, 2)) if is_correct: self.master.event_generate("<<check-correct>>") else: self.master.event_generate("<<check-wrong>>") promopt_string = '' # check之后显示答案和ana按钮 if is_correct: self._label_answer.configure(fg='green') promopt_string += "答对了! " if self.seq == self.total: self._button_return.place(x=930, y=50, anchor='nw') self._button_return.focus() else: self._button_next.place(x=930, y=50, anchor='nw') self._button_next.focus() else: self._label_answer.configure(fg='red') promopt_string += "答错了! 正确答案是: " + self.exercise.key + "。" if len(self.exercise.explain) > 0: promopt_string += " 请点击解析按钮查看解析。" self._ana_button.place(x=100, y=5, anchor='nw') self._answer_variable.set(promopt_string) def _next(self, event=None): print("Exercise Frame _next called") self.master.event_generate("<<next>>") def _return(self, event=None): self.master.event_generate("<<finish>>") def _show_stem(self): self._ana_button.configure(bg='lightgray', fg='black') self._stem_button.configure(bg='blue', fg='white') self._canvas_ana.place_forget() self._canvas_stem.place(x=14, y=42, anchor='nw') def _show_ana(self): self._stem_button.configure(bg='lightgray', fg='black') self._ana_button.configure(bg='blue', fg='white') self._canvas_stem.place_forget() self._canvas_ana.place(x=14, y=42, anchor='nw')
class MainWin(Tk): def __init__(self, client): Tk.__init__(self) self.client = client self.programPanel = ProgramPanel(client) self.programPanel.grid(row = 0, column = 0, sticky = NSEW) self.frame = Frame(self) self.frame.grid(row = 0, column = 0, sticky = NSEW) nextRow = Counter() # Create the menu. menu = Frame(self.frame) addButton = Menubutton(menu, text = 'Add') addButton.pack() menu.grid(row = nextRow(), column = 0, sticky = W) # Create the program panel. self.program = ProgramWidget(self.frame, client) self.program.grid(row = nextRow(), column = 0, columnspan = 2, sticky = W) label = Label(self.frame, text = 'AWB') label.grid(row = nextRow(), column = 0) self.recordMode = Button(self.frame, text = 'P', command = self.toggleRecord) modeRow = nextRow() self.recordMode.grid(row = modeRow, column = 0, sticky = W) self.status = Label(self.frame, text = 'Idle') self.status.grid(row = modeRow, column = 1) self.channels = [] self.channelFrame = Frame(self.frame) self.channelFrame.grid(row = nextRow(), columnspan = 2) self.bind('q', self.terminate) self.bind('f', self.foo) self.bind('r', self.toggleRecord) self.bind('k', self.toggleSticky) self.bind('.', self.nextSection) self.bind(',', self.prevSection) self.bind('<space>', self.togglePause) self.bind('K', self.clearAllState) self.protocol('WM_DELETE_WINDOW', self.destroy) self.bind('<F1>', lambda evt: self.frame.tkraise()) self.bind('<F2>', lambda evt: self.programPanel.tkraise()) for i in range(0, 8): # Bind number key. self.bind(str(i), lambda evt, channel = i: self.toggleChannel(channel) ) # Create channel channel = Channel(self.channelFrame, i) self.channels.append(channel) channel.pack(side = LEFT) client.addChannelSubscriber( i, lambda ch, status, channel = channel: channel.changeStatus(status) ) def foo(self, event): print('got foo') def terminate(self, event): self.destroy() def toggleRecord(self, event): self.client.recordEnabled = not self.client.recordEnabled self.recordMode.configure(text = self.client.recordEnabled and 'R' or 'P' ) def togglePause(self, event): self.client.togglePause() if self.client.paused: self.status.configure(text = 'Paused') else: self.status.configure(text = 'Playing') def clearAllState(self, event): self.client.clearAllState() self.status.configure(text = 'Idle') for channel in self.channels: channel.changeStatus(0) def toggleChannel(self, channel): # using "channel" as program self.client.activate(channel) if self.client.recording.get(channel): self.client.endRecord(channel) elif self.client.recordEnabled: self.client.startRecord(channel) self.status.configure(text = 'Recording on %s' % channel) def __getActiveChannel(self): # Move this to awb_client for i, ch in enumerate(self.channels): if ch.active: return i def toggleSticky(self, event): channel = self.__getActiveChannel() self.client.toggleChannelSticky(channel) def nextSection(self, event): self.client.nextOrNewSection() def prevSection(self, event): self.client.prevSection()
class TimerFrame(Frame): # tkinter widgets timer_control_btn = current_time_lbl = copyright_lbl = remaining_time_frame = None section_title_lbl = elapsed_time_lbl = remaining_time_lbl = reset_timer_btn = None inverting_parts = [] ui_colors = [LIGHT, DARK] # timer logic _actual_section = 0 section_remaining = EXAM_SECTIONS[_actual_section][1] timer_id = None def __init__(self, master=None, cnf={}, **kw): super().__init__(master, cnf, **kw) self.COPYRIGHT_FONT = Font(master, family='Helvetica', size=28) self.LABELS_FONT = Font(master, family='Helvetica', size=50) self.SECTION_FONT = Font(master, family='Helvetica', size=76) self.TIME_FONT = Font(master, family='Helvetica', size=130, weight=BOLD) self.setup_ui() self.bind_keyboard() self._update_current_time() def setup_ui(self): """ Basic setup GUI labels and buttons. """ self.pack(fill=BOTH, expand=True, padx=10, pady=10) self.grid_columnconfigure(1, weight=1) self.grid_rowconfigure(1, weight=1) self.timer_control_btn = Button(self, command=self.start_timer, text='START!', font=self.LABELS_FONT) self.timer_control_btn.grid(row=2, column=1, sticky=S) self.reset_timer_btn = Button( self, command=self.reset_timer, text='VYNULOVAT!', font=self.COPYRIGHT_FONT ) self.reset_timer_btn.grid(row=2, column=2, sticky=S + E) self.current_time_lbl = Label(self, font=self.LABELS_FONT) self.current_time_lbl.grid(row=2, column=0, sticky=W + S) self.copyright_lbl = Label(self, text="Josef Kolář © 2016", font=self.COPYRIGHT_FONT) self.copyright_lbl.grid(column=2, row=0, sticky=N + E) self.section_title_lbl = Label(self, font=self.SECTION_FONT) self.section_title_lbl.grid(column=1, row=0, sticky=N) self.elapsed_time_lbl = Label(self, text='0:00', font=self.LABELS_FONT) self.elapsed_time_lbl.grid(column=0, row=0, sticky=N + W) self.remaining_time_frame = Frame(self) self.remaining_time_frame.grid(column=1, row=1) self.remaining_time_lbl = Label( self.remaining_time_frame, text=format_delta(EXAM_SECTIONS[0][1]), font=self.TIME_FONT ) self.remaining_time_lbl.pack() self.inverting_parts.extend(( self.current_time_lbl, self.copyright_lbl, self.section_title_lbl, self.remaining_time_lbl, self.timer_control_btn, self.elapsed_time_lbl, self.reset_timer_btn )) self.refresh_section() def _update_current_time(self): """ Update the timer of current time and set the timing for next second. """ self.current_time_lbl.configure(text=time.strftime('%H:%M:%S')) self.master.after(1000, self._update_current_time) def _invert_ui(self): """ Invert colors in the GUI including font colors and backgrounds. """ self.ui_colors.reverse() bg, fg = self.ui_colors self.master.configure(bg=bg) self.configure(bg=bg) for part in self.inverting_parts: part['background'] = bg part['foreground'] = fg def start_timer(self): """ Start the main timer and timer updating. """ self.timer_control_btn.configure(text='STOP!', command=self.stop_timer) self.timer_id = self.master.after(1000, self.update_timer) def update_timer(self): """ Update the timer time and check the next section. """ self.section_remaining -= timedelta(seconds=1) if self.section_remaining.total_seconds() == 0: self.actual_section += 1 self._invert_ui() elif self.section_remaining.total_seconds() < 5: self._invert_ui() self.remaining_time_lbl.configure(text=format_delta(self.section_remaining)) self.elapsed_time_lbl.configure( text=format_delta(EXAM_SECTIONS[self.actual_section][1] - self.section_remaining) ) if self.section_remaining.total_seconds() > 0: self.timer_id = self.master.after(1000, self.update_timer) def stop_timer(self): """ Stop the main timer. """ if self.timer_id: self.master.after_cancel(self.timer_id) self.timer_control_btn.configure(text='START!', command=self.start_timer) def reset_timer(self): """ Ask for resetting the main timer and may reset the main timer. :return: """ if askyesno('Jste si jisti?', 'Opravdu chcete zastavit a vynulovat čítání?', default=NO): self.stop_timer() self.actual_section = 0 @property def actual_section(self): """ Return actual section index. """ return self._actual_section @actual_section.setter def actual_section(self, new): """ Set the new section index and refresh section state. """ self._actual_section = new self.refresh_section() def refresh_section(self): """ Refresh labels and main timer state. """ section_title, section_length = EXAM_SECTIONS[self.actual_section] self.section_title_lbl.configure(text=section_title) self.section_remaining = copy(section_length) self.remaining_time_lbl.configure(text=format_delta(self.section_remaining)) self.elapsed_time_lbl.configure( text=format_delta(EXAM_SECTIONS[self.actual_section][1] - self.section_remaining) ) def bind_keyboard(self): """ Bind shortcuts to the keyboard. """ self.master.bind('<space>', lambda *args, **kwargs: self.timer_control_btn.invoke()) self.master.bind('<Delete>', lambda *args, **kwargs: self.reset_timer_btn.invoke())
class GUI: """A simple GUI for the PLD heater""" def __init__(self, master): self.PLD_port = "COM5" self.PLD_address = 5 self.PLD = None self.pyrometer_port = "COM10" self.pyrometer = None self.active_plot = 1 self.start_time = None self.label_updater = Thread() self.pyrometer_pld_communication = Thread() self.icon_left = PhotoImage(file="Button_left.png") self.icon_right = PhotoImage(file="Button_right.png") self.window_frame = Frame(master, bd=2, relief=GROOVE) self.sensor_frame = Frame(self.window_frame, bd=2, relief=GROOVE) self.parameter_frame = Frame(self.window_frame, bd=2, relief=GROOVE) self.graph_frame = Frame(self.window_frame, bd=2, relief=GROOVE) self.connect_frame = Frame(self.window_frame, bd=2, relief=GROOVE) self.log_frame = Frame(self.window_frame, bd=2, relief=GROOVE) self.plot_frame = Frame(self.window_frame, bd=2, relief=GROOVE) self.oven_temperature_label = Label(self.sensor_frame, text="Oven temperature: °C") self.external_temperature_label = Label(self.sensor_frame, text="Sample temperature: °C") self.working_setpoint_label = Label(self.sensor_frame, text="Working setpoint: °C") self.working_output_label = Label(self.sensor_frame, text="Working ouput %") self.power_output_label = Label(self.parameter_frame, text="Power output %") self.power_output_entry = Entry(self.parameter_frame) self.power_output_setter_button = Button(self.parameter_frame, text="Set power output [%]", command=self.set_target_output_power, state=DISABLED) self.setpoint_label = Label(self.parameter_frame, text="Setpoint: °C") self.setpoint_entry = Entry(self.parameter_frame) self.setpoint_setter_button = Button(self.parameter_frame, text="Set target setpoint [°C]", command=self.set_target_setpoint, state=DISABLED) self.mode_label = Label(self.parameter_frame, text="Manual control mode") self.mode_switcher_button = Button(self.parameter_frame, text="Switch mode", command=self.switch_mode, state=DISABLED) self.external_sensor_mode_label = Label(self.parameter_frame, text="External sensor mode off") self.external_sensor_mode_button = Button(self.parameter_frame, text="Enable external sensor mode", command=self.enable_external_sensor_temperature, state=DISABLED) self.hold_temperature_button = Button(self.parameter_frame, text="Hold temperature", command=self.hold_temperature, state=DISABLED) self.PLD_com_port_entry = Entry(self.connect_frame) self.PLD_com_port_label = Label(self.connect_frame, text="PLD COM Port") self.PLD_slave_address_entry = Entry(self.connect_frame) self.PLD_salve_address_label = Label(self.connect_frame, text="PLD slave Address (Default 1)") self.PLD_connect_button = Button(self.connect_frame, text="Connect PLD", command=self.connect_pld) self.pyrometer_com_port_entry = Entry(self.connect_frame) self.pyrometer_com_port_label = Label(self.connect_frame, text="Pyrometer COM Port") self.pyrometer_connect_button = Button(self.connect_frame, text="Connect Pyrometer", command=self.connect_pyrometer) self.start_label_updater_button = Button(self.connect_frame, text="Start", command=self.start_label_updater, state=DISABLED) self.log_label = Label(self.log_frame, text="Temperature Log") self.log_text = Text(self.log_frame) self.switch_plot_left_button = Button(self.plot_frame, command=self.switch_plot_left, image=self.icon_left) self.switch_plot_right_button = Button(self.plot_frame, command=self.switch_plot_right, image=self.icon_right) self.plot_label = Label(self.plot_frame, text="Oven temperature") self.pyrometer_plot_frame = Frame(self.plot_frame) self.oven_temperature_plot_frame = Frame(self.plot_frame) self.power_ouput_plot_frame = Frame(self.plot_frame) self.pyrometer_plot = Plot(self.pyrometer_plot_frame, "Time [min]", "T\n\n°C", 350) self.power_ouput_plot = Plot(self.power_ouput_plot_frame, "Time [min]", "P\n\n%", 350) self.oven_temperature_plot = Plot(self.oven_temperature_plot_frame, "Time [min]", "T\n\n°C", 350) self.place_widgets() def place_widgets(self): """Place each widgets""" self.window_frame.place(x=10, y=10, height=415, width=1010) self.connect_frame.place(height=105, width=630, x=10, y=10) self.pyrometer_com_port_label.place(height=25, width=200, x=10, y=10) self.pyrometer_com_port_entry.place(height=25, width=200, x=215, y=10) self.pyrometer_connect_button.place(height=25, width=200, x=420, y=10) self.PLD_com_port_label.place(height=25, width=200, x=10, y=40) self.PLD_com_port_entry.place(height=25, width=200, x=215, y=40) self.PLD_connect_button.place(height=25, width=200, x=420, y=40) self.PLD_salve_address_label.place(height=25, width=200, x=10, y=70) self.PLD_slave_address_entry.place(height=25, width=200, x=215, y=70) self.start_label_updater_button.place(height=25, width=200, x=420, y=70) self.parameter_frame.place(height=135, width=630, x=10, y=125) self.setpoint_label.place(height=25, width=200, x=10, y=10) self.setpoint_entry.place(height=25, width=200, x=215, y=10) self.setpoint_setter_button.place(height=25, width=200, x=420, y=10) self.power_output_label.place(height=25, width=200, x=10, y=40) self.power_output_entry.place(height=25, width=200, x=215, y=40) self.power_output_setter_button.place(height=25, width=200, x=420, y=40) self.mode_switcher_button.place(height=25, width=405, x=215, y=70) self.mode_label.place(height=25, width=200, x=10, y=70) self.external_sensor_mode_label.place(height=25, width=200, x=10, y=100) self.external_sensor_mode_button.place(height=25, width=200, x=215, y=100) self.hold_temperature_button.place(height=25, width=200, x=420, y=100) self.sensor_frame.place(height=135, width=220, x=10, y=270) self.oven_temperature_label.place(height=25, width=200, x=10, y=10) self.external_temperature_label.place(height=25, width=200, x=10, y=40) self.working_setpoint_label.place(height=25, width=200, x=10, y=70) self.working_output_label.place(height=25, width=200, x=10, y=100) self.log_frame.place(height=135, width=400, x=240, y=270) self.log_text.place(height=115, width=380, x=10, y=10) self.plot_frame.place(x=640, y=10, width=360, height=395) self.switch_plot_left_button.place(x=5, y=5, height=30, width=30) self.switch_plot_right_button.place(x=325, y=5, height=30, width=30) self.plot_label.place(x=35, y=5, height=25, width=295) self.pyrometer_plot_frame.place(x=5, y=40, width=350, height=350) self.oven_temperature_plot_frame.place(x=5, y=40, width=350, height=350) self.power_ouput_plot_frame.place(x=5, y=40, width=350, height=350) self.pyrometer_plot.place(x=0, y=0, width=350, height=350) self.oven_temperature_plot.place(x=0, y=00, width=350, height=350) self.power_ouput_plot.place(x=0, y=0, width=350, height=350) self.oven_temperature_plot_frame.lift() def start_label_updater(self): """Read values from instrument objects every second, display them, plot them and write in a logfile""" self.start_time = datetime.now() def update_labels(): while True: pyrometer_temperature = "---" oven_temperature = "---" working_output = "---" working_setpoint = "---" runtime = (datetime.now() - self.start_time).seconds / 60.0 if self.PLD is not None: oven_temperature = self.PLD.oven_temp.get() self.oven_temperature_plot.add_datapoint(runtime, oven_temperature) self.oven_temperature_label.configure(text="Oven temperature: %s °C" % oven_temperature) working_output = self.PLD.working_output.get() self.power_ouput_plot.add_datapoint(runtime, working_output) self.working_output_label.configure(text="Working output: %s %%" % working_output) working_setpoint = self.PLD.working_setpoint.get() self.working_setpoint_label.configure(text="Working setpoint: %s °C" % working_setpoint) if self.pyrometer is not None: pyrometer_temperature = self.pyrometer.temperature.get() self.pyrometer_plot.add_datapoint(runtime, pyrometer_temperature) self.external_temperature_label.configure(text="Sample temperature %s °C" % pyrometer_temperature) logstring = "Time: " + strftime("%X") \ + ("Oven temperature: %s °C" % oven_temperature).ljust(28, " ") \ + ("Power Output %s %%" % working_output).ljust(28, " ")\ + ("Working Setpoint: %s °C" % working_setpoint).ljust(28, " ")\ + ("Pyrometer temperature: %s °C" % pyrometer_temperature).ljust(28, " ") \ + "\n" printstring = "Time: " + strftime("%X") \ + ("Oven temperature: %s °C" % oven_temperature).ljust(28, " ") \ + ("Pyrometer temperature: %s °C" % pyrometer_temperature).ljust(28, " ")\ + "\n" self.log_text.insert(END, printstring) sleep(0.5) self.label_updater._target = update_labels self.label_updater.start() if self.PLD is not None and self.pyrometer is not None: self.start_pyrometer_pld_communication() if self.PLD is not None: self.mode_switcher_button.configure(state=NORMAL) self.power_output_setter_button.configure(state=NORMAL) self.PLD.switch_to_manual_mode() self.mode_label.configure(text="Manual operation mode") self.power_output_setter_button.configure(state=NORMAL) def connect_pld(self): """Connect to the PLD Eurotherm controller, start in manual mode""" if self.PLD_com_port_entry.get() != "": self.PLD_port = self.PLD_com_port_entry.get() if self.PLD_slave_address_entry.get() != "": self.PLD_address = int(self.PLD_slave_address_entry.get()) self.PLD = PLD(self.PLD_port, self.PLD_address) try: self.PLD.switch_to_manual_mode() except IOError: sleep(0.5) self.PLD.switch_to_manual_mode() self.PLD.start_oven_temperature_listener() self.PLD.start_working_output_listener() self.PLD.start_working_setpoint_listener() self.PLD.start_serial_io_handler() self.start_label_updater_button.configure(state=NORMAL) def connect_pyrometer(self): """Connect to the pyrometer""" if self.pyrometer_com_port_entry.get() != "": self.pyrometer_port = self.pyrometer_com_port_entry.get() self.pyrometer = Pyrometer(self.pyrometer_port) self.pyrometer.start_temperature_listener() self.start_label_updater_button.configure(state=NORMAL) self.external_sensor_mode_button.configure(state=NORMAL) def start_pyrometer_pld_communication(self): """Start supplying the PLD with the pyrometer temperature as external sensor temperature""" def talk(): while True: self.PLD.external_sensor_temperature.put(self.pyrometer.temperature) sleep(1) self.pyrometer_pld_communication._target = talk self.pyrometer_pld_communication.start() def set_target_setpoint(self): """Write the target setpoint in the entry widget to the instrument""" self.PLD.target_setpoint = float(self.setpoint_entry.get()) self.setpoint_label.configure(text="Setpoint %s °C" % self.PLD.target_setpoint) self.PLD.write_target_setpoint(self.PLD.target_setpoint) def set_target_output_power(self): """Write the target ouput power in the entry to the instrument""" self.PLD.power_output = float(self.power_output_entry.get()) self.power_output_label.configure(text="Power ouput %s%%" % self.PLD.power_output) self.PLD.write_manual_output_power(self.PLD.power_output) def switch_mode(self): """Switch the instrument between manual and automatic mode""" if not self.PLD.operation_mode: self.PLD.switch_to_manual_mode() self.PLD.operation_mode = 1 self.mode_label.configure(text="Manual operation mode") self.power_output_setter_button.configure(state=NORMAL) self.setpoint_setter_button.configure(state=DISABLED) elif self.PLD.operation_mode: self.PLD.switch_to_automatic_mode() self.PLD.operation_mode = 0 self.mode_label.configure(text="Automatic operation mode") self.setpoint_setter_button.configure(state=NORMAL) self.power_output_setter_button.configure(state=DISABLED) def enable_external_sensor_temperature(self): """Enabele using an external temperarture sensor for the PLD""" self.PLD.set_external_sensor_temperature_mode() self.hold_temperature_button.configure(state=NORMAL) def hold_temperature(self): """Switch the PLD to manual mode and hold the current power output""" self.setpoint_setter_button.configure(state=DISABLED) self.power_output_setter_button.configure(state=NORMAL) self.PLD.hold_current_temperature() def switch_plot_left(self): """Switch the displayed plot""" if self.active_plot: self.active_plot -= 1 self.show_plot() def switch_plot_right(self): """Switch the displayed plot""" if self.active_plot < 2: self.active_plot += 1 self.show_plot() def show_plot(self): """Switch the displayed plot""" if self.active_plot == 0: self.pyrometer_plot_frame.lift() self.plot_label.configure(text="Pyrometer temperature") if self.active_plot == 1: self.oven_temperature_plot_frame.lift() self.plot_label.configure(text="Oven temperature") if self.active_plot == 2: self.power_ouput_plot_frame.lift() self.plot_label.configure(text="Power Output")
class App: """Defines a class that creates the Tkinter GUI.""" def __init__(self, window): """ Constructor - defines all GUI elements. :param window: Tkinter root object. """ # Create frames. self.input_frame = Frame(master=root, bg="#E0E9FF", width=1920, height=100, padx=1, pady=1) self.prediction_frame = Frame(master=root, bg="#E0E9FF", width=1920, height=400, padx=1, pady=1) self.data_frame = Frame(master=root, bg="#E0E9FF", width=1920, height=400, padx=1, pady=1) self.button_frame = Frame(master=root, bg="#E0E9FF", width=1920, padx=1, pady=1) # Place frames in grid layout. self.input_frame.grid(row=1, column=0, sticky="ew") self.prediction_frame.grid(row=2, column=0, sticky="ew") self.data_frame.grid(row=3, column=0, sticky="ew") self.button_frame.grid(row=4, column=0, sticky="ew") # Should frame shrink to wrap subordinate widgets? self.input_frame.grid_propagate(True) self.prediction_frame.grid_propagate(True) self.data_frame.grid_propagate(True) self.data_frame.grid_propagate(True) # Set weights. self.input_frame.grid_rowconfigure(0, weight=1) self.input_frame.grid_columnconfigure(0, weight=1) self.prediction_frame.grid_rowconfigure(0, weight=1) self.prediction_frame.grid_columnconfigure(0, weight=1) self.data_frame.grid_rowconfigure(0, weight=1) self.data_frame.grid_columnconfigure(0, weight=1) self.button_frame.grid_rowconfigure(0, weight=1) self.button_frame.grid_columnconfigure(0, weight=1) # Input text to model. self.input_text = StringVar(value="Enter input to model here...") self.input_text_area = Text(master=self.input_frame, bg="#E0E9FF", width=1920, height=10) self.input_text_area_scrollbar = Scrollbar(master=self.input_frame) self.input_text_area_scrollbar.config( command=self.input_text_area.yview) self.input_text_area.config( yscrollcommand=self.input_text_area_scrollbar.set) self.input_text_area_scrollbar.pack(side=RIGHT, fill=Y) self.input_text_area.pack(expand=YES, fill=BOTH) self.input_text_area.insert(1.0, self.input_text.get()) # Output data from model. self.predicted_text = StringVar( value="Predicted text will appear here...") self.predicted_text_area = Text(master=self.prediction_frame, bg="#E0E9FF", width=1920, height=10) self.predicted_text_area_scrollbar = Scrollbar( master=self.prediction_frame) self.predicted_text_area_scrollbar.config( command=self.predicted_text_area.yview) self.predicted_text_area.config( yscrollcommand=self.predicted_text_area_scrollbar.set) self.predicted_text_area_scrollbar.pack(side=RIGHT, fill=Y) self.predicted_text_area.pack(expand=YES, fill=BOTH) self.predicted_text_area.insert(1.0, self.predicted_text.get()) self.data_text = StringVar( value="Prediction data will appear here...\n") self.data_text_area = Text(master=self.data_frame, bg="#E0E9FF", width=1920, height=20) self.data_text_area_scrollbar = Scrollbar(master=self.data_frame) self.data_text_area_scrollbar.config(command=self.data_text_area.yview) self.data_text_area.config( yscrollcommand=self.data_text_area_scrollbar.set) self.data_text_area_scrollbar.pack(side=RIGHT, fill=Y) self.data_text_area.pack(expand=YES, fill=BOTH) self.data_text_area.insert(1.0, self.data_text.get()) # Message Widget. # self.prediction_message_area = Message(master=self.prediction_frame, bg="#E0E9FF", width=1920, padx=1, pady=1, # anchor="center", justify="left", relief="raised", # textvariable=self.predicted_text) # self.prediction_message_area.pack(expand=YES, fill=BOTH) # # # self.data_message_area = Message(master=self.data_frame, bg="#E0E9FF", width=1920, padx=1, pady=1, # anchor="center", justify="left", relief="raised", # textvariable=self.data_text) # self.data_message_area.pack(expand=YES, fill=BOTH) # Buttons. self.predict_button = Button(self.button_frame, text='Generate Prediction', command=self.predict) self.predict_button.pack(side=LEFT) self.quit_button = Button(self.button_frame, text='Quit Program', command=window.destroy) self.quit_button.pack(side=RIGHT) self.string_var_2 = StringVar() self.message_label = Label(window, textvariable=self.string_var_2, width=40) # Change fonts. myFont = Font(family="Times New Roman", size=16) self.input_text_area.configure(font=myFont) self.predicted_text_area.configure(font=myFont) self.data_text_area.configure(font=myFont) self.predict_button.configure(font=myFont) self.quit_button.configure(font=myFont) def predict(self): """ Callback method that obtains GPT-2 model prediction and associated data. Outputs predicted text to GUI. :return: None. """ debug = 0 self.predicted_text_area.delete(1.0, END) self.data_text_area.delete(1.0, END) # Call GPT-2 model and obtain prediction results/data. results = model.main(str(self.input_text_area.get("1.0", "end-1c"))) output = results model_input = output["Model Input"] decoded_prediction = output["Decoded Prediction"] encoded_prediction = output["Encoded Prediction"] if debug: print(f"Model input: {model_input}") print(f"Encoded prediction: {encoded_prediction}") print(f"Decoded prediction: {decoded_prediction}") # Display the data in the message widget. self.predicted_text.set(f"Original model input: {model_input}\n\n" f"Encoded prediction: {encoded_prediction}\n\n" f"Decoded prediction: {decoded_prediction}") self.predicted_text_area.insert(1.0, self.predicted_text.get()) # self.prediction_message_area.configure(textvariable=self.predicted_text) #################################################################################### if debug: print(f"Object length: {len(testDataDict)}") data_wrapper = {} data = {} counter = 0 self.data_text.set("") for i in range(0, len(output) - 4): myKey = "Token " + str(counter) myValue = output[myKey] data[myKey + " Encoded"] = myValue[0] data[myKey + " Decoded"] = myValue[1] data[myKey + " Encoded Choices"] = myValue[2][0] data[myKey + " Decoded Choices"] = myValue[3] data_wrapper[counter] = data # Append to display all data. self.data_text.set( self.data_text.get() + f"\n" f"Token {counter}:\n" f"Encoded token: {data[myKey + ' Encoded']}\n" f"Decoded token: {data[myKey + ' Decoded']}\n" f"Encoded token choices: {data[myKey + ' Encoded Choices']}\n" f"Decoded token choices: {data[myKey + ' Decoded Choices']}\n") if debug: print(f"Encoded token: {data[myKey + ' Encoded']}") print(f"Decoded token: {data[myKey + ' Decoded']}") print( f"Encoded token choices: {data[myKey + ' Encoded Choices']}" ) print( f"Decoded token choices: {data[myKey + ' Decoded Choices']}" ) data = {} counter += 1 if debug: for key, value in data_wrapper.items(): print(f"Data wrapper key: {key}") print(f"Data wrapper value: {value}") # Display the data in the message widget. self.data_text_area.delete(1.0, END) self.data_text_area.insert(1.0, self.data_text.get()) # self.data_message_area.configure(textvariable=self.data_text) #################################################################################### # Convert data for use in visualization. restructured_data = [] counter = 0 for key, value in data_wrapper.items(): restructured_data.append({ "selected_token": value["Token " + str(counter) + " Decoded"], "token_choices": value["Token " + str(counter) + " Decoded Choices"] }) counter += 1 if debug: print(f"{restructured_data}") for element in restructured_data: print(f"Restructured Data Word: {element['selected_token']}") print(f"Restructured Data Tokens: {element['token_choices']}")
class MainView(Tk): class Constants: title = "Cambio de Moneda" heigth = 100 width = 550 input_width = 250 separator_width = 50 center = N + S + E + W left = W event = "<Button-1>" names = [ 'AUD', 'BGN', 'BRL', 'CAD', 'CHF', 'CNY', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD', 'HRK', 'HUF', 'IDR', 'ILS', 'INR', 'JPY', 'KRW', 'MXN', 'MYR', 'NOK', 'NZD', 'PHP', 'PLN', 'RON', 'RUB', 'SEK', 'SGD', 'THB', 'TRY', 'USD', 'ZAR' ] convert_text = "Convertir" separator_text = "▶" def __init__(self, convert_handler=None): super().__init__() self.__convert_handler = convert_handler self.title(self.Constants.title) self.maxsize(width=self.Constants.width, height=self.Constants.heigth) self.minsize(width=self.Constants.width, height=self.Constants.heigth) self.__configure_grid() self.__configure_UI() def __configure_grid(self): self.grid_rowconfigure(0, weight=True) self.grid_rowconfigure(1, weight=True) self.grid_rowconfigure(2, weight=True) self.grid_columnconfigure(0, minsize=self.Constants.input_width) self.grid_columnconfigure(2, minsize=self.Constants.input_width) self.grid_columnconfigure(1, minsize=self.Constants.separator_width) def __configure_UI(self): self.initial_var = StringVar() self.initial_var.set(self.Constants.names[0]) self.from_menu = OptionMenu(self, self.initial_var, *self.Constants.names) self.from_menu.grid(row=0, column=0, sticky=self.Constants.left) self.final_var = StringVar() self.final_var.set(self.Constants.names[1]) self.to_menu = OptionMenu(self, self.final_var, *self.Constants.names) self.to_menu.grid(row=0, column=2, sticky=self.Constants.left) separator_label = Label(self) separator_label.configure(text=self.Constants.separator_text) separator_label.grid(row=1, column=1, sticky=self.Constants.center) self.__result_label = Label(self) self.__result_label.configure(text="0") self.__result_label.grid(row=1, column=2, sticky=self.Constants.left) self.__convert_button = Button(self) self.__convert_button.configure(text=self.Constants.convert_text) self.__convert_button.grid(row=2, column=2, sticky=self.Constants.center) self.__convert_button.bind(self.Constants.event, self.__did_tap_convert) vcmd = (self.register(self.__checkNumberOnly), '%d', '%P') self.__currency_input = Entry(self, validate="key", validatecommand=vcmd) self.__currency_input.grid(row=1, column=0, sticky=self.Constants.center) def __did_tap_convert(self, event): if self.__convert_handler is None: return try: ammount_to_convert = float(self.__currency_input.get()) except ValueError: return else: self.__convert_handler(self.initial_var.get(), self.final_var.get(), ammount_to_convert) def update_result(self, text): self.__result_label.configure(text=text) def __checkNumberOnly(self, action, value_if_allowed): if action != '1': return True try: float(value_if_allowed) except ValueError: return False else: return True
class CodeSolver: should_i_apply = True # Program config config = { 'system parameters': { 'set_dpi_awareness': True, 'tesseract_directory': r'C:\Program Files\Tesseract-OCR\tesseract.exe' }, 'window settings': { 'transparent_on_lost_focus': True, 'default_transparency_alpha': 0.4, 'set_topmost': True, 'window_width': 700, 'window_height': 550 }, 'canvas settings': { 'resize_threshold': 1, # Prevents resizing on small canvas changes}, 'center_image_on_canvas': True, 'canvas_update_delay': 250 } } sys_cfg = config['system parameters'] # Short names win_cfg = config['window settings'] can_cfg = config['canvas settings'] config_parser = None # Admin settings will always load default unless accepted admin login adm_cfg = { 'use_local_image': False } # Hashed admin password admin_password = '******' admin_privileges = False # Image params/vars new_image = False image = None tk_image = None img = None img_id = None aspect_ratio = None canvas_width = 0 canvas_height = 0 image_width = None image_height = None image_scale = None image_x_offset = None image_y_offset = None bounding_boxes = None last_resize = None pending_boxes: BooleanVar = None pending_redraw: BooleanVar = None # Settings render_boxes = None mode = None # Widgets root = None frame_url = None entry_url = None canvas = None lbl_status = None btn_crack = None txt_output = None scale_slider = None transparency_overlay = None # Program variables pending_timed_highlight = False # Lookup ascii_lookup = None # List of chars that commonly incorrectly translate ordered by priority # Keys should be caps and value must be a set of valid hexadecimal symbols ambiguous_chars = {'G': '6', 'S': '5', 'H': '4', 'Z': '7', 'B': '8', # These are both hexadecimal chars '8': 'B'} def __init__(self): # Read config self.read_config() # Necessary to get PIL to work correctly on high DPI scaling if self.sys_cfg['set_dpi_awareness']: user32 = windll.user32 user32.SetProcessDPIAware() # Load and structure lookup self.ascii_lookup = {} for row in ascii_table: row = row.split(',') self.ascii_lookup[row[3].upper()] = row[4] # Start gui self.init_gui() def read_config(self): try: # Set up parser self.config_parser = configparser.ConfigParser() # Read from file self.config_parser.read('config.ini') # Check for admin privileges (Hidden from default config) if 'ADMIN' in self.config_parser: self.admin_login() if self.admin_privileges: # Read requested admin settings for sub_key in self.adm_cfg: val = self.resolve_type(self.config_parser, 'ADMIN', sub_key) self.adm_cfg[sub_key] = val print('set admin config [{}] to {}'.format(sub_key, val)) # Read all parameters specified in config print('Reading config') for key, sub_dict in self.config.items(): try: for sub_key in sub_dict: val = self.resolve_type(self.config_parser, key, sub_key) self.config[key][sub_key] = val print('set config[{}][{}] to {}'.format(key, sub_key, val)) except KeyError: pass except: traceback.print_exc() @staticmethod def resolve_type(parser, key, sub_key): val = parser[key][sub_key] # Boolean condition if val.lower() in ('true', 'false', '1', '0', 'yes', 'no'): return parser.getboolean(key, sub_key) # Integer condition elif val.isdigit(): return parser.getint(key, sub_key) # Float condition elif val.replace('.', '').isdigit(): return parser.getfloat(key, sub_key) # Default to string return parser.get(key, sub_key) def write_config(self): # List all parameters that should be written try: for key, sub_dict in self.config.items(): self.config_parser.setdefault(key, {}) for sub_key, val in sub_dict.items(): self.config_parser[key][sub_key] = str(val) # Write to file with open('config.ini', 'w') as configfile: self.config_parser.write(configfile) except: traceback.print_exc() def window_close(self): if messagebox.askyesno("Closing", "Exit program?"): self.write_config() self.root.destroy() def admin_login(self): admin_window = Tk() admin_window.title('Admin login') admin_window.geometry('200x60') admin_window.attributes('-toolwindow', 1, '-topmost', True) admin_window.resizable(False, False) admin_window.bind('<Escape>', lambda e: admin_window.destroy()) self.center_window(admin_window) frame_input = Frame(admin_window) Label(frame_input, text='password: '******'cancel', width=8, command=lambda: admin_window.destroy()).pack(side=RIGHT) Button(frame_buttons, text='log in', width=8, command=lambda: self.verify_admin(admin_window, entry_password)).pack(side=RIGHT) admin_window.bind('<Return>', lambda e: self.verify_admin(admin_window, entry_password)) frame_input.pack(side=TOP, padx=5, pady=(5, 0)) frame_buttons.pack(side=BOTTOM, fill=X, padx=5, pady=5) admin_window.mainloop() @staticmethod def hash_password(password): # uuid is used to generate a random number salt = uuid.uuid4().hex return hashlib.sha256(salt.encode() + password.encode()).hexdigest() + ':' + salt @staticmethod def check_password(hashed_password, user_password): password, salt = hashed_password.split(':') return password == hashlib.sha256(salt.encode() + user_password.encode()).hexdigest() def verify_admin(self, parent, entry_widget): password_attempt = entry_widget.get() if self.check_password(self.admin_password, password_attempt): print('***Accepted login as administrator***') self.admin_privileges = True parent.destroy() else: print('***Incorrect administrator password***') self.timed_highlight(parent, entry_widget) def init_gui(self): # Root config self.root = Tk() self.root.report_callback_exception = lambda a_, b_, c_: self.elevate_error() self.root.title('Instech Code Solver v1.0 by Eivind Brate Midtun' + (' (admin privileges activated)' if self.admin_privileges else '')) self.root.minsize(700, 550) self.root.geometry('{}x{}'.format(self.win_cfg['window_width'], self.win_cfg['window_height'])) if self.win_cfg['transparent_on_lost_focus']: self.root.bind("<FocusIn>", lambda e: self.set_root_alpha(1)) self.root.bind("<FocusOut>", lambda e: self.set_root_alpha( self.win_cfg['default_transparency_alpha'])) if self.win_cfg['set_topmost']: self.root.wm_attributes('-topmost', True) self.root.protocol("WM_DELETE_WINDOW", self.window_close) self.root.bind('<Escape>', lambda e: self.window_close()) self.center_window(self.root) self.root.focus_force() # Main frame frame_main = Frame(self.root) frame_main.pack(expand=YES, fill=BOTH) # URL frame self.frame_url = Frame(frame_main) label_url = Label(self.frame_url, text='image url:') self.entry_url = Entry(self.frame_url) self.entry_url.insert(0, "https://images.finncdn.no/dynamic/1280w/2019/4/vertical-1/10/4/144/681/364_714666085.jpg") self.entry_url.focus_set() self.entry_url.select_range(0, END) btn_grab = Button(self.frame_url, text='screen grab', width=10, command=lambda: self.image_grab()) btn_grab.bind("<Enter>", lambda e: self.set_root_alpha(self.win_cfg['default_transparency_alpha'], 1)) btn_grab.bind("<Leave>", lambda e: self.set_root_alpha(1, 2)) btn_grab.pack(side=RIGHT, anchor=E) Button(self.frame_url, text='url grab', width=10, command=lambda: self.get_image('from_url')).pack(side=RIGHT, anchor=E, padx=5) label_url.pack(side=LEFT, anchor=W) self.entry_url.pack(side=LEFT, anchor=W, expand=YES, fill=X) # Input frame frame_input = Frame(frame_main) # Canvas frame frame_canvas = Frame(frame_input) self.canvas = Canvas(frame_canvas, bg='gray') self.canvas.pack(side=TOP, fill=BOTH, expand=YES) self.canvas.bind("<Configure>", lambda e: self.redraw()) # Settings frame frame_settings = Frame(frame_input, borderwidth=1, relief=SUNKEN) self.render_boxes = BooleanVar() self.render_boxes.set(True) Checkbutton(frame_settings, text='Box', font='TkDefaultFont 8', variable=self.render_boxes, command=self.redraw).pack(anchor=W) Label(frame_settings, text='Overlay\nalpha', font='TkDefaultFont 8').pack(side=TOP, anchor=N) self.scale_slider = Scale(frame_settings, command=lambda e: self.set_transparency()) self.mode = IntVar() self.scale_slider.pack(side=TOP, anchor=N) Label(frame_settings, text='Mode:', font='TkDefaultFont 8').pack(anchor=W) Radiobutton(frame_settings, text="Hex", font='TkDefaultFont 8', variable=self.mode, value=0).pack(anchor=W) Radiobutton(frame_settings, text="Dec", font='TkDefaultFont 8', variable=self.mode, value=1).pack(anchor=W) Radiobutton(frame_settings, text="Bin", font='TkDefaultFont 8', variable=self.mode, value=2).pack(anchor=W) Radiobutton(frame_settings, text="Sym", font='TkDefaultFont 8', variable=self.mode, value=3).pack(anchor=W) Radiobutton(frame_settings, text="Oct", font='TkDefaultFont 8', variable=self.mode, value=4).pack(anchor=W) # Input frame continue lbl_input = Label(frame_input, text='Input:') lbl_input.pack(side=TOP, anchor=W) frame_settings.pack(side=LEFT, expand=NO, fill=Y, pady=(2, 2)) frame_canvas.pack(side=RIGHT, expand=YES, fill=BOTH, padx=(2, 0)) # Button frame frame_buttons = Frame(frame_main) self.btn_crack = Button(frame_buttons, state=DISABLED, width=15, text='crack code', command=lambda: self.start_cracking(self.image)) self.lbl_status = Label(frame_buttons, text='Status: Awaiting user', fg='blue') self.btn_crack.pack(side=RIGHT, anchor=E) self.lbl_status.pack(side=LEFT, anchor=W) # Output frame frame_output = Frame(frame_main) lbl_output = Label(frame_output, text='Output:') self.txt_output = Text(frame_output, state=DISABLED, height=6, fg='#FFFFFF', bg='#4C4A48') lbl_output.pack(side=TOP, anchor=W) self.txt_output.pack(side=BOTTOM, fill=X, expand=YES) # Pack frames if self.adm_cfg['use_local_image']: Label(frame_main, text='Using local image', fg='red').pack(side=TOP) self.frame_url.pack(side=TOP, fill=X, padx=20, pady=(10, 0)) frame_buttons.pack(side=BOTTOM, anchor=S, fill=X, expand=NO, padx=20, pady=10) frame_output.pack(side=BOTTOM, anchor=S, fill=X, expand=NO, padx=20) frame_input.pack(side=TOP, expand=YES, fill=BOTH, padx=20) # Init other tk variables self.pending_boxes = BooleanVar() self.pending_redraw = BooleanVar() # Start mainloop self.root.mainloop() def image_grab(self): self.set_root_alpha(0) self.get_image('from_screen') self.set_root_alpha(1) def set_root_alpha(self, alpha, clear_canvas=0): self.root.wm_attributes('-alpha', alpha) if clear_canvas == 1: self.canvas.delete(ALL) elif clear_canvas == 2: self.redraw() def set_transparency(self): self.redraw(False) def elevate_error(self): logging.basicConfig(filename='errors.log', level=logging.ERROR) self.set_status('Error occurred, see error.log', 'red') logging.error(traceback.format_exc()) traceback.print_exc() @staticmethod def center_window(win): win.update_idletasks() width = win.winfo_width() frm_width = win.winfo_rootx() - win.winfo_x() win_width = width + 2 * frm_width height = win.winfo_height() titlebar_height = win.winfo_rooty() - win.winfo_y() win_height = height + titlebar_height + frm_width x = max(10, win.winfo_screenwidth() // 2 - win_width // 2) y = max(10, win.winfo_screenheight() // 2 - win_height // 2) win.geometry('{}x{}+{}+{}'.format(width, height, x, y)) def get_image(self, mode='from_url'): try: if mode == 'from_screen': x0, y0 = self.canvas.winfo_rootx(), self.canvas.winfo_rooty() x1, y1 = x0 + self.canvas.winfo_width(), y0 + self.canvas.winfo_height() bbox = (x0, y0, x1, y1) self.image = ImageGrab.grab(bbox) print('grabbed image x0:{}, y0:{}, x1:{}, y1:{}:'.format(x0, y0, x1, y1)) elif mode == 'from_url': image = r'resources\test_img1.jpg' if self.adm_cfg['use_local_image'] == 'True' else \ request.urlopen(self.entry_url.get()) self.image = Image.open(image) else: return w, h = self.image.size self.aspect_ratio = w / h self.tk_image = ImageTk.PhotoImage(self.image) self.new_image = True self.redraw() self.btn_crack.configure(state=NORMAL) self.set_status('Loaded image URL', 'blue') # Delete bounding box data and clear output self.bounding_boxes = None self.txt_output.config(state=NORMAL) self.txt_output.delete(1.0, END) self.txt_output.config(state=DISABLED) return except error.HTTPError: self.set_status('Invalid image URL', 'red') except FileNotFoundError: self.set_status('Did not find specified local image', 'red') self.timed_highlight(self.root, self.frame_url) def timed_highlight(self, parent, widget): # Initiates a timed highlight if not self.pending_timed_highlight: self.pending_timed_highlight = True widget.configure(highlightcolor='red', highlightbackground='red', highlightthickness=2) parent.after(1500, lambda: self.highlight_off(widget)) def highlight_off(self, widget): # Toggles off the highlight after a set amount of time self.pending_timed_highlight = False widget.configure(highlightthickness=0) def set_status(self, text, fg): self.lbl_status.configure(text='Status: ' + text, fg=fg) def redraw(self, rescale_image=True): # Save window size self.win_cfg['window_width'], self.win_cfg['window_height'] = self.root.winfo_width(), self.root.winfo_height() # Check if image has been loaded if not self.image: return if rescale_image: # Read new canvas size canvas_width, canvas_height = self.canvas.winfo_width(), self.canvas.winfo_height() # Resize if canvas has changed more than threshold since last resize if (self.new_image or self.can_cfg['resize_threshold'] < abs(self.canvas_width - canvas_width) or self.can_cfg['resize_threshold'] < abs(self.canvas_height - canvas_height)): # Save new canvas size self.canvas_width, self.canvas_height = canvas_width, canvas_height # Calculate width, height if self.aspect_ratio < self.canvas_width / self.canvas_height: self.image_width, self.image_height = int(self.canvas_height * self.aspect_ratio), self.canvas_height else: self.image_width, self.image_height = self.canvas_width, int(self.canvas_width / self.aspect_ratio) # Calculate image scale w, h = self.image.size self.image_scale = self.image_width / w # Calculate offsets if self.can_cfg['center_image_on_canvas']: self.image_x_offset = (self.canvas_width - self.image_width) // 2 self.image_y_offset = (self.canvas_height - self.image_height) // 2 else: self.image_x_offset, self.image_y_offset = 0, 0 # Resize image self.img = ImageTk.PhotoImage(self.image.resize((self.image_width, self.image_height))) self.new_image = False # Clear canvas self.canvas.delete(ALL) # Draw new image self.img_id = self.canvas.create_image(self.image_x_offset, self.image_y_offset, image=self.img, anchor=NW) # Create overlay for adjusting contrast overlay_alpha = int(self.scale_slider.get() / 100 * 255) if 0 < overlay_alpha: self.transparency_overlay = ImageTk.PhotoImage( Image.new('RGBA', (self.image_width, self.image_height), (30, 30, 30, overlay_alpha))) self.canvas.create_image(self.image_x_offset, self.image_y_offset, image=self.transparency_overlay, anchor='nw') # Redraw bounding boxes if there are any self.last_resize = datetime.now() if self.render_boxes.get(): self.call_boxing() def call_delayed_func(self, delay, func, limiter): # TODO: Finish this """ :param delay: Delay before update. :param func: Function to be called after set time. :param limiter: BooleanVar() that limits amount of instances to a single. :return: """ # Wait by updating till after user has stopped resizing if delay < (datetime.now() - self.last_resize).seconds: func() elif not limiter: limiter.set(True) self.call_delayed_func(delay, func, limiter) def call_boxing(self): # Start one update worker for box updating if not self.pending_boxes.get(): self.pending_boxes.set(True) self.root.after(self.can_cfg['canvas_update_delay'], self.delay_boxing) def delay_boxing(self): # Wait by updating till after user has stopped resizing if self.can_cfg['canvas_update_delay']*1000 < (datetime.now() - self.last_resize).microseconds: self.draw_boxes_on_canvas() self.pending_boxes.set(False) else: self.root.after(self.can_cfg['canvas_update_delay'], self.delay_boxing) def draw_boxes_on_canvas(self): if not self.bounding_boxes: return for box in self.bounding_boxes.split('\n'): # Split data box = box.split(' ') c = box[0] box = box[1:5] # Convert box data to int box = [int(x) for x in box] # Scale boxes box = [x * self.image_scale for x in box] # Flip data vertically and apply offsets x0 = box[0] + self.image_x_offset y0 = self.image_height - box[1] + self.image_y_offset x1 = box[2] + self.image_x_offset y1 = self.image_height - box[3] + self.image_y_offset # Draw on canvas self.canvas.create_rectangle((x0, y0, x1, y1), outline='red') self.canvas.create_text(x0 + (x1 - x0) // 2, y0 + 6, text=c, fill='orange', font="Times 12") def start_cracking(self, image): raw_data = self.get_data_from_image(image) if raw_data: clean_data = self.interpret_by_regex(raw_data) self.translate_and_apply(clean_data) def interpret_by_regex(self, data): special_cases = '' for key in self.ambiguous_chars: special_cases += key p = re.compile('[0-9a-fA-F' + special_cases + ']{2}') return p.findall(data) def get_data_from_image(self, image): try: pytesseract.tesseract_cmd = self.sys_cfg['tesseract_directory'] self.bounding_boxes = pytesseract.image_to_boxes(image) self.redraw(False) return pytesseract.image_to_string(image) except pytesseract.TesseractNotFoundError: self.set_status('Did not find tesseract.exe at specified directory', 'red') def translate_and_apply(self, data): output_str = '' for hex_num in data: try: hex_num = hex_num.upper() # Replace chars ordered by priority until one makes a key match for key in self.ambiguous_chars: if hex_num in self.ascii_lookup.keys(): break for c in self.ambiguous_chars[key]: replacement = c print('attempting to replace \'{}\' with \'{}\''.format(key, replacement)) hex_num = hex_num.replace(key, replacement) if hex_num in self.ascii_lookup.keys(): print('new key match: {}'.format(hex_num)) break raw_str = self.ascii_lookup[hex_num] output_str += raw_str.replace('SPACE', ' ') except KeyError: print('Did not find symbol for {}'.format(hex_num)) challenges = [ 'Software Architecture', 'Third-party Integration', 'Team Management'] if self.should_i_apply: output_str += ('\n\nI believe the three most difficult challenges are {}' .format(', '.join(challenges))) self.txt_output.config(state=NORMAL) self.txt_output.delete(1.0, END) self.txt_output.insert(END, output_str) self.txt_output.config(state=DISABLED) self.set_status('Cracked code!', 'green')
class Main(Frame): def __init__(self, parent, controller): Frame.__init__(self, parent) self.controller = controller self.db_set = False self.configure(relief=GROOVE) self.configure(borderwidth="2") # Manual link adding self.manual_btn = Button(self) self.manual_btn.place(relx=0.07, rely=0.81, height=45, width=130) self.manual_btn.configure(activebackground="#d9d9d9") self.manual_btn.configure(highlightbackground="#d9d9d9") self.manual_btn.configure(pady="0") self.manual_btn.configure(text="Add manually") self.manual_btn.configure(width=130) self.file_btn = Button(self) self.file_btn.place(relx=0.67, rely=0.81, height=45, width=150) self.file_btn.configure(activebackground="#d9d9d9") self.file_btn.configure(highlightbackground="#d9d9d9") self.file_btn.configure(pady="0") self.file_btn.configure(text="Add from file") self.label = Label(self) self.label.place(relx=0.08, rely=0.0, height=61, width=484) self.label.configure(text="Create new playlists and add content to them") self.label.configure(width=485) self.listbox = Listbox(self) self.listbox.place(relx=0.38, rely=0.22, relheight=0.31, relwidth=0.17) self.listbox.configure(background="white") self.listbox.configure(disabledforeground="#a3a3a3") self.listbox.configure(foreground="#000000") self.listbox.configure(selectmode=SINGLE) self.listbox.configure(width=105) for name, value in config.configparser.items('Playlists'): if os.path.isdir(value): self.listbox.insert('end', name) else: config.remove_value('Playlists', name) self.listbox.bind('<<ListboxSelect>>', self.onselect) self.label_name = Label(self) self.label_name.place(relx=0.7, rely=0.22, height=31, width=84) self.label_name.configure(foreground="#000000") self.label_name.configure(text="Name") self.label_name.configure(width=85) self.entry = Entry(self) self.entry.place(relx=0.63, rely=0.31, relheight=0.08, relwidth=0.29) self.entry.configure(background="white") self.entry.configure(foreground="#000000") self.entry.configure(insertbackground="black") self.entry.configure(takefocus="0") self.entry.configure(width=175) self.change_name = Button(self) self.change_name.place(relx=0.7, rely=0.42, height=34, width=97) self.change_name.configure(activebackground="#d9d9d9") self.change_name.configure(highlightbackground="#d9d9d9") self.change_name.configure(highlightcolor="black") self.change_name.configure(pady="0") self.change_name.configure(text="Rename") self.change_name.configure(width=100) self.new_playlist = Button(self, command=self.new_database) self.new_playlist.place(relx=0.08, rely=0.28, height=54, width=107) self.new_playlist.configure(activebackground="#d9d9d9") self.new_playlist.configure(highlightbackground="#d9d9d9") self.new_playlist.configure(highlightcolor="black") self.new_playlist.configure(pady="0") self.new_playlist.configure(text="Create new playlist") self.new_playlist.configure(width=105) self.db_name = Entry(self) self.db_name.place(relx=0.07, rely=0.44, relheight=0.08, relwidth=0.22) self.db_name.configure(fg='grey') self.db_name.configure(width=135) self.db_name.insert(0, "Input database name here") self.db_name.bind('<Button-1>', lambda event: greytext(self.db_name)) def onselect(self, event): w = event.widget index = int(w.curselection()[0]) value = w.get(index) set_database(config.configparser.get('Playlists', value)) if not database.check_integrity(): messagebox.showwarning('Integrity check failed', 'You might be missing some entries in your list') if not self.db_set: self.manual_btn.configure(command=lambda: self.controller.show_frame('AddManually')) self.file_btn.configure(command=lambda: self.controller.show_frame('ReadFromFile')) self.db_set = True def new_database(self): name = self.db_name.get() names = config.configparser.options('Playlists') print(name, names) if name.strip() == '' or self.db_name.cget('fg') == 'grey': messagebox.showerror('Invalid name', "Please input a valid name for the database") return if name in names: messagebox.showerror('Name already in use', "Please select another name") return path = '../playlists/%s/' % name if set_database(path, create=True) is False: return config.set_value('Playlists', name, path) self.listbox.insert('end', name)
def __init__(self): window = Tk() window.title('Scientific Calculator') # default resolution window.geometry("412x412") window.maxsize(412, 412) window.minsize(412, 412) window.configure(background="white") self.string = StringVar() entry = Entry(window, textvariable=self.string, font="arial 18") entry.grid(row=0, column=0, columnspan=6, pady=4) entry.configure(background="white") entry.focus() values = [ "7", "8", "9", "/", "%", "clear", "AC", "4", "5", "6", "*", "(", ")", "**", "1", "2", "3", "-", "=", ",", "0", ".", "min", "+", "sin", "asin", "cos", "acos", "tan()", "pow", "log10", "max", "abs", "floor", "pi", "e", "log", "ceil", "degrees", "radians" ] text = 1 i = 0 row = 1 col = 0 for txt in values: padx = 10 pady = 10 if (i == 7): row = 2 col = 0 if (i == 14): row = 3 col = 0 if (i == 19): row = 4 col = 0 if (i == 26): row = 5 col = 0 if (i == 33): row = 6 col = 0 if (txt == '='): btn = Button(window, height=2, width=4, padx=70, pady=pady, text=txt, command=lambda txt=txt: self.equals()) btn.grid(row=row, column=col, columnspan=3, padx=2, pady=2) btn.configure(background="yellow") elif (txt == 'clear'): btn = Button(window, height=2, width=4, padx=padx, pady=pady, text=txt, command=lambda txt=txt: self.delete()) btn.grid(row=row, column=col, padx=1, pady=1) btn.configure(background="grey") elif (txt == 'AC'): btn = Button(window, height=2, width=4, padx=padx, pady=pady, text=txt, command=lambda txt=txt: self.clearall()) btn.grid(row=row, column=col, padx=1, pady=1) btn.configure(background="red") else: btn = Button(window, height=2, width=4, padx=padx, pady=pady, text=txt, command=lambda txt=txt: self.addChar(txt)) btn.grid(row=row, column=col, padx=1, pady=1) btn.configure(background="cyan") col = col + 1 i = i + 1 window.mainloop()
class App(object): def __init__(self): #настройка окружения self.pathtoapp = path2program.abspath(".") self.lst = [x for x in listdir(".") if ".prg" in x] #получаем список файлов с расширением prg if len(self.lst)==0: print("No prg file found in directory") input() _exit(0) self.currentfileindex = 0 #устанавливаем индекс текущего файла #настройка графики self.window = Tk() self.window.title("PRG Viewer by Novicov: "+self.pathtoapp) w = 850 h = 500 self.window.minsize(width=w-100,height=h-100) self.window.maxsize(width=w,height=h) #иконка _lst = sys_argv[0].split('\\') self.window.iconbitmap('\\'.join(_lst[:-1])+'\\PRGViewer-logo.ico') #ПАНЕЛИ # self.leftframe = Frame(self.window, bg="blue", width=int(w*0.667),height=h) self.leftframe = Frame(self.window, bg="grey", width=int(w*0.667),height=h) # self.bottomleftframe = Frame(self.leftframe, bg="red", width=w//4, height=int(h*0.2)) self.bottomleftframe = Frame(self.leftframe, bg="grey", width=w//4, height=int(h*0.2)) # self.rightframe = Frame(self.window, bg="yellow",width=int(w*0.333),height=h) self.rightframe = Frame(self.window, bg="dark grey",width=int(w*0.333),height=h) #canvas self.set_canvas( self.leftframe, bg="dark green", width=int(w*0.667),height=int(h*0.8)) # self.set_canvas( self.leftframe, bg="light green", width=100,height=100) #кнопки self.nextButton = Button(self.bottomleftframe,text="Next",width=10) self.prevButton = Button(self.bottomleftframe,text="Prev",width=10) #Список фильтров self.Filter = PRGListBox(self.rightframe,width=w-500) #Выбор файла платы self.infoText = StringVar() self.infoText.set("Current file: "+self.lst[self.currentfileindex]) self.info = Label(self.rightframe,text=self.infoText.get()) self.listFilesText = StringVar() self.listFilesText.set("\n".join(["Files: "]+self.lst)) self.listfiles = Label(self.rightframe,text=self.listFilesText.get(),anchor="w",justify=LEFT) self.helpText = Label(self.rightframe, text="Use Next/Prev (Pg Down/Up) buttons for change file\n"+ "Use Up,Down,Right,Left buttons for move field\n"+ "Select row in ListBox for change vision mode\n"+ "Use +/- (p/m) buttons for scaling of field",anchor="n",justify=LEFT) def set_path_and_current(self, filename): ''' эта функция обрабатывает полный путь до файла ''' try: _lst = filename.split('\\') self.path = '\\'.join(_lst[:-2]) chdir('\\'.join(_lst[:-1])) print(listdir(".")) self.lst = [x for x in listdir(".") if ".prg" in x] self.currentfileindex = self.lst.index(_lst[-1]) self.infoText.set("Current file: "+self.lst[self.currentfileindex]) self.info.configure(text=self.infoText.get()) self.listFilesText.set("\n".join(self.lst)) self.listfiles.configure(text=self.listFilesText.get()) self.canvas.configure(self.lst[self.currentfileindex]) self.canvas.setdefault(reper=True) #рисуем self.canvas.paint() #здесь мы создаем группу gr = list() for item in self.canvas.field: print(item[2][2]) if not (item[2][2] in gr):#выделяем уникальные данные gr.append(item[2][2]) self.Filter.lst.delete(2,END) for item in gr: self.Filter.lst.insert(END,item) except IOError: self.infoText.set("Error") self.info.configure(text=self.infoText.get()) def set_canvas(self,master=None,height=500,width=500,bg="grey" ): if master==None: master=self.window self.canvas = prgCanvas(master,height=height,width=width,bg=bg) def nextprev(self,direction): self.currentfileindex+=1 if abs(direction)==direction else -1 if self.currentfileindex<0: self.currentfileindex = len(self.lst)-1 elif self.currentfileindex>len(self.lst)-1: self.currentfileindex = 0 self.canvas.setdefault(reper=True) self.infoText.set("Current file: "+self.lst[self.currentfileindex]) self.info.configure(text=self.infoText.get()) self.canvas.configure(self.lst[self.currentfileindex]) #рисуем self.canvas.paint() #здесь мы создаем группу gr = list() for item in self.canvas.field: print(item[2][2]) if not (item[2][2] in gr):#выделяем уникальные данные gr.append(item[2][2]) self.Filter.lst.delete(2,END) for item in gr: self.Filter.lst.insert(END,item) def _changemashtab(self,event,dm): self.canvas.mashtab*=dm self.canvas.genfield() def filter_selection(self): name = self.Filter.lst.get(self.Filter.lst.curselection()) if name == "Hide All": print("Hide All") self.canvas.flagDescription = False self.canvas.filter = None self.canvas.genfield() elif name =="Show All": print("Show All") self.canvas.flagDescription = True self.canvas.filter = None self.canvas.genfield() else: print("Other filter"+name) self.canvas.flagDescription = True #устанавливаем фильтр self.canvas.configure(filter=lambda x: x==name) #перерисовываем self.canvas.paint() def configure(self): self.window.bind("<Key-Right>",lambda event:self.canvas.move(10,0)) self.window.bind("<Key-Left>",lambda event:self.canvas.move(-10,0)) self.window.bind("<Key-Down>",lambda event:self.canvas.move(0,10)) self.window.bind("<Key-Up>",lambda event:self.canvas.move(0,-10)) self.window.bind("<Key-plus>",lambda event:self._changemashtab(event,1.1)) self.window.bind("p",lambda event:self._changemashtab(event,1.1)) self.window.bind("<Key-minus>",lambda event:self._changemashtab(event,0.9)) self.window.bind("m",lambda event:self._changemashtab(event,0.9)) self.Filter.lst.bind("<<ListboxSelect>>", lambda event: self.filter_selection()) self.Filter.bind("<Leave>",lambda event: self.window.focus_force()) self.nextButton.configure(command=lambda:self.nextprev(1)) self.prevButton.configure(command=lambda:self.nextprev(-1)) self.window.bind("<Key-Prior>",lambda event:self.nextprev(-1)) #Page Up self.window.bind("<Key-Next>",lambda event:self.nextprev(1)) #Page Down def startloop(self): self.leftframe.pack (side=LEFT,expand="y",fill="both") # self.leftframe.pack () print("leftframe") self.canvas.pack (expand="y",fill="both") self.canvas.canvas.pack () self.canvas.configure(file=self.lst[self.currentfileindex]) self.canvas.paint() self.bottomleftframe.pack() self.nextButton.pack (side=RIGHT) self.prevButton.pack (side=LEFT) self.rightframe.pack(side=RIGHT,expand="y",fill="y") # self.rightframe.pack() print("rightframe") self.info.pack (side=TOP,fill=X,expand=Y) self.listfiles.pack (side=TOP,fill=BOTH,expand=Y) self.Filter.pack (side=TOP, fill=BOTH, expand=Y) self.helpText.pack (side=BOTTOM) self.window.mainloop()
def aviso_versao_atualizada(self, baixada): self.tp_atualizacao = Toplevel( self.tela, self.design.dic["aviso_versao_tp_atualizada"]) self.tp_atualizacao.withdraw() self.tp_atualizacao.focus_force() self.tp_atualizacao.resizable(False, False) self.tp_atualizacao.tk.call('wm', 'iconphoto', self.tp_atualizacao._w, self.icon) #try: # self.tp_atualizacao.wm_attributes('-type', 'splash') #except Exception as erro: # print("Erro ao remover barra de titulos => ", erro) self.tp_atualizacao.grid_columnconfigure(1, weight=1) j_width = self.tp_atualizacao.winfo_reqwidth() j_height = self.tp_atualizacao.winfo_reqheight() t_width = self.tela.winfo_screenwidth() t_heigth = self.tela.winfo_screenheight() self.tp_atualizacao.title( self.interface_idioma["titulo_aviso_atualizado"][self.idioma]) fr_atualizaca = Frame(self.tp_atualizacao) lb_versao_dev = Label( fr_atualizaca, text=self.interface_idioma["atualizado_versao_ultima"][ self.idioma]) lb_versao_tex = Message( fr_atualizaca, text='{}'.format( self.interface_idioma["texto_atualizado"][self.idioma]).format( baixada["versao"]), relief=FLAT) fr_botoes = Frame(fr_atualizaca) bt_cancela = Button( fr_botoes, text=self.interface_idioma["texto_nao_quero"][self.idioma], relief=FLAT) bt_facebook = Button( fr_botoes, self.design.dic["aviso_versao_bt_facebook_atualizada"], text=self.interface_idioma["atualizado_facebook"][self.idioma], relief=FLAT) bt_blogger_ = Button( fr_botoes, self.design.dic["aviso_versao_bt_blog_atualizada"], text=self.interface_idioma["atualizado_blog"][self.idioma], relief=FLAT) # Configurações de desingn fr_atualizaca.configure(self.design.dic["aviso_versao_fr_atualizacao"]) lb_versao_dev.configure(self.design.dic["aviso_versao_lb_dev"]) lb_versao_tex.configure(self.design.dic["aviso_versao_ms"]) fr_botoes.configure(self.design.dic["aviso_versao_btn"]) bt_cancela.configure(self.design.dic["aviso_versao_btn_cancela"], relief=FLAT) #bt_atualiza.configure(self.design.dic["aviso_versao_btn_atualiza"], relief=FLAT) bt_cancela.configure( command=lambda event=None: self.tp_atualizacao.destroy()) bt_facebook.configure(command=lambda event=None: self.abrir_site( "https://www.facebook.com/safiralang/")) bt_blogger_.configure(command=lambda event=None: self.abrir_site( "https://safiralang.blogspot.com/")) fr_atualizaca.grid_columnconfigure(1, weight=1) fr_botoes.grid_columnconfigure(1, weight=1) fr_botoes.grid_columnconfigure(2, weight=1) fr_botoes.grid_columnconfigure(3, weight=1) fr_atualizaca.grid(row=1, column=1, sticky=NSEW) lb_versao_dev.grid(row=1, column=1) lb_versao_tex.grid(row=2, column=1, sticky=NSEW) fr_botoes.grid(row=3, column=1, sticky=NSEW) bt_cancela.grid(row=1, column=1) bt_facebook.grid(row=1, column=2) bt_blogger_.grid(row=1, column=3) self.tp_atualizacao.geometry("+{}+{}".format( int(t_width / 2) - int(j_width / 2), int(t_heigth / 2) - int(j_height / 2))) self.tp_atualizacao.update() self.tp_atualizacao.deiconify()
class Ventana(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent # Elementos interfaz self.ceros = "white" self.unos = "black" self.regla = [2, 3, 3, 3] self.e1 = None self.e2 = None self.contador = 0 self.colorBtn1 = None self.colorBtn2 = None self.barra = None self.canvas = None self.cubo_image = None self.glider = None self.glider2 = None self.glider3 = None self.oscilador = None # variables del juego de la vida self.pausa = True self.tam = 100 self.tam_cuadro = 10 self.distribucion = .5 self.cuadritos = np.zeros(shape=(self.tam, self.tam), dtype=int) self.celulas = np.random.randint(2, size=(self.tam, self.tam), dtype=int) self.tiempo = 0 self.tipo_insertar = dict_tipos["nada"] # Historial de unos self.nom_archivo = None def iniciar(self): self.nom_archivo = "{}.csv".format(self.obtener_hora()) archivo = open(self.nom_archivo, "w") archivo.close() self.canvas.delete('all') self.update_idletasks() self.pausa = True self.contador = 0 self.tiempo = 0 self.tam = int(self.e2.get()) self.tam_cuadro = 0 while self.tam_cuadro * self.tam < 1000: self.tam_cuadro += 1 if self.tam_cuadro * self.tam > 1000: self.tam_cuadro -= 1 self.distribucion = self.barra.get() / 100 self.celulas = np.random.choice( [1, 0], size=(self.tam, self.tam), p=[self.distribucion, 1 - self.distribucion]) self.cuadritos = np.zeros(shape=(self.tam, self.tam), dtype=int) texto = self.e1.get().split(",") self.regla[0] = int(texto[0]) self.regla[1] = int(texto[1]) self.regla[2] = int(texto[2]) self.regla[3] = int(texto[3]) self.contar_unos() print(self.contador) self.re_dibujar() def contar_unos(self): for i in range(self.tam): for j in range(self.tam): if self.celulas[i, j] == 1: self.contador += 1 print("contador_unos : {}".format(self.contador)) def pulsar_cuadrito(self, event): item = self.canvas.find_closest(event.x, event.y)[0] i, j = np.where(self.cuadritos == item) print("{}, {}".format(i[0], j[0])) if self.tipo_insertar == dict_tipos["nada"]: if self.canvas.itemcget(item, "fill") == self.unos: self.canvas.itemconfig(item, fill=self.ceros) self.celulas[i[0]][j[0]] = 0 self.contador -= 1 else: self.canvas.itemconfig(item, fill=self.unos) self.celulas[i[0]][j[0]] = 1 self.contador += 1 elif self.tipo_insertar == dict_tipos["cubo"]: print("cubo") self.insertar_cubo(i[0], j[0]) elif self.tipo_insertar == dict_tipos["glider"]: print("glider") self.insertar_glider(i[0], j[0]) elif self.tipo_insertar == dict_tipos["glider2"]: print("glider2") self.insertar_glider_dos(i[0], j[0]) elif self.tipo_insertar == dict_tipos["glider3"]: print("glider3") self.insertar_glider_tres(i[0], j[0]) elif self.tipo_insertar == dict_tipos["oscilador"]: print("oscilador") self.insertar_oscilador(i[0], j[0]) self.tipo_insertar = dict_tipos["nada"] def insertar_cubo(self, x1, y1): x2 = x1 + 1 y2 = y1 + 1 item1 = self.cuadritos[x1, y1] item2 = self.cuadritos[x1, y2] item3 = self.cuadritos[x2, y1] item4 = self.cuadritos[x2, y2] if self.celulas[x1, y1] == 0: self.celulas[x1, y1] = 1 self.contador += 1 self.canvas.itemconfig(item1, fill=self.unos) if self.celulas[x1, y2] == 0: self.celulas[x1, y2] = 1 self.contador += 1 self.canvas.itemconfig(item2, fill=self.unos) if self.celulas[x2, y1] == 0: self.celulas[x2, y1] = 1 self.contador += 1 self.canvas.itemconfig(item3, fill=self.unos) if self.celulas[x2, y2] == 0: self.celulas[x2, y2] = 1 self.contador += 1 self.canvas.itemconfig(item4, fill=self.unos) def insertar_oscilador(self, i1, j1): i0 = i1 - 1 i2 = i1 + 1 item0 = self.cuadritos[i0, j1] item1 = self.cuadritos[i1, j1] item2 = self.cuadritos[i2, j1] if self.celulas[i0, j1] == 0: self.celulas[i0, j1] = 1 self.contador += 1 self.canvas.itemconfig(item0, fill=self.unos) if self.celulas[i1, j1] == 0: self.celulas[i1, j1] = 1 self.contador += 1 self.canvas.itemconfig(item1, fill=self.unos) if self.celulas[i2, j1] == 0: self.celulas[i2, j1] = 1 self.contador += 1 self.canvas.itemconfig(item2, fill=self.unos) def insertar_glider(self, i1, j1): j2 = j1 + 1 i2 = i1 + 1 i3 = i2 + 1 i4 = i3 + 1 item1 = self.cuadritos[i1, j1] item2 = self.cuadritos[i1, j2] item3 = self.cuadritos[i2, j1] item4 = self.cuadritos[i2, j2] item5 = self.cuadritos[i3, j1] item6 = self.cuadritos[i3, j2] item7 = self.cuadritos[i4, j1] item8 = self.cuadritos[i4, j2] if self.celulas[i1, j1] == 0: self.celulas[i1, j1] = 1 self.contador += 1 self.canvas.itemconfig(item1, fill=self.unos) if self.celulas[i1, j2] == 1: self.celulas[i1, j2] = 0 self.contador -= 1 self.canvas.itemconfig(item2, fill=self.ceros) if self.celulas[i2, j1] == 1: self.celulas[i2, j1] = 0 self.contador -= 1 self.canvas.itemconfig(item3, fill=self.ceros) if self.celulas[i2, j2] == 0: self.celulas[i2, j2] = 1 self.contador += 1 self.canvas.itemconfig(item4, fill=self.unos) if self.celulas[i3, j1] == 1: self.celulas[i3, j1] = 0 self.contador -= 1 self.canvas.itemconfig(item5, fill=self.ceros) if self.celulas[i3, j2] == 0: self.celulas[i3, j2] = 1 self.contador += 1 self.canvas.itemconfig(item6, fill=self.unos) if self.celulas[i4, j1] == 0: self.celulas[i4, j1] = 1 self.contador += 1 self.canvas.itemconfig(item7, fill=self.unos) if self.celulas[i1, j2] == 1: self.celulas[i1, j2] = 0 self.contador -= 1 self.canvas.itemconfig(item8, fill=self.ceros) def insertar_glider_dos(self, i1, j1): i2 = i1 + 1 i3 = i2 + 1 i4 = i3 + 1 j2 = j1 + 1 j3 = j2 + 1 item1 = self.cuadritos[i1, j1] item2 = self.cuadritos[i1, j2] item3 = self.cuadritos[i1, j3] item4 = self.cuadritos[i2, j1] item5 = self.cuadritos[i2, j2] item6 = self.cuadritos[i2, j3] item7 = self.cuadritos[i3, j1] item8 = self.cuadritos[i3, j2] item9 = self.cuadritos[i3, j3] item10 = self.cuadritos[i4, j1] item11 = self.cuadritos[i4, j2] item12 = self.cuadritos[i4, j3] if self.celulas[i1, j1] == 0: self.celulas[i1, j1] = 1 self.contador += 1 self.canvas.itemconfig(item1, fill=self.unos) if self.celulas[i1, j2] == 1: self.celulas[i1, j2] = 0 self.contador -= 1 self.canvas.itemconfig(item2, fill=self.ceros) if self.celulas[i1, j3] == 1: self.celulas[i1, j2] = 0 self.contador -= 1 self.canvas.itemconfig(item3, fill=self.ceros) if self.celulas[i2, j1] == 1: self.celulas[i2, j1] = 0 self.contador -= 1 self.canvas.itemconfig(item4, fill=self.ceros) if self.celulas[i2, j2] == 1: self.celulas[i2, j2] = 0 self.contador -= 1 self.canvas.itemconfig(item5, fill=self.ceros) if self.celulas[i2, j3] == 0: self.celulas[i2, j3] = 1 self.contador += 1 self.canvas.itemconfig(item6, fill=self.unos) if self.celulas[i3, j1] == 1: self.celulas[i3, j1] = 0 self.contador -= 1 self.canvas.itemconfig(item7, fill=self.ceros) if self.celulas[i3, j2] == 1: self.celulas[i3, j2] = 0 self.contador -= 1 self.canvas.itemconfig(item8, fill=self.ceros) if self.celulas[i3, j3] == 0: self.celulas[i3, j3] = 1 self.contador += 1 self.canvas.itemconfig(item9, fill=self.unos) if self.celulas[i4, j1] == 0: self.celulas[i4, j1] = 1 self.contador += 1 self.canvas.itemconfig(item10, fill=self.unos) if self.celulas[i4, j2] == 1: self.celulas[i4, j2] = 0 self.contador -= 1 self.canvas.itemconfig(item11, fill=self.ceros) if self.celulas[i4, j3] == 1: self.celulas[i4, j3] = 0 self.contador -= 1 self.canvas.itemconfig(item12, fill=self.ceros) def insertar_glider_tres(self, i2, j2): i1 = i2 - 1 i3 = i2 + 1 j1 = j2 - 1 j3 = j2 + 1 item1 = self.cuadritos[i1, j1] item2 = self.cuadritos[i1, j2] item3 = self.cuadritos[i1, j3] item4 = self.cuadritos[i2, j1] item5 = self.cuadritos[i2, j2] item6 = self.cuadritos[i2, j3] item7 = self.cuadritos[i3, j1] item8 = self.cuadritos[i3, j2] item9 = self.cuadritos[i3, j3] if self.celulas[i1, j1] == 1: self.celulas[i1, j1] = 0 self.contador -= 1 self.canvas.itemconfig(item1, fill=self.ceros) if self.celulas[i1, j2] == 0: self.celulas[i1, j2] = 1 self.contador += 1 self.canvas.itemconfig(item2, fill=self.unos) if self.celulas[i1, j3] == 1: self.celulas[i1, j2] = 0 self.contador -= 1 self.canvas.itemconfig(item3, fill=self.ceros) if self.celulas[i2, j1] == 1: self.celulas[i2, j1] = 0 self.contador -= 1 self.canvas.itemconfig(item4, fill=self.ceros) if self.celulas[i2, j2] == 1: self.celulas[i2, j2] = 0 self.contador -= 1 self.canvas.itemconfig(item5, fill=self.ceros) if self.celulas[i2, j3] == 0: self.celulas[i2, j3] = 1 self.contador += 1 self.canvas.itemconfig(item6, fill=self.unos) if self.celulas[i3, j1] == 0: self.celulas[i3, j1] = 1 self.contador += 1 self.canvas.itemconfig(item7, fill=self.unos) if self.celulas[i3, j2] == 0: self.celulas[i3, j2] = 1 self.contador += 1 self.canvas.itemconfig(item8, fill=self.unos) if self.celulas[i3, j3] == 0: self.celulas[i3, j3] = 1 self.contador += 1 self.canvas.itemconfig(item9, fill=self.unos) def re_dibujar(self): print("REDIBUJAR") for i in range(self.tam): for j in range(self.tam): if self.celulas[i, j] == 0: self.cuadritos[i, j] = self.canvas.create_rectangle( 0 + (j * self.tam_cuadro), 0 + (i * self.tam_cuadro), self.tam_cuadro + (j * self.tam_cuadro), self.tam_cuadro + (i * self.tam_cuadro), fill=self.ceros, width=0, tag="btncuadrito") else: self.cuadritos[i, j] = self.canvas.create_rectangle( 0 + (j * self.tam_cuadro), 0 + (i * self.tam_cuadro), self.tam_cuadro + (j * self.tam_cuadro), self.tam_cuadro + (i * self.tam_cuadro), fill=self.unos, width=0, tag="btncuadrito") self.canvas.tag_bind("btncuadrito", "<Button-1>", self.pulsar_cuadrito) self.update_idletasks() def init_ui(self): self.parent.title("Juego de la vida") self.pack(fill=BOTH, expand=1) self.canvas = Canvas(self, relief='raised', width=1000, height=1000) scroll = Scrollbar(self, orient=VERTICAL) scroll.pack(side=RIGHT, fill=Y) scroll.config(command=self.canvas.yview) self.canvas.config(yscrollcommand=scroll.set) self.canvas.pack(side=LEFT) Label(self, text="Regla:").pack(side=TOP) self.e1 = Entry(self, fg="black", bg="white") self.e1.insert(10, "2,3,3,3") self.e1.pack(side=TOP) Label(self, text="Tamaño:").pack(side=TOP) self.e2 = Entry(self, fg="black", bg="white") self.e2.insert(10, "100") self.e2.pack(side=TOP) Label(self, text="Porcentaje de unos").pack(side=TOP) self.barra = Scale(self, from_=0, to=100, orient=HORIZONTAL, tickinterval=50) self.barra.set(50) self.barra.pack(side=TOP) btn_iniciar = Button(self, text="Iniciar/Reiniciar", command=self.iniciar) btn_iniciar.pack(side=TOP) button1 = Button(self, text="Pausa/Reanudar", command=self.empezar_dentener) button1.pack(side=TOP) self.colorBtn1 = Button(self, text="Selecciona el color de unos", command=self.get_color_unos, bg=self.unos) self.colorBtn1.pack(side=TOP) self.colorBtn2 = Button(self, text="Selecciona el color de ceros", command=self.get_color_ceros, bg=self.ceros) self.colorBtn2.pack(side=TOP) btn_save = Button(self, text="Guardar", command=self.guardar) btn_save.pack(side=TOP) btn_cargar = Button(self, text="Cargar Matriz", command=self.cargar) btn_cargar.pack(side=TOP) self.cubo_image = PhotoImage(file="./data/cuadrado.png") btn_cubo = Button(self, image=self.cubo_image, command=self.seleccionar_cubo) btn_cubo.pack(side=TOP) self.glider = PhotoImage(file="./data/glider.png") self.glider = self.glider.subsample(2) btn_glider = Button(self, image=self.glider, command=self.seleccionar_glider) btn_glider.pack(side=TOP) self.glider2 = PhotoImage(file="./data/glider2.png") self.glider2 = self.glider2.subsample(2) btn_glider2 = Button(self, image=self.glider2, command=self.seleccionar_glider_dos) btn_glider2.pack(side=TOP) self.glider3 = PhotoImage(file="./data/glider3.png") btn_glider3 = Button(self, image=self.glider3, command=self.seleccionar_glider_tres) btn_glider3.pack(side=TOP) self.oscilador = PhotoImage(file="./data/oscilador.png") btn_osilador = Button(self, image=self.oscilador, command=self.seleccionar_oscilador) btn_osilador.pack(side=TOP) def seleccionar_glider(self): self.tipo_insertar = dict_tipos["glider"] def seleccionar_glider_dos(self): self.tipo_insertar = dict_tipos["glider2"] def seleccionar_glider_tres(self): self.tipo_insertar = dict_tipos["glider3"] def seleccionar_oscilador(self): self.tipo_insertar = dict_tipos["oscilador"] def seleccionar_cubo(self): self.tipo_insertar = dict_tipos["cubo"] @staticmethod def abrir_archivo(): print("abrir archivo") ga = filedialog.askopenfilename( title="Selecciona un archivo", filetypes=(("CSV", "*.csv"), ("Archivo de texto", "*.txt"), ("Todos los archivos", "*.*"))) return ga def actualizar_color_matriz(self): for i in range(self.tam): for j in range(self.tam): if self.celulas[i][j] == 0: self.canvas.itemconfig(self.cuadritos[i][j], fill=self.ceros) else: self.canvas.itemconfig(self.cuadritos[i][j], fill=self.unos) self.update_idletasks() def get_color_unos(self): color = askcolor() if not color[1] is None: self.unos = color[1] self.colorBtn1.configure(bg=self.unos) self.actualizar_color_matriz() def get_color_ceros(self): color = askcolor() if not color[1] is None: self.ceros = color[1] self.colorBtn2.configure(bg=self.ceros) self.actualizar_color_matriz() def guardar(self): temp_nom = "respaldo-{}.csv".format(self.obtener_hora()) archivo = open(temp_nom, 'a') for i in range(self.tam): for j in range(self.tam): archivo.write("{} ".format(self.celulas[i, j])) archivo.write("\n") archivo.write("\n") archivo.close() def cargar(self): print("Cargar archivo") temp_archivo = self.abrir_archivo() self.celulas = np.loadtxt(temp_archivo, dtype=int) self.canvas.delete('all') self.nom_archivo = "{}.csv".format(self.obtener_hora()) archivo = open(self.nom_archivo, "w") archivo.close() texto = self.e1.get().split(",") self.regla[0] = int(texto[0]) self.regla[1] = int(texto[1]) self.regla[2] = int(texto[2]) self.regla[3] = int(texto[3]) self.tam = self.celulas.shape[0] self.cuadritos = np.zeros(shape=(self.tam, self.tam), dtype=int) self.tam_cuadro = 0 self.contador = 0 while self.tam_cuadro * self.tam < 1000: self.tam_cuadro += 1 if self.tam_cuadro * self.tam > 1000: self.tam_cuadro -= 1 self.contar_unos() self.re_dibujar() def empezar_dentener(self): print("empezar_detener") self.pausa = not self.pausa self.animacion() def animacion(self): if not self.pausa: archivo = open(self.nom_archivo, "a") archivo.write("{},{}\n".format(self.tiempo, self.contador)) archivo.close() nueva_poblacion = self.celulas.copy() for i in range(self.tam): for j in range(self.tam): vecinos = self.revisar_vecinos(i, j) if self.celulas[i, j] == 1: if vecinos < self.regla[0] or vecinos > self.regla[1]: nueva_poblacion[i, j] = 0 self.canvas.itemconfig(self.cuadritos[i][j], fill=self.ceros) self.contador -= 1 else: if self.regla[2] <= vecinos <= self.regla[3]: nueva_poblacion[i, j] = 1 self.canvas.itemconfig(self.cuadritos[i][j], fill=self.unos) self.contador += 1 self.celulas[:] = nueva_poblacion[:] self.update_idletasks() print("Termino el t={}".format(self.tiempo)) self.tiempo += 1 self.after(50, self.animacion) def revisar_vecinos(self, i, j): vecinos = self.celulas[i - 1, j - 1] vecinos += self.celulas[i - 1, j] vecinos += self.celulas[i - 1, (j + 1) % self.tam] vecinos += self.celulas[i, (j + 1) % self.tam] vecinos += self.celulas[(i + 1) % self.tam, (j + 1) % self.tam] vecinos += self.celulas[(i + 1) % self.tam, j] vecinos += self.celulas[(i + 1) % self.tam, j - 1] vecinos += self.celulas[i, j - 1] return vecinos @staticmethod def obtener_hora(): return datetime.datetime.fromtimestamp( time.time()).strftime('%Y-%m-%d_%H:%M:%S')
def aviso_versao(self, baixada, recente): """ Aviso, existe uma nova versão disponível """ self.tp_atualizacao = Toplevel( self.tela, self.design.dic["aviso_versao_top_level"]) self.tp_atualizacao.withdraw() self.tp_atualizacao.focus_force() self.tp_atualizacao.resizable(False, False) self.tp_atualizacao.tk.call('wm', 'iconphoto', self.tp_atualizacao._w, self.icon) self.tp_atualizacao.grid_columnconfigure(1, weight=1) self.tp_atualizacao.title( self.interface_idioma["titulo_aviso_atualizacao"][self.idioma]) # Tentar remover a barra de rolagem #try: # self.tp_atualizacao.wm_attributes('-type', 'splash') #except Exception as erro: # print("Erro ao remover barra de titulos => ", erro) # Objetos da interface fr_atualizaca = Frame(self.tp_atualizacao) lb_versao_dev = Label( fr_atualizaca, text=self.interface_idioma["versao_nova_disponivel"][self.idioma]) lb_versao_tex = Message( fr_atualizaca, text='{}'.format(self.interface_idioma["texto_update_disponivel"][ self.idioma]).format(recente)) fr_botoes = Frame(fr_atualizaca) bt_cancela = Button( fr_botoes, text=self.interface_idioma["versao_nao_quero"][self.idioma]) bt_atualiza = Button( fr_botoes, text=self.interface_idioma["atualizar_agora"][self.idioma]) # Configurações de desingn fr_atualizaca.configure(self.design.dic["aviso_versao_fr_atualizacao"]) lb_versao_dev.configure(self.design.dic["aviso_versao_lb_dev"]) lb_versao_tex.configure(self.design.dic["aviso_versao_ms"]) fr_botoes.configure(self.design.dic["aviso_versao_btn"]) bt_cancela.configure(self.design.dic["aviso_versao_btn_cancela"], relief=FLAT) bt_atualiza.configure(self.design.dic["aviso_versao_btn_atualiza"], relief=FLAT) # Eventos bt_atualiza.configure( command=lambda rec=recente: self.aviso_aguarde_instalando(rec)) bt_cancela.configure( command=lambda event=None: self.tp_atualizacao.destroy()) # Posicionamento de itens fr_atualizaca.grid_columnconfigure(1, weight=1) fr_botoes.grid_columnconfigure(1, weight=1) fr_botoes.grid_columnconfigure(2, weight=1) fr_atualizaca.grid(row=1, column=1, sticky=NSEW) lb_versao_dev.grid(row=1, column=1) lb_versao_tex.grid(row=2, column=1, sticky=NSEW) fr_botoes.grid(row=3, column=1, sticky=NSEW) bt_cancela.grid(row=1, column=1) bt_atualiza.grid(row=1, column=2) # Posicionando a tela j_width = self.tp_atualizacao.winfo_reqwidth() j_height = self.tp_atualizacao.winfo_reqheight() t_width = self.tela.winfo_screenwidth() t_heigth = self.tela.winfo_screenheight() self.tp_atualizacao.geometry("+{}+{}".format( int(t_width / 2) - int(j_width / 2), int(t_heigth / 2) - int(j_height / 2))) self.tp_atualizacao.deiconify() self.tp_atualizacao.update()
class ROMToolGUI: def __init__(self, master): self.master = master master.title("petrie's Happy Fun Time ROM Tool") master.wm_iconbitmap(os.getcwd() + "/eyeballfrog.ico") #Handle initialization of directories if (os.path.isfile(os.getcwd() + '/settings.ini')): settingsfile = open(os.getcwd() + '/settings.ini', 'r') settings = settingsfile.readlines() settingsfile.close() self.initarray = [x.rstrip() for x in settings] else: self.initarray = ['./', './', './', './', './'] [self.EngToDebug, self.DebugToEng] = ROMtools.makeDEdict() #set up notebook tabs self.Tabs = ttk.Notebook(master) self.CompFrame = ttk.Frame(self.Tabs) self.DecompFrame = ttk.Frame(self.Tabs) self.ExtractFrame = ttk.Frame(self.Tabs) self.InjectFrame = ttk.Frame(self.Tabs) self.Tabs.add(self.InjectFrame, text='Inject Files') self.Tabs.add(self.ExtractFrame, text='Extract Files') self.Tabs.add(self.CompFrame, text='Compress ROM') self.Tabs.add(self.DecompFrame, text='Decompress ROM') self.Tabs.grid(row=1, column=0, columnspan=4) self.close_button = Button(master, text="Done", command=master.destroy) self.close_button.grid(column=1, row=2, pady=10, columnspan=2) self.master = master #ROM compression frame self.compROMlabel = Label(self.CompFrame, text="Decompressed ROM:", width=30) self.compROMlabel.grid(row=0, column=0, columnspan=1, pady=10) self.compROMtext = StringVar(master=self.master) self.compROMtext.set("No ROM selected") self.compROMname = Label(self.CompFrame, textvariable=self.compROMtext, width=30, wraplength=150) self.compROMname.grid(row=1, column=0, columnspan=1, pady=10) self.compROMtypelabel = Label(self.CompFrame, text="ROM type:") self.compROMtypelabel.grid(row=0, column=1, columnspan=1, pady=10) self.compROMtype = StringVar(master=self.master) self.compROMtype.set("") self.compROMtypedisp = Label(self.CompFrame, textvariable=self.compROMtype) self.compROMtypedisp.grid(row=1, column=1, columnspan=2, pady=10) self.compROMpath = "" self.selectcompROM = Button(self.CompFrame, text="Select ROM", command=self.setcompROM) self.selectcompROM.grid(row=2, column=0, pady=10) self.comp_button = Button(self.CompFrame, text="Compress", command=self.compress, state='disabled') self.comp_button.grid(row=2, column=1, pady=10) #ROM decompression frame self.decompROMlabel = Label(self.DecompFrame, text="Compressed ROM:", width=30) self.decompROMlabel.grid(row=0, column=0, columnspan=1, pady=10) self.decompROMtext = StringVar(master=self.master) self.decompROMtext.set("No ROM selected") self.decompROMname = Label(self.DecompFrame, textvariable=self.decompROMtext, width=30, wraplength=150) self.decompROMname.grid(row=1, column=0, columnspan=1, pady=10) self.decompROMtable = StringVar(master=self.master) self.decompROMtable.set("") self.decompROMtablelabel = Label(self.DecompFrame, textvariable=self.decompROMtable, width=20) self.decompROMtablelabel.grid(row=0, column=1, columnspan=1, pady=10) self.decompROMfiles = StringVar(master=self.master) self.decompROMfiles.set("") self.decompROMfiledisp = Label(self.DecompFrame, textvariable=self.decompROMfiles) self.decompROMfiledisp.grid(row=1, column=1, columnspan=2, pady=10) self.decompROMpath = "" self.selectdecompROM = Button(self.DecompFrame, text="Select ROM", command=self.setdecompROM) self.selectdecompROM.grid(row=2, column=0, pady=10) self.decomp_button = Button(self.DecompFrame, text="Decompress", command=self.decompress, state='disabled') self.decomp_button.grid(row=2, column=1, pady=10) #File Extraction frame self.extractROMlabel = Label(self.ExtractFrame, text="Source ROM:", width=25) self.extractROMlabel.grid(row=0, column=0, columnspan=1, pady=10) self.extractROMtext = StringVar(master=self.master) self.extractROMtext.set("No ROM selected") self.extractROMname = Label(self.ExtractFrame, textvariable=self.extractROMtext, width=25, wraplength=150) self.extractROMname.grid(row=1, column=0, columnspan=1, pady=10) self.extractROMpath = "" self.selectdecompROM = Button(self.ExtractFrame, text="Select ROM", command=self.setextractROM) self.selectdecompROM.grid(row=3, column=0, pady=10) self.extractROMtypelabel = Label(self.ExtractFrame, text="ROM type:") self.extractROMtypelabel.grid(row=0, column=1, columnspan=1, pady=10) self.extractROMtype = StringVar(master=self.master) self.extractROMtype.set("") self.extractROMtypedisp = Label(self.ExtractFrame, textvariable=self.extractROMtype) self.extractROMtypedisp.grid(row=1, column=1, pady=10) self.extract_button = Button(self.ExtractFrame, text="Extract", command=self.extract, state='disabled') self.extract_button.grid(row=3, column=2, pady=20) self.extractnameslabel = Label(self.ExtractFrame, text="Scene Names", width=25) self.extractnameslabel.grid(row=0, column=2, pady=10) self.extractnames = IntVar(master=self.master) self.extractR1 = Radiobutton(self.ExtractFrame, text="English", variable=self.extractnames, value=0) self.extractR1.grid(column=2, row=1) self.extractR2 = Radiobutton(self.ExtractFrame, text="Debug", variable=self.extractnames, value=1) self.extractR2.grid(column=2, row=2) #File Injection frame self.injectROMlabel = Label(self.InjectFrame, text="Host ROM:", width=20) self.injectROMlabel.grid(row=0, column=0, columnspan=1, pady=10) self.injectROMtext = StringVar(master=self.master) self.injectROMtext.set("No ROM selected") self.injectROMname = Label(self.InjectFrame, textvariable=self.injectROMtext, width=20, wraplength=150) self.injectROMname.grid(row=1, column=0, pady=10) self.injectROMpath = "" self.selectinjectROM = Button(self.InjectFrame, text="Select ROM", command=self.setinjectROM) self.selectinjectROM.grid(row=3, column=0, pady=10) self.injectROMlabel = Label(self.InjectFrame, text="File Directory:", width=20) self.injectROMlabel.grid(row=0, column=1, pady=10) self.injectfoldertext = StringVar(master=self.master) self.injectfoldertext.set("No directory selected") self.injectfoldername = Label(self.InjectFrame, textvariable=self.injectfoldertext, width=20, wraplength=150) self.injectfoldername.grid(row=1, column=1, pady=10) # self.injectROMtypelabel = Label(self.InjectFrame,text = "ROM type:",width = 20) # self.injectROMtypelabel.grid(row = 0, column = 2, columnspan = 1,pady = 10) self.injectROMtypelabel = StringVar(master=self.master) self.injectROMtype = "" self.injectROMtypelabel.set("") self.injectROMtypedisp = Label(self.InjectFrame, textvariable=self.injectROMtypelabel) self.injectROMtypedisp.grid(row=2, column=0, pady=10) self.injectroomstartlabel = Label(self.InjectFrame, text="Boot to scene:") self.injectroomstartlabel.grid(row=0, column=2, columnspan=1, pady=10) self.bootscene = StringVar(master=self.master) self.sceneopts = ['Title Screen'] self.bootscene.set('Title Screen') self.scenedict = {} self.scenemenu = OptionMenu(self.InjectFrame, self.bootscene, *self.sceneopts) self.scenemenu.config(width=15) self.scenemenu.grid(row=1, column=2, pady=10) self.roomnum = StringVar(master=self.master) self.rooment = Entry(self.InjectFrame, textvariable=self.roomnum, exportselection=0) self.rooment.grid(row=2, column=2, pady=10) self.injectfolderpath = "" self.selectinjectfolder = Button(self.InjectFrame, text="Directory", command=self.setinjectfolder) self.selectinjectfolder.grid(row=3, column=1, pady=10) self.injectnames = IntVar(master=self.master) self.injectnamescheck = Checkbutton(self.InjectFrame, text="Debug names", variable=self.injectnames) self.injectnamescheck.grid(row=2, column=1) self.inject_button = Button(self.InjectFrame, text="Inject", command=self.inject, state='disabled') self.inject_button.grid(row=3, column=2, pady=10) def storesettings(self): settingsfile = open(os.getcwd() + '/settings.ini', 'w') settings = [x + '\n' for x in self.initarray] settingsfile.writelines(settings) settingsfile.close() def compress(self): self.comp_button.configure(state='disabled') spath = filedialog.asksaveasfilename(filetypes=(("N64 ROM files", "*.z64"), ("All files", "*.*")), initialdir=self.initarray[0]) if (len(spath) == 0): self.comp_button.configure(state='normal') return -1 if (self.compROMtype.get() == 'Unknown'): popupmsg( 'Warning', 'Using default compression for unknown ROM. This may cause errors.' ) ROMtools.compress(self.compROMpath, spath) popupmsg('Success', 'ROM compressed.') self.comp_button.configure(state='normal') def setcompROM(self): rpath = filedialog.askopenfilename(filetypes=(("N64 ROM files", "*.z64"), ("All files", "*.*")), initialdir=self.initarray[0]) if (len(rpath) > 0): self.compROMpath = rpath self.initarray[0] = os.path.dirname(self.compROMpath) self.storesettings() self.compROMtext.set(os.path.basename(self.compROMpath)) self.comp_button.configure(state='normal') self.compROMtype.set(ROMtools.findROMtype(self.compROMpath)[0]) def decompress(self): self.decomp_button.configure(state='disabled') spath = filedialog.asksaveasfilename(filetypes=(("N64 ROM files", "*.z64"), ("All files", "*.*")), initialdir=self.initarray[1]) if (len(spath) == 0): self.decomp_button.configure(state='normal') return -1 ROMtools.decompress(self.decompROMpath, spath) popupmsg('Success', 'ROM decompressed.') self.decomp_button.configure(state='normal') def setdecompROM(self): rpath = filedialog.askopenfilename(filetypes=(("N64 ROM files", "*.z64"), ("All files", "*.*")), initialdir=self.initarray[1]) if (len(rpath) > 0): self.decompROMpath = rpath self.initarray[1] = os.path.dirname(self.decompROMpath) self.storesettings() self.decompROMtext.set(os.path.basename(self.decompROMpath)) self.decomp_button.configure(state='normal') ROMtype = ROMtools.findROMtype(self.decompROMpath) self.decompROMtable.set('File table at 0x' + '{0:X}'.format(ROMtype[1])) self.decompROMfiles.set('Number of files: ' + str(ROMtype[2])) def setextractROM(self): rpath = filedialog.askopenfilename(filetypes=(("N64 ROM files", "*.z64"), ("All files", "*.*")), initialdir=self.initarray[2]) if (len(rpath) > 0): self.extractROMpath = rpath self.initarray[2] = os.path.dirname(self.extractROMpath) self.storesettings() self.extractROMtext.set(os.path.basename(self.extractROMpath)) self.extract_button.configure(state='normal') self.extractROMtype.set( ROMtools.findROMtype(self.extractROMpath)[0]) def extract(self): self.extract_button.configure(state='disabled') spath = filedialog.askdirectory(initialdir=self.initarray[2]) if (len(spath) == 0): self.extract_button.configure(state='normal') return -1 status = ROMtools.extractall(self.extractROMpath, spath, self.extractnames.get()) if (status == -1): popupmsg('Error', 'This ROM type is currently not supported.') if (status == -2): popupmsg('Error', 'ROM info file does not match ROM.') else: popupmsg('Success', 'Files Extracted.') self.extract_button.configure(state='normal') def setinjectROM(self): rpath = filedialog.askopenfilename(filetypes=(("N64 ROM files", "*.z64"), ("All files", "*.*")), initialdir=self.initarray[3]) if (len(rpath) > 0): self.injectROMpath = rpath self.initarray[3] = os.path.dirname(self.injectROMpath) self.storesettings() self.injectROMtype = ROMtools.findROMtype(self.injectROMpath)[0] self.injectROMtypelabel.set("ROM type: " + self.injectROMtype) self.injectROMtext.set(os.path.basename(self.injectROMpath)) [scenes, self.scenedict] = ROMtools.makescenedict(self.injectROMtype) self.sceneopts = [(self.DebugToEng[x]).replace('_', ' ') for x in scenes] self.scenemenu.destroy() self.bootscene.set('Title Screen') self.scenemenu = OptionMenu(self.InjectFrame, self.bootscene, 'Title Screen', *self.sceneopts) self.scenemenu.config(width=15) self.scenemenu.grid(row=1, column=2, pady=10) if (len(self.injectfolderpath) > 0): self.inject_button.configure(state='normal') def setinjectfolder(self): spath = filedialog.askdirectory(initialdir=self.initarray[4]) if (len(spath) > 0): self.injectfolderpath = spath self.initarray[4] = spath self.storesettings() ind = spath.rfind('/') + 1 self.injectfoldertext.set(spath[ind:]) if (len(self.injectROMpath) > 0): self.inject_button.configure(state='normal') def inject(self): self.inject_button.configure(state='disabled') status = ROMtools.injectall(self.injectROMpath, self.injectfolderpath, self.injectnames.get()) if (status == -1): popupmsg('Error', 'This ROM type is currently not supported.') elif (status == -2): popupmsg('Error', 'ROM info file does not match ROM.') elif (status == -3): popupmsg( 'Error', 'Injected file table does not match ROM file table.\nCheck your ROM version.' ) elif (self.bootscene.get() == 'Title Screen'): print('Skipping') #ROMtools.fixboot(self.injectROMpath) elif (not (self.roomnum.get().isnumeric())): popupmsg( 'Warning', 'Files injected.\nHowever, starting room number was invalid.') ROMtools.fixboot(self.injectROMpath) else: scenename = self.EngToDebug[self.bootscene.get().replace(' ', '_')] roomnum = int(self.roomnum.get()) ent = ROMtools.EntranceDict.get(scenename, 'Unknown') if (ent == 'Unknown'): popupmsg( 'Warning', 'Files injected.\nHowever, booting to the chosen scene is currently unsupported.' ) ROMtools.fixboot(self.injectROMpath) self.inject_button.configure(state='normal') return status = ROMtools.loadtoroom(self.injectROMpath, ROMtools.EntranceDict.get(scenename), self.scenedict.get(scenename), roomnum) if (status == -1): popupmsg( 'Warning', 'Files injected.\nHowever, booting to scenes with multiple setups currently unsupported' ) ROMtools.fixboot(self.injectROMpath) elif (status == -2): popupmsg( 'Warning', 'Files injected.\nHowever, the boot modifier did not recognize the ROM. This error should be impossible.' ) ROMtools.fixboot(self.injectROMpath) elif (status == -3): popupmsg( 'Warning', 'Files injected.\nHowever, the room index was out of range.' ) ROMtools.fixboot(self.injectROMpath) self.inject_button.configure(state='normal')
class TkChoice(Frame): def __init__(self, master, arg, data, callbacks): super().__init__(master) title, colnames, widths = arg self.data = None self.tw = None self.callbacks = callbacks Label(self, text=title + " kiválasztása").pack(**pkw) self._build_treeview(data, colnames, widths) self._build_buttonframe(title) def _build_treeview(self, data, colnames, widths): self.tw = Treeview(self, columns=[str(i) for i in range(len(colnames) - 1)]) self._configure_treeview(data, colnames, widths) self._add_scrollbar_to_treeview() self.tw.bind("<<TreeviewSelect>>", self.setdata) self.tw.bind("<Double-Button-1>", self.doubleclicked) self.tw.pack(**pkw) def _configure_treeview(self, data, colnames, widths): for col, name in enumerate(colnames): self.tw.heading(f"#{col}", text=name) for col, cw in enumerate(widths): self.tw.column(f"#{col}", width=cw) for row in data: self.tw.insert("", "end", text=row[0], values=row[1:]) def _add_scrollbar_to_treeview(self): vsb = Scrollbar(self, orient="vertical", command=self.tw.yview) self.tw.configure(yscrollcommand=vsb.set) vsb.pack(side="right", **pkw) def _build_buttonframe(self, title): f = Frame(self) cb = self.callbacks if cb["back"]: Button(f, text="Vissza", command=cb["back"]).pack(side="left", **pkw) if cb["cancel"]: Button(f, text="Mégsem", command=cb["cancel"]).pack(side="left", **pkw) if cb["new"]: Button(f, text=f"Új {title.lower()}...", command=cb["new"]).pack(side="left", **pkw) self.nextb = Button(f, text="Tovább", command=cb["step"], state="disabled") self.nextb.pack(side="left", **pkw) f.pack(**pkw) def doubleclicked(self, event): if not event.widget.selection(items="#0"): return self.callbacks["step"]() def setdata(self, event): sel = event.widget.selection(items="#0") self.data = event.widget.item(sel)["text"] self.nextb.configure(state="active")
class Gui: """ This class is built to let the user have a better interaction with game. inputs => root = Tk() => an object which inherits the traits of Tkinter class agent = an object which inherit the traits of mctsagent class. """ agent_type = {1: "UCT", 2: "RAVE", 3: "LAST-GOOD-REPLY", 4: "POOLRAVE", 5: "DECISIVE-MOVE", 6: "UCB1-TUNED"} AGENTS = {"UCT": UctMctsAgent, "RAVE": RaveMctsAgent, "LAST-GOOD-REPLY": LGRMctsAgent, "POOLRAVE": PoolRaveMctsAgent, "DECISIVE-MOVE": DecisiveMoveMctsAgent, "UCB1-TUNED": UCB1TunedMctsAgent} def __init__(self, root, agent_name='UCT'): self.root = root self.root.geometry('1366x690+0+0') self.agent_name = agent_name try: self.agent = self.AGENTS[agent_name]() except KeyError: print("Unknown agent defaulting to basic") self.agent_name = "uct" self.agent = self.AGENTS[agent_name]() self.game = GameState(8) self.agent.set_gamestate(self.game) self.time = 1 self.root.configure(bg='#363636') self.colors = {'white': '#ffffff', 'milk': '#e9e5e5', 'red': '#9c0101', 'orange': '#ee7600', 'yellow': '#f4da03', 'green': '#00ee76', 'cyan': '#02adfd', 'blue': '#0261fd', 'purple': '#9c02fd', 'gray1': '#958989', 'gray2': '#3e3e3e', 'black': '#000000'} global BG BG = self.colors['gray2'] self.last_move = None self.frame_board = Frame(self.root) # main frame for the play board self.canvas = Canvas(self.frame_board, bg=BG) self.scroll_y = ttk.Scrollbar(self.frame_board, orient=VERTICAL) self.scroll_x = ttk.Scrollbar(self.frame_board, orient=HORIZONTAL) # the notebook frame which holds the left panel frames self.notebook = ttk.Notebook(self.frame_board, width=350) self.panel_game = Frame(self.notebook, highlightbackground=self.colors['white']) self.developers = Frame(self.notebook, highlightbackground=self.colors['white']) # Registering variables for: self.game_size_value = IntVar() # size of the board self.game_time_value = IntVar() # time of CPU player self.game_turn_value = IntVar() # defines whose turn is it self.switch_agent_value = IntVar() # defines which agent to play against self.switch_agent_value.set(1) self.game_turn_value.set(1) self.turn = {1: 'white', 2: 'black'} self.game_size = Scale(self.panel_game) self.game_time = Scale(self.panel_game) self.game_turn = Scale(self.panel_game) self.generate = Button(self.panel_game) self.reset_board = Button(self.panel_game) self.switch_agent = Scale(self.panel_game) self.agent_show = Label(self.panel_game, font=('Calibri', 14, 'bold'), fg='white', justify=LEFT, bg=BG, text='Agent Policy: ' + self.agent_name + '\n') self.hex_board = [] # Holds the IDs of hexagons in the main board for implementing the click and play functions self.game_size_value.set(8) self.game_time_value.set(1) self.size = self.game_size_value.get() self.time = self.game_time_value.get() self.board = self.game.board self.board = int_(self.board).tolist() self.gameboard2hexagons(self.board) # building the game board self.logo = PhotoImage(file='image/hex.png') self.uut_logo = PhotoImage(file='image/uut_2.png') self.generate_black_edge() self.generate_white_edge() # Frame_content self.frame_board.configure(bg=BG, width=1366, height=760) self.frame_board.pack(fill=BOTH) self.notebook.add(self.panel_game, text=' Game ') self.notebook.add(self.developers, text=' Developers ') self.notebook.pack(side=LEFT, fill=Y) self.canvas.configure(width=980, bg=BG, cursor='hand2') self.canvas.pack(side=LEFT, fill=Y) self.canvas.configure(yscrollcommand=self.scroll_y.set) self.scroll_y.configure(command=self.canvas.yview) self.scroll_x.configure(command=self.canvas.xview) self.scroll_y.place(x=387, y=482) self.scroll_x.place(x=370, y=500) # Frame_left_panel """ the left panel notebook ----> Game """ self.panel_game.configure(bg=BG) Label(self.panel_game, text='Board size', font=('Calibri', 14, 'bold'), foreground='white', bg=BG, pady=10).pack(fill=X, side=TOP) # label ---> Board size self.game_size.configure(from_=3, to=20, tickinterval=1, bg=BG, fg='white', orient=HORIZONTAL, variable=self.game_size_value) self.game_size.pack(side=TOP, fill=X) Label(self.panel_game, text='Time', font=('Calibri', 14, 'bold'), foreground='white', bg=BG, pady=10).pack(side=TOP, fill=X) # label ---> Time self.game_time.configure(from_=1, to=20, tickinterval=1, bg=BG, fg='white', orient=HORIZONTAL, variable=self.game_time_value) self.game_time.pack(side=TOP, fill=X) Label(self.panel_game, text='Player', font=('Calibri', 14, 'bold'), foreground='white', bg=BG, pady=10).pack(side=TOP, fill=X) # label ---> Turn self.game_turn.configure(from_=1, to=2, tickinterval=1, bg=BG, fg='white', orient=HORIZONTAL, variable=self.game_turn_value) self.game_turn.pack(side=TOP) Label(self.panel_game, text=' ', font=('Calibri', 14, 'bold'), foreground='white', bg=BG).pack(side=TOP, fill=X) # ################################## AGENT CONTROLS ############################# self.agent_show.pack(fill=X, side=TOP) self.switch_agent.configure(from_=1, to=len(self.agent_type), tickinterval=1, bg=BG, fg='white', orient=HORIZONTAL, variable=self.switch_agent_value, ) self.switch_agent.pack(side=TOP, fill=X) # ################################## MOVE LABELS ################################ self.move_label = Label(self.panel_game, font=('Calibri', 15, 'bold'), height=5, fg='white', justify=LEFT, bg=BG, text='PLAY : CLICK A CELL ON GAME BOARD \nMCTS BOT: CLICK GENERATE') self.move_label.pack(side=TOP, fill=X) self.reset_board.configure(text='Reset Board', pady=10, cursor='hand2', width=22, font=('Calibri', 12, 'bold')) self.reset_board.pack(side=LEFT) self.generate.configure(text='Generate', pady=10, cursor='hand2', width=22, font=('Calibri', 12, 'bold')) self.generate.pack(side=LEFT) """ the left panel notebook ---> Developers """ self.developers.configure(bg=BG) Label(self.developers, text='HEXPY', font=('Calibri', 18, 'bold'), foreground='white', bg=BG, pady=5).pack(side=TOP, fill=X) Label(self.developers, text='DEVELOPED BY:\n' + 'Masoud Masoumi Moghadam\n\n' + 'SUPERVISED BY:\n' + 'Dr.Pourmahmoud Aghababa\n' + 'Dr.Bagherzadeh\n\n' + 'SPECIAL THANKS TO:\n' + 'Nemat Rahmani\n', font=('Calibri', 16, 'bold'), justify=LEFT, foreground='white', bg=BG, pady=10).pack(side=TOP, fill=X) Label(self.developers, image=self.uut_logo, bg=BG).pack(side=TOP, fill=X) Label(self.developers, text='Summer 2016', font=('Calibri', 17, 'bold'), wraplength=350, justify=LEFT, foreground='white', bg=BG, pady=30).pack(side=TOP, fill=X) # Binding Actions """ Binding triggers for the actions defined in the class. """ self.canvas.bind('<1>', self.click2play) self.game_size.bind('<ButtonRelease>', self.set_size) self.game_time.bind('<ButtonRelease>', self.set_time) self.generate.bind('<ButtonRelease>', self.click_to_bot_play) self.reset_board.bind('<ButtonRelease>', self.reset) self.switch_agent.bind('<ButtonRelease>', self.set_agent) @staticmethod def top_left_hexagon(): """ Returns the points which the first hexagon has to be created based on. """ return [[85, 50], [105, 65], [105, 90], [85, 105], [65, 90], [65, 65]] def hexagon(self, points, color): """ Creates a hexagon by getting a list of points and their assigned colors according to the game board """ if color is 0: hx = self.canvas.create_polygon(points[0], points[1], points[2], points[3], points[4], points[5], fill=self.colors['gray1'], outline='black', width=2, activefill='cyan') elif color is 1: hx = self.canvas.create_polygon(points[0], points[1], points[2], points[3], points[4], points[5], fill=self.colors['yellow'], outline='black', width=2, activefill='cyan') elif color is 2: hx = self.canvas.create_polygon(points[0], points[1], points[2], points[3], points[4], points[5], fill=self.colors['red'], outline='black', width=2, activefill='cyan') elif color is 3: hx = self.canvas.create_polygon(points[0], points[1], points[2], points[3], points[4], points[5], fill=self.colors['black'], outline='black', width=2) else: hx = self.canvas.create_polygon(points[0], points[1], points[2], points[3], points[4], points[5], fill=self.colors['white'], outline='black', width=2) return hx def generate_row(self, points, colors): """ By getting a list of points as the starting point of each row and a list of colors as the dedicated color for each item in row, it generates a row of hexagons by calling hexagon functions multiple times. """ x_offset = 40 row = [] temp_array = [] for i in range(len(colors)): for point in points: temp_points_x = point[0] + x_offset * i temp_points_y = point[1] temp_array.append([temp_points_x, temp_points_y]) if colors[i] is 0: hx = self.hexagon(temp_array, 0) elif colors[i] is 1: hx = self.hexagon(temp_array, 4) else: hx = self.hexagon(temp_array, 3) row.append(hx) temp_array = [] return row def gameboard2hexagons(self, array): """ Simply gets the game_board and generates the hexagons by their dedicated colors. """ initial_offset = 20 y_offset = 40 temp = [] for i in range(len(array)): points = self.top_left_hexagon() for point in points: point[0] += initial_offset * i point[1] += y_offset * i temp.append([point[0], point[1]]) row = self.generate_row(temp, self.board[i]) temp.clear() self.hex_board.append(row) def generate_white_edge(self): """ Generates the white zones in the left and right of the board. """ init_points = self.top_left_hexagon() for pt in init_points: pt[0] -= 40 for pt in init_points: pt[0] -= 20 pt[1] -= 40 label_x, label_y = 0, 0 init_offset = 20 y_offset = 40 temp_list = [] for i in range(len(self.board)): for pt in range(len(init_points)): init_points[pt][0] += init_offset init_points[pt][1] += y_offset label_x += init_points[pt][0] label_y += init_points[pt][1] label_x /= 6 label_y /= 6 self.hexagon(init_points, 4) self.canvas.create_text(label_x, label_y, fill=self.colors['black'], font="Times 20 bold", text=chr(ord('A') + i)) label_x, label_y = 0, 0 for j in init_points: temp_list.append([j[0] + (len(self.board) + 1) * 40, j[1]]) self.hexagon(temp_list, 4) temp_list.clear() def generate_black_edge(self): """ Generates the black zones in the top and bottom of the board. """ init_points = self.top_left_hexagon() label_x, label_y = 0, 0 temp_list = [] for pt in init_points: pt[0] -= 60 pt[1] -= 40 for t in range(len(init_points)): init_points[t][0] += 40 label_x += init_points[t][0] label_y += init_points[t][1] label_x /= 6 label_y /= 6 for i in range(len(self.board)): self.hexagon(init_points, 3) self.canvas.create_text(label_x, label_y, fill=self.colors['white'], font="Times 20 bold", text=i + 1) label_x, label_y = 0, 0 for pt in init_points: temp_list.append([pt[0] + (len(self.board) + 1) * 20, pt[1] + (len(self.board) + 1) * 40]) self.hexagon(temp_list, 3) temp_list.clear() for j in range(len(init_points)): init_points[j][0] += 40 label_x += init_points[j][0] label_y += init_points[j][1] label_x /= 6 label_y /= 6 def click2play(self, event): """ Whenever any of the hexagons in the board is clicked, depending on the player turns, it changes the color of hexagon to the player assigned color. """ if self.winner() == 'none': x = self.canvas.canvasx(event.x) y = self.canvas.canvasy(event.y) idd = self.canvas.find_overlapping(x, y, x, y) idd = list(idd) if len(idd) is not 0: clicked_cell = idd[0] if any([clicked_cell in x for x in self.hex_board]): coordinated_cell = clicked_cell - self.hex_board[0][0] col = (coordinated_cell % self.size) turn = self.turn[self.game_turn_value.get()] if coordinated_cell % self.size == 0: row = int(coordinated_cell / self.size) else: row = int(coordinated_cell / self.size) cell = str(chr(65 + row)) + str(col + 1) self.move_label.configure(text=str(turn) + ' played ' + cell, justify=LEFT, height=5) if self.board[row][col] == 0: self.board[row][col] = self.game_turn_value.get() if self.game_turn_value.get() == 1: self.game_turn_value.set(2) else: self.game_turn_value.set(1) self.refresh() y = row x = col if turn[0].lower() == 'w': self.last_move = (x, y) if self.game.turn() == GameMeta.PLAYERS["white"]: self.game.play((x, y)) self.agent.move((x, y)) if self.winner() != 'none': messagebox.showinfo(" GAME OVER", " Wow, You won! \n Winner is %s" % self.winner()) return else: self.game.place_white((x, y)) self.agent.set_gamestate(self.game) if self.winner() != 'none': messagebox.showinfo(" GAME OVER", " Wow, You won! \n Winner is %s" % self.winner()) return elif turn[0].lower() == 'b': self.last_move = (x, y) if self.game.turn() == GameMeta.PLAYERS["black"]: self.game.play((x, y)) self.agent.move((x, y)) if self.winner() != 'none': messagebox.showinfo(" GAME OVER", " Wow, You won! \n Winner is %s" % self.winner()) return else: self.game.place_black((x, y)) self.agent.set_gamestate(self.game) if self.winner() != 'none': messagebox.showinfo(" GAME OVER", " Wow, You won! \n Winner is %s" % self.winner()) return else: messagebox.showinfo(" GAME OVER ", " The game is already over! Winner is %s" % self.winner()) def set_size(self, event): """ It changes the board size and reset the whole game. """ self.canvas.delete('all') self.size = self.game_size_value.get() self.game = GameState(self.size) self.agent.set_gamestate(self.game) self.board = self.game.board self.board = int_(self.board).tolist() self.last_move = None self.move_label.config(text='PLAY : CLICK A CELL ON GAME BOARD \nMCTS BOT: CLICK GENERATE', justify='left', height=5) self.refresh() def set_time(self, event) -> None: """ It changes the time for CPU player to think and generate a move. """ self.time = self.game_time_value.get() print('The CPU time = ', self.time, ' seconds') def set_agent(self, event) -> None: """ It changes the time for CPU player to think and generate a move. """ agent_num = self.switch_agent_value.get() self.agent_name = self.agent_type[agent_num] self.agent = self.AGENTS[self.agent_name](self.game) self.agent_show.config(font=('Calibri', 14, 'bold'), justify=LEFT, text='Agent Policy: ' + self.agent_name + '\n') def winner(self) -> str: """ Return the winner of the current game (black or white), none if undecided. """ if self.game.winner == GameMeta.PLAYERS["white"]: return "white" elif self.game.winner == GameMeta.PLAYERS["black"]: return "black" else: return "none" def click_to_bot_play(self, event): """ By pushing the generate button, It produces an appropriate move by using monte carlo tree search algorithm for the player which turn is his/hers! . """ if self.winner() == 'none': self.agent.search(self.time) num_rollouts, node_count, run_time = self.agent.statistics() move = self.agent.best_move() # the move is tuple like (3, 1) self.game.play(move) self.agent.move(move) row, col = move # Relating the 'move' tuple with index of self.board self.board[col][row] = self.game_turn_value.get() if self.game_turn_value.get() == 1: # change the turn of players self.game_turn_value.set(2) else: self.game_turn_value.set(1) self.refresh() player = self.turn[self.game_turn_value.get()] cell = chr(ord('A') + move[1]) + str(move[0] + 1) self.move_label.config(font=('Calibri', 15, 'bold'), justify='left', text=str(num_rollouts) + ' Game Simulations ' + '\n' + 'In ' + str(run_time) + ' seconds ' + '\n' + 'Node Count : ' + str(node_count) + '\n' + player + ' played at ' + cell, height=5) print('move = ', cell) if self.winner() != 'none': messagebox.showinfo(" GAME OVER", " Oops!\n You lost! \n Winner is %s" % self.winner()) else: messagebox.showinfo(" GAME OVER", " The game is already over! Winner is %s" % self.winner()) def refresh(self): """ Delete the whole world and recreate it again """ self.canvas.delete('all') self.hex_board.clear() self.gameboard2hexagons(self.board) self.generate_black_edge() self.generate_white_edge() def reset(self, event): """ By clicking on the Reset button game board would be cleared for a new game """ self.game = GameState(self.game.size) self.agent.set_gamestate(self.game) self.set_size(event) self.last_move = None self.game_turn_value.set(1) self.move_label.config(text='PLAY : CLICK A CELL ON GAME BOARD \nMCTS BOT: CLICK GENERATE', justify='left', height=5)
class MainView(Tk): class Constants: title = "Cambio de Moneda" heigth = 100 width = 550 input_width = 250 separator_width = 50 center = N + S + E + W left = W event = "<Button-1>" default_from_currency = "USD" default_result_currency = "MXN" convert_text = "Convertir" separator_text = "▶" def __init__(self, convert_handler=None): super().__init__() self.__convert_handler = convert_handler self.title(self.Constants.title) self.maxsize(width=self.Constants.width, height=self.Constants.heigth) self.minsize(width=self.Constants.width, height=self.Constants.heigth) self.__configure_grid() self.__configure_UI() def __configure_grid(self): self.grid_rowconfigure(0, weight=True) self.grid_rowconfigure(1, weight=True) self.grid_rowconfigure(2, weight=True) self.grid_columnconfigure(0, minsize=self.Constants.input_width) self.grid_columnconfigure(2, minsize=self.Constants.input_width) self.grid_columnconfigure(1, minsize=self.Constants.separator_width) def __configure_UI(self): self.currency_combo = ttk.Combobox(self) self.currency_combo["values"] = CurrencyManager.make_list_of_currency( self.Constants.default_from_currency) self.currency_combo.current(0) self.currency_combo.grid(row=0, column=0, sticky=self.Constants.left) self.result_currency_combo = ttk.Combobox(self) self.result_currency_combo[ "values"] = CurrencyManager.make_list_of_currency( self.Constants.default_result_currency) self.result_currency_combo.current(0) self.result_currency_combo.grid(row=0, column=2, sticky=self.Constants.left) separator_label = Label(self) separator_label.configure(text=self.Constants.separator_text) separator_label.grid(row=1, column=1, sticky=self.Constants.center) self.__result_label = Label(self) self.__result_label.configure(text="0") self.__result_label.grid(row=1, column=2, sticky=self.Constants.left) self.__convert_button = Button(self) self.__convert_button.configure(text=self.Constants.convert_text) self.__convert_button.grid(row=2, column=2, sticky=self.Constants.center) self.__convert_button.bind(self.Constants.event, self.__did_tap_convert) vcmd = (self.register(self.__checkNumberOnly), '%d', '%P') self.__currency_input = Entry(self, validate="key", validatecommand=vcmd) self.__currency_input.grid(row=1, column=0, sticky=self.Constants.center) def __did_tap_convert(self, event): if self.__convert_handler is None: return try: ammount_to_convert = float(self.__currency_input.get()) except ValueError: return else: self.__convert_handler(self.currency_combo.get(), self.result_currency_combo.get(), ammount_to_convert) def update_result(self, text): self.__result_label.configure(text=text) def __checkNumberOnly(self, action, value_if_allowed): if action != '1': return True try: float(value_if_allowed) except ValueError: return False else: return True def get_from_currency(self): return self.currency_combo.get()
def __init__(self, parent, controller): Frame.__init__(self, parent) self.controller = controller key = StringVar() self.columnconfigure(0, weight=1, pad=5) self.columnconfigure(1, weight=1, pad=5) self.rowconfigure(0, pad=5) self.rowconfigure(1, pad=5) self.rowconfigure(2, weight=1, pad=5) self.rowconfigure(3, pad=5) self.rowconfigure(4, weight=1, pad=5) # Title bbutton = Button(self, text="<", command=lambda: controller.show_frame("MainPage")) bbutton.grid(row=0, column=0, padx=10, sticky=W) title = Label(self, text="Vigenere Cipher") title.grid(row=0, columnspan=2, padx=10) # Shift Key sentry = Entry(self, textvariable=key) sentry.grid(row=1, column=0, columnspan=2, padx=10, sticky=W + E) sentry.insert(0, "Key") # Text input tinput = Text(self, wrap=WORD) tinput.grid(row=2, columnspan=2, padx=10, pady=10, sticky=N + E + S + W) scrolli = Scrollbar(self, command=tinput.yview) tinput.configure(yscrollcommand=scrolli.set) scrolli.grid(row=2, column=1, pady=10, sticky=N + S + E) tinput.insert(1.0, "Input") tinput.bind("<Control-Key-a>", select_all) # select-all Windows/Linux tinput.bind("<Command-Key-a>", select_all) # select-all Mac # Encode/Decode buttons ebutton = Button(self, text="Encode", width=15) ebutton.grid(row=3, column=0, padx=10, sticky=E) ebutton.configure(command=lambda: self.encode_prep( tinput.get(1.0, 'end-1c'), key.get())) dbutton = Button(self, text="Decode", width=15) dbutton.grid(row=3, column=1, padx=10, sticky=W) dbutton.configure(command=lambda: self.decode_prep( tinput.get(1.0, 'end-1c'), key.get())) # Output box self.output = Text(self, wrap=WORD) self.output.grid(row=4, columnspan=2, padx=10, pady=10, sticky=N + E + S + W) self.output.bind("<1>", lambda event: self.output.focus_set()) scrollo = Scrollbar(self, command=self.output.yview) scrollo.grid(row=4, column=1, pady=10, sticky=N + S + E) self.output.configure(yscrollcommand=scrollo.set) self.output.insert(1.0, "Output") self.output.configure(state="disabled") self.output.bind("<Control-Key-a>", select_all) # select-all Windows/Linux self.output.bind("<Command-Key-a>", select_all) # select-all Mac
rewrite("usable/compare.cpp", compare.get(1.0, END)) tex.configure(state='disabled') checkbox.configure(state='disabled') exit.configure(state='normal') source.configure(state='disabled') execute.configure(state='disabled') spin.configure(state='disabled') compare.configure(state='disabled') generator.configure(state='disabled') if (var1.get() == 1): p = threading.Thread(target=run, args=(str(0), True), name=str(0)) p.start() workers.append(p) printf("Started Thread: 1") else: for i in range(int(spin.get())): p = threading.Thread(target=run, args=(str(i)), name=str(i)) p.start() workers.append(p) printf("Started Thread: " + str(i + 1)) return execute = Button(mainwin, text="Execute", command=printer) execute.grid(row=6, column=18, columnspan=5, sticky="EW", pady=(0, 25)) exit = Button(mainwin, text="Stop", command=exitt) exit.grid(row=6, column=25, columnspan=3, sticky="EW", pady=(0, 25)) exit.configure(state='disabled') mainwin.protocol("WM_DELETE_WINDOW", on_closing) mainwin.mainloop()
class PiAudio(Tk): def __init__(self): Tk.__init__(self) self.nom_carte = 'sysdefault:CARD=U0x46d0x825' self.fichier_courant = None self.stop_thread = False self.options_fichier = {'filetypes': [('Fichiers .wav', '.wav')]} self.creer_composant() self.mainloop() def creer_composant(self): self.columnconfigure(0, weight=1) self.rowconfigure(0, weight=1) self.frame_haut = Frame(self) self.frame_haut.grid(row=0) self.frame_bas = Frame(self) self.frame_bas.grid(row=1) self.bouton_ouvrir = Button(self.frame_haut, text='Lire\nun enregistrement', command=lambda: self.ouvrir()) self.bouton_ouvrir.grid(row=0, column=0) self.bouton_enreg_sous = Button( self.frame_haut, text='Enregistrer\ndu son', command=lambda: self.enregistrer_sous()) self.bouton_enreg_sous.grid(row=0, column=1) self.lire_image = PhotoImage(file='resources/lire.png'), self.bouton_lire = Button(self.frame_bas, image=self.lire_image, command=lambda: self.lire()) self.bouton_lire.grid(row=1, column=0) self.bouton_lire.configure(state='disabled') self.stop_image = PhotoImage(file='resources/stop.png'), self.bouton_stop = Button(self.frame_bas, image=self.stop_image, command=lambda: self.stop()) self.bouton_stop.grid(row=1, column=1) self.bouton_stop.configure(state='disabled') self.enreg_image = PhotoImage(file='resources/enreg.png'), self.bouton_enreg = Button(self.frame_bas, image=self.enreg_image, command=lambda: self.enregistrer()) self.bouton_enreg.grid(row=1, column=2) self.bouton_enreg.configure(state='disabled') self.title(self.__class__.__name__) def ouvrir(self): fichier = askopenfilename(**self.options_fichier) if fichier: self.fichier_courant = fichier self.bouton_lire.configure(state='active') self.bouton_stop.configure(state='active') self.bouton_enreg.configure(state='disabled') def enregistrer_sous(self): fichier = asksaveasfilename(**self.options_fichier) if fichier: self.fichier_courant = fichier self.bouton_lire.configure(state='disabled') self.bouton_stop.configure(state='active') self.bouton_enreg.configure(state='active') def lire(self): self.stop_thread = False t = threading.Thread(target=self._lire) t.start() def _lire(self): with wave.open(self.fichier_courant, 'rb') as w: output = alsaaudio.PCM() output.setchannels(w.getnchannels()) output.setrate(w.getframerate()) output.setformat(alsaaudio.PCM_FORMAT_S16_LE) output.setperiodsize(1024) self.stop_thread = False while True: data = w.readframes(320) if not data or self.stop_thread: break output.write(data) def stop(self): self.stop_thread = True self.bouton_lire.configure(state='active') self.bouton_enreg.configure(state='active') def enregistrer(self): self.stop_thread = False self.bouton_lire.configure(state='disabled') self.bouton_enreg.configure(state='disabled') t = threading.Thread(target=self._enregistrer) t.start() def _enregistrer(self): entree = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NONBLOCK, self.nom_carte) entree.setchannels(1) entree.setrate(44100) entree.setformat(alsaaudio.PCM_FORMAT_S16_LE) entree.setperiodsize(1024) with wave.open(self.fichier_courant, 'w') as w: w.setnchannels(1) w.setsampwidth(2) w.setframerate(44100) while True: _, data = entree.read() w.writeframes(data) if self.stop_thread: break
label = Label(instance, text="Distância(metros)") label.pack() label.configure(background='#b2c1ff') entry = Entry(instance) entry.pack() entry.insert(INSERT, '') entry.configure(width=200) # Print the contents of entry widget to console def select_dir(): t = threading.Thread(target=selectDirAction, args=( labelText, entry, )) t.start() # Create a button that will print the contents of the entry button = Button(instance, text='Selecionar diretorio', command=select_dir) button.configure(width=200, background='#c6b6e0') button.pack() #instance.eval('tk::PlaceWindow %s center' % instance.winfo_pathname(instance.winfo_id())) instance.resizable(False, False) label2 = Label(instance, textvariable=labelText) label2.pack() label2.configure(background='#cccccc') instance.mainloop()
class Application: def __init__(self, master,name): master.geometry("600x450+405+183") self.TPanedwindow1 = ttk.Panedwindow(master, orient="horizontal") self.TPanedwindow1.place(relx=0.0, rely=0.0, relheight=0.98 , relwidth=1.01) self.TPanedwindow1_p1 = ttk.Labelframe(width=405) self.TPanedwindow1.add(self.TPanedwindow1_p1) self.TPanedwindow1_p2 = ttk.Labelframe() self.TPanedwindow1.add(self.TPanedwindow1_p2) self.txtMsgs = tk.Text(self.TPanedwindow1_p1,state='disabled') self.txtMsgs.place(relx=0.0, rely=0.0, relheight=0.93, relwidth=1.0, y=-12 , h=12) self.txtMsgs.configure(background="white") self.txtMsgs.configure(font="TkTextFont") self.txtMsgs.configure(foreground="black") self.txtMsgs.configure(highlightbackground="#d9d9d9") self.txtMsgs.configure(highlightcolor="black") self.txtMsgs.configure(insertbackground="black") self.txtMsgs.configure(selectbackground="#c4c4c4") self.txtMsgs.configure(selectforeground="black") self.txtMsgs.configure(width=405) self.txtMsg = tk.Entry(self.TPanedwindow1_p1) self.txtMsg.place(relx=0.0, rely=0.95,height=20, relwidth=0.73) self.txtMsg.configure(background="white") self.txtMsg.configure(disabledforeground="#a3a3a3") self.txtMsg.configure(font="TkFixedFont") self.txtMsg.configure(foreground="#000000") self.txtMsg.configure(highlightbackground="#d9d9d9") self.txtMsg.configure(highlightcolor="black") self.txtMsg.configure(insertbackground="black") self.txtMsg.configure(selectbackground="#c4c4c4") self.txtMsg.configure(selectforeground="black") self.btnSend = Button(self.TPanedwindow1_p1, command = self.btnSendClicked) self.btnSend.place(relx=0.74, rely=0.94, height=24, width=107, y=3) self.btnSend.configure(activebackground="#d9d9d9") self.btnSend.configure(activeforeground="#000000") self.btnSend.configure(background="#d9d9d9") self.btnSend.configure(disabledforeground="#a3a3a3") self.btnSend.configure(foreground="#000000") self.btnSend.configure(highlightbackground="#d9d9d9") self.btnSend.configure(highlightcolor="black") self.btnSend.configure(pady="0") self.btnSend.configure(text='Send') self.list = Listbox(self.TPanedwindow1_p2) self.list.place(relx=0.0, rely=0.0, relheight=1.0, relwidth=1.0 , y=-12, h=12) self.list.configure(background="white") self.list.configure(disabledforeground="#a3a3a3") self.list.configure(font="TkFixedFont") self.list.configure(foreground="#000000") self.list.configure(highlightbackground="#d9d9d9") self.list.configure(highlightcolor="black") self.list.configure(selectbackground="#c4c4c4") self.list.configure(selectforeground="black") self.list.configure(width=134) #self.btnSend.bind("<Button-1>", self.btnSendClicked) self.list.bind('<<ListboxSelect>>', self.listBoxSelectionChanged) self.name = name self.startBroadCasting() # start broadcasting that i am online # Send button click event def btnSendClicked(self): pass # list box selection chnaged event to update the chat def listBoxSelectionChanged(self,event): try: try: self.txtMsgs.delete("1.0",END) # clear the chat area except Exception as e : pass peerName = str(self.list.get(ANCHOR)) # get current selected peer name peerName = peerName.lower() if(peerName in peersChatList.keys()): self.txtMsgs.insert(END,peersChatList[peerName]) # update chat else: self.txtMsgs.insert(END,"") except Exception as e: pass # one of the peers that is started first will become UDP server that listens broadcast request and handles whos online class UDPServerThread(threading.Thread): def __init__(self, threadID, name,listBoxClients): threading.Thread.__init__(self) self.threadID = threadID self.name = name self.listBoxClients = listBoxClients def run(self): print("Starting " + self.name) self.serverSide() # to handle udp connections def serverSide(self): name = self.name address = ('', 54545) server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1) server_socket.bind(address) while True: # keep listening print("Listening") try: recv_data, addr = server_socket.recvfrom(2048) # get data from socket sender_ip = addr[0] # get sender ip data_received = recv_data.decode() # get data print(sender_ip,':',data_received) if data_received.lower() in peersList.keys() or data_received.lower() == name.lower(): # check if name already exists ask sender to change name server_socket.sendto("Invalid Name".encode(), addr) continue server_socket.sendto(name.encode(), addr) # send my name to connecting client time.sleep(1) server_socket.sendto(key.encode(),addr) # send key for encrypting/decrypting for peer in peersList.keys(): # tell each available peer that a new client has arrived so that they can update their list server_socket.sendto(str((peer.lower(),peersList[peer])).encode(),addr) for sck in udpSockets: # send other available client details to new client try: sck[0].sendto(str((data_received,sender_ip)).encode(),sck[1]) except : pass udpSockets.append((server_socket,addr)) peersList[data_received.lower()] = sender_ip self.listBoxClients.insert(END,data_received) # add client in list except Exception as e: pass # this class handles UDP thread functionality, i.e when a new client arrives UDP server will broadcast a message and this class handles it and updates its list. class UDPClientThread(threading.Thread): def __init__(self, threadID, name,listBoxClients,client_socket): threading.Thread.__init__(self) self.threadID = threadID self.listBoxClients = listBoxClients self.name = name self.client_socket = client_socket def run(self): print("Starting " + self.name) self.clientSide() # this method handles the udp connections def clientSide(self): while True: try: self.client_socket.settimeout(1000) peer_data,sender_address = self.client_socket.recvfrom(2048) # get data sent by udp server peer = str(peer_data.decode()) # decode the data peer_name = str(peer.split(', ')[0].replace('(','')).replace("'","") # get peerName peer_addr = str(peer.split(', ')[1].replace(')','')).replace("'","") # get perrAddress peersList[peer_name.lower()] = peer_addr self.listBoxClients.insert(END,peer_name.lower()) # add client in list except Exception as e: pass # this function starts broadcasting and if a UDP server is available connect to it otherwise start a server def startBroadCasting(self): address = ('<broadcast>', 54545) client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) client_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) global key name = self.name client_socket.sendto(name.encode(), address) # send the name to server try: # try to connect to a broadcast server if available client_socket.settimeout(5) recv_data, addr = client_socket.recvfrom(2048) # get the message from server while str(recv_data.decode()) == "Invalid Name": # if server says its invaild name then ask to re input the name name = input("Name already taken, Enter Naw name = ") client_socket.sendto(name.encode(), address) recv_data, addr = client_socket.recvfrom(2048) peersList[recv_data.decode().lower()] = addr[0] # add the server in peer list self.list.insert(END,recv_data.decode().lower()) # update the listBox recv_data, addr = client_socket.recvfrom(2048) # get key from server key = recv_data.decode() self.UDPClientThread(1, name,self.list, client_socket).start() #starts udp client except Exception as e: # if server is not available start udp server key = genKey(500) # generate key self.UDPServerThread(2, name,self.list).start()
class RunPage(Frame): def __init__(self, parent, controller): Frame.__init__(self, parent) self.controller = controller self.reserve_time = StringVar() self.reserve_date = StringVar() self.success = StringVar() self.success.set("No") self.counter = IntVar() self.counter.set(0) self.run_flag = IntVar() self.run_flag.set(0) self.T = {} self.message_count_down = False self.show_notice = True self.successed_info = [] self.Config_Path = self.controller.Config_Path self.Cookie_Path = self.controller.Cookie_Path self.frame_1 = LabelFrame( self, text="选择预定日期与开始时间(点击自动选择并查询)", height=100, width=630 ) self.day = 0 self.days = {} self.choose_days = {} for i in range(7): _today = date.today() self.days[i] = StringVar() _day = _today + timedelta(days=i) _day = _day.strftime("%Y-%m-%d") self.days[i].set(_day) self.choose_days[i] = Radiobutton( self.frame_1, text=self.days[i].get(), variable=self.reserve_date, value=self.days[i].get(), command=partial(self.set_reserve_date, i), ) self.times = {} self.choose_times = {} for i in range(7): self.times[i] = StringVar() _time = "{0:02d}:00:00".format(8 + 2 * i) self.times[i].set(_time) self.choose_times[i] = Radiobutton( self.frame_1, text=self.times[i].get(), variable=self.reserve_time, value=self.times[i].get(), command=self.set_reserve_time, ) # ------------------- self.frame_2 = LabelFrame(self, height=150, width=630) self.label_date_1 = Label(self.frame_2, text="预定日期:", anchor=E) self.label_date_2 = Label( self.frame_2, textvariable=self.reserve_date, anchor=W ) self.label_time_1 = Label(self.frame_2, text="预定时间段(2小时):", anchor=E) self.label_time_2 = Label( self.frame_2, textvariable=self.reserve_time, anchor=W ) self.label_couner = Label(self.frame_2, text="刷新次数:", anchor=E) self.couner_num = Label(self.frame_2, textvariable=self.counter) self.label_sucessed = Label(self.frame_2, text="是否预定成功?:", anchor=E) self.is_sucessed = Label(self.frame_2, bg="Red", textvariable=self.success) self.button_start = Button( self.frame_2, text="开始监控", bg="SpringGreen", command=self.start_job ) self.button_stop = Button( self.frame_2, text="结束", state=DISABLED, bg="LightGray", command=self.stop_job, ) self.label_notice = Label(self.frame_2, text="显示警告与提示?", anchor=E) self.button_notice = Button( self.frame_2, text="是", bg="Pink", command=self.turn_on_notice ) self.label_sucessed_place = Label(self.frame_2, text="预定成功的场地:", anchor=E) self.label_successed_place_info = Label(self.frame_2) # ------------------- self.frame_3 = LabelFrame(self, text="场地状态(点击刷新)", height=600, width=630) self.courts = {} self.show_courts = {} for i in range(8): self.courts[i] = IntVar() self.courts[i].set("") self.show_courts[i] = Button( self.frame_3, font=("Helvetica 10"), text="{}号场地".format(i + 1), command=self.get_status, ) self.create_page() def create_page(self): f_x = 56 height = 28 space = 20 f1_width = 98 f3_width = 120 self.frame_1.place( x=f_x - 30, y=space, width=700, height=height * 2 + space * 3 ) for i in range(7): self.choose_days[i].place( x=5 + f1_width * i, y=10, width=f1_width, height=height ) self.choose_times[i].place( x=5 + f1_width * i, y=20 + height, width=f1_width, height=height ) if not self.reserve_date.get(): self.choose_days[2].select() self.day = 2 if not self.reserve_time.get(): self.choose_times[6].select() self.frame_2.place( x=f_x, y=space + height * 4 + space, width=630, height=height * 3 + space * 4, ) self.label_date_1.place(x=space, y=space, width=120, height=height) self.label_date_2.place(x=space + 120, y=space, width=80, height=height) self.label_time_1.place(x=space, y=space * 2 + height, width=120, height=height) self.label_time_2.place( x=space + 120, y=space * 2 + height, width=80, height=height ) self.button_start.place(x=space + 100 + 100, y=space, width=180, height=height) self.button_stop.place( x=space + 120 + 80, y=space * 2 + height, width=180, height=height ) self.label_couner.place( x=space * 2 + 100 + 100 + 180, y=space, width=100, height=height ) self.couner_num.place( x=space * 2 + 100 + 100 + 180 + 100, y=space, width=80, height=height ) self.label_sucessed.place( x=space * 2 + 100 + 100 + 180, y=space * 2 + height, width=100, height=height, ) self.is_sucessed.place( x=space * 2 + 100 + 100 + 180 + 100, y=space * 2 + height, width=80, height=height, ) self.label_notice.place( x=space, y=space * 3 + height * 2, width=120, height=height ) self.button_notice.place( x=space + 120, y=space * 3 + height * 2, width=50, height=height ) # ------------------- self.frame_3.place(x=f_x, y=150 + 100 + space * 4, width=630, height=height * 6) for i in range(8): self.show_courts[i].place( x=10 + (f3_width + 40) * (i % 4), y=10 + (height * 2 + space) * (i // 4), width=f3_width, height=height * 2, ) self.show_courts[i].configure( background="LightGray", highlightbackground="Gold", foreground="Black" ) def job(self): _st = "07:59:30" # 开始时间 _end = "22:00:00" # 结束时间 i = 1 # 刷新次数计数器 infos = backend.load_config(self.Config_Path) while True: if self.run_flag.get() == 0: break elif _st <= strftime("%H:%M:%S", localtime()) < _end: if backend.judge_time(): dt = 2 else: dt = 20 self.update_status(True, infos, dt) else: dt = 40 self.update_status(False, infos, dt) sleep(dt) self.counter.set(i) self.couner_num.configure(textvariable=self.counter) i += 1 def start_job(self): if self.run_flag.get() == 0 and self.success.get() == "No": self.run_flag.set(1) for i in range(7): self.choose_days[i].config(state=DISABLED) self.choose_times[i].config(state=DISABLED) self.button_start.configure( bg="LightGray", state=ACTIVE, text="正在运行 ...", fg="Green" ) self.button_stop.configure(bg="Tomato", state=NORMAL, text="结束", fg="Black") # sort_place_order(self.controller) ct = int(random() * 10000) self.T[ct] = Thread(target=self.job, args=()) self.T[ct].daemon = True self.T[ct].start() elif self.success.get() == "Yes": messagebox.showinfo("提示", " =_=已经预定到啦=_= \n\n 请网页上查看! \n") else: messagebox.showinfo("提示", " =_=已经在运行啦=_= \n\n 不要重复点击! \n") def stop_job(self): if self.run_flag.get() == 1: self.run_flag.set(0) for i in range(7): self.choose_days[i].config(state=NORMAL) self.choose_times[i].config(state=NORMAL) self.button_stop.configure(bg="Gray", state=ACTIVE, text="已经停止", fg="White") self.button_start.configure( bg="SpringGreen", state=NORMAL, text="开始监控", fg="Black" ) else: messagebox.showinfo("提示", " =_=当前没有后台监控任务=_= \n\n 不要重复点击! \n ") def update_status(self, doit=False, infos=None, dt=0, mark=True): """doit 预定 flag,infos 同伴信息,dt 睡眠时间,秒;mark 用于防止递归。""" _date = self.reserve_date.get() _time = self.reserve_time.get() if _date and _time: res = {} court = backend.pian_status res, _ = backend.get_status( self.Config_Path, self.Cookie_Path, (_date, _time) ) if infos and infos["place_sort"]: sorted_keys = sort_place_order(court, infos["place_sort"]) else: sorted_keys = res.keys() for key in sorted_keys: # 2:已预约;4:不开放;1:可预约;3:使用中;5:预约中,'':不可预约 ii = int(court[key]) res_status = res[key][0] res_note = res[key][1] if res_status == 1: self.try_to_reverse(doit, infos, key, ii, _date, _time, dt) elif res_status == 2: self.show_courts[ii - 1].configure( text="{}号场地\n已被预约".format(ii), background="Black", highlightbackground="Gold", foreground="Gold", font=("Helvetica 10"), ) elif res_status == 3: self.show_courts[ii - 1].configure( text="{}号场地\n使用中".format(ii), background="Yellow", highlightbackground="Gold", foreground="Gold", font=("Helvetica 10"), ) elif res_status == 4: self.show_courts[ii - 1].configure( text="{}号场地\n不开放".format(ii), background="Gray", highlightbackground="Gold", foreground="White", font=("Helvetica 10"), ) if res_note: if len(res_note) >= 10: self.show_courts[ii - 1].configure( text="{}号场地(不开放)\n{}".format(ii, res_note), font=("Helvetica 8"), ) else: self.show_courts[ii - 1].configure( text="{}号场地(不开放)\n{}".format(ii, res_note) ) elif res_status == 5: self.show_courts[ii - 1].configure( text="{}号场地\n预约中".format(ii), background="Green", highlightbackground="Gold", foreground="Cyan", font=("Helvetica 10"), ) else: self.show_courts[ii - 1].configure( text="{}号场地\n不可预约".format(ii), background="LightGray", highlightbackground="Gold", foreground="Gold", font=("Helvetica 10"), ) if mark: self.mark_successed_place(court, _date, _time) if doit and infos: # 没有可预定或正在预定的场地,则退出预定 if res and (1, "") not in res.values() and (5, "") not in res.values(): self.stop_job() # 退出线程 messagebox.showinfo( "提示", "-" * 20 + "\n =_=没有可预约的场地=_= \n\n 请选择其他时间和日期的场地预约! \n ", ) def try_to_reverse(self, doit, infos, key, ii, _date, _time, dt): """尝试预定单个场地""" _text = "{}号场地\n可预约".format(ii) if doit and infos and self.success.get() != "Yes" and self.run_flag.get() == 1: is_ok = False try: is_ok = backend.appointment( self.Config_Path, self.Cookie_Path, key, _date, _time, infos, self.day, ) except UserWarning as UW: msg = ( "-" * 20 + "\n{}\n".format(UW) + "-" * 20 + "\n{}秒后重试".format(dt), ) if not self.message_count_down and self.show_notice: mymessage.CountDownMessageBox(self, msg) except Warning as War: _text = "{}号场地\n尝试预约,已失败".format(ii) self.stop_job() # 退出线程 msg = "-" * 20 + "\n错误信息:\n{}\n".format(War) + "-" * 20 if self.show_notice: messagebox.showerror("发生错误", msg) if is_ok: self.success.set("Yes") self.successed_info = [key, _date, _time] self.stop_job() # 退出线程 self.color_target_court(ii, _text) def color_target_court(self, ii, _text): """上色 可预约场地""" self.show_courts[ii - 1].configure( text=_text, background="Green", highlightbackground="Gold", foreground="Gold", font=("Helvetica 10"), ) def mark_successed_place(self, court, _date, _time): """标记已经预定了的场地""" if ( self.successed_info and _date == self.successed_info[1] and _time == self.successed_info[2] ): # 更新场地状态,如果显示已被预定,就表示成功预定该场地。 self.update_status(mark=False) res, _ = backend.get_status( self.Config_Path, self.Cookie_Path, (_date, _time) ) key = self.successed_info[0] if res[key][0] == 2: ii = int(court[key]) # 高亮 成功 YES self.is_sucessed.configure( textvariable=self.success, bg="LightGray", fg="Magenta" ) # 显示预定信息 success_text = str(ii) + "号 " + _date + " " + _time self.label_successed_place_info.configure( fg="Magenta", text=success_text ) self.label_sucessed_place.place( x=20 + 200, y=20 * 3 + 28 * 2, width=180, height=28 ) self.label_successed_place_info.place( x=20 + 380, y=20 * 3 + 28 * 2, width=200, height=28 ) self.show_courts[ii - 1].configure( text="{}号场地\n程序预约了该场地".format(ii), background="Magenta", highlightbackground="Green", foreground="White", font=("Helvetica 10"), ) else: self.successed_info = [] self.success.set("No") def set_reserve_date(self, day): self.update_status() self.day = day def set_reserve_time(self): self.update_status() def get_status(self): if self.run_flag.get() != 1: self.update_status() def turn_on_notice(self): if self.show_notice: self.show_notice = False self.button_notice.configure(text="否", bg="LightGray") else: self.show_notice = True self.button_notice.configure(text="是", bg="Pink")
class Lapchat: def __init__(self, master): master.title("Lapchat") master.resizable(False, False) master.geometry("400x450") #master.iconbitmap("4.ico") master.configure(bg="#3D9970") #==============Initializing communication============== self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.host = socket.gethostname() self.port = 12345 self.client = (self.host, self.port) self.top_frame = Frame(master, width=400, height=45, bg="#6666ff") self.top_frame.place(x=0, y=0) self.message_count = 1.5 self.filename = None self.message_session = Text(master, bd=3, relief="flat", font=("consolas", 12, "italic"), undo=True, wrap="word") self.message_session.config(width=35, height=15, bg="#AAAAAA", fg="blue") self.overscroll = Scrollbar(master, command=self.message_session.yview) self.overscroll.config(width=20) self.message_session["yscrollcommand"] = self.overscroll.set self.message = Entry(bg="#ffffff", width=30, bd=5, relief="flat") self.message.bind("<Return>", self.send_msg) self.send_message = Button(master, text="send", fg="blue", width=10, height=1, relief="flat") self.send_message.configure(command=self.send_msg) self.attachment = Button(master, text="File", fg="red", width=5, height=1, relief="flat") self.attachment.configure(command=self.select_file) self.file_label = Label(master, fg="#008080", font=("verdana", 7), width=50) self.message_session.place(x=40, y=50) self.overscroll.place(x=360, y=50) self.message.place(x=40, y=345) self.send_message.place(x=240, y=345) self.attachment.place(x=325, y=345) def get_filename(self, folder): self.temp_filename = folder.split("/") self.temp_filename = self.temp_filename[-1] return self.temp_filename def select_file(self, event=None): self.select_file = filedialog.askopenfilename() self.filename = self.select_file self.temp_filename = self.get_filename(self.select_file) self.file_label.config(text=self.temp_filename) self.file_label.place(x=40, y=380) def receive_sms_txt(self, receive_txt=None): print("Receiving sms again") print(self.received_message) if receive_txt: self.sm = receive_txt else: self.sm = self.received_message self.message.delete(0, "end") self.sm = "client:" + self.sm + "\n" self.message_session.insert(self.message_count, self.sm) self.message_count += 1.5 self.received_message = None def receive_file(self, size, name): with open(name, "wb") as rec_file: print(size) print(name) while size > 0: received_buffer = self.server.recv(1024) rec_file.write(received_buffer) size = size - len(received_buffer) print(size) print("File received successful") self.server.send(("ready_received").encode()) self.received_message = None def try_sample1(self): self.receive_sms_thread = threading.Thread(target=self.receive_file, args=(self.received_size, self.received_name)) self.receive_sms_thread.start() self.receive_sms_thread.join() def receive_sms(self): while True: try: self.server.connect(self.client) while True: try: print("receiving messages") self.received_message = self.server.recv(1024).decode() print(self.received_message) if "&&&" in self.received_message: self.received_message = self.received_message.split( "&&&") self.received_size = self.received_message[0] self.received_name = self.received_message[1] self.received_size = int(self.received_size) self.receive_sms_txt(receive_txt="File Received") self.try_sample1() else: if self.received_message: self.receive_sms_txt() except: continue except: continue def send_sms_txt(self, file_message=None): if file_message: self.sms = file_message else: self.sms = self.message.get() self.server.send(self.sms.encode()) self.message.delete(0, "end") self.sms = "you:" + self.sms + "\n" self.message_session.insert(self.message_count, self.sms) self.message_count += 1.5 print("Message sent succeful") def send_file(self, size): print(size) with open(self.filename, "rb") as file: size = int(size) while size > 0: buffer = file.read() self.server.send(buffer) buffer_size = len(buffer) break print("File successful sent") def receive_sms_txt(self, receive_txt=None): print("Receiving sms again") print(self.received_message) if receive_txt: self.sm = receive_txt else: self.sm = self.received_message self.message.delete(0, "end") self.sm = "client:" + self.sm + "\n" self.message_session.insert(self.message_count, self.sm) self.message_count += 1.5 self.received_message = None def try_sample(self): sendfile_thread = threading.Thread(target=self.send_file, args=(self.filesize, )) sendfile_thread.start() sendfile_thread.join() self.filename = None self.file_label.place_forget() print("Thread stopped") def send_msg(self, event=None): try: if self.filename: self.ask_send = messagebox.askyesno( "Confirm", "Do want to send message with file") print(self.ask_send) if self.ask_send: self.file_name = self.get_filename(self.filename) self.filesize = str(os.stat(self.filename).st_size) print("file size is : {}".format(self.filesize)) self.embedded_filename = self.filesize + "&&&" + self.file_name self.send_sms_txt() self.send_sms_txt(file_message="File has been sent") self.server.send(self.embedded_filename.encode()) self.try_sample() else: self.filename = None self.file_label.place_forget() self.send_sms_txt() else: self.send_sms_txt() except: self.show_error = messagebox.showerror( "No connection", "Time out , no connection found")
def main(window: tk.Wm, text_widget: tk.Text, button_widget: tk.Button, progress_var: tk.Variable, **kwargs: dict): def save_files(wav_instrument, wav_vocals): """Save output music files""" vocal_name = None instrumental_name = None save_path = os.path.dirname(base_name) # Get the Suffix Name if (not loop_num or loop_num == (total_loops - 1)): # First or Last Loop if data['stackOnly']: if loop_num == (total_loops - 1): # Last Loop if not (total_loops - 1): # Only 1 Loop vocal_name = '(Vocals)' instrumental_name = '(Instrumental)' else: vocal_name = '(Vocal_Final_Stacked_Output)' instrumental_name = '(Instrumental_Final_Stacked_Output)' elif data['useModel'] == 'instrumental': if not loop_num: # First Loop vocal_name = '(Vocals)' if loop_num == (total_loops - 1): # Last Loop if not (total_loops - 1): # Only 1 Loop instrumental_name = '(Instrumental)' else: instrumental_name = '(Instrumental_Final_Stacked_Output)' elif data['useModel'] == 'vocal': if not loop_num: # First Loop instrumental_name = '(Instrumental)' if loop_num == (total_loops - 1): # Last Loop if not (total_loops - 1): # Only 1 Loop vocal_name = '(Vocals)' else: vocal_name = '(Vocals_Final_Stacked_Output)' if data['useModel'] == 'vocal': # Reverse names vocal_name, instrumental_name = instrumental_name, vocal_name elif data['saveAllStacked']: folder_name = os.path.basename( base_name) + ' Stacked Outputs' # nopep8 save_path = os.path.join(save_path, folder_name) if not os.path.isdir(save_path): os.mkdir(save_path) if data['stackOnly']: vocal_name = f'(Vocal_{loop_num}_Stacked_Output)' instrumental_name = f'(Instrumental_{loop_num}_Stacked_Output)' elif (data['useModel'] == 'vocal' or data['useModel'] == 'instrumental'): vocal_name = f'(Vocals_{loop_num}_Stacked_Output)' instrumental_name = f'(Instrumental_{loop_num}_Stacked_Output)' if data['useModel'] == 'vocal': # Reverse names vocal_name, instrumental_name = instrumental_name, vocal_name # Save Temp File # For instrumental the instrumental is the temp file # and for vocal the instrumental is the temp file due # to reversement sf.write(f'temp.wav', wav_instrument.T, sr) appendModelFolderName = modelFolderName.replace('/', '_') # -Save files- # Instrumental if instrumental_name is not None: instrumental_path = '{save_path}/{file_name}.wav'.format( save_path=save_path, file_name= f'{os.path.basename(base_name)}_{instrumental_name}{appendModelFolderName}', ) sf.write(instrumental_path, wav_instrument.T, sr) # Vocal if vocal_name is not None: vocal_path = '{save_path}/{file_name}.wav'.format( save_path=save_path, file_name= f'{os.path.basename(base_name)}_{vocal_name}{appendModelFolderName}', ) sf.write(vocal_path, wav_vocals.T, sr) data.update(kwargs) # Update default settings global default_sr global default_hop_length global default_window_size global default_n_fft default_sr = data['sr'] default_hop_length = data['hop_length'] default_window_size = data['window_size'] default_n_fft = data['n_fft'] stime = time.perf_counter() progress_var.set(0) text_widget.clear() button_widget.configure(state=tk.DISABLED) # Disable Button vocal_remover = VocalRemover(data, text_widget) modelFolderName = determineModelFolderName() if modelFolderName: folder_path = f'{data["export_path"]}{modelFolderName}' if not os.path.isdir(folder_path): os.mkdir(folder_path) # Determine Loops total_loops = data['stackPasses'] if not data['stackOnly']: total_loops += 1 for file_num, music_file in enumerate(data['input_paths'], start=1): try: # Determine File Name base_name = f'{data["export_path"]}{modelFolderName}/{file_num}_{os.path.splitext(os.path.basename(music_file))[0]}' # --Seperate Music Files-- for loop_num in range(total_loops): # -Determine which model will be used- if not loop_num: # First Iteration if data['stackOnly']: if os.path.isfile(data['stackModel']): model_name = os.path.basename(data['stackModel']) model = vocal_remover.models['stack'] device = vocal_remover.devices['stack'] else: raise ValueError( f'Selected stack only model, however, stack model path file cannot be found\nPath: "{data["stackModel"]}"' ) # nopep8 else: model_name = os.path.basename( data[f'{data["useModel"]}Model']) model = vocal_remover.models[data['useModel']] device = vocal_remover.devices[data['useModel']] else: model_name = os.path.basename(data['stackModel']) # Every other iteration model = vocal_remover.models['stack'] device = vocal_remover.devices['stack'] # Reference new music file music_file = 'temp.wav' # -Get text and update progress- base_text = get_baseText(total_files=len(data['input_paths']), total_loops=total_loops, file_num=file_num, loop_num=loop_num) progress_kwargs = { 'progress_var': progress_var, 'total_files': len(data['input_paths']), 'total_loops': total_loops, 'file_num': file_num, 'loop_num': loop_num } update_progress(**progress_kwargs, step=0) update_constants(model_name) # -Go through the different steps of seperation- # Wave source text_widget.write(base_text + 'Loading wave source...\n') X, sr = librosa.load(music_file, data['sr'], False, dtype=np.float32, res_type='kaiser_fast') if X.ndim == 1: X = np.asarray([X, X]) text_widget.write(base_text + 'Done!\n') update_progress(**progress_kwargs, step=0.1) # Stft of wave source text_widget.write(base_text + 'Stft of wave source...\n') X = spec_utils.wave_to_spectrogram(X, data['hop_length'], data['n_fft']) if data['tta']: pred, X_mag, X_phase = vocal_remover.inference_tta( X, device=device, model=model) else: pred, X_mag, X_phase = vocal_remover.inference( X, device=device, model=model) text_widget.write(base_text + 'Done!\n') update_progress(**progress_kwargs, step=0.6) # Postprocess if data['postprocess']: text_widget.write(base_text + 'Post processing...\n') pred_inv = np.clip(X_mag - pred, 0, np.inf) pred = spec_utils.mask_silence(pred, pred_inv) text_widget.write(base_text + 'Done!\n') update_progress(**progress_kwargs, step=0.65) # Inverse stft text_widget.write( base_text + 'Inverse stft of instruments and vocals...\n') # nopep8 y_spec = pred * X_phase wav_instrument = spec_utils.spectrogram_to_wave( y_spec, hop_length=data['hop_length']) v_spec = np.clip(X_mag - pred, 0, np.inf) * X_phase wav_vocals = spec_utils.spectrogram_to_wave( v_spec, hop_length=data['hop_length']) text_widget.write(base_text + 'Done!\n') update_progress(**progress_kwargs, step=0.7) # Save output music files text_widget.write(base_text + 'Saving Files...\n') save_files(wav_instrument, wav_vocals) text_widget.write(base_text + 'Done!\n') update_progress(**progress_kwargs, step=0.8) else: # Save output image if data['output_image']: with open('{}_Instruments.jpg'.format(base_name), mode='wb') as f: image = spec_utils.spectrogram_to_image(y_spec) _, bin_image = cv2.imencode('.jpg', image) bin_image.tofile(f) with open('{}_Vocals.jpg'.format(base_name), mode='wb') as f: image = spec_utils.spectrogram_to_image(v_spec) _, bin_image = cv2.imencode('.jpg', image) bin_image.tofile(f) text_widget.write(base_text + 'Completed Seperation!\n\n') except Exception as e: traceback_text = ''.join(traceback.format_tb(e.__traceback__)) message = f'Traceback Error: "{traceback_text}"\n{type(e).__name__}: "{e}"\nFile: {music_file}\nLoop: {loop_num}\nPlease contact the creator and attach a screenshot of this error with the file and settings that caused it!' tk.messagebox.showerror(master=window, title='Untracked Error', message=message) print(traceback_text) print(type(e).__name__, e) print(message) progress_var.set(0) button_widget.configure(state=tk.NORMAL) # Enable Button return os.remove('temp.wav') progress_var.set(0) text_widget.write(f'Conversion(s) Completed and Saving all Files!\n') text_widget.write( f'Time Elapsed: {time.strftime("%H:%M:%S", time.gmtime(int(time.perf_counter() - stime)))}' ) # nopep8 button_widget.configure(state=tk.NORMAL) # Enable Button
class McAfeeEpoGUI(object): """ gui class """ def __init__(self, master): self.master = master self.master.title( _("McAfee EPO Reputation GUI (Revision: %(revision)s)") % {'revision': REVISION}) self.hashlistdict = list() try: self.localuser = getpass.getuser() except: self.localuser = "******" self.opendir_button = Button(master, text=_("Open Directory"), command=self.open_directory) self.opendir_button.grid(row=0, column=0, sticky=N + W + E) self.send_button = Button(master, text=_("Send Files to EPO"), state=DISABLED, command=self.send_to_epo) self.send_button.grid(row=1, column=0, sticky=N + W + E) self.save_button = Button(master, text=_("Save as CSV"), state=DISABLED, command=self.save_file_as_csv) self.save_button.grid(row=2, column=0, sticky=N + W + E) self.check_ssl_val = IntVar(master) self.check_ssl_val.set(VERIFY_CERTIFICATE) self.check_ssl = Checkbutton(master, text=_("Verify Server Cert"), variable=self.check_ssl_val) self.check_ssl.grid(row=10, column=0, sticky=W) self.reputation_label = Label(master, text=_("Reputation:")) self.reputation_label.grid(row=4, column=0, sticky=W) self.reputation_value = StringVar(master) self.reputation_value.set(_("Known trusted")) self.reputation_list = OptionMenu(master, self.reputation_value, *sorted(REPUTATIONVALUES.keys())) self.reputation_list.grid(row=5, column=0, sticky=W + E) self.filetype_label = Label(master, text=_("File-Types:")) self.filetype_label.grid(row=6, column=0, sticky=W) self.filetype_label_value = StringVar(master) self.filetype_label_value.set(_("exe")) self.filetype_label_options = OptionMenu( master, self.filetype_label_value, *sorted(FILETYPEVALUES.keys())) self.filetype_label_options.grid(row=7, column=0, sticky=W + E) self.infofield = Text(master) self.infofield.grid(row=0, column=1, rowspan=40, sticky=W + E) self.infofield.insert( INSERT, _("McAfee EPO Reputation GUI \n\nfor setting reputation values for all the files " "in a chosen directory\n\n")) self.infofield.insert(INSERT, _('Steps:\n')) self.infofield.insert(INSERT, _('1.) Open directory\n')) self.infofield.insert(INSERT, _('2.) Optional: change default values\n')) self.infofield.insert( INSERT, _('3.) Optional: send file hashes to EPO server\n')) self.infofield.insert( INSERT, _('4.) Optional: download hashes as csv file\n\n\n')) self.infofield.insert( INSERT, _('Current user: %(username)s\n') % {"username": self.localuser}) self.infofield.configure(state=DISABLED) self.statusbar = StatusBar(master) self.statusbar.grid(row=40, column=1, sticky=W + E) self.statusbar.set(_("Ready for loading files")) self.userurl_label = Label(master, text=_("EPO-URL:")) self.userurl_label.grid(row=11, column=0, sticky=W) self.userurl_value = Entry(master) self.userurl_value.insert(0, URL) self.userurl_value.grid(row=12, column=0, sticky=W + E) self.username_label = Label(master, text=_("EPO-Username:"******"EPO-Password:"******"*") self.userpass_value.insert(0, PASSWORD) self.userpass_value.grid(row=16, column=0, sticky=W + E) def open_directory(self): """ open directory """ folder = askdirectory(title=_("Choose a directory")) if folder: self.hashlistdict = list() self.get_values( folder, REPUTATIONVALUES.get(self.reputation_value.get(), DEFAULTREPUTATION), FILETYPEVALUES.get(self.filetype_label_value.get(), [])) self.infofield.configure(state=NORMAL) self.infofield.delete("1.0", END) if len(self.hashlistdict) == 0: messagebox.showerror(_("File"), _("No suitable files found")) self.send_button.configure(state=DISABLED) self.save_button.configure(state=DISABLED) return self.infofield.insert( INSERT, _("Number of files found: %(numberoffiles)s\n\n") % {"numberoffiles": len(self.hashlistdict)}) for item in self.hashlistdict: md5 = base64.b64decode(item["md5"]).hex() sha1 = base64.b64decode(item["sha1"]).hex() self.infofield.insert( INSERT, "%s\n\tmd5: %s\n\tsha1:%s\n" % (item["name"], md5, sha1)) self.infofield.configure(state=DISABLED) self.send_button.configure(state=NORMAL) self.save_button.configure(state=NORMAL) # print(REPUTATIONVALUES.get(self.reputation_value.get(), REPUTATIONDEFAULT)) else: messagebox.showerror(_("Directory"), _("Please pick a directory")) def send_to_epo(self): """ send hash values to EPO server """ # get SSL check value verifyssl = self.check_ssl_val.get() == 1 # update reputation value reputation = REPUTATIONVALUES.get(self.reputation_value.get(), DEFAULTREPUTATION) for item in self.hashlistdict: item["reputation"] = reputation # get access credentials epo_url = self.userurl_value.get() epo_username = self.username_value.get() epo_password = self.userpass_value.get() # check if at least there are values if not epo_url or not epo_username or not epo_password: messagebox.showerror(_("Error"), _("EPO credentials missing")) return # create client client = mcafee_epo.Client(epo_url, epo_username, epo_password, verify=verifyssl, timeout=TIMEOUT) # send hashes try: # if there are more than HASHESPERREQUEST hashes, send them in multiple requests if len(self.hashlistdict) > HASHESPERREQUEST: for part in range(0, len(self.hashlistdict), HASHESPERREQUEST): self.statusbar.set( _("Sending hashes %(current)d of %(total)d") % dict(current=part, total=len(self.hashlistdict))) result = client('tie.setReputations', params=dict(fileReps=json.dumps( self.hashlistdict[part:part + HASHESPERREQUEST]))) else: result = client( 'tie.setReputations', params=dict(fileReps=json.dumps(self.hashlistdict))) except Exception as exception: messagebox.showerror( _("Error"), _("Error sending hashes: %(error)s") % {"error": exception}) else: self.statusbar.set(_("Hashes sent to EPO")) if result: messagebox.showinfo(_("Success"), _("Hashes successfully sent to EPO")) else: messagebox.showinfo(_("Error"), _("Something went wrong")) def save_file_as_csv(self): """ save file hashes as csv file :return: """ timestamp = datetime.datetime.now().strftime("%Y%m%d") filepointer = asksaveasfile(defaultextension=".csv", initialfile="output_%s.csv" % (timestamp), filetypes=((_("CSV Files"), "*.csv"), )) if filepointer: filepointer.write( _("filename;comment;md5 hash;sha1 hash;reputation\n")) for item in self.hashlistdict: md5 = base64.b64decode(item["md5"]).hex() sha1 = base64.b64decode(item["sha1"]).hex() filepointer.write("%s;%s;%s;%s;%s\n" % (item["name"], item["comment"], md5, sha1, item["reputation"])) filepointer.close() else: messagebox.showerror(_("File"), _("Please specify a filename")) def get_values(self, folder, reputation, filetypes): """ get all the files for the folder and set reputation value :param folder: chosen by askdirectory popup :param reputation: chosen from gui value :param filetypes: chosen from gui value """ for root, _, files in os.walk(folder): for file in files: if len(filetypes) > 0 and file.split(".")[-1] not in filetypes: continue fname = root + "/" + file filecontent = "" with open(fname, 'rb') as filepointer: filecontent = filepointer.read() md5 = hashlib.md5(filecontent).digest() sha1 = hashlib.sha1(filecontent).digest() fdict = { "name": "%s" % file, "comment": "%s %s@WebAPI" % (datetime.datetime.now().strftime("%Y-%m-%d"), self.localuser), "md5": base64.b64encode(md5).decode("utf-8"), "sha1": base64.b64encode(sha1).decode("utf-8"), "reputation": reputation } self.hashlistdict.append(fdict)
class ExamineProduct: def __init__(self, service, product, top_level): self.top_level = top_level self.service = service self.product = product self.img = None self.monitor_bu = None self.monitor_label = None self.figure = None self.current_price_label = None self.best_price_label = None self.init_gui() def init_gui(self): self.top_level.geometry("600x750") Label(self.top_level, text=self.product.title).grid(row=0, column=0, columnspan=2) # May want to customize in near future link_label = Label(self.top_level, text="Emag - Link to shop", fg="blue", cursor="hand2") link_label.grid(row=1, column=0, columnspan=2) link_label.bind('<Button-1>', self.open_browser) img_data = self.service.get_image(self.product._id) self.img = ImageTk.PhotoImage( Image.open(BytesIO(img_data)).resize((150, 150))) panel = Label(self.top_level, image=self.img) panel.grid(row=2, column=0, rowspan=2) self.current_price_label = Label(self.top_level) self.current_price_label.grid(row=3, column=1) self.best_price_label = Label(self.top_level) self.best_price_label.grid(row=2, column=1) self.set_price_labels() monitoring_status = 'This device is being monitored' if self.product.monitored else 'This device is not being monitored' fg = 'green' if self.product.monitored else 'red' self.monitor_label = Label(self.top_level, text=monitoring_status, fg=fg) self.monitor_label.grid(row=4, column=1) text_bu = 'Turn off' if self.product.monitored else 'Turn on' self.monitor_bu = Button(self.top_level, text=text_bu, command=self.set_monitoring) self.monitor_bu.grid(row=4, column=0) self.set_price_plot() Button(self.top_level, text='Remove product').grid(row=6, column=0, columnspan=2) for x in range(7): Grid.rowconfigure(self.top_level, x, weight=1) for x in range(2): Grid.columnconfigure(self.top_level, x, weight=1) def set_price_plot(self): if self.figure is not None: self.figure.clf() history = self.service.get_all_history(self.product._id) # Plotting part self.figure = plt.Figure(figsize=(5, 4), dpi=100) ax = self.figure.add_subplot(111) # Tkinter widget line = FigureCanvasTkAgg(self.figure, self.top_level) line.get_tk_widget().grid(row=5, column=0, columnspan=2) if len(history) > 0: data = { 'Date': [h[0] for h in history], 'Price (ron)': [h[1] for h in history] } df = DataFrame(data, columns=['Date', 'Price (ron)']) df = df[['Date', 'Price (ron)']].groupby('Date').sum() df.plot(kind='line', legend=True, ax=ax, color='r', marker='o', fontsize=10) ax.set_title('Price evolution') def set_monitoring(self): self.service.set_monitoring_product(self.product._id, not self.product.monitored) def open_browser(self, event): webbrowser.open_new(self.product.link) def set_price_labels(self): current_price = self.product.current_price current_price_str = 'Current price: ' + str( current_price) + ' ron (' + str( self.product.current_price_date.strftime("%Y-%m-%d %H:%M:%S") ) + ')' if current_price != -1 else 'No data record' self.current_price_label.config(text=current_price_str) lowest_price = self.product.best_price lowest_price_str = 'Best price' + str(lowest_price) + ' ron (' + str( self.product.best_price_date.strftime("%Y-%m-%d %H:%M:%S") ) + ')' if lowest_price != -1 else 'No data record' self.best_price_label.config(text=lowest_price_str) def update(self, data, event): if event == Events.MONITORING: if data[0] == self.product._id: self.product.monitored = data[1] self.monitor_bu.configure( text='Turn off' if self.product.monitored else 'Turn on') self.monitor_label.configure( text='This device is being monitored' if self.product. monitored else 'This device is not being monitored') self.monitor_label.configure( fg='green' if self.product.monitored else 'red') elif event == Events.SCAN: if self.product.monitored: self.product = self.service.find_product(self.product._id) self.set_price_labels() self.set_price_plot() else: print('examine_product: update() event case not implemented')
class ReadFromFile(Frame): def __init__(self, parent, controller): Frame.__init__(self, parent) self.controller = controller self.link_first = True self.items = [] self.place(relx=0.0, rely=0.0, relheight=0.62, relwidth=0.72) self.configure(relief=GROOVE) self.configure(borderwidth="2") label_top = Label(self) label_top.place(relx=0.42, rely=0.03, height=21, width=105) label_top.configure(text="Select a file to read") self.file_select = Button(self, command=self.fopen) self.file_select.place(relx=0.43, rely=0.14, height=34, width=97) self.file_select.configure(text="Select file") self.back = Button(self, command=lambda: controller.show_frame('Main')) self.back.place(relx=0.8, rely=0.87, height=34, width=97) self.back.configure(text="Go back") self.delimeter = Entry(self) self.delimeter.place(relx=0.02, rely=0.11, relheight=0.06, relwidth=0.21) self.delimeter.insert(0, ' -<>- ') label_delim = Label(self) label_delim.place(relx=0.02, rely=0.03, height=21, width=57) label_delim.configure(text="Delimeter") self.switch_label = Label(self) self.switch_label.place(relx=0.73, rely=0.31, height=21, width=38) self.switch_label.configure(text="Link") self.switch_label2 = Label(self) self.switch_label2.place(relx=0.9, rely=0.31, height=21, width=38) self.switch_label2.configure(text="Name") self.change_order = Button(self, command=self.switch_order) self.change_order.place(relx=0.82, rely=0.31, height=24, width=32) self.change_order.configure(text="<->") name_or_link = Label(self) name_or_link.place(relx=0.75, rely=0.19, height=21, width=97) name_or_link.configure(text="Name or link first") self.items_text = Text(self) self.items_text.place(relx=0.02, rely=0.5, relheight=0.46, relwidth=0.76) self.items_text.configure(wrap=tk.WORD) label_items = Label(self) label_items.place(relx=0.35, rely=0.42, height=21, width=35) label_items.configure(text="Items") self.commit_btn = Button(self, command=self.commit) self.commit_btn.place(relx=0.83, rely=0.64, height=34, width=67) self.commit_btn.configure(text="Commit") self.Label12 = Label(self) self.Label12.place(relx=0.02, rely=0.19, height=21, width=88) self.Label12.configure(text="Link formatting (optional)") self.link_part1 = Entry(self, fg='grey') self.link_part1.place(relx=0.02, rely=0.28, relheight=0.06, relwidth=0.37) self.link_part1.insert(0, "Start of the link here") self.link_part1.bind('<Button-1>', lambda event: greytext(self.link_part1)) self.link_part2 = Entry(self, fg='grey') self.link_part2.place(relx=0.02, rely=0.36, relheight=0.06, relwidth=0.37) self.link_part2.insert(0, "End of the link here") self.link_part2.bind('<Button-1>', lambda event: greytext(self.link_part2)) def fopen(self): filename = askopenfilename() if filename == '': return self.items.clear() self.items_text.delete(1.0, 'end') with open(filename, encoding='utf-8-sig') as f: lines = f.read().splitlines() delim = self.delimeter.get() for line in lines: try: link, name = line.split(delim, 1) if not self.link_first: name, link = link, name if '{DELETED} ' in name[:13]: continue s, e = self.get_link_formatting() link = s + link + e self.items += [(link, name)] self.items_text.insert('end', ("name: " + name + "\nlink: " + link + '\n\n')) except ValueError: print("Something went wrong: ", line) def get_link_formatting(self): link1, link2 = self.link_part1, self.link_part2 start = '' end = '' if link1.cget('fg') != 'grey': start = link1.get() if link2.cget('fg') != 'grey': end = link2.get() return start, end def switch_order(self): s1, s2 = self.switch_label, self.switch_label2 text1, text2 = s1.cget('text'), s2.cget('text') s1.configure(text=text2) s2.configure(text=text1) self.link_first = not self.link_first def commit(self): for item in self.items: self.controller.add_item(item[0], item[1]) print('Items added')
class WindowApp(object): """ The PDF Stampede app window """ def __init__(self, resizable=(True, True), geometry=(620, 220)): assert (isinstance(resizable, (tuple, list))) assert (isinstance(geometry, (tuple, list))) self.root = Tk() self.config = configparser.ConfigParser() self.config_file_name = "config.ini" self.config.read(self.config_file_name) self.default_case = StringVar(value=self.config["DEFAULT"].get("case", "CASE")) self.default_team = StringVar(value=self.config["DEFAULT"].get("team", "TEAM")) self.default_series = StringVar() self.default_last_index = StringVar() self.root.title("The Stampede") self.root.resizable(width=resizable[0], height=resizable[1]) self.root.geometry('{}x{}'.format(geometry[0], geometry[1])) self.root.minsize(geometry[0], geometry[1]) self.root.maxsize(geometry[0]+200, geometry[1]) self.file_name = StringVar() self.file_name.trace("w", self.file_name_changed) self.stamp_button = None self.add_widgets() self.add_menus() self.center(self.root) def add_widgets(self): # File frame = Frame(self.root) frame.pack(side=TOP, fill=X, expand=True, ipady=5) file_label = Label(frame, text="PDF File", width=10) file_label.pack(side=LEFT, padx=5, pady=5) file_entry = Entry(frame, state=DISABLED, textvariable=self.file_name) file_entry.pack(padx=5, side=LEFT, fill=X, expand=True) file_button = Button(frame, text="Browse...", command=self.choose_pdf) file_button.pack(padx=5, side=RIGHT) # Case frame = Frame(self.root) frame.pack(side=TOP, fill=X, expand=True) case_label = Label(frame, text="Case", width=10) case_label.pack(side=LEFT, padx=5, pady=5) case_entry = Entry(frame, textvariable=self.default_case) case_entry.pack(fill=X, padx=5, expand=True) # Team frame = Frame(self.root) frame.pack(fill=BOTH, expand=True) team_label = Label(frame, text="Team", width=10) team_label.pack(side=LEFT, padx=5, pady=5) team_entry = Entry(frame, textvariable=self.default_team) team_entry.pack(fill=X, padx=5, expand=True) # Series frame = Frame(self.root) frame.pack(fill=BOTH, expand=True) series_label = Label(frame, text="Series", width=10) series_label.pack(side=LEFT, padx=5, pady=5) series_entry = Entry(frame, textvariable=self.default_series) series_entry.pack(fill=X, padx=5, expand=True) # Last index frame = Frame(self.root) frame.pack(fill=BOTH, expand=True) last_index_label = Label(frame, text="Last index", width=10) last_index_label.pack(side=LEFT, padx=5, pady=5) last_index_entry = Entry(frame, textvariable=self.default_last_index) last_index_entry.pack(fill=X, padx=5, expand=True) bottom_frame = Frame(self.root) bottom_frame.pack(side=BOTTOM, fill=X, ipady=5, padx=5) close_button = Button(bottom_frame, text="Quit", command=self.root.quit) close_button.pack(side=RIGHT) self.stamp_button = Button(bottom_frame, text="Stamp it!", state=DISABLED, command=self.stamp_it) self.stamp_button.pack(side=RIGHT) def stamp_it(self): stamp_it( self.file_name.get(), self.default_case.get(), self.default_team.get(), self.default_series.get(), self.default_last_index.get(), ) def add_menus(self): menu_bar = Menu(self.root) stampede_menu = Menu(menu_bar, tearoff=0) stampede_menu.add_command(label="Settings", command=self.edit_default_settings) stampede_menu.add_separator() stampede_menu.add_command(label="Quit", command=self.root.quit) menu_bar.add_cascade(label="Stampede", menu=stampede_menu) self.root.config(menu=menu_bar) def run(self): self.root.mainloop() def center(self, window): window.update_idletasks() width = window.winfo_width() height = window.winfo_height() x = (window.winfo_screenwidth() // 2) - (width // 2) y = (window.winfo_screenheight() // 2) - (height // 2) window.geometry('{}x{}+{}+{}'.format(width, height, x, y)) def edit_default_settings(self): SettingsDialog(self.root, config=self.config, config_file_name=self.config_file_name) def choose_pdf(self): self.file_name.set(filedialog.askopenfilename(filetypes=(("PDF files", "*.pdf"),))) def file_name_changed(self, *args): if self.file_name.get(): self.stamp_button.configure(state=NORMAL) else: self.stamp_button.configure(state=DISABLED)
class Tabblet(): def __init__(self): self.tkvar = tkinter.Tk() with open("options.json") as j: joptions = json.load(j) self.tkvar.wm_title("Tabblet") self.tkvar.iconbitmap('resources\\tabbleto.ico') self.screenwidth = self.tkvar.winfo_screenwidth() self.screenheight = self.tkvar.winfo_screenheight() self.windowwidth = int(joptions['width']) self.windowheight = int(joptions['height']) self.windowx = (self.screenwidth-self.windowwidth) / 2 self.windowy = ((self.screenheight-self.windowheight) / 2) - 27 self.geometrystring = '%dx%d+%d+%d' % (self.windowwidth, self.windowheight, self.windowx, self.windowy) self.tkvar.geometry(self.geometrystring) self.image_resetwindow = PhotoImage(file="resources\\resetwindow.gif") self.button_resetwindow = Button(self.tkvar, command= lambda: self.tkvar.geometry(self.geometrystring)) self.button_resetwindow.configure(relief="flat", image=self.image_resetwindow) self.button_resetwindow.pack(expand=False,anchor="ne") self.tkvar.bind('<Configure>', lambda event: self.button_resetwindow.place(x=self.tkvar.winfo_width()-20, y=0)) self.tkvar.bind('<B1-Motion>', self.dragmotion) self.tkvar.bind('<ButtonPress-1>', lambda event: self.mousestate(True)) self.tkvar.bind('<ButtonRelease-1>', lambda event: self.mousestate(False)) self.velocityx = 0 self.velocityy = 0 self.mousepositionsx = [2] self.mousepositionsy = [2] self.ismousepressed = False self.labelvelocityind = Label(self.tkvar, text='•') velocitythread = threading.Thread(target=self.velocitymanager) velocitythread.daemon = True velocitythread.start() self.tkvar.mainloop() def dragmotion(self, event): #print(event.x, event.y) self.mousepositionsx.append(event.x) self.mousepositionsy.append(event.y) self.mousepositionsx = self.mousepositionsx[-20:] self.mousepositionsy = self.mousepositionsy[-20:] print(event.x, event.y) def mousestate(self, state): self.ismousepressed = state def velocitymanager(self): while True: if not self.ismousepressed: try: self.velocityx = (sum(self.mousepositionsx)/len(self.mousepositionsx)) - self.mousepositionsx[-1] self.velocityy = (sum(self.mousepositionsy)/len(self.mousepositionsy)) - self.mousepositionsy[-1] except: self.velocityx = 0 self.velocityy = 0 self.velocityx = int(self.velocityx * 0.9) self.velocityy = int(self.velocityy * 0.9) #print(self.velocityx, self.velocityy, self.ismousepressed) if abs(self.velocityx) < 2: self.velocityx = 0 if abs(self.velocityy) < 2: self.velocityy = 0 time.sleep(0.0165) #60 fps baby self.labelvelocityind.configure(text="•") self.labelvelocityind.place(x=512+self.velocityx, y=288+self.velocityy) self.mousepositionsx = self.mousepositionsx[1:] self.mousepositionsy = self.mousepositionsy[1:]
class CsvConcatenation(): """ csv concatenation class""" def __init__(self, master): self.concatlist = [] self.master = master self.master.title("CSV CONCATENATION") self.master.geometry("250x120") self.master.resizable(False, False) self.menu = Menu(self.master) # menu self.file_menu = Menu(self.menu, tearoff=0) self.file_menu.add_command(label="Add for concatenation", accelerator='Ctrl+O', command=self.addtolist) self.file_menu.add_command(label="Concatenation", accelerator='Ctrl+S', command=self.savefile) self.file_menu.add_command(label="Show List", accelerator='Ctrl+F5', command=self.showlista) self.file_menu.add_command(label="Exit", accelerator='Alt+F4', command=self.exitmenu) self.menu.add_cascade(label="File", menu=self.file_menu) self.edit_menu = Menu(self.menu, tearoff=0) self.edit_menu.add_command(label="Delete first insert", accelerator='Ctrl+F', command=self.delfirst) self.edit_menu.add_command(label="Delete last insert", accelerator='Ctrl+Z', command=self.dellast) self.edit_menu.add_command(label="Clear list", accelerator='Ctrl+T', command=self.clearl) self.menu.add_cascade(label="Edit", menu=self.edit_menu) self.about_menu = Menu(self.menu, tearoff=0) self.about_menu.add_command(label="About", accelerator='Ctrl+I', command=aboutmenu) self.menu.add_cascade(label="About", menu=self.about_menu) self.help_menu = Menu(self.menu, tearoff=0) self.help_menu.add_command(label="Help", accelerator='Ctrl+F1', command=helpmenu) self.menu.add_cascade(label="Help", menu=self.help_menu) #keybinds self.master.config(menu=self.menu) self.master.bind('<Control-f>', lambda event: self.delfirst()) self.master.bind('<Control-o>', lambda event: self.addtolist()) self.master.bind('<Control-i>', lambda event: aboutmenu()) self.master.bind('<Control-z>', lambda event: self.dellast()) self.master.bind('<Control-t>', lambda event: self.clearl()) self.master.bind('<Control-s>', lambda event: self.savefile()) self.master.bind('<Alt-F4>', lambda event: self.exitmenu()) self.master.bind('<Control-F5>', lambda event: self.showlista()) self.master.bind('<Control-F1>', lambda event: helpmenu()) self.welcomleb = Label(self.master, text="Welcome to the csv concatenation\n") self.welcomleb.pack() self.addtoconcatlist = Button(self.master, text="ADD FOR CONCATENATION", command=self.addtolist) self.addtoconcatlist.pack() setslist = list(["Horizontal", "Vertical"]) self.varnumset = StringVar(master) self.varnumset.set(setslist[0]) self.popupsetmenu = OptionMenu(self.master, self.varnumset, *setslist) self.popupsetmenu.pack() self.concatenationb = Button(self.master, text="CONCATENATION", state="disable", command=self.concatenation) self.concatenationb.pack() def delfirst(self): """ deletes the first element of the list """ if not self.concatlist: msg.showerror("Error", "The list is empty") else: self.concatlist.pop(0) msg.showinfo( "Delete", "Success The first element of the list has been deleted ") if len(self.concatlist) < 2: self.concatenationb.configure(state="disable") def dellast(self): """ deletes last element of the list """ if not self.concatlist: msg.showerror("Error", "The list is empty") else: self.concatlist.pop() msg.showinfo( "Delete", "Success The last element of the list has been deleted ") if len(self.concatlist) < 2: self.concatenationb.configure(state="disable") def showlista(self): """ shows the list of files """ if not self.concatlist: msg.showinfo("LIST", "LIST IS EMPTY") else: msg.showinfo("LIST", self.concatlist) def clearl(self): """ clears the list """ self.concatlist.clear() self.concatenationb.configure(state="disable") msg.showinfo( "LIST CLEARED", "THE CONCATENATION LIST IS CLEAR\n" + "YOU CAN CONCATANATE NEW FILES") def exitmenu(self): """ exit menu function""" if msg.askokcancel("Quit?", "Really quit?"): self.master.destroy() def concat(self, axis): """ concatenation button""" concatdf = pd.concat(self.concatlist, axis=axis) filenamesave = filedialog.asksaveasfilename( initialdir="/", title="Select file", filetypes=(("csv files", "*.csv"), ("all files", "*.*"))) if '.csv' in filenamesave: msg.showinfo("SUCCESS", "THE CSV FILE CREATED SUCCESSFULLY") concatdf.to_csv(filenamesave, index=False) self.concatlist.clear() self.concatenationb.configure(state="disable") msg.showinfo( "LIST CLEARED", "THE CONCATENATION LIST IS CLEAR\n" + "YOU CAN CONCATENATE NEW FILES") else: msg.showerror("ERROR", "NO FILE SAVED") def checkcolumns(self, pandascheck): """ check if column names are the same """ if str(pandascheck.columns) == str(self.columnsofthefirst): msg.showinfo("SUCCESS", "THE CSV FILE " + " ADDED SUCCESSFULLY") else: self.concatlist.pop() msg.showerror( "ERROR", "THE CSV FILE MUST HAVE" + "THE SAME COLUMN NAME AS THE FIRST INSERTED FILE") def checkinsertion(self, pandascheck): """ checks if the name of the columns of the added csv are the same with the first added""" if len(self.concatlist) == 1: self.columnsofthefirst = pandascheck.columns msg.showinfo("SUCCESS", "THE CSV FILE " + " ADDED SUCCESSFULLY") else: self.checkcolumns(pandascheck) self.concatenationb.configure(state="active") def addtolistval(self, filename): """checks if inserted file is a .csv""" if ".csv" in filename: pandascheck = pd.read_csv(filename) self.concatlist.append(pandascheck) self.checkinsertion(pandascheck) else: msg.showerror("Error", "NO CSV FILE ADDED") def addtolist(self): """ adds file to list """ filename = filedialog.askopenfilename(initialdir="/", title="Select csv file", filetypes=(("csv files", "*.csv"), ("all files", "*.*"))) self.addtolistval(filename) def concatenation(self): """ concatenation button function """ if self.varnumset.get() == "Horizontal": self.concat(axis=1) else: self.concat(axis=0) def savefile(self): """ saves the new file """ if len(self.concatlist) >= 2: self.concatenation() else: msg.showerror("SAVE ERROR", "INSERT MORE FILES")
def cargarHerramientas(self, data, ruta0=getcwd()): #se cargan todos los elementos en el directorio ./libs/ if sys.platform.startswith('win32'): tree = listdir(ruta0 + "\\libs\\") elif sys.platform.startswith('linux') or sys.platform.startswith( 'darwin'): tree = listdir(ruta0 + "/libs/") for i in tree: if i == data[ "Nombre_Archivo"]: #compara si algun archivo se llama igual que a como lo indica en el diccionario del jason name = i.replace(".py", "") name = "libs." + name module = importlib.import_module(name) #importa el modulo try: class_ = getattr(module, data["Clase"]) #apuntamos a la clase instance = class_( self.master) #creamos una instacia de la clase method_to_call = getattr( instance, data["Metodo"]) #cargamos un metodo en la variable #method_to_call() if data["Imagen"] == 1: ruta = data["Nombre"] + "." + data["Tipo"] load = Image.open(ruta) render = ImageTk.PhotoImage(load) nbutton = Button(self, image=render, bg=data["Fondo"], borderwidth=data["BorderWidth"], activebackground=data["FondoActivo"], highlightthickness=0, cursor="hand2") nbutton.configure( command=lambda: method_to_call(self.master)) nbutton.image = render nbutton.place(x=data["x"], y=data["y"]) self.__list_button.append(nbutton) elif data["Etiqueta"] == 1: nbutton = Button(self, text=data["Texto"], bg=data["Fondo"], fg=data["Color"], borderwidth=data["BorderWidth"], activebackground=data["FondoActivo"], cursor="hand2") nbutton.configure( command=lambda: method_to_call(self.master)) nbutton.config(font=(data["Tipografia"], data["Size"])) nbutton.place(x=data["x"], y=data["y"]) self.__list_button.append(nbutton) else: nbutton = Button(self, text=data["Texto"], bg=data["Fondo"], fg=data["Color"], borderwidth=data["BorderWidth"], activebackground=data["FondoActivo"], cursor="hand2") nbutton.configure( command=lambda: method_to_call(self.master)) nbutton.config(font=(data["Tipografia"], data["Size"])) nbutton.place(x=data["x"], y=data["y"]) self.__list_button.append(nbutton) except Exception as e: print(e)
class FilePickEdit(Frame): def __init__(self, master, file_mask, default_file, edit_height = None, user_onChange = None, rename_on_edit=0, font = None, coloring=True, allowNone=False, highlighter=None, directory='.'): """ file_mask: file mask (e.g. "*.foo") or list of file masks (e.g. ["*.foo", "*.abl"]) """ self.master = master self.directory = directory self.user_onChange = user_onChange Frame.__init__(self, master) row = 0 self.unmodified = True self.allowNone = allowNone self.file_extension = "" if type(file_mask) != list: file_mask = [file_mask] if "." in file_mask[0]: self.file_extension = file_mask[0][file_mask[0].rfind('.'):] # read filenames self.file_mask = file_mask self.updateList() # filename frame self.list_frame = Frame(self) self.list_frame.grid(row=row, column=0, sticky="WE") self.list_frame.columnconfigure(0, weight=1) # create list self.picked_name = StringVar() self.makelist() # refresh button self.refresh_button = Button(self.list_frame, text='<- refresh', command=self.refresh, height=1) self.refresh_button.grid(row=0, column=1, sticky='E') # save button self.save_button = Button(self.list_frame, text="save", command=self.save, height=1) self.save_button.grid(row=0, column=2, sticky="E") # editor row += 1 if coloring: self.editor = SyntaxHighlightingText(self, self.onEdit, highlighter=highlighter) else: self.editor = ScrolledText2(self, self.onEdit) if font is not None: self.editor.configure(font=font) if edit_height is not None: self.editor.configure(height=edit_height) self.editor.grid(row=row, column=0, sticky="NEWS") self.rowconfigure(row, weight=1) self.columnconfigure(0, weight=1) # option to change filename on edit row += 1 self.options_frame = Frame(self) self.options_frame.grid(row=row, column=0, sticky=W) self.rename_on_edit = IntVar() self.cb = Checkbutton(self.options_frame, text="rename on edit", variable=self.rename_on_edit) self.cb.pack(side=LEFT) self.cb.configure(command=self.onChangeRename) self.rename_on_edit.set(rename_on_edit) # filename frame row += 1 self.filename_frame = Frame(self) self.filename_frame.grid(row=row, column=0, sticky="WE") self.filename_frame.columnconfigure(0, weight=1) # save as filename self.save_name = StringVar() self.save_edit = Entry(self.filename_frame, textvariable = self.save_name) self.save_edit.grid(row=0, column=0, sticky="WE") self.save_name.trace("w", self.onSaveChange) # pick default if applicableButton self.select(default_file) self.row = row def setDirectory(self, directory, keep=False): self.directory = directory self.updateList() self.makelist() # menu = self.list["menu"] scrolledlist # menu = self.list.listbox#["scrolledlist"] # menu.delete(0, 'end') # add the new ones # for filename in self.files: # menu.add_command(label=filename, command=_setit(self.picked_name, filename, None)) # if keep is true, only the files list will be updated but the content of the # text area will not be altered/removed if not keep: self.select("") def refresh(self): sel = self.get() self.updateList() self.select(sel, notify=False) def reloadFile(self): self.editor.delete("1.0", END) filename = self.picked_name.get() if os.path.exists(os.path.join(self.directory, filename)): new_text = open(os.path.join(self.directory, filename)).read() if new_text.strip() == "": new_text = "// %s is empty\n" % filename new_text = new_text.replace("\r", "") else: new_text = "" self.editor.insert(INSERT, new_text) def setText(self, txt): """ Replaces the text in the edit field as by typing into it. """ self.select("") if txt.strip() == "": txt = "// empty database\n" self.editor.insert(INSERT, txt) self.onEdit() def onSelChange(self): self.reloadFile() filename = self.picked_name.get() self.save_name.set(filename) self.save_edit.configure(state=DISABLED) self.unmodified = True if self.user_onChange is not None: self.user_onChange(filename) def onSaveChange(self, name, index, mode): pass def autoRename(self): # modify "save as" name filename = self.picked_name.get() if filename == "": filename = "new" + self.file_extension # if no file selected, create new filename ext = "" extpos = filename.rfind(".") if extpos != -1: ext = filename[extpos:] base = filename[:extpos] hpos = base.rfind("-") num = 0 if hpos != -1: try: num = int(base[hpos+1:]) base = base[:hpos] except: pass while True: num += 1 filename = "%s-%d%s" % (base, num, ext) if not os.path.exists(filename): break self.save_name.set(filename) # user callback if self.user_onChange is not None: self.user_onChange(filename) def onEdit(self): if self.unmodified: self.unmodified = False # do auto rename if it's enabled or there is no file selected (editing new file) if self.rename_on_edit.get() == 1 or self.picked_name.get() == "": self.autoRename() # enable editing of save as name self.save_edit.configure(state=NORMAL) def onChangeRename(self): # called when clicking on "rename on edit" checkbox if self.rename_on_edit.get() == 1: if (not self.unmodified) and self.save_name.get() == self.picked_name.get(): self.autoRename() else: self.save_name.set(self.picked_name.get()) def updateList(self): self.files = [] if self.allowNone: self.files.append("") if os.path.exists(self.directory): for filename in os.listdir(self.directory): for fm in self.file_mask: if fnmatch(filename, fm): self.files.append(filename) self.files.sort() if len(self.files) == 0 and not self.allowNone: self.files.append("(no %s files found)" % str(self.file_mask)) def select(self, filename, notify=True): """ selects the item given by filename """ if filename in self.files: if not havePMW: self.picked_name.set(filename) else: self.list.selectitem(self.files.index(filename)) if notify: self.onSelChange(filename) else: self.editor.delete("1.0", END) def makelist(self): if havePMW: self.list = ComboBox(self.list_frame, selectioncommand = self.onSelChange, scrolledlist_items = self.files, ) self.list.grid(row=0, column=0, padx=0, pady=0, sticky="NEWS") self.list.component('entryfield').component('entry').configure(state = 'readonly', relief = 'raised') self.picked_name = self.list else: self.list = OptionMenu(*(self.list_frame, self.picked_name) + tuple(self.files)) self.list.grid(row=0, column=0, sticky="NEW") self.picked_name.trace("w", self.onSelChange) def save(self): self.get() def set(self, selected_item): self.select(selected_item) def get(self): """ gets the name of the currently selected file, saving it first if necessary """ filename = self.save_name.get() if self.unmodified == False: self.unmodified = True # save the file f = open(os.path.join(self.directory, filename), "w") f.write(self.editor.get("1.0", END).encode('utf-8')) f.close() # add it to the list of files # if not filename in self.files: # self.files.append(filename) # self.files.sort() # self.list.destroy() # self.makelist() # set it as the new pick #if havePMW: # self.picked_name.selectitem(self.files.index(filename), 1) #else: # self.picked_name.set(filename) # self.select(filename) self.refresh() self.select(filename, notify=False) self.save_edit.configure(state=DISABLED) return filename def get_text(self): return self.editor.get("1.0", END) def get_filename(self): return self.save_name.get() def set_enabled(self, state): self.editor.configure(state=state) if havePMW: self.list.component('entryfield_entry').configure(state=state) # self.list.component('arrowbutton').configure(state=state) self.list.component('arrowbutton').bind('<1>', (lambda a: 'break') if state==DISABLED else self.list._postList) else: self.list.configure(state=state) self.save_button.configure(state=state) self.cb.configure(state=state) self.save_edit.configure(state=state)