class LongTextbox(Textbox): def config(self, **kwargs): if 'height' in kwargs: self.sentry.config(height=kwargs['height']) if 'width' in kwargs: self.sentry.config(width=kwargs['width']) if 'text' in kwargs: self.sentry.insert(END, kwargs['text']) if 'lang' in kwargs: self.lang = kwargs['lang'] self.label.config(text=self.lang[self.text]) def place(self, **kwargs): self.parent = kwargs['parent'] self.row = kwargs['row'] self.column = kwargs['column'] self.label = Label(self.parent, text=self.lang[self.text]) self.sentry = ScrolledText(self.parent, relief=SOLID) self.label.grid(row=self.row, column=self.column) self.sentry.grid(row=self.row, column=self.column+1, sticky=E) def getData(self): return self.sentry.get('1.0', END + '-1c') def setData(self, data): self.sentry.delete('1.0', END) self.config(text=data)
class GuiConsole(Frame): def __init__(self, master=None, cnf={}, **kw): super(GuiConsole, self).__init__(master, cnf, **kw) self.pack(fill=BOTH, expand=YES) self.console = ScrolledText(self, font=('Source Code Pro', 12, 'normal')) self.console.pack(side=TOP, fill=BOTH, expand=YES, padx=5, pady=5) self.console.focus() self.console.mark_set(INSERT, '1.0') def clear(self): self.console.delete('1.0', END) def write(self, text): text = '{}'.format(text) self.console.insert(INSERT, text) self.console.mark_set(INSERT, INSERT+'+{}c'.format(len(text))) def writeline(self, text): self.write('{}\n'.format(text)) def writelines(self, lines): for line in lines: self.writeline(line) def read(self): pass
class LongTextbox(Textbox): def config(self, **kwargs): try: self.sentry.config(height=kwargs['height']) except: pass #print("the widget could not be configured") try: self.sentry.config(width=kwargs['width']) except: pass #print("the widget could not be configured") try: #self.text = kwargs['text'] #self.sentry.delete(1.0, END) self.sentry.insert(END, kwargs['text']) except: pass #print("the widget could not be configured") try: self.lang = kwargs['lang'] self.label.config(text=self.lang[self.text]) except: pass def trytoplace(self, **kwargs): self.parent = kwargs['parent'] self.row = kwargs['row'] self.column = kwargs['column'] def place(self, **kwargs): try: self.trytoplace(**kwargs) except: pass #print("widget could not be placed") self.label = Label(self.parent, text=self.lang[self.text]) self.sentry = ScrolledText(self.parent, relief=SOLID) self.label.grid(row=self.row, column=self.column) self.sentry.grid(row=self.row, column=self.column+1, sticky=E) def getData(self): return self.sentry.get('1.0', END + '-1c') def setData(self, data): self.sentry.delete('1.0', END) self.config(text=data)
class HMDmain(tk.Frame): def __init__(self, parent, *args, **kwargs): tk.Frame.__init__(self, parent, *args, **kwargs) self.parent = parent self.parent.option_add('*tearOff', False) self.after(50, self.onAfter) #set this frame to expand to %100 available space self.columnconfigure(0, weight=1) self.rowconfigure(0, weight=1) #init menu menubar = Menu(self.parent) self.parent.config(menu=menubar) fileMenu = Menu(menubar) fileMenu.add_command(label="Save", command=self.onSave) fileMenu.add_command(label="Load", command=self.onLoad) fileMenu.add_command(label="Exit", command=self.onExit) menubar.add_cascade(label="File", menu=fileMenu) #init textbox self.text = ScrolledText(self, wrap='word') #add widgets to the layout manager self.text.grid(sticky=inflate) def onExit(self): self.quit() def onSave(self): darkIO.DarkIO.save(asksaveasfilename(), self.text.get(0.0, 'end')) def onLoad(self): if not askyesno( "Clear All Text", "Loading a new file will clear the current project \n" "Would you like to continue?"): return loadText = "" try: fname = askopenfile() loadText = darkIO.DarkIO.load(fname.name) except UnicodeDecodeError: showerror("Invalid File Type", "Unable to read file.") else: self.text.delete(0.0, 'end') self.text.insert(0.0, loadText) def onAfter(self): print("Working") self.after(30000, self.onAfter)
class MessageTester: def __init__(self, root): root.title("Message tester") Label(root, text="Enter message event below", bg="light green").pack() self.event_field = ScrolledText(root, width=180, height=10) self.event_field.pack() Label(root, text="Enter test case below", bg="light green").pack() self.test_case_field = ScrolledText(root, width=180, height=20) self.test_case_field.pack() Label(root, text="Test result:", bg="light green").pack() self.result_field = ScrolledText(root, width=180, height=10) self.result_field.pack() self.result_field.config(state=DISABLED) self.button = Button(root, text="Evaluate", fg="red", command=self._clicked) self.button.pack() self.event_field.delete('1.0', END) self.event_field.insert('insert', EXAMPLE_EVENT) self.test_case_field.delete('1.0', END) self.test_case_field.insert('insert', EXAMPLE_TEST_CASE) def _clicked(self): event = self.event_field.get('1.0', END) test_case = self.test_case_field.get('1.0', END) evaluation = skill_tester.EvaluationRule(ast.literal_eval(test_case)) evaluation.evaluate(ast.literal_eval(event)) self.result_field.config(state=NORMAL) self.result_field.delete('1.0', END) self.result_field.insert('insert', evaluation.rule) self.result_field.config(state=DISABLED)
class Application(tkinter.Tk): def __init__(self): """Initialize widgets, methods.""" tkinter.Tk.__init__(self) self.grid() fontoptions = families(self) font = Font(family="Verdana", size=10) menubar = tkinter.Menu(self) fileMenu = tkinter.Menu(menubar, tearoff=0) editMenu = tkinter.Menu(menubar, tearoff=0) fsubmenu = tkinter.Menu(editMenu, tearoff=0) ssubmenu = tkinter.Menu(editMenu, tearoff=0) # adds fonts to the font submenu and associates lambda functions for option in fontoptions: fsubmenu.add_command(label=option, command = lambda: font.configure(family=option)) # adds values to the size submenu and associates lambda functions for value in range(1,31): ssubmenu.add_command(label=str(value), command = lambda: font.configure(size=value)) # adds commands to the menus menubar.add_cascade(label="File",underline=0, menu=fileMenu) menubar.add_cascade(label="Edit",underline=0, menu=editMenu) fileMenu.add_command(label="New", underline=1,command=self.new, accelerator="Ctrl+N") fileMenu.add_command(label="Open", command=self.open, accelerator="Ctrl+O") fileMenu.add_command(label="Save", command=self.save, accelerator="Ctrl+S") fileMenu.add_command(label="Exit", underline=1,command=exit, accelerator="Ctrl+Q") editMenu.add_command(label="Copy", command=self.copy, accelerator="Ctrl+C") editMenu.add_command(label="Cut", command=self.cut, accelerator="Ctrl+X") editMenu.add_command(label="Paste", command=self.paste, accelerator="Ctrl+V") editMenu.add_cascade(label="Font", underline=0, menu=fsubmenu) editMenu.add_cascade(label="Size", underline=0, menu=ssubmenu) editMenu.add_command(label="Color", command=self.color) editMenu.add_command(label="Bold", command=self.bold, accelerator="Ctrl+B") editMenu.add_command(label="Italic", command=self.italic, accelerator="Ctrl+I") editMenu.add_command(label="Underline", command=self.underline, accelerator="Ctrl+U") editMenu.add_command(label="Overstrike", command=self.overstrike, accelerator="Ctrl+T") editMenu.add_command(label="Undo", command=self.undo, accelerator="Ctrl+Z") editMenu.add_command(label="Redo", command=self.redo, accelerator="Ctrl+Y") self.config(menu=menubar) self.bind_all("<Control-n>", self.new) self.bind_all("<Control-o>", self.open) self.bind_all("<Control-s>", self.save) self.bind_all("<Control-q>", self.exit) self.bind_all("<Control-b>", self.bold) self.bind_all("<Control-i>", self.italic) self.bind_all("<Control-u>", self.underline) self.bind_all("<Control-T>", self.overstrike) self.bind_all("<Control-z>", self.undo) self.bind_all("<Control-y>", self.redo) self.text = ScrolledText(self, state='normal', height=80, wrap='word', font = font, pady=2, padx=3, undo=True) self.text.grid(column=0, row=0, sticky='NSEW') # Frame configuration self.grid_columnconfigure(0, weight=1) self.resizable(True, True) def new(self, *args): """Creates a new window.""" app = Application() app.title('Python Text Editor') app.option_add('*tearOff', False) app.mainloop() def color(self): """Changes selected text color.""" try: (rgb, hx) = tkinter.colorchooser.askcolor() self.text.tag_add('color', 'sel.first', 'sel.last') self.text.tag_configure('color', foreground=hx) except TclError: pass def bold(self, *args): """Toggles bold for selected text.""" try: current_tags = self.text.tag_names("sel.first") if "bold" in current_tags: self.text.tag_remove("bold", "sel.first", "sel.last") else: self.text.tag_add("bold", "sel.first", "sel.last") bold_font = Font(self.text, self.text.cget("font")) bold_font.configure(weight="bold") self.text.tag_configure("bold", font=bold_font) except TclError: pass def italic(self, *args): """Toggles italic for selected text.""" try: current_tags = self.text.tag_names("sel.first") if "italic" in current_tags: self.text.tag_remove("italic", "sel.first", "sel.last") else: self.text.tag_add("italic", "sel.first", "sel.last") italic_font = Font(self.text, self.text.cget("font")) italic_font.configure(slant="italic") self.text.tag_configure("italic", font=italic_font) except TclError: pass def underline(self, *args): """Toggles underline for selected text.""" try: current_tags = self.text.tag_names("sel.first") if "underline" in current_tags: self.text.tag_remove("underline", "sel.first", "sel.last") else: self.text.tag_add("underline", "sel.first", "sel.last") underline_font = Font(self.text, self.text.cget("font")) underline_font.configure(underline=1) self.text.tag_configure("underline", font=underline_font) except TclError: pass def overstrike(self, *args): """Toggles overstrike for selected text.""" try: current_tags = self.text.tag_names("sel.first") if "overstrike" in current_tags: self.text.tag_remove("overstrike", "sel.first", "sel.last") else: self.text.tag_add("overstrike", "sel.first", "sel.last") overstrike_font = Font(self.text, self.text.cget("font")) overstrike_font.configure(overstrike=1) self.text.tag_configure("overstrike", font=overstrike_font) except TclError: pass def undo(self, *args): """Undo function""" try: self.text.edit_undo() except TclError: pass def redo(self, *args): """Redo function""" try: self.text.edit_redo() except TclError: pass def copy(self, *args): """Copy text""" self.clipboard_clear() self.clipboard_append(self.text.selection_get()) def cut(self, *args): """Cut text""" self.copy self.text.delete("sel.first", "sel.last") def paste(self, *args): """Paste text""" insertion = self.selection_get(selection = "CLIPBOARD") self.text.insert(0.0, insertion) def open(self, *args): """Opens a file dialog to open a plain text file.""" filename = tkinter.filedialog.askopenfilename() with open(filename) as f: text = f.read() self.text.delete("1.0", "end") self.text.insert('insert', text) def save(self, *args): try: """Opens a file dialog to save the text in plain text format.""" text = self.text.get("1.0", "end") filename = tkinter.filedialog.asksaveasfilename() with open(filename, 'w') as f: f.write(text) except FileNotFoundError: pass def exit(self, *args): """Exits the program.""" self.quit()
class GameWindow(tk.Frame): def __init__( self, parent, controller, ): tk.Frame.__init__(self, parent) # Controller references the MainApp class. We use this to access its instance variables. self.controller = controller # Array of button handles self.buttons = [] # iterator to determine which column to place the button in within the grid self.current_col = 0 self.chosen_wildcard = {} self.grid_rowconfigure(1) self.grid_columnconfigure(1, weight=1) title_label = ttk.Label(self, text="PyUno") self.turn_label = ttk.Label(self, text="turn") self.currentcard_label = ttk.Label(self, text='Current card') self.currentcard_frame = ttk.Frame(self) card_label = ttk.Label(self, text="Cards in your hand") chat_label = ttk.Label(self, text="Chat") self.chat_area = ScrolledText(self, height=10) chat_frame = ttk.Frame(self) sendchat_label = ttk.Label(chat_frame, text='Send Message:') self.sendchat_entry = ttk.Entry(chat_frame, text='', width=50) sendchat_button = ttk.Button(chat_frame, text='Send message', command=self.send_message) ping_button = ttk.Button(self, text='Ping server', command=lambda player_name=self.controller. uno_client.player['player_name']: self. controller.ping_client.send_ping(player_name)) title_label.grid(row=0, column=1) self.turn_label.grid(row=1, column=1) self.currentcard_label.grid(row=2, column=1) self.currentcard_frame.grid(row=3, column=1) card_label.grid(row=4, column=1) # Button array needs its own frame self.button_frame = ttk.Frame(self) self.wildcolor_frame = ttk.Frame(self) self.skipturn_button = ttk.Button(self, text='Skip your turn', command=self.skip_turn) self.buttons.append(self.skipturn_button) self.button_frame.grid(row=5, column=1) self.skipturn_button.grid(row=6, column=1) chat_label.grid(row=8, column=1) self.chat_area.grid(row=9, column=1) chat_frame.grid(row=10, column=1) ping_button.grid(row=11, column=1) #Chat stuff is in its own frame sendchat_label.grid(row=0, column=0) self.sendchat_entry.grid(row=0, column=1) sendchat_button.grid(row=0, column=2) messagereceive_thread = threading.Thread(target=self.receive_messages) messagereceive_thread.start() self.show_currentcard() self.generate_cardbuttons() self.generate_wildcolorbuttons() self.init_turn() self.change_cardstate() if not self.controller.uno_client.your_turn: wait_thread = threading.Thread(target=self.done_wait) wait_thread.start() # Generates the initial hand as buttons. def generate_cardbuttons(self): # Accessing player's hand hand = self.controller.uno_client.player['hand'] # Iterate through cards in hand and create a new button. for card in hand: # Initialize Button control card_button = ttk.Button(self.button_frame, text=card['type'], style="%s.TButton" % card['color'], width=10, command=lambda current_card=card: self. button_action(current_card)) # Append button control to array self.buttons.append(card_button) # Add button to grid dynamically card_button.grid(row=0, column=self.current_col, sticky='ew') # Increment for next button self.current_col += 1 # Determine which action to send to the server depending on which button is clicked. def button_action(self, card): uno_client = self.controller.uno_client if card['type'] == 'Wild' or card['type'] == 'Wild 4': self.chosen_wildcard = card self.wildcolor_frame.grid(row=7, column=1) else: if card['type'] == uno_client.current_card['type'] or card[ 'color'] == uno_client.current_card['color']: uno_client.send_card(card) button = self.get_button(card) button.destroy() self.buttons.remove(button) self.next_turn() else: messagebox.showinfo( "Incorrect match", "Incorrect card match! Please match by card type or color. " + "If you can't, skip your turn") def skip_turn(self): uno_client = self.controller.uno_client skipturn_card = {'type': 'skip turn'} uno_client.player['hand'].append(skipturn_card) uno_client.send_card(skipturn_card) self.next_turn() def next_turn(self): uno_client = self.controller.uno_client self.turn_label['text'] = 'Wait for your turn' uno_client.your_turn = False self.change_cardstate() self.update() uno_client.wait_turndata() if not uno_client.win: self.show_currentcard() self.add_draw() self.turn_label['text'] = 'Your turn' uno_client.your_turn = True self.change_cardstate() else: messagebox.showinfo("Game ended", "%s wins!" % uno_client.win) def get_button(self, card): for button in self.buttons: if button['text'] == card['type'] and button['style'].startswith( card['color']): return button def show_currentcard(self): current_card = self.controller.uno_client.current_card card_button = ttk.Button(self.currentcard_frame, text=current_card['type'], style="%s.TButton" % current_card['color'], width=10) card_button.grid(row=0, column=0, sticky='ew') def add_draw(self): uno_client = self.controller.uno_client cards = uno_client.cards_drawn for card in cards: card_button = ttk.Button(self.button_frame, text=card['type'], style="%s.TButton" % card['color'], width=10, command=lambda current_card=card: self. button_action(current_card)) # Append button control to array self.buttons.append(card_button) # Add button to grid dynamically card_button.grid(row=0, column=self.current_col, sticky='ew') # Increment for next button self.current_col += 1 def init_turn(self): uno_client = self.controller.uno_client player = uno_client.player turn = uno_client.turn if player['player_name'] == turn: self.turn_label['text'] = 'Your turn' uno_client.your_turn = True else: self.turn_label['text'] = 'Wait for your turn' def change_cardstate(self): state = 'normal' if self.controller.uno_client.your_turn else 'disabled' for button in self.buttons: button['state'] = state def done_wait(self): self.controller.uno_client.wait_turndata() self.turn_label['text'] = 'Your turn' self.controller.uno_client.your_turn = True self.change_cardstate() self.show_currentcard() self.add_draw() def receive_messages(self): chat_client = self.controller.chat_client while True: messages = chat_client.receive_messages() self.chat_area.delete('1.0', 'end') for message in messages: self.chat_area.insert('end', message) def send_message(self): player_name = self.controller.uno_client.player['player_name'] self.controller.chat_client.send_message(player_name, self.sendchat_entry.get()) self.sendchat_entry.delete('0', 'end') def generate_wildcolorbuttons(self): color_label = ttk.Label(self.wildcolor_frame, text='Choose wild card color:') color_label.grid(row=0, column=0) colors = ['yellow', 'green', 'red', 'blue'] current_col = 1 for color in colors: color_button = ttk.Button(self.wildcolor_frame, text=color, style="%s.TButton" % color, width=10, command=lambda wild_color=color: self. determine_wildcolor(wild_color)) # Add button to grid dynamically color_button.grid(row=0, column=current_col) # Increment for next button current_col += 1 print(self.wildcolor_frame) def determine_wildcolor(self, color): uno_client = self.controller.uno_client uno_client.change_cardcolor(self.chosen_wildcard, color) self.change_wildcard_buttoncolor(self.chosen_wildcard) self.wildcolor_frame.grid_remove() uno_client.send_card(self.chosen_wildcard) button = self.get_button(self.chosen_wildcard) button.destroy() self.buttons.remove(button) self.next_turn() def change_wildcard_buttoncolor(self, wild_card): for button in self.buttons: if button['text'] == wild_card['type']: button['style'] = '%s.TButton' % wild_card['color']
class ChatForm(tk.Frame): font_color = "#000000" font_size = 12 def on_list_click(self, e): name = self.chatroom_user_list.get( self.chatroom_user_list.curselection()) for tmp in memory.chatroom_user_list[self.username]: if tmp[1] == name: uname = tmp[0] for fn in memory.friend_list: if uname == fn[1]: # It's friend... uname = memory.friend_list[fn] + " (" + uname + ")" run(uname) return # Not friend... result = messagebox.askokcancel("还不是好友?", "你和" + name + "还不是好友,是否立即添加?") if result: friend_name = uname.encode() serializeMessage = common_handler.pack_message( common_handler.MessageType.add_friend, friend_name) client_socket.send_msg(serializeMessage) messagebox.showinfo('添加好友', '好友请求已发送') def __init__(self, master=None, username=None, nickname="Unkown"): super().__init__(master) self.master = master self.username = username self.nickname = nickname self.master.resizable(width=True, height=True) self.master.geometry('660x500') self.master.minsize(420, 370) self.master.title("与 {} 聊天中...".format(self.nickname)) memory.Chat_window[self.username] = self print(memory.Chat_window) # Chatroom window for v in memory.friend_list: if v[1] == self.username: if v[0] == 2: self.left_frame = tk.Frame(self) self.scroll = Scrollbar(self.left_frame) self.scroll.pack(side=RIGHT, fill=Y) self.chatroom_user_list = Listbox( self.left_frame, yscrollcommand=self.scroll.set) self.chatroom_user_list.bind("<Double-Button-1>", self.on_list_click) self.scroll.config(command=self.chatroom_user_list.yview) self.chatroom_user_list.pack(expand=True, fill=BOTH) self.update_chatroom_user_list(v[1]) self.left_frame.pack(side=RIGHT, expand=True, fill=BOTH) # self.friend_name = tk.Label( # self.left_frame, text=nickname, bg='#EEE', width=15) # self.friend_name.pack(expand=True, fill=BOTH, ipadx=5, ipady=5) self.right_frame = tk.Frame(self, bg='white') self.right_frame.pack(side=LEFT, expand=True, fill=BOTH) self.input_frame = tk.Frame(self.right_frame) self.input_textbox = ScrolledText(self.right_frame, height=7) self.input_textbox.bind("<Control-Return>", self.send_message) self.input_textbox.bind_all('<Key>', self.apply_font_change) self.send_btn = tk.Button(self.input_frame, text='发送消息(Ctrl+Enter)', command=self.send_message) self.send_btn.pack(side=RIGHT, expand=False) self.font_btn = tk.Button(self.input_frame, text='字体颜色', command=self.choose_color) self.font_btn.pack(side=LEFT, expand=False) self.font_btn = tk.Button(self.input_frame, text='字体大小', command=self.choose_font_size) self.font_btn.pack(side=LEFT, expand=False) # self.image_btn = tk.Button( # self.input_frame, text='发送图片', command=self.send_image) # self.image_btn.pack(side=LEFT, expand=False) self.chat_box = ScrolledText(self.right_frame, bg='white') self.input_frame.pack(side=BOTTOM, fill=X, expand=False) self.input_textbox.pack(side=BOTTOM, fill=X, expand=False, padx=(0, 0), pady=(0, 0)) self.chat_box.pack(side=BOTTOM, fill=BOTH, expand=True) self.chat_box.bind("<Key>", lambda e: "break") self.chat_box.tag_config("default", lmargin1=10, lmargin2=10, rmargin=10) self.chat_box.tag_config("me", foreground="green", spacing1='5') self.chat_box.tag_config("them", foreground="blue", spacing1='5') self.chat_box.tag_config("message", foreground="black", spacing1='0') self.chat_box.tag_config("system", foreground="grey", spacing1='0', justify='center', font=(None, 8)) self.pack(expand=True, fill=BOTH, padx=5, pady=5, ipadx=5, ipady=5) def append_to_chat_box(self, time, user, message, tags): if user == memory.username: user = "******" time_info = "%s %s 说:\n" % (time, user) self.chat_box.insert(tk.END, time_info, [tags, 'message']) self.chat_box.insert(tk.END, message, [tags, 'default']) self.chat_box.insert(tk.END, "\n", [tags, 'message']) self.chat_box.update() self.chat_box.see(tk.END) def send_message(self, _=None): stime = dtime.datetime.now() time_info = "%s年%s月%s日 %s时%s分%s秒" % (stime.year, stime.month, stime.day, stime.hour, stime.minute, stime.second) message = self.input_textbox.get("1.0", END) if not message or message.replace(" ", "").\ replace("\r", "").replace("\n", "") == '': return for k1 in memory.friend_list: if k1 == (1, self.username): self.append_to_chat_box(time_info, "我", message, 'me') self.input_textbox.delete("1.0", END) # format datetime send_message_handler(time_info, message, self.username) return 'break' def choose_color(self): _, self.font_color = colorchooser.askcolor( initialcolor=self.font_color) self.apply_font_change(None) def choose_font_size(self): result = simpledialog.askinteger("设置", "请输入字体大小", initialvalue=self.font_size) if result is None: return self.font_size = result self.apply_font_change(None) def apply_font_change(self, _): try: self.input_textbox.tag_config('new', foreground=self.font_color, font=(None, self.font_size)) self.input_textbox.tag_add('new', '1.0', END) except Exception: pass def close_window(self): del memory.Chat_window[self.username] self.master.destroy() def update_chatroom_user_list(self, chatroom_name): cn = chatroom_name.encode() serializeMessage = common_handler.pack_message( common_handler.MessageType.query_room_users, cn) client_socket.send_msg(serializeMessage)
class ScrolledTextInfoFrame(Frame): def __init__(self, master, *args, **kwargs): self.master = master super(ScrolledTextInfoFrame, self).__init__(self.master, *args, **kwargs) self.saved_time = StringVar() self.highlighter = Highlighter() self._create_widgets() # the associated file self._file = None # TODO: rename the textentry def _create_widgets(self): # create a Text widget and read in the file self.textentry = ScrolledText(self, wrap=WORD) self.textentry.grid(column=0, row=0, columnspan=2, sticky='nsew') for key, value in self.highlighter.style: self.textentry.tag_configure(key, foreground=value) self.save_label = Label(self, textvar=self.saved_time) self.save_label.grid(column=0, row=1, sticky='es') self.save_btn = Button(self, text="Save", command=self.save_file) self.save_btn.grid(column=1, row=1, sticky='es') self.grid_columnconfigure(0, weight=1) self.grid_columnconfigure(1, weight=0) self.grid_rowconfigure(0, weight=1) self.grid_rowconfigure(1, weight=0) def update(self): self._update_savetime() self.textentry.delete(1.0, END) with open(self.file.file, 'r') as file: self.textentry.insert(END, file.read()) if HAS_PYGMENTS: if self.highlighter.change_type(self.file.dtype): # remove current tags for tag in self.textentry.tag_names(): self.textentry.tag_configure(tag, foreground="#000000") for key, value in self.highlighter.style.items(): self.textentry.tag_configure(key, foreground=value) self.syn() def _update_savetime(self): self.saved_time.set("Last saved:\t{0}\t".format(self.file.saved_time)) @threaded def syn(self, event=None): """ Allow for syntax highlighting. Source: https://stackoverflow.com/a/30199105 This will highlight the entire document once. Dynamic highlighting not yet supported. #TODO: (maybe?): https://stackoverflow.com/questions/32058760/improve-pygments-syntax-highlighting-speed-for-tkinter-text/32064481 # noqa This is threaded to hopefully stop it blocking the view from displaying and causing a race condition. """ self.textentry.mark_set("range_start", "1.0") data = self.textentry.get("1.0", "end-1c") lexer = self.highlighter.lexer if lexer is not None: for token, content in lex(data, lexer()): self.textentry.mark_set("range_end", "range_start + %dc" % len(content)) self.textentry.tag_add(str(token), "range_start", "range_end") self.textentry.mark_set("range_start", "range_end") def save_file(self): """ Write the current data in the text widget back to the file """ file_contents = self.textentry.get("1.0", "end-1c") with open(self.file.file, 'w') as file: file.write(file_contents) savetime = datetime.now().strftime("%Y-%m-%d %H:%M:%S") self.file.saved_time = savetime self._update_savetime() # also re-apply the syntax highlighting self.syn() @property def file(self): return self._file @file.setter def file(self, other): """ Set the file property to whatever the new file is. When this happens the update command will be called which will redraw the channel info list """ # if the file is being set as a con_file continue if other != self._file: self._file = other self.update()
class Main(tk.Frame): def __init__(self, parent, verbose=False, emulate_wheel=False, print_arduino=False): self.parent = parent parent.columnconfigure(0, weight=1) # parent.rowconfigure(1, weight=1) self.verbose = verbose self.var_cache_size = tk.IntVar() self.var_sess_dur = tk.IntVar() self.var_rec_zeros = tk.IntVar() self.var_emulate_wheel = tk.IntVar() self.var_track_per = tk.IntVar() self.var_save_txt = tk.BooleanVar() self.var_cache_size.set(500) self.var_sess_dur.set(1) self.var_rec_zeros.set(1) self.var_emulate_wheel.set(emulate_wheel) self.var_track_per.set(50) self.var_save_txt.set(True) self.parameters = { 'emulate_wheel': self.var_emulate_wheel, 'session_dur': self.var_sess_dur, 'record_zeros': self.var_rec_zeros, 'track_period': self.var_track_per, } self.var_print_arduino = tk.BooleanVar() self.var_stop = tk.BooleanVar() self.var_print_arduino.set(print_arduino) self.var_stop.set(False) # Counters # IMPORTANT: need to keep `counter_vars` in same order as `arduino_events` self.var_counter_wheel = tk.IntVar() counter_vars = [self.var_counter_wheel] self.counter = { ev: var_count for ev, var_count in zip(arduino_events.values(), counter_vars) } self.var_start_time = tk.StringVar() self.var_stop_time = tk.StringVar() # Lay out GUI frame_setup = tk.Frame(parent) frame_setup.grid(row=0, column=0) frame_setup_col0 = tk.Frame(frame_setup) frame_setup_col1 = tk.Frame(frame_setup) # frame_setup_col2 = tk.Frame(frame_setup) frame_setup_col0.grid(row=0, column=0, sticky='we') frame_setup_col1.grid(row=0, column=1, sticky='we') # frame_setup_col2.grid(row=0, column=2, sticky='we') frame_monitor = tk.Frame(parent) frame_monitor.grid(row=1, column=0) # frame_monitor.rowconfigure(0, weight=1) # frame_monitor.columnconfigure(1, weight=1) # Session frame frame_params = tk.Frame(frame_setup_col0) frame_params.grid(row=0, column=0, padx=15, pady=5) frame_params.columnconfigure(0, weight=1) frame_session = tk.Frame(frame_params) frame_misc = tk.Frame(frame_params) frame_session.grid(row=0, column=0, sticky='e', padx=px, pady=py) frame_misc.grid(row=2, column=0, sticky='e', padx=px, pady=py) # Arduino frame frame_arduino = ttk.LabelFrame(frame_setup_col0, text='Arduino') frame_arduino.grid(row=1, column=0, padx=px, pady=py, sticky='we') # Notes frame frame_notes = tk.Frame(frame_setup_col1) frame_notes.grid(row=0, sticky='wens', padx=px, pady=py) frame_notes.grid_columnconfigure(0, weight=1) # Saved file frame frame_file = tk.Frame(frame_setup_col1) frame_file.grid(row=1, column=0, padx=px, pady=py, sticky='we') frame_file.columnconfigure(0, weight=3) frame_file.columnconfigure(1, weight=1) # Start-stop frame frame_start = tk.Frame(frame_setup_col1) frame_start.grid(row=3, column=0, sticky='we', padx=px, pady=py) frame_start.grid_columnconfigure(0, weight=1) frame_start.grid_columnconfigure(1, weight=1) # Monitor frame frame_counter = tk.Frame(frame_monitor) frame_live = tk.Frame(frame_monitor) frame_counter.grid(row=0, column=0, padx=px, pady=py, sticky='we') frame_live.grid(row=1, column=0, padx=px, pady=py, sticky='wens') # Add GUI components ## frame_params ### frame_session ## UI for trial control self.entry_session_dur = ttk.Entry(frame_session, textvariable=self.var_sess_dur, width=entry_width) tk.Label(frame_session, text='Session duration (min): ', anchor='e').grid(row=0, column=0, sticky='e') self.entry_session_dur.grid(row=0, column=1, sticky='w') ### frame_misc ### UI for miscellaneous parameters self.entry_rec_all = ttk.Checkbutton(frame_misc, variable=self.var_rec_zeros) self.entry_track_period = ttk.Entry(frame_misc, textvariable=self.var_track_per, width=entry_width) tk.Label(frame_misc, text='Record zeros: ', anchor='e').grid(row=0, column=0, sticky='e') tk.Label(frame_misc, text='Track period (ms): ', anchor='e').grid(row=1, column=0, sticky='e') self.entry_rec_all.grid(row=0, column=1, sticky='w') self.entry_track_period.grid(row=1, column=1, sticky='w') ### frame_arduino ### UI for Arduino self.arduino = arduino.Arduino(frame_arduino, main_window=self.parent, verbose=self.verbose, params=self.parameters) self.arduino.grid(row=0, column=0, sticky='we') self.arduino.var_uploaded.trace_add('write', self.gui_util) ## Notes self.entry_subject = ttk.Entry(frame_notes) self.entry_weight = ttk.Entry(frame_notes) self.scrolled_notes = ScrolledText(frame_notes, width=20, height=15) tk.Label(frame_notes, text='Subject: ').grid(row=0, column=0, sticky='e') tk.Label(frame_notes, text='Weight (g): ').grid(row=1, column=0, sticky='e') tk.Label(frame_notes, text='Notes:').grid(row=2, column=0, columnspan=2, sticky='w') self.entry_subject.grid(row=0, column=1, sticky='w') self.entry_weight.grid(row=1, column=1, sticky='w') self.scrolled_notes.grid(row=3, column=0, columnspan=2, sticky='wens') ## UI for saved file self.entry_save_file = ttk.Entry(frame_file) self.button_set_file = ttk.Button(frame_file, command=self.get_save_file) tk.Label(frame_file, text='File to save data:', anchor='w').grid(row=0, column=0, columnspan=2, sticky='w') self.entry_save_file.grid(row=1, column=0, sticky='wens') self.button_set_file.grid(row=1, column=1, sticky='e') folder_icon_file = os.path.join(source_path, 'graphics/folder.png') icon_folder = ImageTk.PhotoImage(file=folder_icon_file) self.button_set_file.config(image=icon_folder) self.button_set_file.image = icon_folder ## Start frame self.button_start = ttk.Button( frame_start, text='Start', command=lambda: self.parent.after(0, self.start)) self.button_stop = ttk.Button(frame_start, text='Stop', command=lambda: self.var_stop.set(True)) self.button_start.grid(row=2, column=0, sticky='we') self.button_stop.grid(row=2, column=1, sticky='we') ## Counter frame tk.Label(frame_counter, text='Start time: ').grid(row=0, column=0, sticky='e') tk.Label(frame_counter, text='End time: ').grid(row=1, column=0, sticky='e') self.entry_start_time = ttk.Entry(frame_counter, textvariable=self.var_start_time, state='readonly', width=entry_width) self.entry_stop_time = ttk.Entry(frame_counter, textvariable=self.var_stop_time, state='readonly', width=entry_width) self.entry_start_time.grid(row=0, column=1, sticky='wens') self.entry_stop_time.grid(row=1, column=1, sticky='wens') ## Live frame data_types = {arduino_events[code_wheel]: 'line'} # tk.Label(frame_live, text='Also under construction').grid() self.live_view = live_data_view.LiveDataView(frame_live, x_history=30000, scale_x=0.001, data_types=data_types, ylim=(-25, 50), xlabel='Time (s)') ###### GUI OBJECTS ORGANIZED BY TIME ACTIVE ###### # List of components to disable at open self.obj_to_disable_on_upload = [ child for child in (frame_session.winfo_children() + frame_misc.winfo_children()) ] self.obj_to_enable_on_upload = [self.button_start] self.obj_to_disable_at_open = [ self.entry_session_dur, self.entry_track_period, ] self.obj_to_enable_at_open = [ self.button_start, ] self.obj_to_disable_at_start = [ self.entry_subject, self.entry_weight, self.entry_save_file, self.button_set_file, self.button_start, ] self.obj_to_enable_at_start = [self.button_stop] # Default values self.button_start['state'] = 'disabled' self.button_stop['state'] = 'disabled' ###### SESSION VARIABLES ###### self.q_serial = Queue() # self.update_serial() def get_save_file(self): ''' Opens prompt for file for data to be saved Runs when button beside save file is pressed. ''' save_file = tkFileDialog.asksaveasfilename( initialdir=self.entry_save_file.get(), defaultextension='.h5', filetypes=[ ('CSV file', '*.csv'), ('HDF5 file', '*.h5 *.hdf5'), ]) self.entry_save_file.delete(0, 'end') self.entry_save_file.insert(0, save_file) def gui_util(self, option, indx=None, mode=None): ''' Updates GUI components Enable and disable components based on events to prevent bad stuff. ''' if option == 'start': for obj in self.obj_to_disable_at_start: obj['state'] = 'disabled' for obj in self.obj_to_enable_at_start: obj['state'] = 'normal' elif option == 'stop': for obj in self.obj_to_disable_at_start: obj['state'] = 'normal' for obj in self.obj_to_enable_at_start: obj['state'] = 'disabled' elif option == 'uploaded': new_state = 'disable' if self.parent.getvar( 'uploaded') else 'normal' for obj in self.obj_to_disable_on_upload: obj['state'] = new_state for obj in self.obj_to_enable_on_upload: obj['state'] = 'disable' if new_state == 'normal' else 'normal' def start(self, code_start='E'): self.gui_util('start') now = datetime.now() # Create default filename if not defined if not self.entry_save_file.get(): # Default file name if not os.path.exists('data'): os.makedirs('data') if self.var_save_txt.get(): ext = '.csv' else: ext = '.h5' filename = 'data/data-' + now.strftime('%y%m%d-%H%M%S') + ext state = self.entry_save_file['state'] self.entry_save_file['state'] = 'normal' self.entry_save_file.delete(0, 'end') self.entry_save_file.insert(0, filename) self.entry_save_file['state'] = state else: if os.path.splitext( self.entry_save_file.get())[1] in ['.h5', '.hdf5']: self.var_save_txt.set(False) # Filename for HDF5 file if self.var_save_txt.get(): self.hdf5_filename = os.path.splitext( self.entry_save_file.get())[0] + '.h5' else: self.hdf5_filename = self.entry_save_file.get() # Try to open/create file try: # Create file if it doesn't already exist, append otherwise ('a' parameter) with h5py.File(self.hdf5_filename, 'a') as _: pass except IOError: tkMessageBox.showerror('File error', 'Could not create file to save data.') self.gui_util('stop') return # Prepare HDF5 file with h5py.File(self.hdf5_filename, 'a') as hdf5_file: # Create group for experiment # Append to existing file (if applicable). If group already exists, append number to name. date = str(now.date()) subj = self.entry_subject.get() or '?' index = 0 file_index = '' while True: try: hdf5_grp_exp = hdf5_file.create_group( f'{subj}/{date + file_index}') except (RuntimeError, ValueError): index += 1 file_index = '-' + str(index) else: break self.hdf5_grp_name = f'{subj}/{date + file_index}' hdf5_grp_exp['weight'] = int( self.entry_weight.get()) if self.entry_weight.get() else 0 # *** Create file structure *** self.cache_size = self.var_cache_size.get() nstepframes = 2 * 60000 * self.var_sess_dur.get( ) / self.var_track_per.get() chunk_size = (self.cache_size, 2) hdf5_grp_behav = hdf5_grp_exp.create_group('behavior') hdf5_grp_behav.create_dataset(name='wheel', dtype='int32', shape=(int(nstepframes) * 1.1, 2), chunks=chunk_size) # Store session parameters into behavior group for key, value in self.parameters.items(): hdf5_grp_behav.attrs[key] = value.get() # Create cache self.cache = { 'wheel': np.zeros((self.cache_size, 2)), } # Reset counters and clear data for counter in self.counter.values(): counter.set(0) self.live_view.clear_data() # Clear Queues for q in [self.q_serial]: with q.mutex: q.queue.clear() # Create thread to scan serial suppress = [ # code_wheel if self.var_suppress_print_movement.get() else None ] thread_scan = threading.Thread(target=scan_serial, args=(self.q_serial, self.arduino.ser, self.var_print_arduino.get(), suppress, code_end)) thread_scan.daemon = True # Don't remember why this is here # Start session self.arduino.ser.flushInput() # Remove data from serial input self.arduino.ser.write(code_start.encode()) thread_scan.start() self.start_time = datetime.now() end_time = self.start_time + timedelta(minutes=self.var_sess_dur.get()) self.var_start_time.set(self.start_time.strftime('%H:%M:%S')) self.var_stop_time.set(end_time.strftime('%H:%M:%S')) print('Session start {}'.format(self.start_time)) # Update GUI self.update_session() def update_session(self): # Checks Queue for incoming data from arduino. Data arrives as comma- # separated values with the first element ('code') defining the type of # data. # Rate to update GUI # Should be faster than data coming in, ie tracking rate refresh_rate = 10 # End on 'Stop' button (by user) if self.var_stop.get(): self.var_stop.set(False) self.arduino.ser.write('0'.encode()) print('User triggered stop, sending signal to Arduino...') # Watch incoming queue # Data has format: [code, ts, extra values] # Empty queue before leaving. Otherwise, a backlog will grow. while not self.q_serial.empty(): code, ts, data = self.q_serial.get() # print(code, ts, data) # End session if code == code_end: arduino_end = ts print('Arduino ended, finalizing data...') self.stop_session(arduino_end=arduino_end) return # Record data to cache event_var = arduino_events[code] event_n = self.counter[arduino_events[code]].get() cache_n = event_n % self.cache_size self.cache[event_var][cache_n, :] = [ts, data] self.counter[event_var].set(event_n + 1) # Record data to HDF5 when cache fills if cache_n >= self.cache_size - 1: with h5py.File(self.hdf5_filename, 'a') as hdf5_file: cache_slice = slice(event_n - cache_n, event_n + 1) dataset = hdf5_file[ f'{self.hdf5_grp_name}/behavior/{event_var}'] dataset[cache_slice, :] = self.cache[event_var] self.cache[event_var][:] = 0 # Update live view if code == code_wheel: self.live_view.update_view([ts, data], name=arduino_events[code_wheel]) self.parent.after(refresh_rate, self.update_session) def stop_session(self, frame_cutoff=None, arduino_end=None): '''Finalize session Closes hardware connections and saves HDF5 data file. Resets GUI. ''' end_time = datetime.now().strftime('%H:%M:%S') print('Session ended at ' + end_time) self.gui_util('stop') self.arduino.close_serial() # Finalize data print('Finalizing behavioral data') with h5py.File(self.hdf5_filename, 'a') as hdf5_file: # Write remainder of cache hdf5_grp_behav = hdf5_file[f'{self.hdf5_grp_name}/behavior'] hdf5_grp_behav.attrs['start_time'] = self.start_time.strftime( '%H:%M:%S') hdf5_grp_behav.attrs['end_time'] = end_time hdf5_grp_behav.attrs['arduino_end'] = arduino_end for ev in arduino_events.values(): event_n = self.counter[ev].get() cache_n = event_n % self.cache_size cache_slice = slice(event_n - cache_n, event_n) # No `+ 1`???????? dataset = hdf5_grp_behav[ev] # pdb.set_trace() dataset[cache_slice, :] = self.cache[ev][:cache_n, :] dataset.resize((event_n, 2)) # Write notes hdf5_file[self.hdf5_grp_name].attrs['notes'] = \ self.scrolled_notes.get(1.0, 'end') # Create csv files if indicated if self.var_save_txt.get(): filename_base = os.path.splitext(self.entry_save_file.get())[0] with h5py.File(self.hdf5_filename, 'r') as hdf5_file: hdf5_grp_behav = hdf5_file[f'{self.hdf5_grp_name}/behavior'] # Save attributes subj = self.entry_subject.get() or '?' wt = hdf5_file[f"{self.hdf5_grp_name}/weight"].value notes = hdf5_file[self.hdf5_grp_name].attrs['notes'] with open(f"{filename_base}-attributes.csv", 'w') as file: file.write(f"subject,{subj}\n") file.write(f"weight,{wt}\n") for k, v in hdf5_grp_behav.attrs.items(): file.write(f"{k},{v}\n") file.write(f"notes:\n{notes}") # Save datasets for ev in arduino_events.values(): np.savetxt(f"{filename_base}-{ev}.csv", hdf5_grp_behav[ev], delimiter=',') os.remove(self.hdf5_filename) # Clear self.parameters self.parameters = {} # Clear GUI self.entry_subject.delete(0, 'end') self.entry_weight.delete(0, 'end') self.entry_save_file.delete(0, 'end') self.scrolled_notes.delete('1.0', 'end') print('All done!') pdb.set_trace()
class AppletEditTimecard(object): # pylint: disable=too-many-instance-attributes """""" def __init__(self, parent): """""" self.parent = parent self.timecard_obj = None self.edit_amt_app = None self.root = tkinter.Toplevel() self.root.iconify() self.root.title('Edit Timecard') self.root.geometry('800x%s' % 600) self.msgvar = tkinter.StringVar(self.root) self.date = tkinter.StringVar(self.root) tkinter.Label( self.root, text='Description' ).grid(row=0, column=0) self.msg = tkinter.Message( self.root, textvariable=self.msgvar ).grid(row=0, column=1, sticky=tkinter.E) tkinter.Label( self.root, text='Date' ).grid(row=1, column=0, sticky=tkinter.E) tkinter.Entry( self.root, textvariable=self.date ).grid(row=1, column=1, sticky=tkinter.W) tkinter.Label( self.root, text='Notes' ).grid(row=2, column=0, sticky=tkinter.E) self.notes_entry = ScrolledText(self.root, height=10) self.notes_entry.grid(row=2, column=1, sticky=tkinter.W) tkinter.Label( self.root, text='Period Start' ).grid(row=3, column=0, sticky=tkinter.E) self.period_start = tkinter.StringVar(self.root) self.period_start_entry = tkinter.Entry(self.root, textvariable=self.period_start) self.period_start_entry.grid(row=3, column=1, sticky=tkinter.W) period_end_label = tkinter.Label(self.root, text='Period End') period_end_label.grid(row=4, column=0, sticky=tkinter.E) self.period_end = tkinter.StringVar(self.root) self.period_end_entry = tkinter.Entry(self.root, textvariable=self.period_end) self.period_end_entry.grid(row=4, column=1, sticky=tkinter.W) message_label = tkinter.Label(self.root, text='Message') message_label.grid(row=5, column=0, sticky=tkinter.E) self.message_entry = tkinter.Text(self.root, height=2) self.message_entry.grid(row=5, column=1, sticky=tkinter.W) button_frame = tkinter.Frame(self.root) button_frame.grid(row=6, column=1, sticky=tkinter.E) save_button = tkinter.Button( button_frame, text="Save", name="save-button", command=self.save_btn, padx=7, pady=2) save_button.pack(side='left') edit_amounts_btn = tkinter.Button( button_frame, text="Edit Amounts", name="edit-amounts-button", command=self.edit_amounts_btn_cb, padx=7, pady=2) edit_amounts_btn.pack(side='left') cancel_button = tkinter.Button( button_frame, text="Cancel", name="cancel-button", command=self.cancel_btn, padx=7, pady=2) cancel_button.pack(side='left') def cancel_btn(self): """""" self.parent.root.deiconify() self.root.iconify() def edit_amounts_btn_cb(self): """""" if self.edit_amt_app is None: self.edit_amt_app = AppletEditTimecardAmounts(self) self.root.iconify() self.edit_amt_app.root.deiconify() self.edit_amt_app.set_edit_form(self.timecard_obj) def form_to_obj(self): """Update Timecard obj from form""" self.timecard_obj.period_start = dt.strptime(self.period_start.get(), api.DATE_INPUT_FORMAT).strftime(api.DATE_ISO_FORMAT) self.timecard_obj.period_end = dt.strptime( self.period_end.get(), api.DATE_INPUT_FORMAT).strftime(api.DATE_ISO_FORMAT) self.timecard_obj.date = dt.strptime(self.date.get(), api.DATE_INPUT_FORMAT).strftime(api.DATE_ISO_FORMAT) self.timecard_obj.message = self.message_entry.get('1.0', 'end-1c') self.timecard_obj.notes = self.notes_entry.get('1.0', 'end-1c') def save_btn(self): """Saves edited timecard before posting.""" self.form_to_obj() print(self.timecard_obj.to_dict()) result = api.TimecardSchema().load(self.timecard_obj.to_dict()) if result.errors: print(result.errors) else: lib.save_timecard(self.timecard_obj.to_dict()) self.root.iconify() self.parent.root.deiconify() self.parent.load() def set_edit_form(self, timecard_dict): """""" self.timecard_obj = api.Timecard(**timecard_dict) self.root.title('Edit Timecard Number %s' % self.timecard_obj.id) self.date.set(dt.strptime( self.timecard_obj.date, api.DATE_ISO_FORMAT).strftime(api.DATE_INPUT_FORMAT)) self.notes_entry.delete('1.0', tkinter.END) self.notes_entry.insert( tkinter.END, self.timecard_obj.notes if self.timecard_obj.notes else '') self.period_start.set( dt.strptime( self.timecard_obj.period_start, api.DATE_ISO_FORMAT).strftime(api.DATE_INPUT_FORMAT)) self.period_end.set( dt.strptime( self.timecard_obj.period_end, api.DATE_ISO_FORMAT).strftime(api.DATE_INPUT_FORMAT)) self.message_entry.delete('1.0', tkinter.END) self.message_entry.insert( tkinter.END, self.timecard_obj.message if self.timecard_obj.message else '') self.update_summary() def update_summary(self): """""" set_edit_timecard_msg(self.msgvar, self.timecard_obj)
class RssTkinkerGui: def __init__(self): self.tk = Tk() self.pane = PanedWindow(self.tk, orient=HORIZONTAL, borderwidth=3) self.rssContent = ScrolledText(self.tk, ) # Text wrap=WORD self.rssContent.insert('0.0', ''' В поле новой ленты: ввести ссылку и <Enter> чтобы добавить ленту В списке: <F5> чтобы одновить <Delete> чтобы удалить ''') self.fr = Frame(self.tk) self.newUrlEntry = Entry(self.fr, width=28) self.urlsListbox = Listbox(self.fr,selectmode=SINGLE) def on_urls_listbox_select(self,event): feed_url = self.urlsListbox.get(self.urlsListbox.curselection()[0]) feed = RssFeed() feed.load_from_database(feed_url) self.rssContent.delete('0.0', END) for item in feed.items: # description & pub_date self.rssContent.insert('0.0', '\n' + item.pub_date + '\n\n\t' + item.description + '\n_______________________________________\n\n') # title with link hyperlink = HyperlinkManager(self.rssContent, item.link) self.rssContent.insert('0.0', item.title, hyperlink.add(self.link_callback)) def link_callback(self,asd): # TODO browser print('LINK! ' + asd) webbrowser.open(asd) def on_urls_listbox_delete(self,event): feed_url = self.urlsListbox.get(self.urlsListbox.curselection()[0]) feed = RssFeed() feed.remove_from_database(feed_url) self.fill_urlsListbox() def on_urls_listbox_f5(self,event): feed_url = self.urlsListbox.get(self.urlsListbox.curselection()[0]) feed = RssFeed() feed.load_from_xml_rss(feed_url) feed.store_to_database() self.on_urls_listbox_select(event) def add_new_url(self,event): newUrl = self.newUrlEntry.get() thread = Thread(load_from_xml_into_db(newUrl)) thread.start() self.fill_urlsListbox() def fill_urlsListbox(self): self.urlsListbox.delete(0, END) for url in get_feed_urls_list(): self.urlsListbox.insert(END, url) def launch(self): self.tk.wm_minsize(width=400, height=100) self.tk.title("Adelier's RssFeadReader") self.tk.geometry('800x600') self.pane.pack(side=LEFT, fill=BOTH, expand=TRUE) self.pane.add(self.fr) #fr.pack(side=LEFT, fill=Y, expand=TRUE) self.newUrlEntry.bind("<Return>", self.add_new_url) self.newUrlEntry.pack(side=TOP, anchor=W, fill=X) self.urlsListbox.bind('<<ListboxSelect>>', self.on_urls_listbox_select) self.urlsListbox.bind('<Delete>', self.on_urls_listbox_delete) self.urlsListbox.bind('<F5>', self.on_urls_listbox_f5) self.fill_urlsListbox() self.urlsListbox.pack(anchor=W, fill=BOTH, expand=TRUE) self.pane.add(self.rssContent) self.tk.mainloop()
class Edit(Screen): def __init__(self): Screen.__init__(self) self.checked = tk.IntVar() self.editkey = 0 self.lbl_title = tk.Label(self, text=" Edit Game ", font=TITLE_FONT) self.lbl_title.grid(row=0, column=0, columnspan=4, pady=20) self.lbl_genre = tk.Label(self, text="Genre:", font=NON_TITLE_FONT) self.lbl_genre.grid(row=1, column=0) self.ent_genre = tk.Entry(self, font=NON_TITLE_FONT, bd=3) self.ent_genre.grid(row=1, column=1) self.lbl_title = tk.Label(self, text="Title:", font=NON_TITLE_FONT) self.lbl_title.grid(row=1, column=2) self.ent_title = tk.Entry(self, font=NON_TITLE_FONT, bd=3) self.ent_title.grid(row=1, column=3) self.lbl_developer = tk.Label(self, text="Developer:", font=NON_TITLE_FONT) self.lbl_developer.grid(row=2, column=0) self.ent_developer = tk.Entry(self, font=NON_TITLE_FONT, bd=3) self.ent_developer.grid(row=2, column=1) self.lbl_publisher = tk.Label(self, text="Publisher:", font=NON_TITLE_FONT) self.lbl_publisher.grid(row=2, column=2) self.ent_publisher = tk.Entry(self, font=NON_TITLE_FONT, bd=3) self.ent_publisher.grid(row=2, column=3) self.lbl_platform = tk.Label(self, text="Platform:", font=NON_TITLE_FONT) self.lbl_platform.grid(row=3, column=0) self.ent_platform = tk.Entry(self, font=NON_TITLE_FONT, bd=3) self.ent_platform.grid(row=3, column=1) self.lbl_release_date = tk.Label(self, text="Release Date:", font=NON_TITLE_FONT) self.lbl_release_date.grid(row=3, column=2) self.ent_release_date = tk.Entry(self, font=NON_TITLE_FONT, bd=3) self.ent_release_date.grid(row=3, column=3) self.lbl_rating = tk.Label(self, text="Rating:", font=NON_TITLE_FONT) self.lbl_rating.grid(row=4, column=0) self.ent_rating = tk.Entry(self, font=NON_TITLE_FONT, bd=3) self.ent_rating.grid(row=4, column=1) self.gamemodes = ["Single", "Multi", "Either"] self.tk_which_gamemode = tk.StringVar(self) self.tk_which_gamemode.set(self.gamemodes[0]) self.lbl_gamemodes = tk.Label(self, text="Gamemode(s):", font=NON_TITLE_FONT) self.lbl_gamemodes.grid(row=4, column=2) self.dbx_gamemodes = tk.OptionMenu(self, self.tk_which_gamemode, *self.gamemodes) self.dbx_gamemodes.grid(row=4, column=3, sticky="news") self.lbl_price = tk.Label(self, text="Price (USD):", font=NON_TITLE_FONT) self.lbl_price.grid(row=5, column=0) self.ent_price = tk.Entry(self, font=NON_TITLE_FONT, bd=3) self.ent_price.grid(row=5, column=1) self.lbl_purchase_date = tk.Label(self, text="Purchase Date:", font=NON_TITLE_FONT) self.lbl_purchase_date.grid(row=5, column=2) self.ent_purchase_date = tk.Entry(self, font=NON_TITLE_FONT, bd=3) self.ent_purchase_date.grid(row=5, column=3) self.chk_completed = tk.Checkbutton(self, text="Completed?", variable=self.checked, font=NON_TITLE_FONT) self.chk_completed.grid(row=6, column=0, columnspan=4, sticky="news") self.lbl_notes = tk.Label(self, text="Notes:", font=NON_TITLE_FONT) self.lbl_notes.grid(row=7, column=0, columnspan=4, sticky="news") self.scr_notes = ScrolledText(self, width=40, height=8) self.scr_notes.grid(row=8, column=0, columnspan=4) #Buttons to cancel adding/editing, reset the changes, or to confirm changes frm_add_or_edit_buttons = Edit_Buttons(self) frm_add_or_edit_buttons.grid(row=9, column=0, columnspan=4, sticky="news") def update(self): entry = games[self.editkey] self.ent_genre.delete(0, "end") self.ent_genre.insert(0, entry[0]) self.ent_title.delete(0, "end") self.ent_title.insert(0, entry[1]) self.ent_developer.delete(0, "end") self.ent_developer.insert(0, entry[2]) self.ent_publisher.delete(0, "end") self.ent_publisher.insert(0, entry[3]) self.ent_platform.delete(0, "end") self.ent_platform.insert(0, entry[4]) self.ent_release_date.delete(0, "end") self.ent_release_date.insert(0, entry[5]) self.ent_rating.delete(0, "end") self.ent_rating.insert(0, entry[6]) for i in range(3): if entry[7] == self.gamemodes[i]: self.tk_which_gamemode.set(self.gamemodes[i]) self.ent_price.delete(0, "end") self.ent_price.insert(0, entry[8]) if entry[9] == "Yes": self.chk_completed.toggle() self.ent_purchase_date.delete(0, "end") self.ent_purchase_date.insert(0, entry[10]) self.scr_notes.delete('0.0', "end") self.scr_notes.insert('0.0', entry[11])
class Add(Screen): def __init__(self): Screen.__init__(self) self.checked = tk.IntVar() self.lbl_title = tk.Label(self, text=" Add Game ", font=TITLE_FONT) self.lbl_title.grid(row=0, column=0, columnspan=4, pady=20) self.lbl_genre = tk.Label(self, text="Genre:", font=NON_TITLE_FONT) self.lbl_genre.grid(row=1, column=0) self.ent_genre = tk.Entry(self, font=NON_TITLE_FONT, bd=3) self.ent_genre.grid(row=1, column=1) self.lbl_title = tk.Label(self, text="Title:", font=NON_TITLE_FONT) self.lbl_title.grid(row=1, column=2) self.ent_title = tk.Entry(self, font=NON_TITLE_FONT, bd=3) self.ent_title.grid(row=1, column=3) self.lbl_developer = tk.Label(self, text="Developer:", font=NON_TITLE_FONT) self.lbl_developer.grid(row=2, column=0) self.ent_developer = tk.Entry(self, font=NON_TITLE_FONT, bd=3) self.ent_developer.grid(row=2, column=1) self.lbl_publisher = tk.Label(self, text="Publisher:", font=NON_TITLE_FONT) self.lbl_publisher.grid(row=2, column=2) self.ent_publisher = tk.Entry(self, font=NON_TITLE_FONT, bd=3) self.ent_publisher.grid(row=2, column=3) self.lbl_platform = tk.Label(self, text="Platform:", font=NON_TITLE_FONT) self.lbl_platform.grid(row=3, column=0) self.ent_platform = tk.Entry(self, font=NON_TITLE_FONT, bd=3) self.ent_platform.grid(row=3, column=1) self.lbl_release_date = tk.Label(self, text="Release Date:", font=NON_TITLE_FONT) self.lbl_release_date.grid(row=3, column=2) self.ent_release_date = tk.Entry(self, font=NON_TITLE_FONT, bd=3) self.ent_release_date.grid(row=3, column=3) self.lbl_rating = tk.Label(self, text="Rating:", font=NON_TITLE_FONT) self.lbl_rating.grid(row=4, column=0) self.ent_rating = tk.Entry(self, font=NON_TITLE_FONT, bd=3) self.ent_rating.grid(row=4, column=1) #Setup for the "gamemode(s)" drop-down menu self.gamemodes = ["Single", "Multi", "Either"] self.tk_which_gamemode = tk.StringVar(self) self.tk_which_gamemode.set(self.gamemodes[0]) self.lbl_gamemodes = tk.Label(self, text="Gamemode(s):", font=NON_TITLE_FONT) self.lbl_gamemodes.grid(row=4, column=2) self.dbx_gamemodes = tk.OptionMenu(self, self.tk_which_gamemode, *self.gamemodes) self.dbx_gamemodes.grid(row=4, column=3, sticky="news") self.lbl_price = tk.Label(self, text="Price (USD):", font=NON_TITLE_FONT) self.lbl_price.grid(row=5, column=0) self.ent_price = tk.Entry(self, font=NON_TITLE_FONT, bd=3) self.ent_price.grid(row=5, column=1) self.lbl_purchase_date = tk.Label(self, text="Purchase Date:", font=NON_TITLE_FONT) self.lbl_purchase_date.grid(row=5, column=2) self.ent_purchase_date = tk.Entry(self, font=NON_TITLE_FONT, bd=3) self.ent_purchase_date.grid(row=5, column=3) self.chk_completed = tk.Checkbutton(self, text="Completed?", font=NON_TITLE_FONT) self.chk_completed.grid(row=6, column=0, columnspan=4, sticky="news") self.lbl_notes = tk.Label(self, text="Notes:", font=NON_TITLE_FONT) self.lbl_notes.grid(row=7, column=0, columnspan=4, sticky="news") self.scr_notes = ScrolledText(self, width=40, height=8) self.scr_notes.grid(row=8, column=0, columnspan=4) #Buttons to cancel adding/editing, reset the changes, or to confirm changes frm_add_or_edit_buttons = Add_Buttons(self) frm_add_or_edit_buttons.grid(row=9, column=0, columnspan=4, sticky="news") def reset(self): self.ent_genre.delete(0, "end") self.ent_title.delete(0, "end") self.ent_developer.delete(0, "end") self.ent_publisher.delete(0, "end") self.ent_platform.delete(0, "end") self.ent_release_date.delete(0, "end") self.ent_rating.delete(0, "end") self.tk_which_gamemode.set(self.gamemodes[0]) self.ent_price.delete(0, "end") self.chk_completed.deselect() self.ent_purchase_date.delete(0, "end") self.scr_notes.delete(1.0, "end")
class GUI: BUTTON_H = 20 BUTTON_W = 80 def __init__(self, w, h): self.w = w self.h = h self.msg_list = {} # {id: [sender, time, msg], ...} self.friend_list = {} # {id: [username, login_status], ...} self.friend_req_list = {} # {id: req_note, ...} self.id2item_friend_treeview_table = {} self.selected_fri_id = None self.root = Tk() self.root.geometry("{}x{}".format(w, h)) self.logic_proc_ins = logicProc() self._init_ui() def _init_ui(self): # Friend treeview self.friend_treeview = Treeview(master=self.root, columns=("Friends_ID", "Friends_Name"), show="headings") self.friend_treeview.heading("#1", text="ID") self.friend_treeview.heading("#2", text="Name") self.friend_treeview.column("#1", width=int(self.w / 8)) self.friend_treeview.column("#2", width=int(self.w / 8)) self.friend_treeview.place(x=0, y=self.BUTTON_H) self.friend_treeview.bind("<<TreeviewSelect>>", self._friend_treeview_select_change) # Scrollbar for friend treeview friend_tv_scrollbar = Scrollbar(master=self.root, orient="vertical", command=self.friend_treeview.yview) friend_tv_scrollbar.place(x=int(self.w / 4), y=self.BUTTON_H) # friend_tv_scrollbar.config(command = self.friend_treeview.yview) self.friend_treeview.configure(yscrollcommand=friend_tv_scrollbar.set) # Display text field self.display_msg_box = ScrolledText( master=self.root, height=int((self.h - 2 * self.BUTTON_H) / 20), width=int((self.w / 4 * 3 - 10) / 10)) self.display_msg_box.place(x=int(self.w / 4 + 10), y=self.BUTTON_H) # Display input_box self.input_box = Entry( master=self.root, width=int((self.w * (3 / 4) - 10 - 3 * self.BUTTON_W) / 18)) self.input_box.place(x=int(self.w / 4 + 10 + 2 * self.BUTTON_W), y=self.h - self.BUTTON_H) # View all friends button self.view_all_friends_bt = Button( master=self.root, text="All friends", command=self._view_all_friends_bt_clicked) self.view_all_friends_bt.place(x=0, y=0) # Friend request self.friend_request_bt = Button( master=self.root, text="Request", command=self._friend_request_bt_clicked) self.friend_request_bt.place(x=self.BUTTON_W, y=0) # Add friend self.add_friend_bt = Button(master=self.root, text="Add friend", command=self._add_friend_bt_clicked) self.add_friend_bt.place(x=2 * self.BUTTON_W, y=0) # Login / logout button self.loginout_bt = Button(master=self.root, text="Login", command=self._loginout_bt_clicked) self.loginout_bt.place(x=3 * self.BUTTON_W, y=0) # signup self.signup_bt = Button(master=self.root, text="Sign up", command=self._signup_bt_clicked) self.signup_bt.place(x=4 * self.BUTTON_W, y=0) # erase selected history button self.clear_selected_history_bt = Button( master=self.root, text="Clear history", command=self._clear_selected_history_bt_clicked) self.clear_selected_history_bt.place(x=int(self.w / 4 + 10 + self.BUTTON_W), y=self.h - self.BUTTON_H) # send button self.send_bt = Button(master=self.root, text="Send", command=self._send_bt_clicked) self.send_bt.place(x=self.w - self.BUTTON_W, y=self.h - self.BUTTON_H) def run(self): try: with open("client.config", "r") as f: data = f.read() data = data.split("\n") data = [data[i].split(":") for i in range(len(data))] for i in range(len(data)): if data[i][0] == "SERVER_ADDR": server_addr = eval(data[i][1]) break else: raise (Exception) except: self._pop_top_window(200, 200, [ "Fail to load config file!", "Check your client.config file!" ], command=self.root.destroy) conn_rt = self.logic_proc_ins.connect(server_addr) if conn_rt == 0: self._pop_top_window(200, 200, [ "Fail to connect to server!", "Server address is {}".format(server_addr) ], command=self.root.destroy) self.root.after(50, self._refresh) print("run") self.root.mainloop() def _refresh(self): # print( # self.msg_list, # self.friend_list, # self.friend_req_list, # self.selected_fri_id, # self.id2item_friend_treeview_table # ) if self.logic_proc_ins.login_status == True: data = self.logic_proc_ins.refresh() if data != 0: # print("data", data) self.msg_list = data["msg"] self.friend_list = data["friend"] self.friend_req_list = data["freq"] if (self.selected_fri_id not in self.msg_list) and ( self.selected_fri_id != None): print("msglist add", self.selected_fri_id) self.msg_list.update({self.selected_fri_id: []}) self._refresh_friend_treeview() if self.selected_fri_id != None: self._refresh_msgbox(self.selected_fri_id) self.root.after(1000, self._refresh) def _loginout_bt_clicked(self): if self.logic_proc_ins.login_status == ONLINE: rt = self.logic_proc_ins.sign_out() if rt != 1: self._pop_top_window(200, 100, ["Fail to log out!"]) else: self.loginout_bt["text"] = "Login " self.msg_list = {} self.friend_list = {} self.friend_req_list = {} else: LOGINOUT_WIN_W = 200 LOGINOUT_WIN_H = 150 top = Toplevel() top.geometry("{}x{}".format(LOGINOUT_WIN_W, LOGINOUT_WIN_H)) Label(top, text="ID:").place(x=0, y=0) Label(top, text="PWD:").place(x=0, y=int(LOGINOUT_WIN_H / 3)) id_entry = Entry(top, width=20) pwd_entry = Entry(top, width=20) id_entry.place(x=int(LOGINOUT_WIN_W / 4), y=0) pwd_entry.place(x=int(LOGINOUT_WIN_W / 4), y=int(LOGINOUT_WIN_H / 3)) def _cancel(): top.destroy() def _login(): user_id = id_entry.get() pwd = pwd_entry.get() try: user_id = int(user_id) if pwd == "": raise (Exception) except: self._pop_top_window(200, 100, ["Invalid input!"]) # warning = Toplevel() # Message(warning, text = "Invalid input!").pack() # def destroy_warning(): # warning.destroy() # Button(warning, text = "OK", command = destroy_warning).pack() return # print("SIGN IN") try: sign_in_rt = self.logic_proc_ins.sign_in(user_id, pwd) if sign_in_rt != 1: raise (Exception) except: # warning = Toplevel() # Message(warning, text = "Login failed").pack() # def destroy_warning_1(): # warning.destroy() # Button(warning, text = "OK", command = destroy_warning_1).pack() self._pop_top_window(200, 100, ["Login failed!"]) return else: self.loginout_bt["text"] = "Logout" top.destroy() Button(top, text="CANCEL", command=_cancel).place(x=0, y=int(LOGINOUT_WIN_H / 3 * 2)) Button(top, text="LOGIN", command=_login).place(x=int(LOGINOUT_WIN_W / 2), y=int(LOGINOUT_WIN_H / 3 * 2)) def _signup_bt_clicked(self): SIGNUP_WIN_W = 200 SIGNUP_WIN_H = 150 top = Toplevel() top.geometry("{}x{}".format(SIGNUP_WIN_W, SIGNUP_WIN_H)) Label(top, text="User name").place(x=0, y=0) Label(top, text="Passwd").place(x=0, y=int(SIGNUP_WIN_H / 3)) un_ent = Entry(top, width=20) un_ent.place(x=int(SIGNUP_WIN_W / 2), y=0) pwd_ent = Entry(top, width=20) pwd_ent.place(x=int(SIGNUP_WIN_W / 2), y=int(SIGNUP_WIN_H / 3)) def _cancel(): top.destroy() def _signup(): un = un_ent.get() pwd = pwd_ent.get() try: if 0 < len(un) <= 50 and 0 < len(pwd) <= 50: # valid rt = self.logic_proc_ins.sign_up(un, pwd) if rt == 0: raise (Exception("fail")) else: self._pop_top_window( 200, 200, ["Success!", "Your ID is {}".format(int(rt))]) else: raise (Exception("invalid_input")) except Exception as e: # warning = Toplevel() # Message(warning, text = e).pack() # def destroy_warning(): # warning.destroy() # Button(warning, text = "OK", command = destroy_warning).pack() self._pop_top_window(200, 200, [e]) Button(top, text="CANCEL", command=_cancel).place(x=0, y=int(SIGNUP_WIN_H / 3 * 2)) Button(top, text="SIGNUP", command=_signup).place(x=int(SIGNUP_WIN_W / 2), y=int(SIGNUP_WIN_H / 3 * 2)) def _friend_treeview_select_change(self, event): # update selected selected = event.widget.selection()[0] sel_friend_id = self.friend_treeview.item(selected)["values"][0] self._refresh_msgbox(friend_id=sel_friend_id) self.selected_fri_id = sel_friend_id def _refresh_msgbox(self, friend_id): def _format_msgoutput(raw_msg): fmted_msg = "" for i in range(len(raw_msg)): fmted_msg += raw_msg[i][1] fmted_msg += "\n" if raw_msg[i][0] == 1: fmted_msg += "Me: " else: fmted_msg += "Friend: " fmted_msg += raw_msg[i][2] fmted_msg += "\n\n" return fmted_msg if friend_id in self.msg_list: msg = self.msg_list[friend_id] self.display_msg_box.delete("1.0", "end") self.display_msg_box.insert(END, _format_msgoutput(msg)) self.display_msg_box.see(END) def _refresh_friend_treeview(self): for item in (self.id2item_friend_treeview_table.values()): self.friend_treeview.delete(item) self.id2item_friend_treeview_table = {} for i in range(len(self.msg_list)): fri_id = list(self.msg_list.keys())[i] print(fri_id) if fri_id in self.friend_list: fri_name = self.friend_list[fri_id][0] item = self.friend_treeview.insert("", "end", values=[fri_id, fri_name]) self.id2item_friend_treeview_table.update({fri_id: item}) if self.selected_fri_id in self.id2item_friend_treeview_table: self.friend_treeview.selection_set( self.id2item_friend_treeview_table[self.selected_fri_id]) def _view_all_friends_bt_clicked(self): AF_WIN_W = int(self.w / 2) AF_WIN_H = int(self.h / 2) def _selected_friend_id(): iid = all_friends_tree.selection()[0] return all_friends_tree.item(iid)["values"][0] def _all_friends_tree_select_change(event): pass def _del_friend_bt_clicked(): self.logic_proc_ins.del_friend(_selected_friend_id()) self._refresh() def _send_msg(): selected_fri_id = _selected_friend_id() try: if selected_fri_id not in self.id2item_friend_treeview_table: item = self.friend_treeview.insert( "", index=0, values=[ selected_fri_id, self.friend_list[selected_fri_id][0] ]) self.id2item_friend_treeview_table.update( {selected_fri_id: item}) self.friend_treeview.selection_set( self.id2item_friend_treeview_table[selected_fri_id]) self.selected_fri_id = selected_fri_id if selected_fri_id not in self.msg_list: print("msglist add", selected_fri_id) self.msg_list.update({selected_fri_id: []}) top.destroy() except Exception as e: print(e, selected_fri_id) pass return top = Toplevel() top.geometry("{}x{}".format(AF_WIN_W, AF_WIN_H)) all_friends_tree = Treeview(top, columns=("ID", "Name", "Status"), show="headings") all_friends_tree.heading("#1", text="ID") all_friends_tree.heading("#2", text="Name") all_friends_tree.heading("#3", text="Status") all_friends_tree.column("#1", width=int(AF_WIN_W / 3)) all_friends_tree.column("#2", width=int(AF_WIN_W / 3)) all_friends_tree.column("#3", width=int(AF_WIN_W / 3)) # for fri_id in list(self.friend_list.keys()): for i in range(len(self.friend_list)): fri_id = list(self.friend_list.keys())[i] fri_name = self.friend_list[fri_id][0] fri_status = self.friend_list[fri_id][1] all_friends_tree.insert("", "end", values=[fri_id, fri_name, fri_status]) all_friends_tree.pack() # TODO: add scroll bar Button(master=top, text="Delete", command=_del_friend_bt_clicked).pack() Button(master=top, text="SendMSG", command=_send_msg).pack() def _clear_selected_history_bt_clicked(self): fri_item = self.friend_treeview.selection() fri_id = self.friend_treeview.item(fri_item)["values"][0] self.logic_proc_ins.clear_history(fri_id) def _send_bt_clicked(self): self.logic_proc_ins.send_message(self.selected_fri_id, self.input_box.get()) self.input_box.delete(0, END) pass def _friend_request_bt_clicked(self): FR_WIN_W = int(self.w / 2) FR_WIN_H = int(self.h / 2) top = Toplevel() top.geometry("{}x{}".format(FR_WIN_W, FR_WIN_H)) friend_req_tree = Treeview(top, columns=("ID", "Req_Note"), show="headings") friend_req_tree.place(x=0, y=0) friend_req_tree.heading("#1", text="ID") friend_req_tree.heading("#2", text="Req_Note") friend_req_tree.column("#1", width=int(FR_WIN_W / 2)) friend_req_tree.column("#2", width=int(FR_WIN_W / 2)) # for fri_id in list(self.friend_req_list.keys()): # [] for i in range(len(self.friend_req_list)): fri_id = list(self.friend_req_list.keys())[i] fri_req_note = self.friend_req_list[fri_id] friend_req_tree.insert("", "end", values=[fri_id, fri_req_note]) def _select_react(event): selected = event.widget.selection()[0] fri_id = friend_req_tree.item(selected)["values"][0] def _refresh(): pass def _accept(): if self.logic_proc_ins.accept_friend(fri_id) == 1: self._refresh() _refresh() confirm_msgbox.destroy() return # success else: self._pop_top_window(200, 100, ["Fail!"]) return def _refuse(): if self.logic_proc_ins.refuse_friend(fri_id) == 1: self._refresh() _refresh() return else: self._pop_top_window(200, 100, "Fail!") return confirm_msgbox = Toplevel() Button(confirm_msgbox, text="Accept", command=_accept).pack() Button(confirm_msgbox, text="Refuse", command=_refuse).pack() friend_req_tree.bind("<<TreeviewSelect>>", _select_react) def _add_friend_bt_clicked(self): ADDF_WIN_W = 200 ADDF_WIN_H = 150 top = Toplevel() top.geometry("{}x{}".format(ADDF_WIN_W, ADDF_WIN_H)) Label(top, text="Friend ID").place(x=0, y=0) Label(top, text="Note").place(x=0, y=int(ADDF_WIN_H / 3)) friend_id_ent = Entry(master=top, width=20) friend_id_ent.place(x=int(ADDF_WIN_W / 2), y=0) req_note_ent = Entry(master=top, width=20) req_note_ent.place(x=int(ADDF_WIN_W / 2), y=int(ADDF_WIN_H / 3)) def _cancel(): top.destroy() return def _add(): try: fri_id = int(friend_id_ent.get()) req_note = req_note_ent.get() except: self._pop_top_window(200, 100, ["Invalid input!"]) return try: rt = self.logic_proc_ins.add_friend(fri_id, req_note) if rt != 1: raise (Exception) except: self._pop_top_window(200, 100, "Fail to add friend!") return else: top.destroy() return Button(top, text="Cancel", command=_cancel).place(x=0, y=int(ADDF_WIN_H / 3 * 2)) Button(top, text="Add", command=_add).place(x=int(ADDF_WIN_W / 2), y=int(ADDF_WIN_H / 3 * 2)) def _pop_top_window(self, width, height, messages, command=None): def _clicked(): if command != None: print("command") command() top.destroy() top = Toplevel() top.geometry("{}x{}".format(width, height)) for msg in messages: Message(top, text=msg).pack() Button(top, text="OK", command=_clicked).pack()
class Pybot: def __init__(self, root): self.root = root self.font = ('arial', 12) self.background_color = '#7e7a79' self.text_color = '#ffffff' # Addd Widgets .... # Add menu .... menubar = Menu(self.root) option_menu = Menu(menubar, tearoff=0) option_menu.add_command(label="Clear Chat", command=self.clear_chat) option_menu.add_command(label="Save Chat", command=self.save_chat) option_menu.add_command(label="Change Font", command=None) option_menu.add_separator() option_menu.add_command(label="Exit", command=self.root.quit) menubar.add_cascade(label="Options", menu=option_menu) self.root.config(menu=menubar) self.text_area = ScrolledText(self.root, font=self.font, bg=self.background_color, fg=self.text_color, undo=True, wrap=WORD, bd=3, relief=RAISED) self.text_area.config(spacing1=5) self.text_area.config(spacing2=5) self.text_area.config(spacing1=5) self.text_area.place(x=10, y=10, width=480, height=440) frame = Frame(self.root, bg=self.background_color, bd=2, relief=RAISED) frame.place(x=10, y=460, width=480, height=50) self.entry_box = Entry(frame, font=('arial', 14), bd=1, relief=RAISED, width=35) self.entry_box.grid(row=0, column=0, pady=9, padx=5) self.send_buttton = Button(frame, text="Send", width=6, command=self.human_input) self.send_buttton.grid(row=0, column=1, pady=9, padx=5) def human_input(self): input = self.entry_box.get() if input: self.text_area.insert(END, "Human : " + input) self.entry_box.delete(0, END) self.call_bot(input) def bot_output(self, input): appid = "9XQRJ4-8URH6GHPKG" client = wolframalpha.Client(appid) res = client.query(input) answer = next(res.results).text if answer: self.text_area.insert(END, "\nPyBot : " + answer + '\n') def call_bot(self, input): x = threading.Thread(target=self.bot_output, args=(input, )) x.start() def save_chat(self): filename = filedialog.asksaveasfile() if filename: with open(filename, "w") as f: f.write(self.text_area.get(0.0, END)) def clear_chat(): if messagebox.askyesno("PyBot Says", "Do you really want ot delete recent Chats"): self.text_area.delete(0.0, END)
class Client(object): logger = StreamLogger = logging.getLogger("FileLogger") def __init__(self): self.is_connected = False self.udp_server_started = False self.raw_server_started = False self.tcp_listen_started = False self.host = conf_read("config/config.conf", "target", "host") self.port = conf_read("config/config.conf", "target", "port") self.buffer = conf_read("config/config.conf", "target", "buffer") self.local_host = conf_read("config/config.conf", "local", "host") self.local_port = conf_read("config/config.conf", "local", "port") self.tcp_sock = None self.udp_sock = None self.raw_sock = None self.window = Tk() self.window.title("Client") self.window.geometry("700x510") Label(self.window, text='Host: ').place(x=25, y=30) Label(self.window, text='Port: ').place(x=25, y=70) Label(self.window, text='Buffer: ').place(x=25, y=110) self.var_host = StringVar() self.var_host.set(conf_read("config/config.conf", "target", "host")) entry_host = Entry(self.window, textvariable=self.var_host) entry_host.place(x=140, y=30) self.btn_connect = Button(self.window, text='Connect', width=12, activeforeground='blue', relief=RAISED, command=self.connect) self.btn_connect.place(x=350, y=30) self.btn_disconnect = Button(self.window, text='Disconnect', width=12, activeforeground='blue', relief=RAISED, command=self.disconnect) self.btn_disconnect.place(x=470, y=30) self.btn_disconnect.config(state="disabled") self.var_port = StringVar() self.var_port.set(conf_read("config/config.conf", "target", "port")) entry_port = Entry(self.window, textvariable=self.var_port) entry_port.place(x=140, y=70) self.var_buffer = StringVar() self.var_buffer.set(conf_read("config/config.conf", "target", "buffer")) entry_buffer = Entry(self.window, textvariable=self.var_buffer) entry_buffer.place(x=140, y=110) self.var_trans_mode = StringVar() Label(self.window, text='Transmission mode').place(x=400, y=65) r1 = Radiobutton(self.window, text='TCP', variable=self.var_trans_mode, activeforeground='blue', value='tcp', command=self.radio_button_changed_tcp) r1.place(x=400, y=85) r1.select() Radiobutton(self.window, text='UDP', variable=self.var_trans_mode, activeforeground='blue', value='udp', command=self.radio_button_changed).place(x=400, y=105) Label(self.window, text='Received msg: ').place(x=25, y=150) self.txt_rev_msg = ScrolledText(self.window, height=10, bd=2, wrap=CHAR, relief='groove', bg="WhiteSmoke") self.txt_rev_msg.place(x=25, y=170) Label(self.window, text='Your msg: ').place(x=25, y=350) self.txt_msg = ScrolledText(self.window, height=6.5, width=57, bd=2, wrap=WORD, relief='groove', bg="WhiteSmoke") self.txt_msg.place(x=25, y=380) self.btn_send = Button(self.window, text='Send', width=15, activeforeground='blue', command=self.send_msg) self.btn_send.place(x=500, y=470) self.window.protocol('WM_DELETE_WINDOW', self.close_window) self.window.mainloop() def connect(self): sock = None self.btn_connect.config({"state": "disabled"}) trans_mode = self.var_trans_mode.get() addr = (self.var_host.get(), int(self.var_port.get())) try: if trans_mode == "tcp": if self.tcp_sock is None or "closed" in str(self.tcp_sock): self.tcp_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.tcp_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock = self.tcp_sock elif trans_mode == "udp": if self.udp_sock is None or "closed" in str(self.udp_sock): self.udp_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.udp_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock = self.udp_sock sock.connect(addr) self.is_connected = True except socket.error as e: self._insert_text(e.strerror) print(e) pass finally: time.sleep(0.5) if trans_mode == "tcp": self._receive_data(trans_mode) if trans_mode == "udp": self._insert_text("UDP connected".encode("utf-8"), trans_mode) self.btn_disconnect.config(state="normal") def radio_button_changed(self): self.btn_connect.config(state="disabled") self.btn_disconnect.config(state="disabled") def radio_button_changed_tcp(self): if self.tcp_sock: if "closed" not in str(self.tcp_sock): self.btn_connect.config(state="normal") self.btn_disconnect.config(state="disabled") else: self.btn_connect.config(state="disabled") self.btn_disconnect.config(state="normal") else: self.btn_connect.config(state="normal") self.btn_disconnect.config(state="disabled") def disconnect(self): self._send_data(self.var_trans_mode.get(), "Connection closed") self._insert_text("Connection closed".encode("utf-8"), self.var_trans_mode.get()) self.btn_disconnect.config(state="disabled") if self.tcp_sock and "closed" not in str(self.tcp_sock): self.tcp_sock.shutdown(2) self.tcp_sock.close() if self.udp_sock and "closed" not in str(self.udp_sock): self.udp_sock.shutdown(2) self.udp_sock.close() self.is_connected = False time.sleep(0.5) self.btn_connect.config(state="normal") def send_msg(self): trans_mode = self.var_trans_mode.get() self.btn_send.config({"state": "disabled"}) data = self.txt_msg.get("0.0", "end") if data: if self.is_connected: self._send_data(trans_mode, data) if not self.tcp_listen_started: self.start_thread(self._start_tcp_listen, (self.tcp_sock, )) self.tcp_listen_started = True else: if trans_mode == "udp": udp_interval = conf_read("config/config.conf", "udp", "interval") try: self.udp_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.udp_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) except socket.error as e: self._insert_text(e.strerror) self._send_data(trans_mode, data) if not self.udp_server_started: self.start_thread(self._start_udp_server) self.udp_server_started = True time.sleep(float(udp_interval)) elif trans_mode == "raw_socket": self.send_raw_msg(self.host, data.encode("utf-8")) if not self.raw_server_started: self.start_thread(self._start_raw_server, (self.local_host, )) self.udp_server_started = True else: self._insert_text( "Please connect to a server at first".encode("utf-8"), trans_mode) self.btn_send.config({"state": "normal"}) def send_raw_msg(self, dest_addr, data, packet_id=None): try: my_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP) except socket.error as e: self._insert_text(e.strerror) print(e.strerror) raise packet_id = packet_id if packet_id else random.randint(0, 0xffff) packet = create_packet(packet_id, data) print("packet:", packet) while packet: sent = my_socket.sendto(packet, (dest_addr, 1)) packet = packet[sent:] rec_packet, addr = my_socket.recvfrom(1024) print(rec_packet) self._insert_text(rec_packet, "raw_socket") self.txt_msg.delete('0.0', 'end') my_socket.close() def start_thread(self, func, params=()): t = threading.Thread(target=func, args=params) t.setDaemon(True) t.start() def _start_raw_server(self, host_ip): if os.name == "nt": protocol = socket.IPPROTO_IP else: protocol = socket.IPPROTO_ICMP try: my_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, 1) except socket.error as e: print(e.strerror) raise my_socket.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) my_socket.bind((host_ip, 0)) while True: rec_packet, addr = my_socket.recvfrom(1024) print(rec_packet) #msg = rec_packet[-192:].decode("utf-8").strip("@") self._insert_text("Raw socket msg: {}\n".format(str(rec_packet))) time.sleep(0.1) if not rec_packet: break def _start_udp_server(self): try: my_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) my_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) my_sock.bind((self.local_host, int(self.local_port))) while True: rev_data, address = my_sock.recvfrom(int(self.buffer)) print(rev_data) self.txt_rev_msg.insert(END, "Msg from server: {}".format(rev_data)) self.txt_rev_msg.insert(END, "\n") self.txt_rev_msg.update() if not rev_data: break my_sock.close() except socket.error as e: self._insert_text(e.strerror) print(e) finally: pass def _start_tcp_listen(self, tcp_sock): try: while True: rev_data = tcp_sock.recv(int(self.buffer)) print(rev_data) self.txt_rev_msg.insert(END, "Msg from server: {}".format(rev_data)) self.txt_rev_msg.insert(END, "\n") self.txt_rev_msg.update() if not rev_data: break tcp_sock.close() except socket.error as e: self._insert_text(e.strerror) print(e) finally: pass def _multiple_send(self, data, mysock, addr=None): tcp_interval = conf_read("config/config.conf", "tcp", "interval") udp_interval = conf_read("config/config.conf", "tcp", "interval") sd_buffer = int(self.var_buffer.get()) data_len = len(data) start = 0 while start <= data_len: end_len = sd_buffer if (start + sd_buffer) <= data_len else data_len if not addr: mysock.send(data[start:end_len].encode("utf-8")) time.sleep(float(tcp_interval)) else: mysock.sendto(data[start:end_len].encode("utf-8"), addr) time.sleep(float(udp_interval)) start = start + sd_buffer def _send_data(self, trans_mode, data): addr = (self.var_host.get(), int(self.var_port.get())) tcp_interval = conf_read("config/config.conf", "tcp", "interval") sd_buffer = int(self.var_buffer.get()) data_len = len(data) try: if trans_mode == "tcp": self._multiple_send(data, self.tcp_sock) #self.tcp_sock.send(data.encode("utf-8")) elif trans_mode == "udp": if self.is_connected: self.udp_sock.send(data.encode("utf-8")) else: # self.udp_sock.sendto( # data.encode("utf-8"), # addr) self._multiple_send(data, self.udp_sock, addr) elif trans_mode == "raw_socket": packet_id = random.randint(0, 0xffff) packet = create_packet(packet_id, data.encode("utf-8")) while packet: # The icmp protocol does not use a port, but the function # below expects it, so we just give it a dummy port. sent = self.raw_sock.sendto(packet, (self.var_host.get(), 0)) packet = packet[sent:] else: self.tcp_sock.send(data.encode("utf-8")) #self._receive_data(trans_mode) except socket.error as e: self._insert_text(e.strerror) print(e) finally: time.sleep(float(tcp_interval)) self.txt_msg.delete('0.0', 'end') def _receive_data(self, trans_mode): if trans_mode == "tcp": pass #rev_data = self.tcp_sock.recv(int(self.buffer)) elif trans_mode == "udp": print("udp") rev_data, address = self.udp_sock.recvfrom(int(self.buffer)) elif trans_mode == "raw_socket": rev_data, addr = self.raw_sock.recvfrom(int(self.buffer)) print(rev_data, addr) else: rev_data = self.tcp_sock.recv(int(self.buffer)) #self._insert_text(rev_data, trans_mode) def _insert_text(self, data, trans_mode="na"): if trans_mode == "na": self.txt_rev_msg.insert(END, data) elif trans_mode != "raw_socket": self.txt_rev_msg.insert(END, data.decode("utf-8")) else: self.txt_rev_msg.insert(END, "Raw socket Msg: {}".format(str(data))) self.txt_rev_msg.insert(END, "\n") self.txt_rev_msg.update() def close_window(self): ans = askyesno(title='Confirm', message='Close the window?') if ans: self.window.destroy() if self.tcp_sock and "closed" not in str(self.tcp_sock): self.tcp_sock.shutdown(2) self.tcp_sock.close() if self.udp_sock and "closed" not in str(self.udp_sock): self.udp_sock.close() else: return
class textEditor(): alltabs = None def __init__(self, window, labelFrame, tabs, vocab, startWithSameLetter, tabsOpen, file_path=""): self.window = window # record the directory path of the file self.file_path = file_path if file_path: self.file_name = self.file_path else: # if the file path doesn't exist, name it accordingly self.file_name = 'Untitled' # record the necessary passed-in parameters self.labelFrame = labelFrame self.tabsOpen = tabsOpen self.tabs = tabs self.vocab = vocab self.startWithSameLetter = startWithSameLetter # create the main gui elements in the respective tab frame self.notepad = ScrolledText(self.labelFrame, font=("Calibri", 15)) editorbox = self.notepad self.var = tk.IntVar() self.autoCorrectOption = tk.Checkbutton(self.labelFrame, \ text="Enable Auto-Correct", variable=self.var, command=self.switchSpellChecker) self.autoComplete_suggestions = tk.Listbox(self.labelFrame) self.autoCorrect_suggestions = tk.Listbox(self.labelFrame) myFont = Font(family="Calibri", size=15) self.autoComplete_suggestions.configure(font=myFont) self.autoCorrect_suggestions.configure(font=myFont) # create funtionality bars inside tab frame self.createMenuBar() self.createToolBar(self.labelFrame) self.autoCorrectOption.grid(row=1, column=9) self.notepad.config(undo=True) self.notepad.config(height=900) self.notepad.grid(row=2, column=0, columnspan=11, sticky="WE") self.window.protocol("WM_DELETE_WINDOW", lambda: newFileTab.closeCheck(self.tabsOpen)) # add pre-set markup on the entire text widget in the tab frame self.notepad.tag_configure("misspelling", foreground="red", underline=True) # bind all navigation to checking the spelling of the word self.nav_click = self.notepad.bind("<ButtonRelease-1>", self.spellChecker) self.nav_up = self.notepad.bind("<Up>", self.spellChecker) self.nav_down = self.notepad.bind("<Down>", self.spellChecker) self.nav_left = self.notepad.bind("<Left>", self.spellChecker) self.nav_right = self.notepad.bind("<Right>", self.spellChecker) # check each word's spelling after typed and mark it up self.notepad.bind("<space>", self.markUp) self.notepad.bind(".", self.markUp) # keep calling autocomplete while user is writing for letter in "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM": self.notepad.bind("<KeyRelease-" + letter + ">", self.autoComplete) self.notepad.bind("<KeyRelease-BackSpace>", self.autoComplete) # bind file shortcuts self.notepad.bind('<Control-s>', newFileTab.saveToFile) self.notepad.bind('<Control-o>', newFileTab.openFile) self.notepad.bind('<Control-n>', newFileTab.createFile) self.notepad.bind('<Control-c>', newFileTab.copySelected) self.notepad.bind('<Control-x>', newFileTab.cutSelected) self.notepad.bind('<Control-v>', newFileTab.pasteClipboard) # this function creates the top menu bar including all functionalities def createMenuBar(self): menuBar = Menu(self.window) # create drop-down options for the file menu fileMenu = tk.Menu(menuBar, tearoff=0) fileMenu.add_command( label="New Document", command=lambda: newFileTab.createFile(self.tabsOpen)) fileMenu.add_command( label="Open Local File", command=lambda: newFileTab.openFile(self.tabsOpen)) fileMenu.add_command( label="Save file", command=lambda: newFileTab.saveToFile(self.tabsOpen)) fileMenu.add_separator() fileMenu.add_command( label="Close File", command=lambda: newFileTab.closeFile(self.tabsOpen)) fileMenu.add_command(label="Exit", command=lambda: newFileTab.quit(self.tabsOpen)) menuBar.add_cascade(label="File", menu=fileMenu) # create drop-down options for the edit menu editMenu = tk.Menu(menuBar, tearoff=0) editMenu.add_command( label="Undo", command=lambda: newFileTab.undoEdit(self.tabsOpen)) editMenu.add_command( label="Redo", command=lambda: newFileTab.redoEdit(self.tabsOpen)) editMenu.add_command( label="Copy", command=lambda: newFileTab.copySelected(self.tabsOpen)) editMenu.add_command( label="Cut", command=lambda: newFileTab.cutSelected(self.tabsOpen)) editMenu.add_command( label="Paste", command=lambda: newFileTab.pasteClipboard(self.tabsOpen)) menuBar.add_cascade(label="Edit", menu=editMenu) self.window.config(menu=menuBar) '''icon pics retrieved from: https://icons-for-free.com/folder+open+icon-1320161390409087972/''' # this function creates the tool bar with clickable icon shortcuts for the functionalities def createToolBar(self, labelFrame): # add icon for handling creating new files new_img = tk.PhotoImage(file="newicon.png") new_img = new_img.zoom(1) new_img = new_img.subsample(15) # add icon for handling opening local files open_img = tk.PhotoImage(file="openicon.png") open_img = open_img.zoom(1) open_img = open_img.subsample(15) # add icon for handling saving files save_img = tk.PhotoImage(file="saveicon.png") save_img = save_img.zoom(1) save_img = save_img.subsample(4) # add icon for handling copying from files copy_img = tk.PhotoImage(file="copyicon.png") copy_img = copy_img.zoom(1) copy_img = copy_img.subsample(4) # add icon for handling cutting from files cut_img = tk.PhotoImage(file="cuticon.png") cut_img = cut_img.zoom(1) cut_img = cut_img.subsample(4) # add icon for handling cutting from clipboard paste_img = tk.PhotoImage(file="pasteicon.png") paste_img = paste_img.zoom(1) paste_img = paste_img.subsample(4) # add icon for handling undo edits undo_img = tk.PhotoImage(file="undoicon.png") undo_img = undo_img.zoom(1) undo_img = undo_img.subsample(4) # add icon for handling redo edits redo_img = tk.PhotoImage(file="redoicon.png") redo_img = redo_img.zoom(1) redo_img = redo_img.subsample(4) # add icon for handling closing current file tab close_img = tk.PhotoImage(file="closeicon.png") close_img = close_img.zoom(1) close_img = close_img.subsample(4) # create all respective buttons and configure them to their appropriate icons and function calls new_button = tk.Button( labelFrame, image=new_img, command=lambda: newFileTab.createFile(self.tabsOpen)) open_button = tk.Button( labelFrame, image=open_img, command=lambda: newFileTab.openFile(self.tabsOpen)) save_button = tk.Button( labelFrame, image=save_img, command=lambda: newFileTab.saveToFile(self.tabsOpen)) copy_button = tk.Button( labelFrame, image=copy_img, command=lambda: newFileTab.copySelected(self.tabsOpen)) cut_button = tk.Button( labelFrame, image=cut_img, command=lambda: newFileTab.cutSelected(self.tabsOpen)) paste_button = tk.Button( labelFrame, image=paste_img, command=lambda: newFileTab.pasteClipboard(self.tabsOpen)) undo_button = tk.Button( labelFrame, image=undo_img, command=lambda: newFileTab.undoEdit(self.tabsOpen)) redo_button = tk.Button( labelFrame, image=redo_img, command=lambda: newFileTab.redoEdit(self.tabsOpen)) close_button = tk.Button( labelFrame, image=close_img, command=lambda: newFileTab.closeFile(self.tabsOpen)) new_button.image = new_img open_button.image = open_img save_button.image = save_img copy_button.image = copy_img cut_button.image = cut_img paste_button.image = paste_img undo_button.image = undo_img redo_button.image = redo_img close_button.image = close_img # grid the buttons appropriately onto the tab frame new_button.grid(row=1, column=1) open_button.grid(row=1, column=2) save_button.grid(row=1, column=3) copy_button.grid(row=1, column=4) cut_button.grid(row=1, column=5) paste_button.grid(row=1, column=6) undo_button.grid(row=1, column=7) redo_button.grid(row=1, column=8) close_button.grid(row=1, column=10) # this function takes automatically the first choice from the suggestion # box and replaces it with the word that is underlined as misspelt def autoCorrect(self, event): lastWord = self.getLastWord() if self.spellCheckerList(lastWord): # get first suggestiosn from listbox contents bestSuggestion = self.spellCheckerList(lastWord)[0] # configure and find first and last index of word to be replaced start = self.notepad.get('1.0', tk.END).index(lastWord) end = start + len(lastWord) line_num = int(float(self.notepad.index(tk.CURRENT))) start_i = str(line_num) + '.' + str(start) end_i = str(line_num) + '.' + str(end) # delete the misspelled word by the best suggestion in text widget self.notepad.delete(start_i, end_i) self.notepad.insert(start_i, bestSuggestion) # this function unbinds the arrows with the list from the dictionary # so that the list dosen't appear when pressing the auto-correct option def switchSpellChecker(self): self.notepad.unbind('<ButtonRelease-1>') self.notepad.unbind('<Up>') self.notepad.unbind('<Down>') self.notepad.unbind('<Left>') self.notepad.unbind('<Right>') self.notepad.unbind("<space>") # if the autocorrect option is pressed if self.var.get(): # replace the spellchecker bindings to autocorrect self.notepad.bind("<space>", self.autoCorrect) self.notepad.bind(".", self.autoCorrect) # if it is not pressed else: # rebind the orginal keys for the spellchecker listbox functionality self.notepad.bind("<ButtonRelease-1>", self.spellChecker) self.notepad.bind("<Up>", self.spellChecker) self.notepad.bind("<Down>", self.spellChecker) self.notepad.bind("<Left>", self.spellChecker) self.notepad.bind("<Right>", self.spellChecker) # check each word's spelling after typed and mark it up self.notepad.bind("<space>", self.isSpeltCorrect) self.notepad.bind(".", self.isSpeltCorrect) # this function gets the last word that was typed by the user def getLastWord(self): # split all input text at all white space characters (e.g. space, tab, enter) wordsList = re.split("\s+", self.notepad.get("1.0", tk.END)) # remove last empty string wordsList.remove('') # last word is at the last index of the words list lastWord = wordsList[len(wordsList) - 1] # remove unnecessary punctuations next to the last word lastWord_stripped = lastWord.translate( str.maketrans('', '', string.punctuation)) return lastWord_stripped.lower() # here we edit the words that are misspelt after # getting the words from the screen and correct their form def spellCheckerList(self, word_to_check): edits = {} # if there's no word selected or a space is selected if word_to_check == "" or word_to_check == " ": return # if the word is misspelt, record its respective edit distances and frequencies elif not self.isSpeltCorrect(word_to_check): # compute for min edit distance from each word in dictionary for word in self.vocab: edits_num = self.minEditDistance(word_to_check, word) # record all words corresponding to edits numbers 1 and 2 in a dictionary if edits_num <= 2: # if there is a key in the dictionary corresponding to the same edit distance if edits_num in edits: # add it to its list of values edits[edits_num].append(word) else: # if not, create a new key for the number of edits and add it edits[edits_num] = [word] # record and sort frequencies of words corresponding for 1 edit and 2 edits freqs1 = [] freqs2 = [] # sorting words with edit distance 1 one based on frequency if 1 in edits: for similar_word in edits.get(1): # record frequency of each word with the same edit distance freq = self.vocab.get(similar_word) freqs1.append(freq) # sorting words with edit distance 1 one based on frequency if 2 in edits: for similar_word in edits.get(2): # record frequency of each word with the same edit distance freq = self.vocab.get(similar_word) freqs2.append(freq) # rearrange frequencies individually freqs1.sort() freqs2.sort() # combine the two frequency lists in order of 1 then 2 to get appropriate suggestions list # the smallest edit distance if the first priority, then its frequency freqs = freqs1 + freqs2 suggestions = [] for f in freqs: for word in self.vocab: # get words based on their corresponding frequencies in order if self.vocab.get(word) == f: # add each corresponding word to the suggestions list suggestions.append(word) return suggestions '''STILL TO DO, CONSIDER CAPITALIZATION IN SPELLCHECKER and replacement word/pop-up lists''' # this function checks if the word is spelt correctly or not # it returns a boolean value based on this condition def isSpeltCorrect(self, word): if word in self.vocab: return True return False # this functions recognizes the word and finds similar words # depending on their frequency, this will be then added to the # suggestion list. this function updates after typing each charachter def autoCompleteList(self, e): typed_word = self.getCurrWord(e).lower() if typed_word == "": return freqs = [] suggestions = [] inp_length = len(typed_word) for word in self.vocab: # check for english words that start with the same characters if word[:inp_length].lower() == typed_word: print('hi') # record the frequency ranks of such words freq = self.vocab.get(word) freqs.append(freq) # order frequencies freqs.sort() for f in freqs: for word in self.vocab: # get words based on their corresponding frequencies in order if self.vocab.get(word) == f: suggestions.append(word) return suggestions # this function takes the list of words suggested if any and # inserts them on the screen in the autocomplete suggestions listbox def autoComplete(self, event): self.autoComplete_suggestions.destroy() self.autoComplete_suggestions = tk.Listbox(window) myFont = Font(family="Calibri", size=15) self.autoComplete_suggestions.configure(font=myFont) word = self.getCurrWord(event).lower() # ignore autocomplete call if the word is empty if not word: return # if there is one character typed if len(word) == 1: # use pre-loaded dictionary to get suggestiosn into listbox suggestions = self.startWithSameLetter.get(word) i = 0 # add the first 10 word suggestions, as long as they exist while i < 11 and i < len(suggestions): for l in suggestions: # add them to the suggestions listbox in order self.autoComplete_suggestions.insert(i, l + " ") i += 1 else: # if typed portion is a part of a valid word if self.autoCompleteList(event): # get autocomplete list and append its first 10 values into the listbox suggestions = self.autoCompleteList(event)[:10] for i in range(len(suggestions)): self.autoComplete_suggestions.insert( i, suggestions[i] + " ") # if not, indicate lack of matches on listbox else: self.autoComplete_suggestions.insert(0, "No matches found.") # remove duplicate words in the suggestions listbox and the typed word if word in self.autoComplete_suggestions.get(0, tk.END): index = self.autoComplete_suggestions.get(0, tk.END).index(word) # delete duplicate word from suggestions listbox self.autoComplete_suggestions.delete(index) # if there are more suggestions available after 10, add the next one if len(self.autoCompleteList(event)) >= 11: self.autoComplete_suggestions.insert( 10, self.autoCompleteList(event)[10] + " ") # place the listbox where the typing cursor is (x, y, w, h) = self.notepad.bbox('insert') self.autoComplete_suggestions.place(x=x + 140, y=y + 200, anchor="center") self.autoComplete_suggestions.bind('<<ListboxSelect>>', self.autoCompleteClickSelect) # this function also draws a list box with all the suggested words that # could replace the misspelt word. def spellChecker(self, event): self.autoComplete_suggestions.destroy() self.autoCorrect_suggestions.destroy() self.autoCorrect_suggestions = tk.Listbox(self.labelFrame) myFont = Font(family="Calibri", size=15) self.autoCorrect_suggestions.configure(font=myFont) # if the selected word is the one being currently typed # autocomplete it and don't spellcheck it (word not fully typed yet) '''if self.getCurrWord(event) and self.getNavigWord(event): self.autoComplete(event) return''' word = self.getNavigWord(event) # if the suggestions listbox is not empty, clear it if len(self.autoCorrect_suggestions.get(0, tk.END)) != 0: self.autoCorrect_suggestions.delete(0, tk.END) # exit spell checker if the word is spelt correctly if self.isSpeltCorrect(word): return # if current word is not empty and is spelled incorrectly elif len(self.notepad.get('1.0', 'end-1c')) != 0: if self.spellCheckerList(word): # append first 10 suggestions into listbox suggestions = self.spellCheckerList(word)[:10] for i in range(len(suggestions)): self.autoCorrect_suggestions.insert(i, suggestions[i]) else: # if not close matches from min edit function, display appropriate message self.autoCorrect_suggestions.insert(0, "No matches found.") self.autoCorrect_suggestions.insert(1, "Add word to dictionary") if len(word) != 1: # place the listbox where the cursor is (x, y, w, h) = self.notepad.bbox('insert') self.autoCorrect_suggestions.place(x=x + 115, y=y + 160, anchor="center") self.autoComplete_suggestions = tk.Listbox(self.labelFrame) myFont = Font(family="Calibri", size=15) self.autoComplete_suggestions.configure(font=myFont) self.autoCorrect_suggestions.bind('<<ListboxSelect>>', self.autoCorrectClickSelect) # this function takes the selection that the user made from the suggestion box # and overwrites the word in he screen def autoCorrectClickSelect(self, event): selected_word = self.autoCorrect_suggestions.get( self.autoCorrect_suggestions.curselection()) # get the entire word the cursor is on navigWord = self.getNavigWord(event) if selected_word == "No matches found.": self.autoCorrect_suggestions.destroy() return elif selected_word == "Add word to dictionary": self.vocab[navigWord] = len(self.vocab) + 1 else: start = self.notepad.get('1.0', tk.END).index(navigWord) end = start + len(navigWord) line_num = int(float(self.notepad.index(tk.CURRENT))) # configure start and end indices of the word to be corrected syntax correctly start_i = str(line_num) + '.' + str(start) end_i = str(line_num) + '.' + str(end) # delete the misspelled word and replace it by the correct one selected from the listbox self.notepad.delete(start_i, end_i) self.notepad.insert(start_i, selected_word) if self.autoCorrect_suggestions.winfo_exists: self.autoCorrect_suggestions.destroy() # this function takes the selection that the user made from the suggestion box # and overwrites the word in the screen for the autocomplete option def autoCompleteClickSelect(self, event): if self.autoComplete_suggestions.curselection(): selected_word = self.autoComplete_suggestions.get( self.autoComplete_suggestions.curselection()) if selected_word == "No matches found.": self.autoComplete_suggestions.destroy() return # get the partial word currently being typed currWord = self.getCurrWord(event).lower() # configure start and end indices of the word to be corrected syntax correctly start = self.notepad.get('1.0', tk.END).index(currWord) end = start + len(currWord) line_num = int(float(self.notepad.index(tk.CURRENT))) start_i = str(line_num) + '.' + str(start) end_i = str(line_num) + '.' + str(end) # delete the misspelled word and replace it by the correct one selected from the listbox self.notepad.delete(start_i, end_i) self.notepad.insert(start_i, selected_word) self.autoComplete_suggestions.destroy() # this function underlines the word that is misspelt and # colors it with red def markUp(self, misspelt_word): lastWord = self.getLastWord() # if word contains numbers of special characters, don't mark it up if not lastWord.isalpha(): return self.autoComplete_suggestions.destroy() # search for starting index of the misspelt word index = self.notepad.search(r'\s', "insert", backwards=True, regexp=True) if index == "": index = "1.0" else: index = self.notepad.index("%s+1c" % index) word = self.notepad.get(index, "insert").translate( str.maketrans('', '', string.punctuation)) # if word spelled correctly, remove pre-set misspelling tag if word.lower() in self.vocab: self.notepad.tag_remove("misspelling", index, "%s+%dc" % (index, len(word))) else: self.notepad.tag_add("misspelling", index, "%s+%dc" % (index, len(word))) '''modfiied code from: https://stackoverflow.com/questions/3732605/add-advanced-features-to-a-tkinter-text-widget''' # This function finds the minimum edit distance using a modified version of the Levistein algorithm # This is my own implementation of the algorithm def minEditDistance(self, misspelt_word, vocab_word): rows = len(misspelt_word) + 1 columns = len(vocab_word) + 1 matrix = [] # split list of lists based on rows # initialize values for column contents for each row for i in range(rows): matrix.append([]) for j in range(columns): matrix[i].append(-1) # empty string row first_row = [] for n in range(columns): first_row.append(n) matrix = [first_row] + matrix[1:] # add first column values in matrix n = 0 for i in range(rows): matrix[i][0] = n n += 1 # for each letter of the misspelt word for r in range(rows - 1): # go through each letter in the vocab word for c in range(columns - 1): # if the letters are the same if vocab_word[c] == misspelt_word[r]: # copy down the value at the relative left diagonal position in the matrix # into the corresponding matrix position of the current string comparison matrix[r + 1][c + 1] = matrix[r][c] # if letters are different else: # take the minimum value of the three upper left diagonals to the current position adj_min = min(matrix[r][c], matrix[r][c + 1], matrix[r + 1][c]) # add 1 to get the minimum additional edit to transform the two strings parts so far # add resulting value into corresponding matrix position matrix[r + 1][c + 1] = adj_min + 1 # minimum number of edits is the last computed value of the matrix minEdits = matrix[rows - 1][columns - 1] return minEdits # this function gets the word that the cursor is hovering over in the text widget # and returns it. def getNavigWord(self, event): start = self.notepad.index("insert wordstart") end = self.notepad.index("insert wordend") nav_word = self.notepad.get(start, end) # remove unnecessary punctuations next to the typed word nav_word_stripped = nav_word.translate( str.maketrans('', '', string.punctuation)) return nav_word_stripped.lower() # this function gets the word that is being modified currently from the user # and returns it. def getCurrWord(self, event): all_typed = self.notepad.get("1.0", "end") i = all_typed.rfind(" ") curr_word = all_typed[i + 1:].strip() # remove unnecessary punctuations next to the typed word curr_word_stripped = curr_word.translate( str.maketrans('', '', string.punctuation)) return curr_word_stripped.lower()
class GetTk(object): """ 不继承 """ # 主窗口 root = tk.Tk() # 按钮 button1 = button2 = button3 = button4 = None # 画布 canvas = None # 提示信息 test_information = None test_var = None choice_image = None use_information = None # 标题 label_of_canvas = None label_of_text = None # 主界面 def set_windows(self): self.root.title("手写数字识别") self.root.resizable(False, False) self.root.geometry("1200x600") # return self.root # 循环刷新界面 没有使用对象里面的参数,所以需要设置成为静态方法 @staticmethod def set_loop(): tk.mainloop() # 按键 def set_button1(self): self.button1 = tk.Button(self.root, text="绘制", font=("华文楷书", 13), bg="#E8D098", fg="blue", width=10, height=1, padx=1, pady=2, command=self.draw_pic) self.button1.place(x=630, y=480) def set_button3(self): self.button3 = tk.Button(self.root, text="识别", font=("华文楷书", 13), bg="#E8D098", fg="blue", width=10, height=1, padx=1, pady=2, command=self.insert_text) self.button3.place(x=820, y=480) def set_button4(self): self.button4 = tk.Button(self.root, text="清屏", font=("华文楷书", 13), bg="#E8D098", fg="blue", width=10, height=1, padx=1, pady=2, command=self.cls) self.button4.place(x=1000, y=480) # 画布 def set_canvas(self): self.canvas = tk.Canvas(self.root, bg='white', width=80, height=80) self.canvas.place(x=500, y=360) # 提示信息 def set_text(self): self.test_information = ScrolledText(self.root, fg="blue", font=("华文楷书", 10), width=60, height=21) self.test_information.place(x=600, y=105) # 信息数据的变更 def change_information(self): self.test_var = tk.StringVar() self.test_var = "测试数据" return self.test_var # 标签 def set_choice(self): self.choice_image = tk.Label(self.root, text="待识别图片", font=("华文楷书", 11), fg="blue") self.choice_image.place(x=495, y=340) def set_label_canvas(self): self.label_of_text = tk.Label(self.root, text="使用说明", font=("华文楷书", 20), fg="purple") self.label_of_text.place(x=200, y=60) def set_use_information(self): information = "1. 点击“绘制”按钮,在弹出的画布上绘制待识别数字。\n" information2 = "2. 使用鼠标左键绘制图画。点击‘s’,保存当前图片;\n" information3 = "点击“SPACE”,刷新画布;点击”ESC“,退出绘制界面。\n" information4 = "3. 点击”识别“按钮,在弹出的窗口中选择目标图片。\n" information5 = "4. 点击”清屏“按钮,将程序界面数据清空。\n" self.use_information = tk.Label(self.root, text=information, font=("华文楷书", 12), fg="green") tk.Label(self.root, text=information2, font=("华文楷书", 12), fg="green" ).place(x=40, y=170) tk.Label(self.root, text=information3, font=("华文楷书", 12), fg="green" ).place(x=40, y=200) tk.Label(self.root, text=information4, font=("华文楷书", 12), fg="green" ).place(x=40, y=230) tk.Label(self.root, text=information5, font=("华文楷书", 12), fg="green" ).place(x=40, y=260) self.use_information.place(x=40, y=140) def set_labels_text(self): self.label_of_text = tk.Label(self.root, text="处理信息", font=("华文楷书", 20), fg="purple") self.label_of_text.place(x=800, y=60) def show_on_canvas(self, the_path): print(the_path) global show_image,get_image get_image = Image.open(the_path) get_image = get_image.resize((80,80)) show_image = ImageTk.PhotoImage(get_image) # 改变图片大小,进行展示 self.canvas.create_image(40, 40, image=show_image) # 绑定插入数据 def insert_text(self): # 打开文件夹 try: get_path = tk.filedialog.askopenfilename() if get_path: information = '您选择了新的图片,所在位置是 : ' self.test_information.tag_config("tag_1", backgroun="yellow", foreground="red") self.test_information.tag_config("tag_2", backgroun="white", foreground="blue") self.test_information.insert("end", information, "tag_2") self.test_information.insert("insert", get_path, "tag_1") self.test_information.insert("insert", "\n") self.test_information.see(END) # 在画布上面显示图片 self.show_on_canvas(get_path) # 识别 # 直接采用PIL处理图像 # get_image = Image.open(get_path).convert('L') # im = get_image.resize((28, 28)) # im = np.asarray(im) # im = cv.imread(get_path) # 读取图片 # im = cv.cvtColor(im, cv.COLOR_RGB2GRAY) # 转换了灰度化 # im = cv.resize(im, (28, 28), interpolation=cv.INTER_NEAREST) # 图像预处理采用第三种方法 im = io.imread(get_path) im = color.rgb2gray(im) im = transform.resize(im, (28,28)) im = im.reshape((-1, 784)) im = im.astype('float') the_x = im the_y = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) # 这里这个不是关键,所以可以随便给初始值 the_y = the_y.reshape([1, 10]) with tf.Session() as sess: # 打包的时候写成绝对路径 new_saver = tf.train.import_meta_graph('F:/digits/CNN/checkpoint-2/digits.ckpt-20000.meta') get_model = new_saver.restore(sess, 'F:/digits/CNN/checkpoint-2/digits.ckpt-20000') x = sess.graph.get_tensor_by_name("input_x:0") result = sess.graph.get_tensor_by_name("predict:0") result = sess.run(result, feed_dict={x: the_x}) # print(np.argmax(result)) information = '该图片的识别结果为 :' self.test_information.insert("end", information, "tag_2") self.test_information.insert("insert", np.argmax(result), "tag_1") self.test_information.insert("insert", "\n") self.test_information.see(END) else: print("用户取消") except: print("您没有选择图片") def cls(self): self.test_information.delete(0.0, END) # 将带显示图片清空 self.set_canvas() def draw_pic(self): index = 1 drawing = False ix, iy = -1, -1 def draw(event, x, y, flags, image): b = g = r = 255 color = (b, g, r) global drawing, ix, iy # 点击鼠标开始绘制 if event == cv.EVENT_LBUTTONDOWN: drawing = True ix, iy = x, y # 鼠标左键按住的情况下面,鼠标移动 elif event == cv.EVENT_MOUSEMOVE and flags == cv.EVENT_FLAG_LBUTTON: if drawing == True: cv.circle(img, (x, y), 14, color, -1) elif event == cv.EVENT_LBUTTONUP: drawing == False # 实在不行的话,直接封装成一个函数 img = np.zeros((360, 360, 3), np.uint8) cv.namedWindow("") cv.setMouseCallback("", draw) while True: cv.imshow("", img) k = cv.waitKey(1) if k == 27: cv.destroyAllWindows() break elif k == 32: img = np.zeros((360, 360, 3), np.uint8) elif k == 115: # 这里是小写字母 cv.imwrite("F:/digits/CNN/pictures/test_{}.jpg".format(index), img) index += 1 # 监听案件 def listen_button3(self): self.insert_text() # 清空屏幕 def listen_button4(self): self.cls() # 绘制图画 def listen_button1(self): self.draw_pic()
class App(tk.Frame): GETTER = DataGetter WRITER = XLSWriter def __init__(self, root, *args, **kwargs): self.master = root self.infile = None self.table = None tk.Frame.__init__(self, self.master, *args, **kwargs) self.menu = Menu(self.master) self.master.config(menu=self.menu) self.settings = Menu(self.menu) self.menu.add_cascade(label="Settings", menu=self.settings) self.text_options = {"state": "disabled", "bg": "black", "fg": "#08c614", "insertbackground": "#08c614", "selectbackground": "#f01c1c"} self.text = ScrolledText(self, **self.text_options) self.text.pack(expand=True, fill="both") # ====================================================================== self.top_method = tk.Frame(self) self.prompt_method = tk.Label( self.top_method, text="Conversion method( metoda prevodu ): " ) self.prompt_method.pack(side="left", fill="x") self.method_option = IntVar() self.method_check_box = Checkbutton(self.top_method, text="MIFARE", variable=self.method_option) self.method_check_box.pack(expand=True) self.top_method.pack(fill="x") # ====================================================================== self.top_table = tk.Frame(self) self.prompt_table = tk.Label( self.top_table, text="Choose table name( zvol tabulku ): " ) self.prompt_table.pack(side="left", fill="x") option_lst_table = ["identifikatory", "unspecified"] self.drop_var_table = StringVar() self.drop_var_table.set(option_lst_table[0]) self.table_options = OptionMenu( self.top_table, self.drop_var_table, *option_lst_table ) self.table_options.pack(side="left", expand=1) self.executer_table = tk.Button( self.top_table, text="Select", command=self.choose_table ) self.executer_table.pack(side="left", padx=5, pady=2) self.top_table.pack(fill="both") # ====================================================================== self.top_columns = tk.Frame(self) self.prompt_columns = tk.Label( self.top_columns, text="Choose column name with 'hex string'( identifikator ): " ) self.prompt_columns.pack(side="left", fill="x") option_lst_columns = ["unspecified"] self.drop_var_columns = StringVar() self.drop_var_columns.set(option_lst_columns[0]) self.column_options = OptionMenu( self.top_columns, self.drop_var_columns, *option_lst_columns ) self.column_options.pack(expand=True) self.top_columns.pack(fill="x") # ====================================================================== self.top_indexes = tk.Frame(self) self.prompt_indexes = tk.Label( self.top_indexes, text="Choose column name with 'name'( meno majitela ): " ) self.prompt_indexes.pack(side="left", fill="x") option_lst_indexes = ["unspecified"] self.drop_var_indexes = StringVar() self.drop_var_indexes.set(option_lst_indexes[0]) self.index_option = OptionMenu( self.top_indexes, self.drop_var_indexes, *option_lst_indexes ) self.index_option.pack(expand=True) self.top_indexes.pack(fill="x") # ====================================================================== self.settings.add_command(label="Exit", command=self.on_exit) self.console_log = Menu(self.menu) self.menu.add_command(label="Log", command=self.save_console_output) self.help = Menu(self.menu) self.menu.add_cascade(label="HELP", menu=self.help) self.bottom_in = tk.Frame(self) self.prompt = tk.Label(self.bottom_in, text="Choose '.mdb' file:( .mdb subor ) ") self.prompt.pack(side="left", fill="x") self.entry_in = tk.Entry(self.bottom_in) self.entry_in.bind("<Return>", self.choose_file_prompt) self.entry_in.pack(side="left", fill="x", expand=True) self.executer_in = tk.Button( self.bottom_in, text="Select", command=self.choose_file ) self.executer_in.pack(side="left", padx=5, pady=2) self.do_it = tk.Button( self.bottom_in, text="RUN", bg="green", command=self.run_conversion ) self.do_it.pack(side="left", padx=5, pady=2) # packing bottom frames self.bottom_in.pack(side="bottom", fill="both") def choose_file(self): name = askopenfilename( filetypes=(("mdb files", "*.mdb"), ("all files", "*.*")) ) # tkinter.messagebox.showerror('file_name', name) if not name: return self.infile = name try: self.update_om_tables() except Exception: self.show_error(traceback.format_exc()) self.show("Chosen infile:") self.show("\t" + name + "\n") def choose_file_prompt(self, event=None): file_path = self.entry_in.get() if not file_path: return if os.path.isfile(file_path): file_ = file_path.split(os.sep)[-1].split(".") if len(file_) == 2 and file_[1] == "mdb": self.infile = file_path self.show("Chosen infile:\n\t{}".format(file_path)) else: self.show_error("Incorrect extension.") elif os.path.isdir(file_path): self.show_error("Provided path is a directory.") else: self.show_error("Incorrect file path.") def show_error(self, message): """Inserts message into the Text wiget""" self.text.config(state="normal") self.text.insert("end", message + "\n", 'error') self.text.tag_config('error', foreground='red') self.text.see("end") self.text.config(state="disabled") def show(self, message): """Inserts message into the Text wiget""" self.text.config(state="normal") self.text.insert("end", message + "\n") self.text.see("end") self.text.config(state="disabled") def clear_entry_in(self): """Clears the Entry command widget""" self.entry_in.delete(0, "end") def clear_text(self): """Clears the Text widget""" self.text.config(state="normal") self.text.delete(1.0, "end-1c") self.text.config(state="disabled") def clear(self, event=None): """Does not stop an eventual running process, but just clears the Text and Entry widgets.""" self.clear_entry_in() self.clear_text() def save_console_output(self): log = self.text.get("1.0", "end-1c") file_ = asksaveasfile( filetypes=(("txt files", "*.txt"), ("all files", "*.*")) ) try: file_.write(log) except Exception: self.show_error(traceback.format_exc()) else: self.show("Log saved to {}".format(file_.name)) finally: file_.close() def choose_columns(self): pass def choose_indexes(self): pass def choose_table(self, event=None): self.table = self.drop_var_table.get() try: display_str = self.update_om_columns() except Exception: self.show_error(traceback.format_exc()) else: self.show("TABLE SCHEME:") self.show(display_str + "\n") self.drop_var_table.set(self.table) self.show("Chosen table:") self.show("\t" + self.drop_var_table.get()) def show_whole_selection(self): self.show("Infile: {}".format(self.infile)) self.show("Table: {}".format(self.table)) def update_om_tables(self): menu = self.table_options['menu'] new_choices = App.GETTER.show_tables(path=self.infile) self.drop_var_table.set(new_choices[0]) menu.delete(0, 'end') for table_name in new_choices: menu.add_command( label=table_name, command=lambda value=table_name: self.drop_var_table.set(value) ) def update_om_columns(self): menu1, menu2 = self.column_options['menu'], self.index_option['menu'] try: show_str, new_choices = App.GETTER.show_columns( path=self.infile, table=self.table ) except ValueError: new_choices = App.GETTER.show_columns( path=self.infile, table=self.table ) show_str = "\n".join(["\t" + i for i in new_choices]) except Exception: self.show_error(traceback.format_exc()) return self.drop_var_columns.set(new_choices[0]) self.drop_var_indexes.set(new_choices[1]) menu1.delete(0, 'end') menu2.delete(0, 'end') for column in new_choices: menu1.add_command( label=column, command=lambda value=column: self.drop_var_columns.set(value) ) menu2.add_command( label=column, command=lambda value=column: self.drop_var_indexes.set(value) ) return show_str def run_conversion(self): obj = self.GETTER( db_path=self.infile, table_name=self.table, hex_num=self.drop_var_columns.get(), name=self.drop_var_indexes.get(), conversion_method=self.method_option.get(), ) obj.run() outfile = asksaveasfilename( defaultextension='.xls', filetypes=(("xls files", ".xls"), ("all files", "*.*")) ) wrt = self.WRITER(outfile) wrt.write(obj.result) self.show("\nChosen outfile:") self.show("\t" + outfile) def on_exit(self): now = str(datetime.datetime.now()) self.show("\n" + now + "\n\t\t\t\t\t\t" + "bye") self.quit()
class Google_translator: def __init__(self, root): self.root = root self.root.title('Google Translator') self.root.geometry('280x460') self.root.config(bg="#4285F4") self.google_logo = PhotoImage(file='img\\logo.png') self.mic_img = PhotoImage(file="img\\microphone.png") self.speaker_img = PhotoImage(file="img\\speaker (1).png") self.input_text = ScrolledText(self.root, width=30, height=7) self.input_text.place(x=10, y=10) self.choose_langauge = ttk.Combobox(self.root, state='readonly', font=('arial', 10), width=34) self.choose_langauge['values'] = ( 'Afrikaans', 'Albanian', 'Arabic', 'Armenian', ' Azerbaijani', 'Basque', 'Belarusian', 'Bengali', 'Bosnian', 'Bulgarian', ' Catalan', 'Cebuano', 'Chichewa', 'Chinese', 'Corsican', 'Croatian', ' Czech', 'Danish', 'Dutch', 'English', 'Esperanto', 'Estonian', 'Filipino', 'Finnish', 'French', 'Frisian', 'Galician', 'Georgian', 'German', 'Greek', 'Gujarati', 'Haitian Creole', 'Hausa', 'Hawaiian', 'Hebrew', 'Hindi', 'Hmong', 'Hungarian', 'Icelandic', 'Igbo', 'Indonesian', 'Irish', 'Italian', 'Japanese', 'Javanese', 'Kannada', 'Kazakh', 'Khmer', 'Kinyarwanda', 'Korean', 'Kurdish', 'Kyrgyz', 'Lao', 'Latin', 'Latvian', 'Lithuanian', 'Luxembourgish', 'Macedonian', 'Malagasy', 'Malay', 'Malayalam', 'Maltese', 'Maori', 'Marathi', 'Mongolian', 'Myanmar', 'Nepali', 'Norwegian' 'Odia', 'Pashto', 'Persian', 'Polish', 'Portuguese', 'Punjabi', 'Romanian', 'Russian', 'Samoan', 'Scots Gaelic', 'Serbian', 'Sesotho', 'Shona', 'Sindhi', 'Sinhala', 'Slovak', 'Slovenian', 'Somali', 'Spanish', 'Sundanese', 'Swahili', 'Swedish', 'Tajik', 'Tamil', 'Tatar', 'Telugu', 'Thai', 'Turkish', 'Turkmen', 'Ukrainian', 'Urdu', 'Uyghur', 'Uzbek', 'Vietnamese', 'Welsh', 'Xhosa', 'Yiddish', 'Yoruba', 'Zulu', ) self.choose_langauge.place(x=10, y=140) self.choose_langauge.current(0) self.output_text = ScrolledText(self.root, width=30, height=10) self.output_text.place(x=10, y=175) button = Button(self.root, text="Translate", cursor="hand2", width=10, command=self.translate) button.place(x=190, y=350) copy_button = Button(self.root, text="Copy Text", cursor="hand2", width=10, command=self.copy_text) copy_button.place(x=100, y=350) clear = Button(self.root, text="Clear", cursor="hand2", width=10, command=self.clear) clear.place(x=10, y=350) Button(self.root, image=self.mic_img, bd=0, bg="white", command=self.listen).place(x=220, y=90) Button(self.root, image=self.speaker_img, bd=0, bg="white", command=self.speak).place(x=220, y=303) Label(root, image=self.google_logo).place(x=10, y=390) Label(root, text="Google", font=('arial black', 30), bg="#4285F4", fg="white").place(x=100, y=385) def translate(self): language_1 = self.input_text.get(1.0, END) cl = self.choose_langauge.get() if language_1 == '': messagebox.showerror('Google Translator', 'please fill the box') else: translator = Translator() output = translator.translate(language_1, dest=cl) self.output_text.delete(1.0, END) self.output_text.insert('end', output.text) def clear(self): self.input_text.delete(1.0, 'end') self.output_text.delete(1.0, 'end') def copy_text(self): self.output_text.clipboard_clear() self.output_text.clipboard_append(self.output_text.get(1.0, END)) def speak(self): tts = gTTS(text=self.output_text.get(1.0, END), lang="en") r = random.randint(0, 100000) audio_file = "audio-"+str(r)+".mp3" tts.save(audio_file) playsound.playsound(audio_file) os.remove(audio_file) def listen(self): r = sr.Recognizer() with sr.Microphone() as source: audio = r.listen(source) string = "" string = r.recognize_google(audio) self.input_text.delete("1.0", END) self.input_text.insert(END, string)
class OptimizerMainWindow: """ classdocs """ # TODO: change that name def reactToClick(self, event): a = AddRestrictionDialog(self) def __init__(self, optimizer): # always have a reference to model/controller self.optimizer = optimizer # setup main GUI and make stretchable self.guiRoot = Tk() self.guiRoot.title("OPTIMIZR") self.guiRoot.columnconfigure(1, weight=1) self.guiRoot.rowconfigure(0, weight=1) # left (settings) and right (sequences) part self.frameLeft = Frame(self.guiRoot) self.frameLeft.grid(row=0, column=0, sticky=W + E + N + S) self.frameLeft.columnconfigure(0, weight=1) self.frameRight = Frame(self.guiRoot) self.frameRight.grid(row=0, column=1, sticky=W + E + N + S) self.frameRight.columnconfigure(0, weight=1) self.frameRight.rowconfigure(0, weight=1) self.frameRight.rowconfigure(1, weight=1) self.frameSpeciesControll = LabelFrame(self.frameLeft, text="Species", pady=10, padx=10) self.frameSpeciesControll.columnconfigure(1, weight=1) self.frameOptimizationControll = LabelFrame(self.frameLeft, text="Optimization", pady=10, padx=10) self.frameRestrictionControll = LabelFrame(self.frameLeft, text="Restriction Enzymes", pady=10, padx=10) self.frameSpeciesControll.grid(row=0, column=0, sticky=W + E, padx=10, pady=10) self.frameOptimizationControll.grid(row=1, column=0, sticky=W + E, padx=10, pady=10) self.frameRestrictionControll.grid(row=2, column=0, sticky=W + E, padx=10, pady=10) # Species Controll Label(self.frameSpeciesControll, text="Source:").grid(row=0, column=0) Label(self.frameSpeciesControll, text="Target:").grid(row=1, column=0) self.comboSourceSpecies = Combobox(self.frameSpeciesControll, state="readonly") self.comboSourceSpecies.grid(row=0, column=1, pady=5, sticky="ew") self.comboTargetSpecies = Combobox(self.frameSpeciesControll, state="readonly") self.comboTargetSpecies.grid(row=1, column=1, pady=5, sticky="we") self.buttonSpeciesList = Button(self.frameSpeciesControll, text="Edit Species List") self.buttonSpeciesList.grid(row=2, column=1, pady=5, sticky="e") self.comboSourceSpecies.bind("<<ComboboxSelected>>", self.actionOptimizerSettingsChanged) self.comboTargetSpecies.bind("<<ComboboxSelected>>", self.actionOptimizerSettingsChanged) # Optimization Controll Label(self.frameOptimizationControll, text="Optimization Strategy:").grid(row=0, column=0) self.comboOptimizationStrategy = Combobox(self.frameOptimizationControll, state="readonly") self.comboOptimizationStrategy.grid(row=0, column=1) self.comboOptimizationStrategy["values"] = self.optimizer.possibleOptimizationStrategies self.comboOptimizationStrategy.bind("<<ComboboxSelected>>", self.actionOptimizerSettingsChanged) # Restriction Enzymes self.listRestriction = Listbox(self.frameRestrictionControll) self.listRestriction.grid(row=0, column=0, columnspan=3, pady=5, sticky=W + E) self.frameRestrictionControll.columnconfigure(0, weight=1) self.buttonRestricionAdd = Button(self.frameRestrictionControll, text=" + ") self.buttonRestricionDel = Button(self.frameRestrictionControll, text=" - ") self.buttonRestricionAdd.grid(row=1, column=1, padx=5) self.buttonRestricionDel.grid(row=1, column=2, padx=5) # Source Sequence Frame self.frameSourceSequence = LabelFrame(self.frameRight, text="Source Sequence", padx=10, pady=10) self.frameResultSequence = LabelFrame(self.frameRight, text="Result Sequence", padx=10, pady=10) self.frameSourceSequence.grid(row=0, column=0, sticky="wens", padx=10, pady=10) self.frameResultSequence.grid(row=1, column=0, sticky="wens", padx=10, pady=10) self.buttonSourceLoad = Button(self.frameSourceSequence, text=" Load ") self.textSourceSeq = ScrolledText(self.frameSourceSequence, height=10) self.buttonSourceLoad.grid(row=0, column=1, sticky="e", pady=5) self.textSourceSeq.grid(row=1, column=0, columnspan=2, sticky="wens") self.frameSourceSequence.columnconfigure(0, weight=1) self.frameSourceSequence.rowconfigure(1, weight=1) self.textSourceSeq.frame.columnconfigure(1, weight=1) self.textSourceSeq.frame.rowconfigure(0, weight=1) self.buttonOptimize = Button(self.frameResultSequence, text=" OPTIMIZE! ") self.buttonOptimize.bind("<ButtonRelease>", self.actionOptimize) self.buttonRemoveRestriction = Button(self.frameResultSequence, text=" RESTRICTION-B-GONE! ") self.buttonRemoveRestriction.bind("<ButtonRelease>", self.actionRemoveRestricion) self.buttonSaveResult = Button(self.frameResultSequence, text=" Save ") self.textResultSequence = ScrolledText(self.frameResultSequence, height=10) self.buttonOptimize.grid(column=0, row=0, pady=5, sticky="w") self.buttonRemoveRestriction.grid(column=1, row=0, pady=5, padx=10, sticky="w") self.textResultSequence.grid(row=1, column=0, columnspan=4, sticky="wens") self.buttonSaveResult.grid(row=2, column=3, pady=5, sticky="e") self.frameResultSequence.columnconfigure(2, weight=1) self.frameResultSequence.rowconfigure(1, weight=1) self.textResultSequence.frame.columnconfigure(1, weight=1) self.textResultSequence.frame.rowconfigure(0, weight=1) self.textSourceSeq.bind("<<Modified>>", self.actionSequenceModified) self.textResultSequence.bind("<<Modified>>", self.actionSequenceModified) # generate color tags for textboxes for i in range(101): # green for normal codons (r, g, b) = colorsys.hsv_to_rgb(210 / 360, i / 100, 1.0) colorHex = "#%02x%02x%02x" % (int(r * 255), int(g * 255), int(b * 255)) self.textSourceSeq.tag_config("normal" + str(i), background=colorHex) self.textResultSequence.tag_config("normal" + str(i), background=colorHex) # red for codons with restriction sites (r, g, b) = colorsys.hsv_to_rgb(5 / 360, i / 100, 1.0) colorHex = "#%02x%02x%02x" % (int(r * 255), int(g * 255), int(b * 255)) self.textSourceSeq.tag_config("restrict" + str(i), background=colorHex) self.textResultSequence.tag_config("restrict" + str(i), background=colorHex) # Set (minimum + max) Window size self.guiRoot.update() self.guiRoot.minsize(self.guiRoot.winfo_width(), self.guiRoot.winfo_height()) self.buttonRestricionAdd.bind("<ButtonRelease>", self.reactToClick) self.buttonRestricionDel.bind("<ButtonRelease>", self.actionRestrictionEnzymeDelete) self.buttonSpeciesList.bind("<ButtonRelease>", self.actionEditSpeciesButton) self.buttonSourceLoad.bind("<ButtonRelease>", self.actionLoadSequence) self.buttonSaveResult.bind("<ButtonRelease>", self.actionSaveSequence) # TEST # self.listRestriction.insert("end", "EcoRI") # self.listRestriction.insert("end", "BamHI") # # dummy event to manually trigger update self.guiRoot.bind("<<Update>>", self.actionUpdate) self.actionUpdate(None) self.guiRoot.mainloop() def actionRestrictionEnzymeDelete(self, event): try: selectedEnzyme = self.listRestriction.selection_get() self.optimizer.restrictionEnzymeList.remove(selectedEnzyme) self.guiRoot.event_generate("<<Update>>") except tkinter.TclError: # no selection pass def actionUpdate(self, event): # print("update called") # clear list of restriction enzymes self.listRestriction.delete(0, "end") for r in self.optimizer.restrictionEnzymeList: self.listRestriction.insert("end", r) self.comboSourceSpecies.delete(0, "end") self.comboTargetSpecies.delete(0, "end") speciesValues = list() for (taxid, name) in self.optimizer.speciesList: speciesValues.append(taxid + ": " + name) self.comboSourceSpecies["values"] = speciesValues self.comboTargetSpecies["values"] = speciesValues if self.comboSourceSpecies.get() not in speciesValues: self.comboSourceSpecies.set("") if self.comboTargetSpecies.get() not in speciesValues: self.comboTargetSpecies.set("") self.textSourceSeq.edit_modified(True) self.textResultSequence.edit_modified(True) self.optimizer.saveConfig("config.ini") def actionEditSpeciesButton(self, event): speciesListDialog = SpeciesListDialog(self) def actionOptimizerSettingsChanged(self, event=None): # print("Something happened") strategy = self.comboOptimizationStrategy.get() sourceString = self.comboSourceSpecies.get() targetString = self.comboTargetSpecies.get() if not (strategy and sourceString and targetString): return sourceTaxid = sourceString.split(":")[0] targetTaxid = targetString.split(":")[0] self.optimizer.setOptimizer(sourceTaxid, targetTaxid, strategy) self.textSourceSeq.edit_modified(True) self.textResultSequence.edit_modified(True) # self.optimizer.testPrint() def actionOptimize(self, event=None): self.optimizer.runOptimization() self.textSourceSeq.edit_modified(True) self.textResultSequence.edit_modified(True) def actionRemoveRestricion(self, event=None): self.optimizer.runRestricionRemoval() self.textSourceSeq.edit_modified(True) self.textResultSequence.edit_modified(True) def actionSequenceModified(self, event=None): # necessary if, otherwise -> infinite loop if self.textSourceSeq.edit_modified(): seq = self.textSourceSeq.get("1.0", "end").strip() seq = stripCharsNotInList(seq.upper(), ["A", "C", "G", "T"]) self.optimizer.setSourceSeq(seq) oldInsert = self.textSourceSeq.index("insert") self.textSourceSeq.delete("1.0", "end") sourceCodons = self.optimizer.getCodonsForPrint(True) if not sourceCodons: self.textSourceSeq.insert("end", self.optimizer.sourceSequence) else: for (co, sc, r) in sourceCodons: if sc: if not r: self.textSourceSeq.insert("end", co, "normal" + str(int(sc * 100))) # print("normal"+str(int(sc*100))) else: self.textSourceSeq.insert("end", co, "restrict" + str(int(sc * 100))) else: # remainder without color self.textSourceSeq.insert("end", co) self.textSourceSeq.mark_set("insert", oldInsert) # reset the modified status at the very end self.textSourceSeq.edit_modified(False) if self.textResultSequence.edit_modified(): seq = self.textResultSequence.get("1.0", "end").strip() # self.optimizer.setOptimizedSeq(seq) oldInsert = self.textResultSequence.index("insert") self.textResultSequence.delete("1.0", "end") targetCodons = self.optimizer.getCodonsForPrint(False) if not targetCodons: self.textSourceSeq.insert("end", self.optimizer.optimizedSequence) else: for (co, sc, r) in targetCodons: if sc: if not r: self.textResultSequence.insert("end", co, "normal" + str(int(sc * 100))) # print("normal"+str(int(sc*100))) else: self.textResultSequence.insert("end", co, "restrict" + str(int(sc * 100))) else: # remainder without color self.textResultSequence.insert("end", co) self.textSourceSeq.mark_set("insert", oldInsert) self.textResultSequence.edit_modified(False) def actionLoadSequence(self, event=None): filename = tkinter.filedialog.askopenfilename() if filename: seq = sequenceIO.readFile(filename) self.textSourceSeq.delete("1.0", "end") self.textSourceSeq.insert("end", seq) self.textSourceSeq.edit_modified(True) def actionSaveSequence(self, event=None): filename = tkinter.filedialog.asksaveasfilename() if filename: # print("file is " + filename) with open(filename, mode="w") as fd: fd.write(self.optimizer.optimizedSequence)
class Windows: ''' GUI ''' def __init__(self): self.file = None self.file_strings = None self.scale = 1 self.dom = xml.dom.minidom.parse('KeyWords.xml') self.module = 'normal' self.type = None self.root = tk.Tk() self.menu = tk.Menu(self.root) self.root.config(menu=self.menu) self.child_menu = tk.Menu(self.menu) self.menu.add_cascade(label='模式', menu=self.child_menu) self.root_set() self.title_frame() self.option_frame() self.res_frame() self.buttons_frame() self.menu_init() self.loop() def menu_init(self): menu_root = self.dom.documentElement children = menu_root.childNodes index = 0 for child in children: try: switch = child.getAttribute('mode') if switch == 'On' or switch == 'on': self.child_menu.add_command(label=child.nodeName, command=eval('self.' + child.nodeName)) except: pass pass ''' -------------------------------------------------------------------------------- 这里下面的CNC和UD方法都是控制菜单栏中选择模式的 若要添加,方法名请与xml上节点名称相同 请不要修改CNC(默认)相关方法,避免出现意外的处理错误 -------------------------------------------------------------------------------- ''' def CNC(self): self.type = 'CNC' def UD(self): self.type = 'UD' ''' -------------------------------------------------------------------------------- 以上的CNC和UD方法都是控制菜单栏中选择模式的 若要添加,方法名请与xml上节点名称相同 请不要修改CNC(默认)相关方法,避免出现意外的处理错误(相关请见Windows.__run()中对与默认模式的处理) -------------------------------------------------------------------------------- ''' def root_set(self): self.root.title('金工助手') self.root.minsize(width=1280, height=720) self.root.maxsize(width=1280, height=720) def title_frame(self): title_frame = tk.Frame(self.root) title_frame.pack(pady=10) title_label = tk.Label(title_frame, text='金工助手', font=('黑体', 20, 'bold')) title_label.pack(pady=10) def option_frame(self): option_frame = tk.Frame(self.root) option_frame.pack(pady=10) self.cs = tk.StringVar() self.cs.set('') self.choose_entry = tk.Entry(option_frame, width=60, textvariable=self.cs) self.choose_entry.grid(row=0, column=0, columnspan=3, padx=10) choose_button = tk.Button(option_frame, text='选取文件', command=self.__choose_file) choose_button.grid(row=0, column=3, padx=10) choose_normal_button = tk.Button(option_frame, text='普通模式', command=self.__choose_normal) choose_normal_button.grid(row=1, column=1, padx=20, pady=10) choose_step_button = tk.Button(option_frame, text='单步调试', command=self.__choose_step) choose_step_button.grid(row=1, column=2, padx=20, pady=10) fs_label = tk.Label(option_frame, text='放缩倍数') fs_label.grid(row=2, column=1) self.fs_int = tk.IntVar() self.fs_int.set(self.scale) fs_entry = tk.Entry(option_frame, width=10, textvariable=self.fs_int) fs_entry.grid(row=2, column=2) def res_frame(self): res_frame = tk.Frame(self.root) res_frame.pack(pady=10) self.res_entry = ScrolledText(res_frame, width=150, height=20, undo=True, state=tk.DISABLED) self.res_entry.pack(pady=10) def buttons_frame(self): buttons_frame = tk.Frame(self.root) buttons_frame.pack(pady=10) run_button = tk.Button(buttons_frame, text='运行', font=('黑体', 20, 'bold'), command=self.__run) quit_button = tk.Button(buttons_frame, text='退出', font=('黑体', 20, 'bold'), command=self.__quit) run_button.grid(row=0, column=0, padx=20, pady=10) quit_button.grid(row=0, column=1, padx=20, pady=10) def loop(self): self.root.mainloop() def __choose_file(self): self.file = filedialog.askopenfilename() if self.file == '': return 0 if self.file[-3:] != 'txt': showwarning('警告!', '本脚本只支持读取txt格式文件(文本文档)') return 0 self.cs.set(self.file) self.res_entry.config(state=tk.NORMAL) self.res_entry.delete('1.0', tk.END) self.file_strings = open(self.file, 'r') for line in self.file_strings.readlines(): self.res_entry.insert(tk.END, line) self.res_entry.config(state=tk.DISABLED) self.m = Main(self.file, self.module, self.type) self.m.check() def __choose_normal(self): self.module = 'normal' showwarning('切换模式成功', '已经切换成一步到位的模式') self.m.updata(state=self.module) def __choose_step(self): self.module = 'step' showwarning('切换模式成功', '已经切换成单步调试的模式') self.m.updata(state=self.module) def __quit(self): self.root.destroy() self.file_strings.close() def __run(self): if self.type is None: self.type = 'CNC' self.m.updata(fs=self.fs_int.get()) self.m.updata(type=self.type) self.m.run() def __file(self): return self.file
class BatchRenameApp(Frame): """Batch renaming app""" def __init__(self, parent=None): self.parent=parent if not self.parent: Frame.__init__(self) self.main=self.master else: self.main=Toplevel() self.master=self.main self.main.title('Batch Rename') ws = self.main.winfo_screenwidth() hs = self.main.winfo_screenheight() w = 800; h=500 x = (ws/2)-(w/2); y = (hs/2)-(h/2) self.main.geometry('%dx%d+%d+%d' % (w,h,x,y)) self.doGUI() self.currentdir = os.path.expanduser('~') return def doGUI(self): """Create GUI""" self.m = PanedWindow(self.main, orient=HORIZONTAL) self.m.pack(side=LEFT,fill=BOTH,expand=1) self.fileslist = ScrolledText(self.m, width=50, height=20) self.m.add(self.fileslist) self.preview = ScrolledText(self.m, width=20, height=20) self.m.add(self.preview) fr=Frame(self.main, padding=(4,4), width=90) b=Button(fr,text='Add Folder',command=self.addFolder) b.pack(side=TOP,fill=BOTH,pady=2) b=Button(fr,text='Clear',command=self.clear) b.pack(side=TOP,fill=BOTH,pady=2) self.patternvar = StringVar() self.patternvar.set('*.*') self.filepattern = Entry(fr, textvariable=self.patternvar) Label(fr,text='Wildcard:').pack(side=TOP) self.filepattern.pack(side=TOP,fill=BOTH,pady=2) self.findvar = StringVar() self.findvar.set(' ') self.findtext = Entry(fr, textvariable=self.findvar) Label(fr,text='Find:').pack(side=TOP) self.findtext.pack(side=TOP,fill=BOTH,pady=2) self.replacevar = StringVar() self.replacevar.set('.') self.replacetext = Entry(fr, textvariable=self.replacevar) Label(fr,text='Replace With:').pack(side=TOP) self.replacetext.pack(side=TOP,fill=BOTH,pady=2) b=Button(fr,text='Preview',command=self.dopreview) b.pack(side=TOP,fill=BOTH,pady=2) b=Button(fr,text='Execute',command=self.execute) b.pack(side=TOP,fill=BOTH,pady=2) fr.pack(side=LEFT,fill=BOTH) return def addFolder(self,path=None): """Get a folder""" if path==None: path = filedialog.askdirectory(parent=self.main, initialdir=self.currentdir, title='Select folder') if path: self.path = path #self.refresh() self.dopreview() self.currentdir = path return def refresh(self): """Load files list""" self.fileslist.delete('1.0',END) fp = self.patternvar.get() flist = glob.glob(os.path.join(self.path,fp)) filestr = '\n'.join(flist) self.fileslist.insert(END, filestr) return def dopreview(self): """Preview update""" self.refresh() self.preview.delete('1.0',END) flist = self.fileslist.get('1.0',END) flist = flist.split('\n') find = self.findvar.get() repl = self.replacevar.get() new = doFindReplace(files=flist, find=find, replace=repl) new = '\n'.join(new) self.preview.insert(END,new) return def clear(self): self.fileslist.delete('1.0',END) self.preview.delete('1.0',END) self.path = None return def execute(self): """Do rename""" n = messagebox.askyesno("Rename", "Rename the files?", parent=self.master) if not n: return flist = self.fileslist.get('1.0',END).split('\n') find = self.findvar.get() repl = self.replacevar.get() doFindReplace(files=flist, find=find, replace=repl, rename=True) self.refresh() return
class UpgrTool(Frame): def __init__(self, parent=None): Frame.__init__(self, parent) self.pack(side=TOP, fill=BOTH, expand=YES) self.iniCtrls() self.bind("<Destroy>", self.onDestroy) def iniCtrls(self): frmTop = Frame(self) frmTop.pack(side=TOP, fill=X) self.status_bar = StatusBar(self) self.status_bar.pack(side=BOTTOM, fill=X) self.status_bar.config(bd=2, relief=SUNKEN) frmMiddle = Frame(self) frmMiddle.pack(fill=BOTH, expand=YES) self.btnCheckScripts = Button(frmTop, text='Check scripts', command=self.onCheckScripts) self.btnCheckScripts.pack(side=LEFT, padx=5, pady=5) Button(frmTop, text='Clear', command=self.onClear).pack(side=RIGHT, padx=5, pady=5) self.st = ScrolledText(frmMiddle, font=('courier', 9, 'normal')) self.st.pack(side=TOP, fill=BOTH, expand=YES) def onCheckScripts(self): root_name = r'C:\Users\KSHIPKOV\Documents\SVN\HS\Materials\Source code\Oracle\48to96\Output' # K1/B self.st.insert(END, '\n') flag = True dname = os.path.join(root_name, 'K1', 'B') self.st.insert(END, 'Проверка наличия вызовов скриптов из %s\n' % (dname)) names = [ fname.lower() for fname in os.listdir(dname) if (os.path.isfile(os.path.join(dname, fname))) ] # список скриптов в каталоге d = {} # Словарь для имён вызываемых скриптов me = re.compile(r'@@K1\\B\\(.*)') with open( os.path.join(root_name, "K1_B.sql") ) as fh: # Парсим головной скрипт для получения имён вызываемых скриптов for line in fh: mo = me.match(line) if mo: filename = mo.group(1) d[filename.lower( )] = 1 # Заносим в словарь имя вызываемого скрипта for x in names: if not x in d: self.st.insert(END, 'Не вызывается скрипт: ' + x + '\n') flag = False if flag: self.st.insert(END, 'OK\n') # K2/B self.st.insert(END, '\n') flag = True dname = os.path.join(root_name, 'K2', 'B') self.st.insert(END, 'Проверка наличия вызовов скриптов из %s\n' % (dname)) names = [ fname.lower() for fname in os.listdir(dname) if (os.path.isfile(os.path.join(dname, fname))) ] # список скриптов в каталоге d = {} # Словарь для имён вызываемых скриптов me = re.compile(r'@@K2\\B\\(.*)') with open( os.path.join(root_name, "K2_B.sql") ) as fh: # Парсим головной скрипт для получения имён вызываемых скриптов for line in fh: mo = me.match(line) if mo: filename = mo.group(1) d[filename.lower( )] = 1 # Заносим в словарь имя вызываемого скрипта for x in names: if not x in d: self.st.insert(END, 'Не вызывается скрипт: ' + x + '\n') flag = False if flag: self.st.insert(END, 'OK\n') def onClear(self): self.st.delete('1.0', END) def onDestroy(self, event): pass
class EditorTab(tk.Frame): def __init__(self, master, filepath: str, new_file=False): tk.Frame.__init__(self, master) self.new_file = new_file self.filepath = filepath self.filename = get_filename(filepath) if not new_file else filepath self.master = master self.modified = False self.text_editor = ScrolledText(self, font=("", 15), undo=True, maxundo=-1, wrap="none") self.text_editor.config(highlightthickness=0, bd=0) self.text_editor.grid(row=0, column=1, sticky=tk.NSEW) self.scrollbar_x = tk.Scrollbar(self, orient=tk.HORIZONTAL, command=self.text_editor.xview) self.scrollbar_x.grid(row=1, column=0, columnspan=2, stick=tk.EW) self.text_editor.configure(xscrollcommand=self.scrollbar_x.set) self.line_nb_canvas = tk.Canvas(self, bg=self.text_editor.cget("bg"), bd=0, highlightthickness=0) self.line_nb_canvas.grid_propagate(False) self.line_nb_canvas.grid(row=0, column=0, sticky=tk.NS) self.grid_rowconfigure(0, weight=1) self.grid_columnconfigure(1, weight=1) self.default_file_content = str() @property def id(self) -> str: return str(self) def get(self) -> str: return self.text_editor.get("1.0", "end-1c") @property def lines(self): return self.get().splitlines() def update_lines(self): self.line_nb_canvas.delete("all") font = self.text_editor.cget("font") i = 1 y = 0 while self.text_editor.compare(f"{i}.0", "<", tk.END): dline = self.text_editor.dlineinfo(f"{i}.0") if dline: y = dline[1] else: y = -20 self.line_nb_canvas.create_text(1, y, anchor="ne", text=str(i), font=font, fill=Color(175, 175, 175).hex) i += 1 all_boxes = [ self.line_nb_canvas.bbox(item) for item in self.line_nb_canvas.find_all() ] max_width = (min(box[2] - box[0] for box in all_boxes)) * 4 self.line_nb_canvas.configure(width=max_width + 20) for item in self.line_nb_canvas.find_all(): self.line_nb_canvas.move(item, max_width, 0) def get_filename_from_champion_name(self) -> (str, None): content = self.lines for line in content: if line.startswith(".name"): first_quote = line.find('"') if first_quote == -1: break second_quote = line.find('"', first_quote + 1) if second_quote == -1: break name = line[first_quote + 1:second_quote] if len(name) == 0: break return name.replace(" ", "_").lower() + ".s" return None def open(self) -> bool: if not os.path.isfile(self.filepath): showwarning("An error occurs...", f"Can't open '{self.filepath}'") return False with open(self.filepath, "r") as file: self.default_file_content = file.read() self.text_editor.insert("1.0", self.default_file_content) self.text_editor.edit_reset() self.text_editor.edit_modified(False) self.set_modified_status(False, on_opening=True) return True def save(self) -> bool: if self.new_file: return self.master.save_file_as() self.default_file_content = self.text_editor.get("1.0", "end-1c") with open(self.filepath, "w") as file: file.write(self.default_file_content) self.set_modified_status(False) self.text_editor.edit_modified(False) return True def save_as(self, filepath: str) -> bool: self.master.files_opened[filepath] = self.master.files_opened[ self.filepath] self.master.files_opened.pop(self.filepath) self.filepath = filepath self.filename = get_filename(filepath) self.new_file = False return self.save() def close(self) -> bool: if self.modified: save_file = askyesnocancel( f"{self.filename} - Modifications not saved", "This file was modified and was not saved.\nDo you want to save this file ?" ) if save_file is None: return False if save_file and not self.save(): return False self.master.forget(self.id) self.master.files_opened.pop(self.filepath) return True def undo(self) -> None: try: self.text_editor.edit_undo() except tk.TclError: pass def redo(self) -> None: try: self.text_editor.edit_redo() except tk.TclError: pass def copy_to_clipboard(self, remove_from_editor=False) -> bool: try: txt = self.text_editor.get("sel.first", "sel.last") self.clipboard_clear() self.clipboard_append(txt) if remove_from_editor: self.text_editor.delete("sel.first", "sel.last") except tk.TclError: return False return True def paste_from_clipboard(self) -> None: try: self.text_editor.get("sel.first", "sel.last") except tk.TclError: pass else: self.text_editor.mark_set("insert", "sel.first") self.text_editor.delete("sel.first", "sel.last") self.text_editor.insert("insert", self.clipboard_get()) def check_file_status(self) -> None: actual = self.text_editor.get("1.0", "end-1c") if self.text_editor.edit_modified(): self.text_editor.edit_separator() self.text_editor.edit_modified(False) self.set_modified_status(actual != self.default_file_content) def set_modified_status(self, status: bool, on_opening=False) -> None: self.modified = status if not on_opening: if self.modified and not self.new_file: self.master.tab(self.id, text=self.filename + " - Modified") else: self.master.tab(self.id, text=self.filename) def add(self) -> None: self.master.add(self, text=self.filename) def select(self) -> None: self.master.select(self.id) self.text_editor.focus_set() def set_template(self, name: str, comment: str, author: str) -> None: content = [ line for line in self.lines if not line.startswith(".name") and not line.startswith(".comment") ] header = [ "#", "# {name} champion for CoreWar".format(name=name), "#", "# By {author}".format(author=author), "#", "# {date}".format(date=date.today().strftime("%c")), "#", "" ".name \"{name}\"".format(name=name), ".comment \"{comment}\"".format(comment=comment), "" ] content = header + content self.text_editor.delete("1.0", "end") self.text_editor.insert("1.0", "\n".join(content)) def insert_command(self, cmd: str) -> None: insert = self.text_editor.index(tk.INSERT).split(".") end_of_line = insert[0] + "." + tk.END self.text_editor.insert(end_of_line, "\n" + cmd)
class Pynote: def __init__(self, root): self.root = root # create menu bar .. menubar = Menu(root) filemenu = Menu(menubar, tearoff = 0) filemenu.add_command(label = "New", command = self.new_file) filemenu.add_command(label = "Open", command = self.open_file) filemenu.add_command(label = "Save", command = self.save) filemenu.add_command(label = "Save as...", command = self.save_as) filemenu.add_separator() filemenu.add_command(label = "Exit", command = root.quit) menubar.add_cascade(label = "File", menu = filemenu) self.root.config(menu = menubar) self.textarea = ScrolledText(self.root, font = ('arial', 14), undo = True, wrap = WORD) self.textarea.place(relwidth = 1, relheight = 1) # methods ...... def new_file(self, *args): self.textarea.delete(1.0, END) self.filename = None def open_file(self, *args): self.filename = filedialog.askopenfilename( defaultextension = ".txt", filetypes = [("All Files", "*.*"), ("Text Files", "*.txt"), ("Python Scripts", "*.py"), ("Markdown Documents", "*.md"), ("JavaScript Files", "*.js"), ("HTML Documents", "*.html"), ("CSS Documents", "*.css")]) if self.filename: self.textarea.delete(1.0, END) with open(self.filename, "r") as f: self.textarea.insert(1.0, f.read()) def save(self, *args): if self.filename: try: textarea_content = self.textarea.get(1.0, END) with open(self.filename, "w") as f: f.write(textarea_content) except Exception as e: print(e) else: self.save_as() def save_as(self, *args): try: new_file = filedialog.asksaveasfilename( initialfile = "Untitled.txt", defaultextension = ".txt", filetypes = [("All Files", "*.*"), ("Text Files", "*.txt"), ("Python Scripts", "*.py"), ("Markdown Documents", "*.md"), ("JavaScript Files", "*.js"), ("HTML Documents", "*.html"), ("CSS Documents", "*.css")]) textarea_content = self.textarea.get(1.0, END) with open(new_file, "w") as f: f.write(textarea_content) except Exception as e: print(e)
class Stego: def __init__(self, master): print("Setting up GUI") self.master = master self.master.title(TITLE) # Images Container imagesContainer = Frame(master=self.master, bg=self.master['bg']) self.canvasOrig = Canvas(bg='white') self.canvasOrig.pack(in_=imagesContainer, side='left') self.canvasNew = Canvas(bg='white') self.canvasNew.pack(in_=imagesContainer, side='left') imagesContainer.pack(side='top', fill='x') # File Opening/Saving Container fileSelectsContainer = Frame(master=self.master, bg=self.master['bg']) self.pickFileBtn = Button(text='Select an image', command=self.openFileHandle) self.pickFileBtn.pack(in_=fileSelectsContainer, side='left') self.saveNewBtn = Button(text='Save new image', command=self.saveImageHandle) self.saveNewBtn['state'] = DISABLED self.saveNewBtn.pack(in_=fileSelectsContainer, side='left') fileSelectsContainer.pack(side='top', fill='none', expand=True) # Text Input self.textInput = ScrolledText(master=self.master, width=TEXT_INPUT_W, height=TEXT_INPUT_H) self.textInput['state'] = DISABLED self.textInput.pack() # Step Input Container stepsContainer = Frame(master=self.master, bg=self.master['bg']) stepsLabel = Label(text='Step: ') stepsLabel.pack(in_=stepsContainer, side='left') self.stepsVar = StringVar() self.stepsVar.set(DEFAULT_STEP_COUNT) self.stepsInput = Entry(textvariable=self.stepsVar) self.stepsInput['state'] = DISABLED self.stepsInput.pack(in_=stepsContainer, side='left') self.maskSteps = IntVar() self.maskSteps.set(DEFAULT_MASK) self.maskStepsBtn = Checkbutton(text='Mask Steps', variable=self.maskSteps) self.maskStepsBtn['state'] = DISABLED self.maskStepsBtn.pack(in_=stepsContainer, side='left') stepsContainer.pack(side='top', fill='none', expand=True) # Message Buttons Container messageBtnsContainer = Frame(master=self.master, bg=self.master['bg']) self.hideMessageBtn = Button(text='Hide Message', command=self.hideMessageHandle) self.hideMessageBtn['state'] = DISABLED self.hideMessageBtn.pack(in_=messageBtnsContainer, side='left') self.showMessageBtn = Button(text='Recover Message', command=self.recoverMessageHandle) self.showMessageBtn['state'] = DISABLED self.showMessageBtn.pack(in_=messageBtnsContainer, side='left') messageBtnsContainer.pack(side='top', fill='none', expand=True) # Close Button self.closeBtn = Button(master=self.master, text='Close', command=master.quit) self.closeBtn.pack() def enableButtons(self): print("Enabling Buttons") self.saveNewBtn['state'] = NORMAL self.saveNewBtn.update() self.showMessageBtn['state'] = NORMAL self.showMessageBtn.update() self.hideMessageBtn['state'] = NORMAL self.hideMessageBtn.update() self.textInput['state'] = NORMAL self.textInput.update() self.stepsInput['state'] = NORMAL self.stepsInput.update() self.maskStepsBtn['state'] = NORMAL self.maskStepsBtn.update() # pickFileBtn callback def openFileHandle(self): print("Open File Handler Hit") filePath = filedialog.askopenfilename(initialdir=os.getcwd(), title='Select a File', filetypes=(('png files', '*.png'), ('all files', '*.*'))) print("File Path Selected: {}".format(filePath)) if filePath == "": return self.canvasOrig.filePath = filePath self.canvasOrig.img = PIL.Image.open(filePath) w, h = self.canvasOrig.img.size self.canvasOrig.config(width=w, height=h) self.canvasOrig.tkImg = PIL.ImageTk.PhotoImage(self.canvasOrig.img) self.canvasOrig.imgSprite = self.canvasOrig.create_image( w / 2, h / 2, anchor=CENTER, image=self.canvasOrig.tkImg) self.canvasOrig.update() self.enableButtons() # Convert a string to an array of bits def convertStringToBitsArray(self): print("Converting Message to Bit Array") bytes = bytearray() bytes.extend(self.textInput.get('1.0', END).encode('utf-8')) bytes.append(23) # End of Transmission Block utf-8 character bits = np.unpackbits(bytes) return bits def hideMessageHandle(self): print("Hide Message Handler Hit") self.canvasNew.filePath = self.canvasOrig.filePath self.canvasNew.img = PIL.Image.open(self.canvasNew.filePath) w, h = self.canvasNew.img.size self.canvasNew.config(width=w, height=h) self.canvasNew.tkImg = PIL.ImageTk.PhotoImage(self.canvasNew.img) self.canvasNew.imgSprite = self.canvasNew.create_image( w / 2, h / 2, anchor=CENTER, image=self.canvasNew.tkImg) self.canvasNew.update() bits = self.convertStringToBitsArray() size = self.canvasNew.img.size width, height = size newImg = PIL.Image.new('RGB', (width, height), 'white') pixels = newImg.load() # Use best fit steps if user did not enter a step count if self.stepsVar.get() == '': totalPixels = width * height - 4 tempStep = max(totalPixels * 3 // len(bits), 1) # Biggest step we can hold in 12 bits is 4095 step = min(tempStep, MAX_STEP) self.stepsVar.set(str(step)) else: # Use User input step step = int(self.stepsVar.get()) if step > MAX_STEP: step = MAX_STEP self.stepsVar.set(str(step)) print("Step Count: {}".format(step)) settingsBits = '{0:012b}'.format(step) bitsPtr = 0 settingsPtr = 0 for i in range(width): for j in range(height): pixel = self.canvasNew.img.getpixel((i, j)) if settingsPtr < len(settingsBits) and self.maskSteps.get( ) == 0: r = (pixel[0] & ~1) | int(settingsBits[settingsPtr]) settingsPtr += 1 g = (pixel[1] & ~1) | int(settingsBits[settingsPtr]) settingsPtr += 1 b = (pixel[2] & ~1) | int(settingsBits[settingsPtr]) settingsPtr += 1 pixels[i, j] = (r, g, b) elif settingsPtr < len(settingsBits) and self.maskSteps.get( ) == 1: pixels[i, j] = pixel settingsPtr += 1 else: if (i * width + j) % step == 0: # Change this pixel if bitsPtr + 3 < len(bits): r = (pixel[0] & ~1) | bits[bitsPtr] bitsPtr += 1 g = (pixel[1] & ~1) | bits[bitsPtr] bitsPtr += 1 b = (pixel[2] & ~1) | bits[bitsPtr] bitsPtr += 1 pixels[i, j] = (r, g, b) else: pixels[i, j] = pixel else: # Use original pixel pixels[i, j] = pixel self.canvasNew.img = newImg self.canvasNew.tkImg = PIL.ImageTk.PhotoImage(self.canvasNew.img) self.canvasNew.imgSprite = self.canvasNew.create_image( width / 2, height / 2, anchor=CENTER, image=self.canvasNew.tkImg) self.canvasNew.update() print('Hide Message Handle Hit') def saveImageHandle(self): print('Save Message Handle Hit') filepath = filedialog.asksaveasfilename( initialdir=os.getcwd(), title='Save as', filetypes=(('png file', '*.png'), ('all files', '*.*'))) if '.png' != filepath[-4:]: filepath += '.png' self.canvasNew.img.save(filepath, 'png') print("File saved as: {}".format(filepath)) def recoverMessageHandle(self): print("Recover Message Handler Hit") self.canvasNew.filePath = self.canvasOrig.filePath self.canvasNew.img = PIL.Image.open(self.canvasNew.filePath) w, h = self.canvasNew.img.size self.canvasNew.config(width=w, height=h) self.canvasNew.tkImg = PIL.ImageTk.PhotoImage(self.canvasNew.img) self.canvasNew.imgSprite = self.canvasNew.create_image( w / 2, h / 2, anchor=CENTER, image=self.canvasNew.tkImg) self.canvasNew.update() newImg = PIL.Image.new('RGB', (w, h), 'white') pixels = newImg.load() allBitsArr = [] if self.stepsVar.get() != '': print("Using User Input for Steps") step = max(int(self.stepsVar.get()), 1) else: print("Using Calculated Number for Steps") settingsBits = "" for x in range(4): pixel = self.canvasNew.img.getpixel((0, x)) rBit = (pixel[0] & 1) gBit = (pixel[1] & 1) bBit = (pixel[2] & 1) settingsBits += (str(rBit)) settingsBits += (str(gBit)) settingsBits += (str(bBit)) pixels[0, x] = (0, 0, 0) step = int(settingsBits, 2) self.stepsVar.set(step) for i in range(w): for j in range(h): # Ignore first 4 pixels (Message starts after the first 4 pixels) if i == 0 and j < 4: continue pixel = self.canvasNew.img.getpixel((i, j)) if ( i * w + j ) % step == 0: # Get bits of msg and change this pixel to black rBit = (pixel[0] & 1) gBit = (pixel[1] & 1) bBit = (pixel[2] & 1) allBitsArr.append(rBit) allBitsArr.append(gBit) allBitsArr.append(bBit) pixels[i, j] = (0, 0, 0) else: # Use original pixel pixels[i, j] = pixel msgBytes = np.packbits(allBitsArr) msg = "" for ele in msgBytes: if ele == 23: break msg += str(chr(ele)) self.textInput.delete('1.0', END) self.textInput.insert('1.0', msg) print("Message recovered: {}".format(msg)) self.canvasNew.img = newImg self.canvasNew.tkImg = PIL.ImageTk.PhotoImage(self.canvasNew.img) self.canvasNew.imgSprite = self.canvasNew.create_image( w / 2, h / 2, anchor=CENTER, image=self.canvasNew.tkImg) self.canvasNew.update()
class ValidatorApp: VERBOSITY_LEVELS = {"Less": "", "Standard (-v)": "-v", "More (-vv)": "-vv"} def __init__(self, config: Config = None): """Constructs the GUI element of the Validation Tool""" self.task = None self.config = config or Config() self._root = Tk() self._root.title(self.config.app_name) self._root.protocol("WM_DELETE_WINDOW", self.shutdown) if self.config.terms_link_text: menubar = Menu(self._root) menubar.add_command( label=self.config.terms_link_text, command=lambda: webbrowser.open(self.config.terms_link_url), ) self._root.config(menu=menubar) parent_frame = Frame(self._root) main_window = PanedWindow(parent_frame) main_window.pack(fill=BOTH, expand=1) control_panel = PanedWindow( main_window, orient=HORIZONTAL, sashpad=4, sashrelief=RAISED ) actions = Frame(control_panel) control_panel.add(actions) control_panel.paneconfigure(actions, minsize=250) if self.config.disclaimer_text or self.config.requirement_link_text: self.footer = self.create_footer(parent_frame) parent_frame.pack(fill=BOTH, expand=True) # profile start number_of_categories = len(self.config.category_names) category_frame = LabelFrame(actions, text="Additional Validation Categories:") category_frame.grid(row=1, column=1, columnspan=3, pady=5, sticky="we") self.categories = [] for x in range(0, number_of_categories): category_name = self.config.category_names[x] category_value = IntVar(value=0) category_value._name = "category_{}".format(category_name.replace(" ", "_")) # noinspection PyProtectedMember category_value.set(self.config.get_category_value(category_value._name)) self.categories.append(category_value) category_checkbox = Checkbutton( category_frame, text=category_name, variable=self.categories[x] ) ToolTip(category_checkbox, self.config.get_description(category_name)) category_checkbox.grid(row=x + 1, column=1, columnspan=2, sticky="w") settings_frame = LabelFrame(actions, text="Settings") settings_frame.grid(row=3, column=1, columnspan=3, pady=10, sticky="we") verbosity_label = Label(settings_frame, text="Verbosity:") verbosity_label.grid(row=1, column=1, sticky=W) self.verbosity = StringVar(self._root, name="verbosity") self.verbosity.set(self.config.default_verbosity(self.VERBOSITY_LEVELS)) verbosity_menu = OptionMenu( settings_frame, self.verbosity, *tuple(self.VERBOSITY_LEVELS.keys()) ) verbosity_menu.config(width=25) verbosity_menu.grid(row=1, column=2, columnspan=3, sticky=E, pady=5) report_format_label = Label(settings_frame, text="Report Format:") report_format_label.grid(row=2, column=1, sticky=W) self.report_format = StringVar(self._root, name="report_format") self.report_format.set(self.config.default_report_format) report_format_menu = OptionMenu( settings_frame, self.report_format, *self.config.report_formats ) report_format_menu.config(width=25) report_format_menu.grid(row=2, column=2, columnspan=3, sticky=E, pady=5) input_format_label = Label(settings_frame, text="Input Format:") input_format_label.grid(row=3, column=1, sticky=W) self.input_format = StringVar(self._root, name="input_format") self.input_format.set(self.config.default_input_format) input_format_menu = OptionMenu( settings_frame, self.input_format, *self.config.input_formats ) input_format_menu.config(width=25) input_format_menu.grid(row=3, column=2, columnspan=3, sticky=E, pady=5) self.halt_on_failure = BooleanVar(self._root, name="halt_on_failure") self.halt_on_failure.set(self.config.default_halt_on_failure) halt_on_failure_label = Label(settings_frame, text="Halt on Basic Failures:") halt_on_failure_label.grid(row=4, column=1, sticky=E, pady=5) halt_checkbox = Checkbutton( settings_frame, offvalue=False, onvalue=True, variable=self.halt_on_failure ) halt_checkbox.grid(row=4, column=2, columnspan=2, sticky=W, pady=5) directory_label = Label(actions, text="Template Location:") directory_label.grid(row=4, column=1, pady=5, sticky=W) self.template_source = StringVar(self._root, name="template_source") directory_entry = Entry(actions, width=40, textvariable=self.template_source) directory_entry.grid(row=4, column=2, pady=5, sticky=W) directory_browse = Button(actions, text="...", command=self.ask_template_source) directory_browse.grid(row=4, column=3, pady=5, sticky=W) validate_button = Button( actions, text="Validate Templates", command=self.validate ) validate_button.grid(row=5, column=1, columnspan=2, pady=5) self.result_panel = Frame(actions) # We'll add these labels now, and then make them visible when the run completes self.completion_label = Label(self.result_panel, text="Validation Complete!") self.result_label = Label( self.result_panel, text="View Report", fg="blue", cursor="hand2" ) self.underline(self.result_label) self.result_label.bind("<Button-1>", self.open_report) self.result_panel.grid(row=6, column=1, columnspan=2) control_panel.pack(fill=BOTH, expand=1) main_window.add(control_panel) self.log_panel = ScrolledText(main_window, wrap=WORD, width=120, height=20) self.log_panel.configure(font=font.Font(family="Courier New", size="11")) self.log_panel.pack(fill=BOTH, expand=1) main_window.add(self.log_panel) # Briefly add the completion and result labels so the window size includes # room for them self.completion_label.pack() self.result_label.pack() # Show report link self._root.after_idle( lambda: ( self.completion_label.pack_forget(), self.result_label.pack_forget(), ) ) self.config.watch( *self.categories, self.verbosity, self.input_format, self.report_format, self.halt_on_failure, ) self.schedule(self.execute_pollers) if self.config.terms_link_text and not self.config.are_terms_accepted: TermsAndConditionsDialog(parent_frame, self.config) if not self.config.are_terms_accepted: self.shutdown() def create_footer(self, parent_frame): footer = Frame(parent_frame) disclaimer = Message( footer, text=self.config.disclaimer_text, anchor=CENTER ) disclaimer.grid(row=0, pady=2) parent_frame.bind( "<Configure>", lambda e: disclaimer.configure(width=e.width - 20) ) if self.config.requirement_link_text: requirement_link = Text( footer, height=1, bg=disclaimer.cget("bg"), relief=FLAT, font=disclaimer.cget("font"), ) requirement_link.tag_configure("center", justify="center") hyperlinks = HyperlinkManager(requirement_link) requirement_link.insert(INSERT, "Validating: ") requirement_link.insert( INSERT, self.config.requirement_link_text, hyperlinks.add(self.open_requirements), ) requirement_link.tag_add("center", "1.0", "end") requirement_link.config(state=DISABLED) requirement_link.grid(row=1, pady=2) ToolTip(requirement_link, self.config.requirement_link_url) footer.grid_columnconfigure(0, weight=1) footer.pack(fill=BOTH, expand=True) return footer def ask_template_source(self): if self.input_format.get() == "ZIP File": template_source = filedialog.askopenfilename( title="Select Archive", filetypes=(("ZIP Files", "*.zip"), ("All Files", "*")), ) else: template_source = filedialog.askdirectory() self.template_source.set(template_source) def validate(self): """Run the pytest validations in a background process""" if not self.delete_prior_report(): return if not self.template_source.get(): self.ask_template_source() template_dir = self.resolve_template_dir() if template_dir: self.kill_background_task() self.clear_log() self.completion_label.pack_forget() self.result_label.pack_forget() self.task = multiprocessing.Process( target=run_pytest, args=( template_dir, self.config.log_file, self.config.status_queue, self.categories_list(), self.VERBOSITY_LEVELS[self.verbosity.get()], self.report_format.get().lower(), self.halt_on_failure.get(), self.template_source.get(), ), ) self.task.daemon = True self.task.start() @property def title(self): """Returns the text displayed in the title bar of the application""" return self._root.title() def execute_pollers(self): """Call all methods that require periodic execution, and re-schedule their execution for the next polling interval""" try: self.poll_log_file() self.poll_status_queue() self.poll_command_queue() finally: self.schedule(self.execute_pollers) @staticmethod def _drain_queue(q): """Yields values from the queue until empty""" while True: try: yield q.get(block=False) except queue.Empty: break def poll_command_queue(self): """Picks up command strings from the commmand queue, and dispatches it for execution. Only SHUTDOWN is supported currently""" for command in self._drain_queue(self.config.command_queue): if command == "SHUTDOWN": self.shutdown() def poll_status_queue(self): """Checks for completion of the job, and then displays the View Report link if it was successful or writes the exception to the ``log_panel`` if it fails.""" for is_success, e in self._drain_queue(self.config.status_queue): if is_success: self.completion_label.pack() self.result_label.pack() # Show report link else: self.log_panel.insert(END, str(e)) def poll_log_file(self): """Reads captured stdout and stderr from the log queue and writes it to the log panel.""" for line in self._drain_queue(self.config.log_queue): self.log_panel.insert(END, line) self.log_panel.see(END) def schedule(self, func: Callable): """Schedule the callable ``func`` to be executed according to the polling_frequency""" self._root.after(self.config.polling_frequency, func) def clear_log(self): """Removes all log entries from teh log panel""" self.log_panel.delete("1.0", END) def delete_prior_report(self) -> bool: """Attempts to delete the current report, and pops up a warning message to the user if it can't be deleted. This will force the user to close the report before re-running the validation. Returns True if the file was deleted or did not exist, or False otherwise""" if not os.path.exists(self.report_file_path): return True try: os.remove(self.report_file_path) return True except OSError: messagebox.showerror( "Error", "Please close or rename the open report file before re-validating", ) return False @property def report_file_path(self): ext_mapping = {"csv": "csv", "html": "html", "excel": "xlsx"} ext = ext_mapping.get(self.report_format.get().lower()) return os.path.join(PATH, OUT_DIR, "report.{}".format(ext)) # noinspection PyUnusedLocal def open_report(self, event): """Open the report in the user's default browser""" webbrowser.open_new("file://{}".format(self.report_file_path)) def open_requirements(self): """Open the report in the user's default browser""" webbrowser.open_new(self.config.requirement_link_url) def start(self): """Start the event loop of the application. This method does not return""" self._root.mainloop() @staticmethod def underline(label): """Apply underline format to an existing label""" f = font.Font(label, label.cget("font")) f.configure(underline=True) label.configure(font=f) def kill_background_task(self): if self.task and self.task.is_alive(): self.task.terminate() for _ in self._drain_queue(self.config.log_queue): pass def shutdown(self): """Shutdown the application""" self.kill_background_task() self._root.destroy() def check_template_source_is_valid(self): """Verifies the value of template source exists and of valid type based on input setting""" if not self.template_source.get(): return False template_path = Path(self.template_source.get()) if not template_path.exists(): messagebox.showerror( "Error", "Input does not exist. Please provide a valid file or directory.", ) return False if self.input_format.get() == "ZIP File": if zipfile.is_zipfile(template_path): return True else: messagebox.showerror( "Error", "Expected ZIP file, but input is not a valid ZIP file" ) return False else: if template_path.is_dir(): return True else: messagebox.showerror( "Error", "Expected directory, but input is not a directory" ) return False def resolve_template_dir(self) -> str: """Extracts the zip file to a temporary directory if needed, otherwise returns the directory supplied to template source. Returns empty string if the template source isn't valid""" if not self.check_template_source_is_valid(): return "" if self.input_format.get() == "ZIP File": temp_dir = tempfile.mkdtemp() archive = zipfile.ZipFile(self.template_source.get()) archive.extractall(path=temp_dir) return temp_dir else: return self.template_source.get() def categories_list(self) -> list: categories = [] selected_categories = self.categories for x in range(0, len(selected_categories)): if selected_categories[x].get(): category = self.config.category_names[x] categories.append(self.config.get_category(category)) return categories
class Application(tk.Frame): def __init__(self, master=None): tk.Frame.__init__(self, master) self.pack() self.createWidgets() def __del__(self): print('del tianyanche') def createWidgets(self): self.contentDest = tk.StringVar() self.contentDest.set('\uf649') self.entryDest = tk.Entry(self, width=40) self.entryDest["textvariable"] = self.contentDest self.entryDest.grid(row=0) self.entryDest.focus() self.entryDest.bind('<Return>', lambda event: self.start()) self.buttonStart = tk.Button(self, text='ヽ(ˋ▽ˊ)ノ ', width=25) self.buttonStart['command'] = self.start self.buttonStart['fg'] = 'black' self.buttonStart.grid(row=1) self.text = ScrolledText(self, font=('Courier New', 13), fg='green', bg='black', width=30) self.text.grid(row=2, columnspan=1) def start(self): self.running = True self.td = threading.Thread(target=self.startThread) self.td.setDaemon(True) self.td.start() def get_info(self, t): url = "http://www.tuling123.com/openapi/api" data = { "key": "13e4499c33c27055a3c7ee2904b8", "info": t, "userid": "masong" } content = requests.post(url, data=data).content result = json.loads(content) return result["text"] def startThread(self): try: spk = win32com.client.Dispatch("SAPI.SpVoice") t = self.contentDest.get() self.text.delete(0.0, "end") self.text.insert("end", u"正在为您检索:【%s】的应答\n" % t) t = self.get_info(t) if not t: t = "不好意思,服务出问题了" self.text.delete(0.0, "end") self.text.insert("end", u"检索结果如下:\n") self.text.insert("end", t) spk.Speak(t) except Exception as e: pass self.text.delete(0.0, "end") self.text.insert("end", "请先安装TTS模块(用以文字转语音)") webbrowser.open("https://www.baidu.com/s?wd=Windows怎么安装TTS模块")
class Rest(ttk.Frame): GET = 'GET' POST = 'POST' PUT = 'PUT' DELETE = 'DELETE' OPTIONS = 'OPTIONS' TRACE = 'TRACE' HEAD = 'HEAD' def __init__(self, root, *args, **kwargs): super(Rest, self).__init__(*args, **kwargs) self.pack() menubar = tkinter.Menu(root) menu_arquivo = tkinter.Menu(menubar, tearoff=0) menubar.add_cascade(label="Arquivo", menu=menu_arquivo) menu_arquivo.add_command(label="Novo", command=self.novo_arquivo) menu_arquivo.add_command(label="Abrir", command=self.abrir_arquivo) menu_arquivo.add_command(label="Salvar", command=self.salvar_arquivo) menu_arquivo.add_command(label="Sair",command=root.quit) root.config(menu=menubar) self.url = tkinter.StringVar() self.frame_url = ttk.Frame(self) self.frame_url.pack() self.lbl_url_entry = tkinter.Label(self.frame_url,text='URL') self.lbl_url_entry.pack(side=tkinter.LEFT) self.url_entry = tkinter.Entry(self.frame_url,textvariable=self.url, width=80) self.url_entry.pack(side=tkinter.LEFT) self.metodo = tkinter.StringVar() self.metodos_combo = ttk.Combobox(self.frame_url, textvariable=self.metodo, width=8) self.metodos_combo.bind("<<ComboboxSelected>>", self.metodo_select) self.metodos_combo['values'] = (Rest.GET, Rest.POST,Rest.PUT, Rest.DELETE, Rest.OPTIONS, Rest.TRACE, Rest.HEAD) self.metodos_combo.pack(side=tkinter.LEFT) self.metodos_combo.state(['readonly']) self.metodo.set( self.metodos_combo['values'][0] ) self.botao_ir = ttk.Button( self.frame_url, text='IR', command=self.request) self.botao_ir.pack(side=tkinter.LEFT) self.frame_header = ttk.Frame(self) self.frame_header.pack(fill=tkinter.X, padx=5, pady=2) self.lbl_headers = tkinter.Label(self.frame_header,text='Headers') self.lbl_headers.pack(side=tkinter.LEFT) self.botao_addheader = ttk.Button( self.frame_header, text='+', command=self.add_header) self.botao_addheader.pack(side=tkinter.RIGHT) self.headers_canvas = tkinter.Canvas(self, borderwidth=0, height=100) self.frame_headers = ttk.Frame(self.headers_canvas) self.frame_headers.pack() #Scrollbar self.scroll_bar_y = tkinter.Scrollbar(self, orient=tkinter.VERTICAL, command=self.headers_canvas.yview) self.headers_canvas.configure(yscrollcommand=self.scroll_bar_y.set) self.scroll_bar_y.pack(side=tkinter.RIGHT, fill=tkinter.Y) self.scroll_bar_x = tkinter.Scrollbar(self, orient=tkinter.HORIZONTAL, command=self.headers_canvas.xview) self.headers_canvas.configure(xscrollcommand=self.scroll_bar_x.set) self.scroll_bar_x.pack(side=tkinter.BOTTOM, fill=tkinter.X) self.headers_canvas.pack(side=tkinter.LEFT, fill=tkinter.BOTH, expand=True) self.headers_canvas.create_window((1,1), window=self.frame_headers, anchor="nw", tags="self.frame_headers") self.frame_headers.bind("<Configure>", self.on_frame_configure) self.lista_headers = [] frame_keyvalue = tkinter.Frame(self.frame_headers) frame_keyvalue.pack() header1 = tkinter.Label(frame_keyvalue, text='Header') header1.pack(side=tkinter.LEFT) value_header1 = tkinter.Label(frame_keyvalue, text='Valor') value_header1.pack(side=tkinter.LEFT) lbl_body = tkinter.Label(root, text='Body') lbl_body.pack() self.body = ScrolledText(root, height=10, width=100) self.body.pack() lbl_retorno = tkinter.Label(root, text='Retorno') lbl_retorno.pack() self.retorno = ScrolledText(root, height=18, width=100) self.retorno.pack() self.metodo_select()#Bloqueando o Body para edição self.lbl_request = tkinter.Label(root,text='') self.lbl_request.pack() def metodo_select(self, value=None): metodo = self.metodo.get() if metodo == Rest.POST or metodo == Rest.PUT: self.body.config(state=tkinter.NORMAL) elif metodo == Rest.GET or metodo == Rest.DELETE: self.body.config(state=tkinter.DISABLED) def remove_header(self, chave, frame): for item in self.lista_headers: if item[0] == chave: self.lista_headers.remove(item) frame.destroy() def add_header(self, key='', value=''): chave = tkinter.StringVar() chave.set(key) valor = tkinter.StringVar() valor.set(value) frame_keyvalue = tkinter.Frame(self.frame_headers) frame_keyvalue.pack() header1 = tkinter.Entry(frame_keyvalue,textvariable=chave) header1.pack(side=tkinter.LEFT) value_header1 = tkinter.Entry(frame_keyvalue,textvariable=valor) value_header1.pack(side=tkinter.LEFT) botao_remover = tkinter.Button(frame_keyvalue, text='-',command=lambda: self.remove_header(chave, frame_keyvalue)) botao_remover.pack(side=tkinter.LEFT) self.lista_headers.append( (chave, valor, frame_keyvalue) ) def on_frame_configure(self, event): '''Reset the scroll region to encompass the inner frame''' self.headers_canvas.configure(scrollregion=self.headers_canvas.bbox("all")) def get_headers(self): headers = {} for keyValue in self.lista_headers: headers[ keyValue[0].get() ] = keyValue[1].get() return headers def get_data(self): return self.body.get(0.0,tkinter.END) def request(self): resposta = '' try: metodo = self.metodo.get() headers = self.get_headers() if metodo == Rest.POST: data = self.get_data() resposta = r.post(self.url.get(), headers=headers, data=data) elif metodo == Rest.GET: resposta = r.get(self.url.get(), headers=headers) elif metodo == Rest.PUT: data = self.get_data() resposta = r.put(self.url.get(), headers=headers, data=data) elif metodo == Rest.DELETE: resposta = r.delete(self.url.get(), headers=headers) elif metodo == Rest.OPTIONS: resposta = r.options(self.url.get(), headers=headers) elif metodo == Rest.TRACE: resposta = r.trace(self.url.get(), headers=headers) elif metodo == Rest.HEAD: resposta = r.head(self.url.get(), headers=headers) except Exception as ex: print(ex) resposta = ex.message self.tratar_resposta(resposta) self.retorno.delete(0.0,tkinter.END) try: load = json.loads(resposta.text) self.retorno.insert(tkinter.END, json.dumps(load, indent=4, sort_keys=True) ) except: soup = BeautifulSoup(resposta.text) self.retorno.insert(tkinter.END, soup.prettify() ) def tratar_resposta(self, resposta): try: texto = 'Status: {0}\n'.format(resposta.status_code) texto += 'Headers:\n' for key in resposta.headers.keys(): texto += '\t {0}:{1}\n'.format(key, resposta.headers[key]) texto += 'Encoding:{0}\n'.format(resposta.encoding) self.lbl_request['text'] = texto except Exception as ex: print(ex) self.lbl_request['text'] = 'Erro' def abrir_arquivo(self): arquivo = askopenfilename(title='Escolher arquivo',filetypes=( ("JSON File", "*.json"), ) ) if arquivo: self.novo_arquivo() # Limpa os campos arquivo_json = None with open(arquivo, 'r') as configuracao: arquivo_json = configuracao.read() arquivo_json = json.loads(arquivo_json) self.url.set( arquivo_json['url'] ) if arquivo_json['method']: if arquivo_json['method'] == Rest.GET: self.metodo.set( Rest.GET ) elif arquivo_json['method'] == Rest.POST: self.metodo.set( Rest.POST ) elif arquivo_json['method'] == Rest.PUT: self.metodo.set( Rest.PUT ) elif arquivo_json['method'] == Rest.DELETE: self.metodo.set( Rest.DELETE ) elif arquivo_json['method'] == Rest.OPTIONS: self.metodo.set( Rest.OPTIONS ) elif arquivo_json['method'] == Rest.TRACE: self.metodo.set( Rest.TRACE ) elif arquivo_json['method'] == Rest.HEAD: self.metodo.set( Rest.HEAD ) self.metodo_select() if arquivo_json['data']: self.body.delete(0.0,tkinter.END) self.body.insert(tkinter.END, arquivo_json['data']) if 'headers' in arquivo_json: for key in arquivo_json['headers'].keys(): self.add_header(key=key, value=arquivo_json['headers'][key]) def novo_arquivo(self): self.url.set('') self.body.delete(0.0,tkinter.END) self.retorno.delete(0.0,tkinter.END) self.lbl_request['text'] = '' self.metodo.set( Rest.GET ) while True: if self.lista_headers: item = self.lista_headers[0] key = item[0] frame = item[2] self.remove_header( key, frame ) else: break def salvar_arquivo(self): arquivo_destino = asksaveasfilename(title='Salvar JSON do Request', filetypes=[('JSON File','*.json')]) if arquivo_destino: dicionario = {} dicionario['headers'] = self.get_headers() dicionario['data'] = self.get_data() dicionario['method'] = self.metodo.get() dicionario['url'] = self.url.get() with open(arquivo_destino, 'w') as destino: destino.write( json.dumps(dicionario) ) messagebox.showinfo('Rest', 'Arquivos salvo com sucesso')
class PageMain(tk.Frame): def __init__(self, parent, user, dept): ttk.Frame.__init__(self, parent) self.parent = parent self.user = user self.dept = dept imgdateset = tk.PhotoImage(file=str(os.getcwd() + "\\" + "icon-icons.com_date.png")) self.imgdateget = imgdateset.subsample( 2, 2) # Resizing image by.subsample to fit on button self.btnselect = StringVar(parent, value="TN") self.komponenMain() self.komponenAtas() self.komponenTengah() self.komponenBawah() def komponenMain(self): self.topFrame = ttk.Frame(self) self.topFrame.pack(side=TOP, fill=X) self.midFrame = ttk.Frame(self) self.midFrame.pack(side=TOP, fill=X) self.botFrame = ttk.Frame(self) self.botFrame.pack(side=TOP, fill=X) footer = ttk.Frame(self) footer.pack(side=BOTTOM, fill=X) ttk.Label(self.topFrame, text='').grid(row=0, column=0) ttk.Label(self.midFrame, text='').grid(row=0, column=0) ttk.Label(self.botFrame, text='').grid(row=0, column=0) ttk.Label(footer, text='').grid(row=0, column=0) def komponenAtas(self): #samping kiri topleft = ttk.Frame(self.topFrame) topleft.grid(row=1, column=1, sticky=W) ttk.Label(topleft, text='No WO').grid(row=0, column=0, sticky=W, padx=20) ttk.Label(topleft, text=':').grid(row=0, column=1, sticky=W, pady=5, padx=10) self.entWo = ttk.Entry(topleft, width=20) self.entWo.grid(row=0, column=2, sticky=W) ttk.Label(topleft, text="IFCA").grid(row=1, column=0, sticky=W, padx=20) ttk.Label(topleft, text=':').grid(row=1, column=1, sticky=W, pady=5, padx=10) self.entIfca = ttk.Entry(topleft, width=15) self.entIfca.grid(row=1, column=2, sticky=W) radiobtn = ttk.Frame(topleft) radiobtn.grid(row=1, column=2) self.rbtnTN = ttk.Radiobutton(radiobtn, text="TN", variable=self.btnselect, value="TN", command=self.auto_ifca) self.rbtnTN.grid(row=0, column=0, sticky=W) self.rbtnBM = ttk.Radiobutton(radiobtn, text="BM", variable=self.btnselect, value="BM", command=self.auto_ifca) ttk.Label(radiobtn, text=" / ").grid(row=0, column=1, sticky=E) self.rbtnBM.grid(row=0, column=2, sticky=W) #tglbuat ttk.Label(topleft, text="Tanggal - Jam").grid(row=2, column=0, sticky=W, padx=20) ttk.Label(topleft, text=':').grid(row=2, column=1, sticky=W, pady=5, padx=10) tglbuat = ttk.Frame(topleft) tglbuat.grid(row=2, column=2, sticky=W) self.entTglbuat = ttk.Entry(tglbuat, width=10) self.entTglbuat.grid(row=1, column=0, sticky=W) self.entJambuat = ttk.Entry(tglbuat, width=7) self.entJambuat.grid(row=1, column=1, sticky=W) self.btnDateCreate = Button(tglbuat, image=self.imgdateget, command=self.onDateCreate) self.btnDateCreate.grid(row=1, column=2, pady=10, padx=5) ttk.Label(topleft, text="Unit").grid(row=3, column=0, sticky=W, padx=20) ttk.Label(topleft, text=':').grid(row=3, column=1, sticky=W, pady=5, padx=10) self.entUnit = ttk.Entry(topleft, width=15) self.entUnit.grid(row=3, column=2, sticky=W) ttk.Label(topleft, text="Work Request").grid(row=4, column=0, sticky=NW, padx=20) ttk.Label(topleft, text=':').grid(row=4, column=1, sticky=NW, padx=10, pady=6) self.entWorkReq = ScrolledText(topleft, height=4, width=35) self.entWorkReq.grid(row=4, column=2, sticky=W) ttk.Label(topleft, text="Staff").grid(row=5, column=0, sticky=W, padx=20) ttk.Label(topleft, text=':').grid(row=5, column=1, sticky=W, pady=5, padx=10) self.entStaff = ttk.Entry(topleft, width=20) self.entStaff.grid(row=5, column=2, sticky=W) #samping kanan topright = ttk.Frame(self.topFrame) topright.grid(row=1, column=2, sticky=W) ttk.Label(topright, text="").grid(row=0, column=0, sticky=W, pady=5, padx=20) ttk.Label(topright, text="").grid(row=1, column=0, sticky=W, pady=5, padx=20) ttk.Label(topright, text="Status").grid(row=2, column=0, sticky=W, pady=5, padx=20) ttk.Label(topright, text=':').grid(row=2, column=1, sticky=W, pady=5, padx=10) self.opsiStatus = ttk.Combobox(topright, \ values = ["","DONE","CANCEL","PENDING"],\ state="readonly", width=10) self.opsiStatus.current(0) self.opsiStatus.grid(row=2, column=2, sticky=W) ttk.Label(topright, text="Tanggal - Jam").grid(row=3, column=0, sticky=W, padx=20) ttk.Label(topright, text=':').grid(row=3, column=1, sticky=W, pady=5, padx=10) tgldone = ttk.Frame(topright) tgldone.grid(row=3, column=2, sticky=W) self.entTgldone = ttk.Entry(tgldone, width=10) self.entTgldone.grid(row=0, column=0, sticky=W) self.entJamdone = ttk.Entry(tgldone, width=7) self.entJamdone.grid(row=0, column=1, sticky=W) self.btnDateDone = Button(tgldone, image=self.imgdateget, command=self.onDateDone) self.btnDateDone.grid(row=0, column=2, pady=10, padx=5) ttk.Label(topright, text="Work Action").grid(row=4, column=0, sticky=NW, padx=20) ttk.Label(topright, text=':').grid(row=4, column=1, sticky=NW, padx=10, pady=6) self.entWorkAct = ScrolledText(topright, height=4, width=35) self.entWorkAct.grid(row=4, column=2, sticky=W) ttk.Label(topright, text="Received").grid(row=5, column=0, sticky=W, padx=20) ttk.Label(topright, text=':').grid(row=5, column=1, sticky=W, pady=5, padx=10) recentry = ttk.Frame(topright) recentry.grid(row=5, column=2, sticky=W) self.entRecDate = ttk.Entry(recentry, width=20) self.entRecDate.grid(row=0, column=0, sticky=W) self.entRecBy = ttk.Entry(recentry, width=25) self.entRecBy.grid(row=0, column=1, sticky=W) def komponenTengah(self): #panel button self.btnClear = Button(self.midFrame, text='New',\ command=self.onClear, width=10,\ relief=RAISED, bd=2, bg="#666", fg="white",\ activebackground="#444",activeforeground="white") self.btnClear.grid(row=1, column=1, pady=0, padx=5) self.btnSave = Button(self.midFrame, text='Save',\ command=self.onSave, width=10,\ relief=RAISED, bd=2, bg="#666", fg="white",\ activebackground="#444",activeforeground="white" ) self.btnSave.grid(row=1, column=2, pady=0, padx=5) self.btnUpdate = Button(self.midFrame, text='Update',\ command=self.onUpdate,state="disable", width=10,\ relief=RAISED, bd=2, bg="#666", fg="white",\ activebackground="#444",activeforeground="white") self.btnUpdate.grid(row=1, column=3, pady=0, padx=5) self.btnDelete = Button(self.midFrame, text='Delete',\ command=self.onDelete,state="disable", width=10,\ relief=RAISED, bd=2, bg="#FC6042", fg="white",\ activebackground="#444",activeforeground="white") self.btnDelete.grid(row=1, column=4, pady=0, padx=5) self.btnReceived = Button(self.midFrame, text='Received',\ command=self.onReceived,state="disable", width=10,\ relief=RAISED, bd=2, bg="#667", fg="white",\ activebackground="#444",activeforeground="white") self.btnReceived.grid(row=1, column=5, pady=0, padx=5) def komponenBawah(self): # search and export row1 = ttk.Frame(self.botFrame) row1.grid(row=0, column=1, sticky=W, padx=10) self.opsicari = ttk.Combobox(row1, \ values = ["IFCA","Tanggal", "Unit", "Work Req."], \ state="readonly", width=10) self.opsicari.current(1) self.opsicari.grid(row=2, column=1, sticky=W) self.opsicari.bind('<<ComboboxSelected>>', self.boxsearchsel) self.entCari = ttk.Entry(row1, width=20) self.entCari.grid(row=2, column=2) self.dateStart = CustomDateEntry(row1, width=10, locale='en_UK') self.dateEnd = CustomDateEntry(row1, width=10, locale='en_UK') ttk.Label(row1, text='~').grid(row=2, column=3) self.entCari.bind('<Return>', self.onSearch) self.dateStart.bind('<Return>', self.onSearch) self.dateEnd.bind('<Return>', self.onSearch) # self.entCari.bind('<KeyRelease>',self.onSearch) #cari saat input apapun self.btnSearch = Button(row1, text='Search',\ command=self.onSearch,\ state="normal", width=10,\ relief=RAISED, bd=2, bg="#667", fg="white",\ activebackground="#444",activeforeground="white") self.btnSearch.grid(row=2, column=6, pady=10, padx=5) self.btnMainExp = Button(row1, text='Export',\ command=self.onMainExport,\ state="normal", width=10,\ relief=RAISED, bd=2, \ bg="#558", fg="white", \ activebackground="#444",activeforeground="white") self.btnMainExp.grid(row=2, column=7, pady=10, padx=5) self.btnImportCsv = Button(row1, text='Import',\ command=self.onImport_csv,\ state="normal", width=10,\ relief=RAISED, bd=2, \ bg="#558", fg="white", \ activebackground="#444",activeforeground="white") self.btnImportCsv.grid(row=2, column=8, pady=10, padx=5) #tabel listifca = ttk.Frame(self.botFrame) listifca.grid(row=2, column=1, sticky=W, padx=10) self.tabelIfca = ttk.Treeview(listifca, columns=judul_kolom, show='headings') self.tabelIfca.bind("<Double-1>", self.mainlog_detail) sbVer = ttk.Scrollbar(listifca, orient='vertical', command=self.tabelIfca.yview) sbVer.pack(side=RIGHT, fill=Y) sbHor = ttk.Scrollbar(listifca, orient='horizontal', command=self.tabelIfca.xview) sbHor.pack(side=BOTTOM, fill=X) self.tabelIfca.pack(side=TOP, fill=BOTH) self.tabelIfca.configure(yscrollcommand=sbVer.set) self.tabelIfca.configure(xscrollcommand=sbHor.set) self.onClear() def entrySet(self, opsi): # 1 on doubleclick main entry, normal if opsi == "mainclear": self.entWo.config(state="normal") self.entIfca.config(state="normal") self.entTglbuat.config(state="normal") self.entJambuat.config(state="normal") self.entUnit.config(state="normal") self.entTgldone.config(state="normal") self.entJamdone.config(state="normal") self.entRecBy.config(state="normal") self.entRecDate.config(state="normal") self.entWo.delete(0, END) self.entIfca.delete(0, END) self.entTglbuat.delete(0, END) self.entJambuat.delete(0, END) self.entUnit.delete(0, END) self.entWorkReq.delete('1.0', 'end') self.entStaff.delete(0, END) self.entTgldone.delete(0, END) self.entJamdone.delete(0, END) self.entWorkAct.delete('1.0', 'end') self.entRecBy.delete(0, END) self.entRecDate.delete(0, END) self.entRecBy.config(state="normal") self.entRecDate.config(state="normal") self.btnDelete.config(state="disable") self.btnReceived.config(state="disable") self.btnUpdate.config(state="disable") self.rbtnTN.grid(row=0, column=0, sticky=W) self.rbtnBM.grid(row=0, column=2, sticky=W) # A. readonly aja, input pake popup self.entTglbuat.config(state="readonly") self.entJambuat.config(state="readonly") self.entTgldone.config(state="readonly") self.entJamdone.config(state="readonly") # A # # mainentry readonly panel kiri kecuali work req dan staff elif opsi == "disablebtn": self.btnDateCreate.config(state="disable") self.btnDateDone.config(state="disable") self.btnSave.config(state="disable") self.rbtnBM.config(state="disable") self.rbtnTN.config(state="disable") elif opsi == "mainreadifca": self.entWo.config(state="readonly") self.entIfca.config(state="readonly") self.entTglbuat.config(state="readonly") self.entJambuat.config(state="readonly") self.entUnit.config(state="readonly") self.entTgldone.config(state="readonly") self.entJamdone.config(state="readonly") self.entRecBy.config(state="readonly") self.entRecDate.config(state="readonly") self.rbtnTN.grid_forget() self.rbtnBM.grid_forget() # 1 # else: pass def checkwo(self, data): if (len(data) < 1): # Jika wo kosong # print("Diterima, len data",len(data),"wo bisa kosong") return data elif (len(data) >= 1 and data.isdigit() == False): # print("Ditolak, digit",data.isdigit()) return False else: # print("no awal",data) while 0 < len(data): # jika ada "0" didepan hapus aja if data[0] == '0': data = data[1:] continue break # print("no akhir",data) sql = ("SELECT * FROM logbook where no_wo LIKE %s") val = (data, ) hasil = getdata_one(sql, val) if (hasil == None): # Jika wo no. baru # print("diterima,",data,"!-",hasil) return data if (data == hasil[1]): # print("ditolak,",data,"=",hasil[1]) return False def checkifca(self, data): if ((data[:2] != "BM") and (data[:2] != "TN")): # print("bukan TIPE yang benar,",data[:2]) return False elif (len(data) != 10): # print("panjang =",len(data)) return False elif (data[2:].isdigit() == False): # print("8 char digit?",data[2:].isdigit()) return False else: sql = ("SELECT * FROM logbook where no_ifca LIKE %s") val = (data, ) hasil = getdata_one(sql, val) if hasil == None: # print("diterima,",data,"!-",hasil) return True if (data == hasil[2]): # print("ditolak,",data,"=",hasil[2]) return False def boxsearchsel(self, event): if self.opsicari.get() == "Tanggal": self.entCari.delete(0, END) self.entCari.grid_forget() self.dateStart.grid(row=2, column=2) self.dateEnd.grid(row=2, column=4) else: self.entCari.delete(0, END) self.dateStart.grid_forget() self.dateEnd.grid_forget() self.entCari.grid(row=2, column=2, sticky=W) def onSearch(self, event=None): self.entrySet("mainclear") self.opsiStatus.current(0) self.querySearch() # set dulu variabel self.sql dan self.val results = getdata_all(self.sql, self.val) self.showtable(results) def querySearch(self): opsi = self.opsicari.get() cari = self.entCari.get() if opsi == "Tanggal": if self.dateStart.get() == self.dateEnd.get(): cari = store_date(self.dateStart.get()) self.sql = "SELECT * FROM logbook WHERE date_create LIKE %s ORDER BY time_create DESC" self.val = ("%{}%".format(cari), ) else: #part jika search between date sdate = store_date(self.dateStart.get()) edate = store_date(self.dateEnd.get()) self.sql = "SELECT * FROM logbook WHERE (date_create BETWEEN %s AND %s) ORDER BY no_ifca DESC" self.val = ('{}'.format(sdate), '{}'.format(edate)) elif opsi == "IFCA": self.sql = "SELECT * FROM logbook WHERE no_ifca LIKE %s ORDER BY no_ifca DESC" self.val = ("%{}%".format(cari), ) elif opsi == "Unit": self.sql = "SELECT * FROM logbook WHERE unit LIKE %s ORDER BY date_create DESC" self.val = ("%{}%".format(cari), ) elif opsi == "Work Req.": self.sql = "SELECT * FROM logbook WHERE work_req LIKE %s ORDER BY date_create DESC" self.val = ("%{}%".format(cari), ) else: pass def auto_wo(self): sql = "SELECT no_wo FROM logbook" val = () hasil = getdata_all(sql, val) # list wo dalam tupple if len(hasil) <= 0: # prevent error jika belum ada data hasil = "0" lastwo = hasil[len(hasil) - 1][ 0] # ambil last wo dari tupple terakhir dan ambil datanya print("last Wo:", lastwo) print("Jumlah Wo:", len(hasil)) # Jumlah wo didapat if lastwo == "": newWoNum = "" # prevent error, ketika IFCA terakhir tanpa no. WO (blank) else: newWoNum = (int(lastwo) + 1) # cari wo, + 1 print("Get new Wo:", newWoNum) self.entWo.delete(0, END) if len(str(newWoNum)) <= 6: self.entWo.insert(0, newWoNum) self.entIfca.focus_set() else: messagebox.showwarning(title="Peringatan", \ message="maaf lebar data untuk no WO hanya sampai 6 digit") def auto_ifca(self): tipe = str(self.btnselect.get()) sql = "SELECT MAX(no_ifca) FROM logbook WHERE no_ifca LIKE %s" val = ("%{}%".format(tipe), ) hasil = getdata_all(sql, val) # max IFCA dalam tupple lastifca = hasil[len(hasil) - 1][0] # Max num ifca terakhir print("Last IFca:", lastifca) if lastifca == None: # prevent error jika belum ada data lastifca = "XX10000000" newIfcaNum = (int(lastifca[2:]) + 1 ) # cari lastifca, hapus tipe(BM/TN) + 1 getNewIfca = tipe + str(newIfcaNum) # Ifca baru siap dipakai print("Get new ifca:", getNewIfca) self.entIfca.delete(0, END) self.entIfca.insert(0, getNewIfca) def showtable(self, data): self.tabelIfca.delete( *self.tabelIfca.get_children()) #refresh, hapus dulu tabel lama for kolom in judul_kolom: self.tabelIfca.heading(kolom, text=kolom) # self.tabelIfca.column("No", width=10,anchor="w") self.tabelIfca.column("WO", width=50, anchor="w") self.tabelIfca.column("IFCA", width=80, anchor="w") self.tabelIfca.column("Tanggal", width=80, anchor="w") self.tabelIfca.column("UNIT", width=80, anchor="w") self.tabelIfca.column("Work Request", width=150, anchor="w") self.tabelIfca.column("Staff", width=70, anchor="w") self.tabelIfca.column("Work Action", width=150, anchor="w") self.tabelIfca.column("Tanggal Done", width=80, anchor="w") self.tabelIfca.column("Jam Done", width=40, anchor="w") self.tabelIfca.column("Received", width=40, anchor="w") i = 0 for dat in data: if (i % 2): baris = "genap" else: baris = "ganjil" #hilangkan nomor mulai dari kolom wo dat[1:] self.tabelIfca.insert('', 'end', values=dat[1:], tags=baris) i += 1 self.tabelIfca.tag_configure("ganjil", background="gainsboro") self.tabelIfca.tag_configure("genap", background="floral white") def onImport_csv(self): Thread(target=self.proses_import).start() def proses_import(self): # section return (abort) if (self.dept != "ROOT"): messagebox.showerror(title="Prohibited", \ message="This command is reserved for Administrator") self.btnImportCsv.grid_forget() return fnames = filedialog.askopenfilename(filetypes=[("Excel CSV", "*.csv")]) if not fnames: print("open file canceled") return with open(fnames) as cek_header: reader = csv.reader(cek_header) for row in reader: if row == header_csv: break else: messagebox.showerror(title="Import File Error", \ message="The header file is invalid!") return with open(fnames) as countrow: reader = csv.reader(countrow) next(reader) # skip the heading lines = len(list(reader)) # jumlah baris dalam file setelah header # lines = sum(1 for row in reader) # ini juga bisa hitung jumlah baris if lines > 5000: messagebox.showerror(title="Import File Error", \ message="Row count: {}. Maximum is 5000".format(lines)) return # section processing start = time.perf_counter() progbar = SetProgBar(self.parent, lines) with open(fnames) as input_file: reader = csv.reader(input_file) next(reader) # skip the heading update = 0 insert = 0 for rowno, row in enumerate(reader): if (row[0].isdigit() == False): # abaikan selain index=digit continue if self.checkifca( row[2]) == False: #check IFCA, jika ada update aja # print("IFCA",row[2],"Sudah terdaftar") sql = "UPDATE logbook SET date_create=%s,time_create=%s,unit=%s,work_req=%s WHERE no_ifca =%s" val = (store_date(row[3]), row[4], row[5], row[6], row[2]) if (insert_data(sql, val)) == True: update += 1 else: messagebox.showerror(title="Import File Error", \ message="Fail on Update {}".format(row[2])) else: # insert baru sql = "INSERT INTO logbook (no_wo,no_ifca,date_create,time_create,unit,work_req,staff,\ work_act,date_done,time_done,status_ifca,received,wo_receiver,date_received,auth_login)" +\ "VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)" # val = (row) val = (row[1],row[2],store_date(row[3]),row[4],row[5],row[6],row[7],row[8],\ store_date(row[9]),row[10],row[11],row[12],row[13],store_date(row[14]),row[15]) if (insert_data(sql, val)) == True: insert += 1 else: messagebox.showerror(title="Import File Error", \ message="Fail on New Insert {}".format(row[2])) progbar.bytes = rowno + 1 finish = time.perf_counter() usedsecs = finish - start if usedsecs > 60: usedsecs = GetDuration(usedsecs).value messagebox.showinfo(title="Import File Result", \ message="Update IFCA: {0}\r\nNew Record: {1}\r\nTime Used: {2}"\ .format(update,insert,usedsecs)) self.onSearch() #Refresh table by search def onMainExport(self): #export from database treeview results = self.tabelIfca.get_children() # dalam format [list] if len(results) > 0: #for testing export # i=1 # for dat in results: # value = self.tabelIfca.item(dat)['values'] # value.insert(0,i) # tambah nomor colom pertama # print(value) # value.insert(4,value.pop(13)) # pindahin jambuat ke kolom 4 # print(value) # i+=1 # end testing directory = filedialog.asksaveasfilename(initialdir = os.getcwd(), \ initialfile = self.entCari.get(), \ defaultextension='.csv', \ title="Save file Export", \ filetypes=[("Excel CSV", "*.csv"),("All", "*.*")]) if not directory: print("cancel export") return try: filename = open(directory, 'w', newline='') except: messagebox.showerror(title="Export File Error", \ message="Permission denied: {}".format(directory)) return cWrite = csv.writer(filename) cWrite.writerow(["Export time", "", datetime.now()]) cWrite.writerow([""]) cWrite.writerow(header_csv) i = 1 for dat in results: value = self.tabelIfca.item(dat)['values'] value.insert(0, i) # tambah nomor colom pertama value.insert(4, value.pop(13)) # pindahin jambuat ke kolom 4 value.insert(11, value.pop(14)) # pindahin status ke kolom 11 cWrite.writerow(value) i += 1 cWrite.writerow([""]) cWrite.writerow(["Save to", directory]) cWrite.writerow(["Finish", len(results), "record(s)"]) filename.close() messagebox.showinfo(title="Export File", \ message="Sudah tersimpan di: {}".format(directory)) else: print("result:", len(results)) def onReceived(self): # try: ifca = self.entIfca.get() dept = self.entRecBy.get().split(".") if len(dept) <= 1: dept = [self.user, "ROOT"] if len(ifca.strip()) == 0: messagebox.showwarning(title="Peringatan", message="No IFCA Kosong.") self.entIfca.focus_set() elif (ifca[:2] == "TN"): if (self.dept == "CS") or (self.dept == "RCP"): if messagebox.askokcancel('Receive WO {}'.format(ifca), 'WO sudah diterima?') == True: self.doReceive(ifca) else: messagebox.showerror(title="Receive WO {}".format(ifca), \ message="WO TN hanya bisa diterima oleh RCP/CS") elif (ifca[:2] == "BM"): if (self.dept == "DOCON") or (self.dept == "ENG"): # antisipasi duplikasi receive if (dept[1] == self.dept): messagebox.showerror(title="Replacing !", \ message="WO Sudah diterima oleh {}".format(self.entRecBy.get())) elif messagebox.askokcancel('Receive WO {}'.format(ifca), 'WO sudah diterima?') == True: self.doReceive(ifca) else: messagebox.showerror(title="Receive WO {}".format(ifca), \ message="WO BM hanya bisa diterima oleh DOCON/ENG") else: pass def doReceive(self, data): receiver = self.user + "." + self.dept tsekarang = datetime.now() sql = "UPDATE logbook SET date_received=%s,received=%s,wo_receiver=%s WHERE no_ifca =%s" val = (tsekarang, True, receiver, data) if (insert_data(sql, val)) == True: # messagebox.showinfo(title="Informasi", \ # message="Wo {} sudah diterima.".format(data)) self.onSearch() #update received sesuai tabel yg dicari def mainlog_detail(self, event): try: curItem = self.tabelIfca.item(self.tabelIfca.focus()) ifca_value = curItem['values'][1] self.entrySet("mainclear") self.entrySet("disablebtn") if self.dept == "ROOT": self.btnDelete.config(state="normal") self.entTglbuat.config(state="normal") self.entJambuat.config(state="normal") self.entTgldone.config(state="normal") self.entJamdone.config(state="normal") sql = "SELECT * FROM logbook WHERE no_ifca = %s" val = (ifca_value, ) data = getdata_one(sql, val) self.entIfca.insert(END, ifca_value) self.entWo.insert(END, data[1]) self.entTglbuat.insert(END, get_date(str(data[3]))) self.entJambuat.insert(END, data[13]) self.entUnit.insert(END, data[4]) self.entWorkReq.insert(END, data[5]) self.entStaff.insert(END, data[6]) self.entTgldone.insert(END, get_date(str(data[8]))) self.entJamdone.insert(END, data[9]) self.entWorkAct.insert(END, data[7]) self.entRecDate.insert(END, get_date(str(data[12]))) self.entRecBy.insert(END, data[11]) if data[14] == "DONE": self.opsiStatus.current(1) self.btnReceived.config(state="normal") # ngapain diUpdate lagi wo sudah DONE elif data[14] == "CANCEL": self.opsiStatus.current(2) self.btnReceived.config(state="normal") elif data[14] == "PENDING": self.opsiStatus.current(3) elif data[14] == "ONPROGRESS" or data[14] == "RETURNED" or data[ 14] == "TAKEN": self.opsiStatus.current(0) else: if self.dept == "ENG": # khusus class ENG self.btnUpdate.config(state="normal") self.btnDateDone.config(state="normal") self.opsiStatus.current(0) if data[10] == True and ifca_value[:2] == "TN": # tidak dapat receive wo TN karena sudah direceive self.btnReceived.config(state="disable") # read only setelah entry terisi self.entrySet("mainreadifca") except: print('Tidak ada data di tabel') def onDelete(self): cIfca = self.entIfca.get() if messagebox.askokcancel( 'Delete Data', 'WO dengan no {} akan dihapus?'.format(cIfca)) == True: sql = "DELETE FROM logbook WHERE no_ifca =%s" val = (cIfca, ) if (insert_data(sql, val)) == True: sql = "DELETE FROM onprogress WHERE no_ifca =%s" val = (cIfca, ) if (insert_data(sql, val)) == True: self.onSearch() #update received sesuai tabel yg dicari messagebox.showinfo(title="Delete {}".format(cIfca), \ message="Data sudah di hapus.") else: pass def onClear(self): self.entrySet("disablebtn") if self.dept == "ENG": # khusus class ENG self.btnDateCreate.config(state="normal") self.btnDateDone.config(state="normal") self.btnSave.config(state="normal") self.rbtnBM.config(state="normal") self.rbtnTN.config(state="normal") self.tabelIfca.delete(*self.tabelIfca.get_children()) self.entCari.delete(0, END) self.dateStart.delete(0, END) self.dateEnd.delete(0, END) self.opsiStatus.current(0) # list wo hari ini self.opsicari.current(1) self.boxsearchsel(None) today = date.today() self.dateStart.insert(END, today.strftime("%d-%m-%Y")) self.dateEnd.insert(END, today.strftime("%d-%m-%Y")) self.onSearch() self.auto_wo() self.entUnit.focus_set() # os.system("cls") def onSave(self): cWo = self.checkwo( self.entWo.get()) # self.checkwo, jika salah return False cIfca = self.entIfca.get() cTglBuat = store_date(self.entTglbuat.get()) #check tgl dulu cJamBuat = self.entJambuat.get() cUnit = self.entUnit.get().upper().strip() cWorkReq = self.entWorkReq.get('1.0', 'end').upper().strip() cStaff = self.entStaff.get().upper().strip() cIfca = self.entIfca.get() if cWo == False: #check WO messagebox.showerror(title="Error", \ message="WO sudah terdaftar atau Input WO salah") elif self.checkifca(cIfca) == False: #check IFCA messagebox.showerror(title="Error", \ message="IFCA sudah terdaftar atau Input IFCA salah") self.entIfca.focus_set() elif len(cTglBuat) == 0 or len( cJamBuat.strip()) != 5: #check tgl jika kosong, batalkan save messagebox.showerror(title="Error", message="Format tanggal salah") elif len(cUnit) == 0: messagebox.showwarning(title="Peringatan", message="Unit harus diisi.") self.entUnit.focus_set() self.entUnit.delete(0, END) else: sql = "INSERT INTO logbook (no_wo,no_ifca,date_create,time_create,unit,work_req,staff,auth_login)"+\ "VALUES(%s,%s,%s,%s,%s,%s,%s,%s)" val = (cWo, cIfca, cTglBuat, cJamBuat, cUnit, cWorkReq, cStaff, self.user) if (insert_data(sql, val)) == True: messagebox.showinfo(title="Informasi", message="Data sudah di tersimpan.") self.onClear() def onUpdate(self): #panel kiri cWo = self.entWo.get() cIfca = self.entIfca.get() cTglBuat = store_date(self.entTglbuat.get()) #check tgl dulu cWorkReq = self.entWorkReq.get('1.0', 'end').upper().strip() cStaff = self.entStaff.get().upper().strip() cStatus = self.opsiStatus.get() cTimeAcc = datetime.now() #panel kanan cWorkAct = self.entWorkAct.get('1.0', 'end').upper().strip() cTglDone = store_date(self.entTgldone.get()) #check tgl dulu jamdone = self.entJamdone.get() #eksekusi sql if len(cWorkReq) <= 0: messagebox.showwarning(title="Peringatan", message="Work Request harus diisi.") self.entWorkReq.focus_set() self.entWorkReq.delete('1.0', 'end') return # stop aja karena cWorkAct tidak diisi if cStatus == "DONE": if len(cStaff) <= 0: messagebox.showwarning(title="Peringatan", message="Staff ENG harus diisi.") self.entStaff.focus_set() self.entStaff.delete(0, END) return # stop aja karena cStaff tidak diisi elif len(cWorkAct) <= 0: messagebox.showwarning(title="Peringatan", message="Work Action harus diisi.") self.entWorkAct.focus_set() self.entWorkAct.delete('1.0', 'end') return # stop aja karena cWorkAct tidak diisi elif len(cTglDone) == 0 or len(jamdone.strip()) != 5: messagebox.showerror(title="Error", message="Format tanggal salah") return # stop aja karena tanggal tidak diisi else: pass elif cStatus == "PENDING": cTglDone = "" jamdone = "" com_auth_by = cStaff + "@" + self.user if len(cStaff) <= 0: messagebox.showwarning(title="Peringatan", message="Staff ENG harus diisi.") self.entStaff.focus_set() self.entStaff.delete(0, END) return # stop aja karena cStaff tidak diisi elif len(cWorkAct) <= 0: messagebox.showwarning(title="Peringatan", message="Work Action harus diisi.") self.entWorkAct.focus_set() self.entWorkAct.delete('1.0', 'end') return # stop aja karena cWorkAct tidak diisi else: ### jgn eksekusi sekarang mungkin? sql = "INSERT INTO onprogress (no_ifca,date_update,commit_update,auth_by,auth_login,auth_dept)"+\ "VALUES(%s,%s,%s,%s,%s,%s)" val = (cIfca, cTimeAcc, cWorkAct, com_auth_by, self.user, self.dept) print("Pending store data,", insert_data(sql, val)) elif cStatus == "CANCEL": cTglDone = "" jamdone = "" if len(cWorkAct) <= 0: messagebox.showwarning(title="Peringatan", message="Work Action harus diisi.") self.entWorkAct.focus_set() self.entWorkAct.delete('1.0', 'end') return # stop aja karena cWorkAct tidak diisi else: # UPDATE tidak perlu tanggal cTglDone = "" jamdone = "" curItem = self.tabelIfca.item(self.tabelIfca.focus()) if cWorkReq == curItem['values'][4] and \ cStaff == curItem['values'][5] and cWorkAct == curItem['values'][6]: print("Tidak ada aktivitas perubahan") else: sql = "UPDATE logbook SET no_wo=%s,no_ifca=%s,date_create=%s,work_req=%s,staff=%s,\ status_ifca=%s,date_done=%s,time_done=%s,work_act=%s,auth_login=%s WHERE no_ifca =%s" val = (cWo, cIfca, cTglBuat, cWorkReq, cStaff, cStatus, cTglDone, jamdone, cWorkAct, self.user, cIfca) if (insert_data(sql, val)) == True: messagebox.showinfo(title="Informasi", \ message="Data sudah di terupdate.") self.onSearch() def onDateCreate(self): setdate = PopupDateTime(self.parent) setdate.parent.wait_window(setdate.top) if len(setdate.value.strip()) > 0: # output <tanggal> <jam>, lanjutkan perintah getdate, gettime = setdate.value.split() #pisah tanggal dan jam self.entTglbuat.config(state="normal") self.entJambuat.config(state="normal") self.entTglbuat.delete(0, END) self.entJambuat.delete(0, END) self.entTglbuat.insert(END, getdate) self.entJambuat.insert(END, gettime) self.entTglbuat.config(state="readonly") self.entJambuat.config(state="readonly") self.entUnit.focus_set() else: # output kosong, batalkan perintah pass def onDateDone(self): setdate = PopupDateTime(self.parent) setdate.parent.wait_window(setdate.top) if len(setdate.value.strip()) > 0: # output <tanggal> <jam>, lanjutkan perintah getdate, gettime = setdate.value.split() #pisah tanggal dan jam self.entTgldone.config(state="normal") self.entJamdone.config(state="normal") self.entTgldone.delete(0, END) self.entJamdone.delete(0, END) self.entTgldone.insert(END, getdate) self.entJamdone.insert(END, gettime) self.entTgldone.config(state="readonly") self.entJamdone.config(state="readonly") else: # output kosong, batalkan perintah pass
class Search(Screen): def __init__(self): Screen.__init__(self) self.lbl_title = tk.Label(self, text ="Search", font = TITLE_FONT) self.lbl_title.grid(row = 0, column = 0, sticky = "news") options=["Genre", "Title", "Developer", "Publisher", "System", "Release Date", "Rating","Game Mode", "Beat the Game", "Purchase Date", "Price", "Notes"] self.tkvar = tk.StringVar(self) self.tkvar.set(options[0]) self.menu = tk.OptionMenu(self, self.tkvar, *options) self.menu.grid(row = 1, column = 0, sticky = "news") self.lbl_search_for = tk.Label(self, text ="Search For?", font = BUTTON_FONT) self.lbl_search_for.grid(row = 3, column = 0, sticky = "news") self.ent_box2 = tk.Entry(self) self.ent_box2.grid(row = 4, column = 0, sticky = "news") self.sct_box1 = ScrolledText(self, height = 8, width = 40) self.sct_box1.grid(row = 5, columnspan = 3, sticky = "news") self.btn_back = tk.Button(self, text = "BACK", font = BUTTON_FONT, command = self.go_main) self.btn_back.grid(row = 6, column = 0, sticky = "news") self.btn_clear = tk.Button(self, text = "CLEAR", font = BUTTON_FONT, command = self.clear) self.btn_clear.grid(row = 6, column = 1, sticky = "news") self.btn_submit = tk.Button(self, text = "SUBMIT", font = BUTTON_FONT, command = self.sumbit_search) self.btn_submit.grid(row = 6, column = 2, sticky = "news") self.checkbox_filter = CheckboxFilter(self) self.checkbox_filter.grid(row = 2, column = 1, rowspan = 3, columnspan = 2, sticky = "news") for key in games.keys(): entry = games[key] self.filter_print(entry) def go_main(self): Screen.current = 0 Screen.switch_frame() def filter_print(self, entry): if self.checkbox_filter.title_filter.get() == True: msg = entry[0]+"\n" self.sct_box1.insert("insert", msg) if self.checkbox_filter.genre_filter.get() == True: msg = entry[1]+"\n" self.sct_box1.insert("insert", msg) if self.checkbox_filter.dev_filter.get() == True: msg = entry[2]+"\n" self.sct_box1.insert("insert", msg) if self.checkbox_filter.pub_filter.get() == True: msg = entry[3]+"\n" self.sct_box1.insert("insert", msg) if self.checkbox_filter.platform_filter.get() == True: msg = entry[4]+"\n" self.sct_box1.insert("insert", msg) if self.checkbox_filter.date_filter.get() == True: msg = entry[5]+"\n" self.sct_box1.insert("insert", msg) if self.checkbox_filter.rate_filter.get() == True: msg = entry[6]+"\n" self.sct_box1.insert("insert", msg) if self.checkbox_filter.beat_filter.get() == True: msg = entry[7]+"\n" self.sct_box1.insert("insert", msg) if self.checkbox_filter.purch_filter.get() == True: msg = entry[8]+"\n" self.sct_box1.insert("insert", msg) if self.checkbox_filter.multi_filter.get() == True: msg = entry[9]+"\n" self.sct_box1.insert("insert", msg) if self.checkbox_filter.price_filter.get() == True: msg = entry[10]+"\n" self.sct_box1.insert("insert", msg) if self.checkbox_filter.note_filter.get() == True: msg = entry[11]+"\n" self.sct_box1.insert("insert", msg) msg = "************\n" self.sct_box1.insert("insert", msg) def clear(self): self.checkbox_filter.title_filter.set(False) self.checkbox_filter.genre_filter.set(False) self.checkbox_filter.dev_filter.set(False) self.checkbox_filter.pub_filter.set(False) self.checkbox_filter.platform_filter.set(False) self.checkbox_filter.date_filter.set(False) self.checkbox_filter.rate_filter.set(False) self.checkbox_filter.beat_filter.set(False) self.checkbox_filter.price_filter.set(False) self.checkbox_filter.purch_filter.set(False) self.checkbox_filter.multi_filter.set(False) self.checkbox_filter.note_filter.set(False) self.sct_box1.delete(0.0, "end") def sumbit_search(self): self.sct_box1.delete(0.0, "end") for key in games.keys(): entry = games[key] self.filter_print(entry) def [r class Add(Screen): def __init__(self): Screen.__init__(self) self.lbl_title = tk.Label(self, text ="Edit", font = TITLE_FONT) self.lbl_title.grid(row = 0, column = 0, sticky = "news") self.lbl_genre = tk.Label(self, text="Genre?", font = BUTTON_FONT) self.lbl_genre.grid(row = 1, column = 0, sticky = "news") self.ent_genre = tk.Entry(self) self.ent_genre.grid(row = 1, column = 1, sticky = "news") self.lbl_dev = tk.Label(self, text="Developer?", font = BUTTON_FONT) self.lbl_dev.grid(row = 2, column = 0 , sticky = "news") self.ent_dev = tk.Entry(self) self.ent_dev.grid(row = 2, column = 1, sticky = "news") self.lbl_title = tk.Label(self, text="Title?", font = BUTTON_FONT) self.lbl_title.grid(row = 1, column = 2 , sticky = "news") self.ent_title = tk.Entry(self) self.ent_title.grid(row = 1, column = 3, sticky = "news") self.lbl_pub = tk.Label(self, text="Publisher?", font = BUTTON_FONT) self.lbl_pub.grid(row = 2, column = 2, sticky = "news") self.ent_pub = tk.Entry(self) self.ent_pub.grid(row = 2, column = 3, sticky = "news") self.lbl_platform = tk.Label(self, text="Platform?", font = BUTTON_FONT) self.lbl_platform.grid(row = 3, column = 2, sticky = "news") self.ent_platform = tk.Entry(self) self.ent_platform.grid(row = 3, column = 3, sticky = "news") self.lbl_year = tk.Label(self, text="Year?", font = BUTTON_FONT) self.lbl_year.grid(row = 3, column = 0, sticky = "news") self.ent_year = tk.Entry(self) self.ent_year.grid(row = 3, column = 1, sticky = "news") self.lbl_rating = tk.Label(self, text="Rating?", font = BUTTON_FONT) self.lbl_rating.grid(row = 5, column = 0, sticky = "news") self.ent_rating = tk.Entry(self) self.ent_rating.grid(row = 5, column = 1, sticky = "news") self.lbl_beat = tk.Label(self, text="Beat It?", font = BUTTON_FONT) self.lbl_beat.grid(row = 4, column = 0, sticky = "news") self.ent_beat = tk.Entry(self) self.ent_beat.grid(row = 4, column = 1, sticky = "news") self.lbl_purch = tk.Label(self, text="Purch. Date?", font = BUTTON_FONT) self.lbl_purch.grid(row = 5, column = 2, sticky = "news") self.ent_purch = tk.Entry(self) self.ent_purch.grid(row = 5, column = 3, sticky = "news") self.lbl_mode = tk.Label(self, text="Mode?", font = BUTTON_FONT) self.lbl_mode.grid(row = 4, column = 2, sticky = "news") options=["Single Player", "Multi-Player"] self.tkvar = tk.StringVar(self) self.tkvar.set(options[0]) self.menu = tk.OptionMenu(self, self.tkvar, *options) self.menu.grid(row = 4, column = 3, sticky = "news") self.lbl_notes = tk.Label(self, text="Notes?", font = BUTTON_FONT) self.lbl_notes.grid(row = 6, column = 0, sticky = "news") self.sct_notes = ScrolledText(self, height = 8, width = 40) self.sct_notes.grid(row = 7, columnspan = 3, sticky = "news") self.btn_cancel = tk.Button(self, text = "Cancel", font = BUTTON_FONT, command = self.main) self.btn_cancel.grid(row = 8, column = 0) self.btn_reset = tk.Button(self, text ="Reset", font = BUTTON_FONT, command = self.clear) self.btn_reset.grid(row = 8, column = 1, sticky = "news") self.btn_confirm = tk.Button(self, text ="Confirm", font = BUTTON_FONT, command = self.go_main) self.btn_confirm.grid(row = 8, column = 2) def go_main(self): Screen.current = 0 messagebox.showinfo(message = "Entry Has been Added") Screen.switch_frame() entry = [] entry.append(self.ent_genre.get()) entry.append(self.ent_title.get()) entry.append(self.ent_dev.get()) entry.append(self.ent_pub.get()) entry.append(self.ent_platform.get()) entry.append(self.ent_year.get()) entry.append(self.ent_rating.get()) entry.append(self.tkvar.get()) entry.append(self.ent_beat.get()) entry.append(self.ent_purch.get()) entry.append(self.sct_notes.get(0.0, "end")) games[len(games) +1] = entry def clear(self): self.ent_genre.delete(0, "end") self.ent_title.delete(0, "end") self.ent_dev.delete(0, "end") self.ent_pub.delete(0, "end") self.ent_platform.delete(0, "end") self.ent_year.delete(0, "end") self.ent_rating.delete(0, "end") self.ent_beat.delete(0, "end") self.ent_purch.delete(0, "end") def main(self): Screen.current = 0 Screen.switch_frame() class PopMessage(tk.Frame): def __init__(self, parent, msg = "Generic"): tk.Frame.__init__(self, master = parent) self.parent = parent self.lbl_continue = tk.Label(self, text = msg) self.lbl_continue.grid(row = 0, column = 0) self.btn_ok = tk.Button(self, text = "Ok", command = self.parent.destroy) self.btn_ok.grid(row = 1, column = 0) class Edit(Screen): def __init__(self): Screen.__init__(self) self.edit_key = 0 self.lbl_title = tk.Label(self, text ="Edit", font = TITLE_FONT) self.lbl_title.grid(row = 0, column = 0, sticky = "news") self.lbl_genre = tk.Label(self, text="Genre?", font = BUTTON_FONT) self.lbl_genre.grid(row = 1, column = 0, sticky = "news") self.ent_genre = tk.Entry(self) self.ent_genre.grid(row = 1, column = 1, sticky = "news") self.lbl_dev = tk.Label(self, text="Developer?", font = BUTTON_FONT) self.lbl_dev.grid(row = 2, column = 0 , sticky = "news") self.ent_dev = tk.Entry(self) self.ent_dev.grid(row = 2, column = 1, sticky = "news") self.lbl_title = tk.Label(self, text="Title?", font = BUTTON_FONT) self.lbl_title.grid(row = 1, column = 2 , sticky = "news") self.ent_title = tk.Entry(self) self.ent_title.grid(row = 1, column = 3, sticky = "news") self.lbl_pub = tk.Label(self, text="Publisher?", font = BUTTON_FONT) self.lbl_pub.grid(row = 2, column = 2, sticky = "news") self.ent_pub = tk.Entry(self) self.ent_pub.grid(row = 2, column = 3, sticky = "news") self.lbl_platform = tk.Label(self, text="Platform?", font = BUTTON_FONT) self.lbl_platform.grid(row = 3, column = 2, sticky = "news") self.ent_platform = tk.Entry(self) self.ent_platform.grid(row = 3, column = 3, sticky = "news") self.lbl_year = tk.Label(self, text="Year?", font = BUTTON_FONT) self.lbl_year.grid(row = 3, column = 0, sticky = "news") self.ent_year = tk.Entry(self) self.ent_year.grid(row = 3, column = 1, sticky = "news") self.lbl_rating = tk.Label(self, text="Rating?", font = BUTTON_FONT) self.lbl_rating.grid(row = 5, column = 0, sticky = "news") self.ent_rating = tk.Entry(self) self.ent_rating.grid(row = 5, column = 1, sticky = "news") self.lbl_beat = tk.Label(self, text="Beat It?", font = BUTTON_FONT) self.lbl_beat.grid(row = 4, column = 0, sticky = "news") self.ent_beat = tk.Entry(self) self.ent_beat.grid(row = 4, column = 1, sticky = "news") self.lbl_purch = tk.Label(self, text="Purch. Date?", font = BUTTON_FONT) self.lbl_purch.grid(row = 5, column = 2, sticky = "news") self.ent_purch = tk.Entry(self) self.ent_purch.grid(row = 5, column = 3, sticky = "news") self.lbl_mode = tk.Label(self, text="Mode?", font = BUTTON_FONT) self.lbl_mode.grid(row = 4, column = 2, sticky = "news") options=["Single Player", "Multi-Player"] self.tkvar = tk.StringVar(self) self.tkvar.set(options[0]) self.menu = tk.OptionMenu(self, self.tkvar, *options) self.menu.grid(row = 4, column = 3, sticky = "news") self.lbl_notes = tk.Label(self, text="Notes?", font = BUTTON_FONT) self.lbl_notes.grid(row = 6, column = 0, sticky = "news") self.sct_notes = ScrolledText(self, height = 8, width = 40) self.sct_notes.grid(row = 7, columnspan = 3, sticky = "news") self.btn_cancel = tk.Button(self, text = "Cancel", font = BUTTON_FONT, command = self.go_main) self.btn_cancel.grid(row = 8, column = 0) self.btn_reset = tk.Button(self, text ="Reset", font = BUTTON_FONT) self.btn_reset.grid(row = 8, column = 1, sticky = "news") self.btn_confirm = tk.Button(self, text ="Confirm", font = BUTTON_FONT, command = self.go_main) self.btn_confirm.grid(row = 8, column = 2) def update(self): entry = games[self.edit_key] self.ent_genre.delete(0, "end") self.ent_genre.insert(0, entry[0]) self.ent_title.delete(0, "end") self.ent_title.insert(0, entry[1]) self.ent_dev.delete(0, "end") self.ent_dev.insert(0, entry[2]) self.ent_pub.delete(0, "end") self.ent_pub.insert(0, entry[3]) self.ent_platform.delete(0, "end") self.ent_platform.insert(0, entry[4]) self.ent_year.delete(0, "end") self.ent_year.insert(0, entry[5]) self.ent_rating.delete(0, "end") self.ent_rating.insert(0, entry[6]) self.ent_beat.delete(0, "end") self.ent_beat.insert(0, entry[8]) self.ent_purch.delete(0, "end") self.ent_purch.insert(0, entry[9]) def go_main(self): self.confirm_edit() Screen.current = 0 Screen.switch_frame() def confirm_edit(self): entry = [] entry.append(self.ent_genre.get()) entry.append(self.ent_title.get()) entry.append(self.ent_dev.get()) entry.append(self.ent_pub.get()) entry.append(self.ent_platform.get()) entry.append(self.ent_year.get()) entry.append(self.ent_rating.get()) entry.append(self.tkvar.get()) entry.append(self.ent_beat.get()) entry.append(self.ent_purch.get()) entry.append(self.sct_notes.get(0.0, "end")) games[self.edit_key] = entry class EditEntry(tk.Frame): def __init__(self,parent): tk.Frame.__init__(self, master = parent) self.parent = parent self.lbl_edit_title = tk.Label(self, text= "Which Title would you like to edit", font = BUTTON_FONT) self.lbl_edit_title.grid(row = 0, column = 0 , sticky = "news") self.options=["Select A Title"] for key in games.keys(): self.options.append(games[key][1]) self.tkvar = tk.StringVar(self) self.tkvar.set(self.options[0]) self.menu = tk.OptionMenu(self, self.tkvar, *self.options) self.menu.grid(row = 1, column = 0, sticky = "news") self.btn_cancel = tk.Button(self, text = "Cancel", font = BUTTON_FONT, command = self.go_main) self.btn_cancel.grid(row = 2, column = 0) self.btn_confirm = tk.Button(self, text ="Confirm", font = BUTTON_FONT, command = self.go_edit) self.btn_confirm.grid(row = 3, column = 0) def go_main(self): self.parent.destroy() Screen.current = 0 Screen.switch_frame() def go_edit(self): if self.tkvar.get() == self.options[0]: popup = tk.Tk() popup.title("Edit") msg ="Error, select a title" frm_error = PopMessage(popup, msg) frm_error.grid(row = 0, column = 0) else: for i in range(len(self.options)): if self.tkvar.get() == self.options[i]: screens[2].edit_key = i break Screen.current = 2 screens[Screen.current].update() Screen.switch_frame() self.parent.destroy() class Save(Screen): def __init__(self): Screen.__init__(self) self.lbl_save = tk.Label(self, text="File Save!", font = BUTTON_FONT) self.lbl_save.grid(row = 0, column = 0 , sticky = "news") self.btn_ok = tk.Button(self, text ="Ok!", font = BUTTON_FONT, command = self.go_main) self.btn_ok.grid(row = 3, column = 0, sticky = "news") def go_main(self): Screen.current = 0 Screen.switch_frame() class Remove(Screen): def __init__(self): Screen.__init__(self) self.lbl_remove = tk.Label(self, text="Which Title would you like to remove?", font = BUTTON_FONT) self.lbl_remove.grid(row = 0, column = 0 , sticky = "news") options=["To Be Entered"] self.tkvar = tk.StringVar(self) self.tkvar.set(options[0]) self.menu = tk.OptionMenu(self, self.tkvar, *options) self.menu.grid(row = 1, column = 0, sticky = "news") self.btn_cancel = tk.Button(self, text = "Cancel", font = BUTTON_FONT, command = self.go_main) self.btn_cancel.grid(row = 2, column = 0, sticky = "news") self.btn_ok = tk.Button(self, text ="Correct", font = BUTTON_FONT, command = self.go_remove) self.btn_ok.grid(row = 3, column = 0, sticky = "news") def go_main(self): Screen.current = 0 Screen.switch_frame() def go_remove(self): Screen.current = 4 Screen.switch_frame() class Rconfirm(Screen): def __init__(self): Screen.__init__(self) self.lbl_rconfirm = tk.Label(self, text="These Games are Marked for Removal", font = BUTTON_FONT) self.lbl_rconfirm.grid(row = 0, column = 0 , sticky = "news") self.sct_rconfirm = ScrolledText(self, height = 8, width = 40) self.sct_rconfirm.grid(row = 1, columnspan = 3, sticky = "news") self.btn_cancel = tk.Button(self, text = "Cancel", font = BUTTON_FONT, command = self.go_main) self.btn_cancel.grid(row = 2, column = 0, sticky = "news") self.btn_verify = tk.Button(self, text ="Verify!", font = BUTTON_FONT) self.btn_verify.grid(row = 3, column = 0, sticky = "news") def go_main(self): Screen.current = 0 Screen.switch_frame() class CheckboxFilter(tk.Frame): def __init__(self, parent ): tk.Frame.__init__(self, master= parent) self.title_filter = tk.BooleanVar() self.title_filter.set(True) self.chk_title = tk.Checkbutton(self, text = "Title", variable = self.title_filter) self.chk_title.grid(row = 0, column = 0, sticky = "news") self.genre_filter = tk.BooleanVar() self.genre_filter.set(True) self.chk_genre = tk.Checkbutton(self, text = "Genre", variable = self.genre_filter) self.chk_genre.grid(row = 1, column = 0, sticky = "news") self.dev_filter = tk.BooleanVar() self.dev_filter.set(True) self.chk_dev = tk.Checkbutton(self, text = "Developer", variable = self.dev_filter) self.chk_dev.grid(row = 2, column = 0, sticky = "news") self.pub_filter = tk.BooleanVar() self.pub_filter.set(True) self.chk_pub = tk.Checkbutton(self, text = "Publisher", variable = self.pub_filter) self.chk_pub.grid(row = 3, column = 0, sticky = "news") self.platform_filter = tk.BooleanVar() self.platform_filter.set(True) self.chk_platform = tk.Checkbutton(self,text = "Platform", variable = self.platform_filter) self.chk_platform.grid(row = 0, column = 1, sticky = "news") self.date_filter = tk.BooleanVar() self.date_filter.set(True) self.chk_date = tk.Checkbutton(self, text = "Release Date", variable = self.date_filter) self.chk_date.grid(row = 1, column = 1, sticky = "news") self.rate_filter = tk.BooleanVar() self.rate_filter.set(True) self.chk_rate = tk.Checkbutton(self, text = "Rating", variable = self.rate_filter) self.chk_rate.grid(row = 2, column = 1, sticky = "news" ) self.multi_filter = tk.BooleanVar() self.multi_filter.set(True) self.chk_multi = tk.Checkbutton(self, text = "Single/Multi", variable = self.multi_filter) self.chk_multi.grid(row = 3, column = 1, sticky = "news") self.price_filter = tk.BooleanVar() self.price_filter.set(True) self.chk_price = tk.Checkbutton(self, text = "Price", variable = self.price_filter) self.chk_price.grid(row = 0, column = 2, sticky = "news") self.beat_filter = tk.BooleanVar() self.beat_filter.set(True) self.chk_beat = tk.Checkbutton(self, text = "Beaten", variable = self.beat_filter) self.chk_beat.grid(row = 1, column = 2, sticky = "news") self.purch_filter = tk.BooleanVar() self.purch_filter.set(True) self.chk_purch = tk.Checkbutton(self, text = "Purchase Date", variable = self.purch_filter) self.chk_purch.grid(row = 2, column = 2, sticky = "news") self.note_filter = tk.BooleanVar() self.note_filter.set(True) self.chk_note = tk.Checkbutton(self, text = "Notes", variable = self.note_filter) self.chk_note.grid(row = 3, column = 2, sticky = "news") ##MAIN if __name__ == "__main__": datafile = open("game_lib.pickle", "rb") games = pickle.load(datafile) datafile.close() root = tk.Tk() root.title("Game Library") root.geometry("500x500") root.grid_columnconfigure(0, weight = 1) screens = [MainMenu(),Add(),Edit(),Search(), Remove(), Save()] screens[0].grid(row = 0, column = 0, sticky = "news") screens[1].grid(row = 0, column = 0, sticky = "news") screens[2].grid(row = 0, column = 0, sticky = "news") screens[3].grid(row = 0, column = 0, sticky = "news") screens[4].grid(row = 0, column = 0, sticky = "news") screens[5].grid(row = 0, column = 0, sticky = "news") screens[0].tkraise() root.mainloop()
class MY_GUI(): def __init__(self, init_window_name): self.init_window_name = init_window_name self.max1 = "" self.filename = "" self.btns_names = ['资产', '价格', '时间日期', '年龄', '其他数值'] #设置窗口 def set_init_window(self): # 设置输入输出框字体 ft = tkFont.Font(family='宋体', size=15) self.init_window_name.title("电子病历标注工具_v1.3 ") #窗口名 #self.init_window_name.geometry('320x160+10+10') #290 160为窗口大小,+10 +10 定义窗口弹出时的默认展示位置 self.init_window_name.geometry('1500x1000+10+10') #self.init_window_name["bg"] = "pink" #窗口背景色,其他背景色见:blog.csdn.net/chl0000/article/details/7657887 #self.init_window_name.attributes("-alpha",0.9) #虚化,值越小虚化程度越高 #标签 self.init_data_label = Label(self.init_window_name, text="待处理数据") self.init_data_label.grid(row=0, column=0) self.result_data_label = Label(self.init_window_name, text="输出结果") self.result_data_label.grid(row=0, column=12) self.log_label = Label(self.init_window_name, text="日志") self.log_label.grid(row=12, column=0) #文本框 self.init_data_Text = ScrolledText(self.init_window_name, width=67, height=35, font=ft) #原始数据录入框 self.init_data_Text.grid(row=1, column=0, rowspan=10, columnspan=10) self.result_data_Text = ScrolledText(self.init_window_name, width=70, height=49, font=ft) #处理结果展示 self.result_data_Text.grid(row=1, column=12, rowspan=15, columnspan=10) self.log_data_Text = Text(self.init_window_name, width=66, height=9) # 日志框 self.log_data_Text.grid(row=13, column=0, columnspan=10) self.init_data_Text.bind("<Button-1>", self.button_start) self.init_data_Text.bind("<ButtonRelease-1>", self.button_end) #按钮 # self.str_trans_to_md5_button = Button(self.init_window_name, text="字符串转MD5", bg="lightblue", width=10,command=self.str_trans_to_md5) # 调用内部方法 加()为直接调用 # self.str_trans_to_md5_button.grid(row=1, column=11) #导入文件按钮 self.input_button = Button(self.init_window_name, text="导入文件", bg="lightgreen", width=8, command=self.openfile) self.input_button.grid(row=0, column=2) # 输入窗口清空按钮 self.delet_input_button = Button(self.init_window_name, text="一键清空", bg="red", width=8, command=self.delet_ofInput) self.delet_input_button.grid(row=0, column=3) #展示窗口清空按钮 self.delet_result_button = Button(self.init_window_name, text="一键清空", bg="red", width=8, command=self.delet_ofResult) self.delet_result_button.grid(row=0, column=13) #导出文件按钮 self.output_button = Button(self.init_window_name, text="导出文件", bg="lightgreen", width=8, command=self.outputfile) self.output_button.grid(row=0, column=14) #标记解剖部位按钮 self.show_button = Button(self.init_window_name, text=self.btns_names[0], bg="lightblue", width='8', command=self.show_jpbw) self.show_button.grid(row=2, column=11) # 标记症状描述按钮 self.show_button = Button(self.init_window_name, text=self.btns_names[1], bg="lightyellow", width='8', command=self.show_zzms) self.show_button.grid(row=3, column=11) # 标记独立症状按钮 self.show_button = Button(self.init_window_name, text=self.btns_names[2], bg="lightgreen", width='8', command=self.show_dlzz) self.show_button.grid(row=4, column=11) # 标记药物按钮 self.show_button = Button(self.init_window_name, text=self.btns_names[3], bg="red", width='8', command=self.show_yw) self.show_button.grid(row=5, column=11) # 标记手术按钮 self.show_button = Button(self.init_window_name, text=self.btns_names[4], bg="lightpink", width='8', command=self.show_ss) self.show_button.grid(row=6, column=11) # 恢复操作按钮 self.recover_button = Button(self.init_window_name, text="恢复", width='8', command=self.recover) self.recover_button.grid(row=0, column=15) # 标注撤销功能ctrl+z实现 self.back_button = Button(self.init_window_name, text="撤销", width='8', command=self.backToHistory) self.back_button.grid(row=0, column=16) self.result_data_Text.bind('<Control-Key-z>', self.backToHistory) self.result_data_Text.edit_separator() #功能函数 def str_trans_to_md5(self): src = self.init_data_Text.get(1.0, END).strip().replace("\n", "").encode() #print("src =",src) if src: try: myMd5 = hashlib.md5() myMd5.update(src) myMd5_Digest = myMd5.hexdigest() #print(myMd5_Digest) #输出到界面 self.result_data_Text.delete(1.0, END) self.result_data_Text.insert(1.0, myMd5_Digest) self.write_log_to_Text("INFO:str_trans_to_md5 success") except: self.result_data_Text.delete(1.0, END) self.result_data_Text.insert(1.0, "字符串转MD5失败") else: self.write_log_to_Text("ERROR:str_trans_to_md5 failed") #获取鼠标选中文本 def button_start(self, event): global s global line_no s = self.init_data_Text.index('@%s,%s' % (event.x, event.y)) line_no = str(s).split('.')[0] s = str(s).split('.')[1] def button_end(self, event): global e e = self.init_data_Text.index('@%s,%s' % (event.x, event.y)) e = str(e).split('.')[1] # 处理选中位置参数 def get_loc(self): e = int(str( self.init_data_Text.index('insert')).split('.')[1]) - 1 # 末尾列数 ll = int(str( self.init_data_Text.index('insert')).split('.')[0]) - 1 # 行号 con_num = len(self.init_data_Text.selection_get()) s = e - con_num + 1 # 开始列数 return s, e, ll #标记1 def show_jpbw(self): self.result_data_Text.edit_separator() start_index, end_index, ll = self.get_loc() print(self.init_data_Text.selection_get() + "\t" + str(self.btns_names[0]) + "\n") self.result_data_Text.insert( END, self.init_data_Text.selection_get() + "\t" + str(start_index) + "\t" + str(end_index) + "\t" + str(ll) + "\t" + str(self.btns_names[0]) + "\n") print(self.result_data_Text.get(END)) self.max1 = self.result_data_Text.get('1.0', END) self.result_data_Text.edit_separator() # 标记2 def show_zzms(self, ): self.result_data_Text.edit_separator() start_index, end_index, ll = self.get_loc() print(self.init_data_Text.selection_get() + "\t" + str(start_index) + "\t" + str(end_index) + "\t" + str(ll) + "\t" + str(self.btns_names[1]) + "\n") self.result_data_Text.insert( END, self.init_data_Text.selection_get() + "\t" + str(start_index) + "\t" + str(end_index) + "\t" + str(ll) + "\t" + str(self.btns_names[1]) + "\n") self.max1 = self.result_data_Text.get('1.0', END) self.result_data_Text.edit_separator() # 标记3 def show_dlzz(self): self.result_data_Text.edit_separator() start_index, end_index, ll = self.get_loc() print(self.init_data_Text.selection_get() + "\t" + str(start_index) + "\t" + str(end_index) + str(self.btns_names[2]) + "\n") self.result_data_Text.insert( END, self.init_data_Text.selection_get() + "\t" + str(start_index) + "\t" + str(end_index) + "\t" + str(ll) + "\t" + str(self.btns_names[2]) + "\n") self.max1 = self.result_data_Text.get('1.0', END) self.result_data_Text.edit_separator() # 标记4 def show_yw(self): self.result_data_Text.edit_separator() start_index, end_index, ll = self.get_loc() print(self.init_data_Text.selection_get() + "\t" + str(self.btns_names[3]) + "\n") self.result_data_Text.insert( END, self.init_data_Text.selection_get() + "\t" + str(start_index) + "\t" + str(end_index) + "\t" + str(ll) + "\t" + str(self.btns_names[3]) + "\n") self.max1 = self.result_data_Text.get('1.0', END) self.result_data_Text.edit_separator() # 标记5 def show_ss(self): self.result_data_Text.edit_separator() start_index, end_index, ll = self.get_loc() print(self.init_data_Text.selection_get() + "\t" + str(self.btns_names[4]) + "\n") self.result_data_Text.insert( END, self.init_data_Text.selection_get() + "\t" + str(start_index) + "\t" + str(end_index) + "\t" + str(ll) + "\t" + str(self.btns_names[4]) + "\n") self.max1 = self.result_data_Text.get('1.0', END) self.result_data_Text.edit_separator() #标注操作撤销功能 def callback(self, event): # 每当有字符插入的时候,就自动插入一个分割符,主要是防止每次撤销的时候会全部撤销 self.result_data_Text.edit_separator() def backToHistory(self): #撤销操作 if len(self.result_data_Text.get('1.0', 'end')) != 0: self.result_data_Text.edit_undo() else: #无字符时不能撤销 return def recover(self): #恢复操作 if len(self.max1) == len(self.result_data_Text.get('1.0', END)): return self.result_data_Text.edit_redo() #输入窗口一键清空功能 def delet_ofInput(self): self.init_data_Text.delete('1.0', 'end') #结果窗口一键清空功能 def delet_ofResult(self): self.result_data_Text.delete('1.0', 'end') #打开文件功能 def openfile(self): fname = filedialog.askopenfilename(title='打开文件', filetypes=[('All Files', '*')]) self.filename = os.path.basename(fname) print(self.filename) f = open(fname, 'r', encoding='utf-8', errors='ignore') # #对文本数据存储进数组,方便后续操作 # line = f.readline() # data_list = [] # while line: # # num = list(map(str, line.split())) # # data_list.append(num) # data_list.append(line) # line = f.readline() # f.close() # data_array = np.array(data_list) # f_contet = data_array # new f_contet = ''.join(f.readlines()) self.init_data_Text.insert(END, f_contet) # 导出文件功能 def outputfile(self): if self.filename != "": # os.chdir(r'E:\GitTest\untitled\文本标注1.1\Annoation') # os.chdir(r'data/out') f = open("data/out/ann" + self.filename, 'w', encoding='utf-8', errors='ignore') f.write(self.result_data_Text.get("1.0", "end")) json1 = json.dumps(self.result_data_Text.get("1.0", END)) print(json1) showinfo(title="成功", message="标注文件已导出至Annoation文件夹") else: showinfo(title="错误", message="未找到指定文件") #获取当前时间 def get_current_time(self): current_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())) return current_time #日志动态打印 def write_log_to_Text(self, logmsg): global LOG_LINE_NUM current_time = self.get_current_time() logmsg_in = str(current_time) + " " + str(logmsg) + "\n" #换行 if LOG_LINE_NUM <= 7: self.log_data_Text.insert(END, logmsg_in) LOG_LINE_NUM = LOG_LINE_NUM + 1 else: self.log_data_Text.delete(1.0, 2.0) self.log_data_Text.insert(END, logmsg_in)
class Frame(Tk.Frame): def __init__(self, master=None): global start_flag Tk.Frame.__init__(self, master) self.gw = Gateway() #### COMMAND DISPLAY self.panid= Tk.IntVar() self.panid=0xABCD self.PanidDisp= Tk.StringVar() self.PanidDisp.set(hex(self.panid)) self.master.title('Lazurite Gateway') self.row_offset = 0 # DISPLAY LOGO # f_command = Tk.Frame(self, relief=Tk.RIDGE, bd=4) f_command = Tk.Frame(self, bd=4) self.image= Tk.PhotoImage(file=LOGO) self.logoBackGround=Tk.Label(f_command, image=self.image, bg='gray', relief=Tk.RIDGE, anchor=Tk.W) f_cb = Tk.Frame(self,bd=4) # DISPLAY Channel self.ch =33 self.chNumberDisp = Tk.IntVar() self.chNumberDisp.set(self.ch) self.l_ch = Tk.Label(f_command,text="Ch", relief=Tk.RIDGE, anchor=Tk.W) self.t_ch = Tk.Entry(f_command,textvariable=self.chNumberDisp,width=10, relief=Tk.SUNKEN, bd=2, state=Tk.NORMAL) self.b_chIncButton = Tk.Button(f_command, font=('Helvetica', '6'), text='+', command=self.chInc) self.b_chDecButton = Tk.Button(f_command, font=('Helvetica', '6'), text='-', command=self.chDec) # DISPLAY Power self.pwr = (1,20) self.l_pwr = Tk.Label(f_command,text="Pwr", relief=Tk.RIDGE, anchor=Tk.W) self.b_pwr = zz.Combobox(f_command,value=self.pwr, width=10,state="readonly") self.b_pwr.current(1) # DISPLAY Rate self.rate = (50,100) self.l_rate = Tk.Label(f_command,text="Rate", relief=Tk.RIDGE, anchor=Tk.W) self.b_rate = zz.Combobox(f_command,value=self.rate, width=10,state="readonly") self.b_rate.current(1) # DISPLAY PANID self.l_panid = Tk.Label(f_command,text="PANID", relief=Tk.RIDGE, anchor=Tk.W) self.t_panid = Tk.Entry(f_command,textvariable=self.PanidDisp,width=10, relief=Tk.SUNKEN, bd=2, state=Tk.NORMAL) # DISPLAY Start/Stop Button self.b_start = Tk.Button(f_command, text='Start', command=self.Start) self.b_stop = Tk.Button(f_command, text='Stop', command=self.Stop, state=Tk.DISABLED) ## Option check buttom self.ign = Tk.BooleanVar() self.c_ign = Tk.Checkbutton(f_command,text="Ignore address",variable=self.ign) # DISPLAY display mode global mac_menu global mac_combobox global mac_mode mac_combobox=zz.Combobox(f_command,value=mac_menu,width=20,state="readonly") mac_combobox.current(mac_mode) ## InfoCorpus # self.InfoCorpus= Tk.PhotoImage(file='InfoCorpusLogo.gif') # self.ImageInforcopus = Tk.Label(f_command, image=self.InfoCorpus, bg='gray', relief=Tk.RIDGE) # DISPLAY save log buttom self.b_savelog=Tk.Button(f_command, text='SAVE', command=self.Save, state=Tk.NORMAL) self.b_clearlog=Tk.Button(f_command, text='CLEAR LOG', command=self.Clear, state=Tk.NORMAL) self.b_view=Tk.Button(f_command, text='VIEW', command=self.View, state=Tk.NORMAL) ## Command Frame Location self.logoBackGround.grid(row=0,column=0) self.b_start.grid(row=0, column=4) self.b_stop.grid(row=0, column=5) self.l_ch.grid(row=2,column=0,sticky=Tk.W + Tk.E,pady=10) self.t_ch.grid(row=2,column=1,padx=20,sticky=Tk.W) self.b_chIncButton.grid(row=2, column=4, sticky=Tk.W + Tk.E + Tk.S) self.b_chDecButton.grid(row=2, column=5, sticky=Tk.W + Tk.E + Tk.S) self.l_pwr.grid(row=4,column=0,sticky=Tk.W + Tk.E,pady=10) self.b_pwr.grid(row=4,column=1,padx=20,sticky=Tk.W) self.l_rate.grid(row=5,column=0,sticky=Tk.W + Tk.E,pady=10) self.b_rate.grid(row=5,column=1,padx=20,sticky=Tk.W) self.l_panid.grid(row=6,column=0,sticky=Tk.W + Tk.E,pady=10) self.t_panid.grid(row=6,column=1,padx=20,sticky=Tk.W) self.c_ign.grid(row=0,column=6,sticky=Tk.W + Tk.E,padx=20) mac_combobox.grid(row=5,column=6,padx=20) self.b_savelog.grid(row=6,column=6,padx=20) self.b_clearlog.grid(row=6,column=7,padx=20) self.b_view.grid(row=6,column=8,padx=20) # self.ImageInforcopus.grid(row=0, column=8) ## LOG WINDOW global XSCALL global YSCALL f_log = Tk.Frame(self) # self.logText = Tk.StringVar() # self.logText.set("") self.s_logtext=ScrolledText(f_log,width=XSCALL, height=YSCALL) self.s_logtext.grid(sticky=Tk.W+Tk.E) self.s_logtext.write = self.write sys.stdout = self.s_logtext ## FRAME Location f_command.pack() f_log.pack() def write(self,str): self.s_logtext.insert(Tk.END,str) time.sleep(0.001) self.s_logtext.yview_scroll(str.count("\n") + 1, "units") def Start(self): global start_flag ## update parameters self.ch = self.chNumberDisp.get() self.pwr = int(self.b_pwr.get()) self.rate = int(self.b_rate.get()) self.panid = int(self.PanidDisp.get(),0) ## parameter check if self.ch < 24 or self.ch > 61: print("ch number error") return if self.pwr != 1 and self.pwr != 20: print("power error =",self.pwr) return if self.rate != 50 and self.rate != 100: print("rate error=",self.rate) return if self.panid <= 0 or self.panid > 0xffff: print("PANID error") return ## Start Gateway self.b_start.configure(state=Tk.DISABLED) self.b_stop.configure(state=Tk.NORMAL) self.b_chIncButton.configure(state=Tk.DISABLED) self.b_chIncButton.configure(state=Tk.DISABLED) self.logoBackGround.configure(bg=BLUE) self.b_savelog.configure(state=Tk.DISABLED) start_flag = True self.init_gateway() def Stop(self): global start_flag self.b_start.configure(state=Tk.NORMAL) self.b_stop.configure(state=Tk.DISABLED) self.b_chIncButton.configure(state=Tk.NORMAL) self.b_chIncButton.configure(state=Tk.NORMAL) self.logoBackGround.configure(bg='gray') self.b_savelog.configure(state=Tk.NORMAL) start_flag = False self.gw.close_driver() self.gw.remove_driver() def chInc(self): self.ch = self.chNumberDisp.get() if self.ch < 61 and self.ch >= 24: self.ch += 1 elif self.ch < 24: self.ch = 24 else: self.ch = 61 self.chSet() def chDec(self): self.ch = self.chNumberDisp.get() if self.ch <= 61 and self.ch > 24: self.ch -= 1 elif self.ch > 61: self.ch = 61 else: self.ch = 24 self.chSet() def chSet(self): self.chNumberDisp.set(self.ch) def Clear(self): self.s_logtext.delete(1.0,Tk.END) def Save(self): filename = Tk.filedialog.asksaveasfile(filetypes = [('Log Files', ('.log'))]) if filename != "": logfile = open(filename.name,mode = 'w') log_data = self.s_logtext.get(1.0,Tk.END) logfile.write(log_data) logfile.close() return def View(self): print ("GADGADGADGADGA") view_file = open("/home/pi/python/camera.jpeg",mode = 'rb') # for i in range(1,1000): # print (view_file.read()) def init_gateway(self): if self.ign.get(): self.mode = 1 else: self.mode = 0 self.gw.load_driver(self.ch,self.pwr,self.rate,self.panid,self.mode) self.gw.open_driver() def close(self): if self.dvice_open: self.gw.close_driver() self.gw.remove_driver()
search_button.place(x=250, y=20) search_lbl = Label(root, text='Searching result for : ', font=('arial', 12, 'bold'), bg='white') search_lbl.place(x=15, y=70) text = ScrolledText(root, font=('times', 12), bd=4, relief=SUNKEN, wrap=WORD) text.place(x=15, y=100, height=300, width=300) lang_list = ['English', 'Hindi', 'Gujrati', 'French', 'German', 'Arabic'] lang.set(lang_list[0]) language = OptionMenu(root, *lang_list, lang) language.place(x=10, y=420) clear_btn = Button(root, text='Clear', font=('arial', 12, 'bold'), width=10, command=lambda: text.delete(0.0, END)) clear_btn.place(x=105, y=420) exit_btn = Button(root, text='Exit', font=('arial', 12, 'bold'), width=10, command=root.quit) exit_btn.place(x=200, y=420) root.mainloop()
class SpinDelight(Frame): def __init__(self): Frame.__init__(self) self.master.geometry("1020x600+150+50") self.master.title("Spin Delight 1.0 - Copyright (c) Robin Thomas") self.master.resizable(0,0) self.grid() self.brwe = Button(self, text = "Browse", command = self.open_file, width = 10, relief = "groove") self.rtxt = Label(self, text="Input Text:") self.txt1 = ScrolledText(self, width = 50, height = 25) self.txt1.bind("<Control-Key-a>", self.select_all_txt1) self.txt1.bind("<Control-Key-A>", self.select_all_txt1) self.spin = Button(self, text = "Spin", command = self.spin_file, width = 10, relief = "groove") self.stxt = Label(self, text="Spun Text:") self.txt2 = ScrolledText(self, width = 50, height = 25) self.txt2.bind("<Control-Key-a>", self.select_all_txt2) self.txt2.bind("<Control-Key-A>", self.select_all_txt2) self.brwe.grid(row = 2, column = 2, pady = 15) self.rtxt.grid(row = 2, column = 0, padx = 25) self.txt1.grid(row = 3, column = 0, columnspan = 10, padx = 25) self.spin.grid(row = 3, column = 12) self.stxt.grid(row = 2, column = 13, padx = 25, pady = 5) self.txt2.grid(row = 3, column = 13, columnspan = 10, padx = 25) def select_all_txt1(self,event): self.txt1.tag_add(SEL, "1.0", END) self.txt1.mark_set(INSERT, "1.0") self.txt1.see(INSERT) return 'break' def select_all_txt2(self,event): self.txt2.tag_add(SEL, "1.0", END) self.txt2.mark_set(INSERT, "1.0") self.txt2.see(INSERT) return 'break' def open_file(self): fname = askopenfilename(filetypes=(("Text files", "*.txt"), ("All files", "*.*") )) if fname: try: self.txt1.delete(0.0, END) f = open(fname,'r') self.txt1.insert(INSERT,f.read()) except: showerror("Open Source File", "Failed to read file\n'%s'" % fname) def spin_file(self): txt = self.txt1.get("1.0", END) self.txt2.delete(0.0, END) if len(txt): try: words = sub(r'([.,?])+', r' \1 ', sub(r'[^a-zA-Z0-9 .,?]+', ' ', txt)).split() w1 = words[0] z = [(words[j - 1], words[j]) for j in range(1, len(words))] values = self.generate_dict(z, w1) string = self.generate_sent(values) if len(string): self.txt2.insert(INSERT, string) else: showerror("Error", "Insufficient data to spin !!") except: showerror("Error", "Nothing to spin !!") def generate_dict(self, x, w1): values = {'.': [w1]} for (wa, wb) in x: if wa in values: values[wa].append(wb) else: values[wa] = [wb] return values def generate_sent(self, values): w1 = '.' w2 = choice(values[w1]) string = w2 values[w1].remove(w2) while values: w1 = w2 if len(values[w1]): w2 = choice(values[w1]) else: del values[w1] w1 = '.' break if w2 in ('.', ',', '?'): string += w2 else: string += " " + w2 values[w1].remove(w2) return string
class MarkovDemo: def __init__(self, master): self.prompt_size = Label(master, anchor=W, text='Encode Word Size') self.prompt_size.pack(side=TOP, fill=X) self.size_entry = Entry(master) self.size_entry.insert(0, '8') self.size_entry.pack(fill=X) self.prompt_plain = Label(master, anchor=W, text='Plaintext Characters') self.prompt_plain.pack(side=TOP, fill=X) self.plain_entry = Entry(master) self.plain_entry.insert(0, '""') self.plain_entry.pack(fill=X) self.showframe = Frame(master) self.showframe.pack(fill=X, anchor=W) self.showvar = StringVar(master) self.showvar.set("encode") self.showfirstradio = Radiobutton(self.showframe, text="Encode Plaintext", variable=self.showvar, value="encode", command=self.reevaluate) self.showfirstradio.pack(side=LEFT) self.showallradio = Radiobutton(self.showframe, text="Decode Cyphertext", variable=self.showvar, value="decode", command=self.reevaluate) self.showallradio.pack(side=LEFT) self.inputbox = ScrolledText(master, width=60, height=10, wrap=WORD) self.inputbox.pack(fill=BOTH, expand=1) self.dynamic_var = IntVar() self.dynamic_box = Checkbutton(master, variable=self.dynamic_var, text='Dynamic Evaluation', offvalue=False, onvalue=True, command=self.reevaluate) self.dynamic_box.pack() self.output = Label(master, anchor=W, text="This is your output:") self.output.pack(fill=X) self.outbox = ScrolledText(master, width=60, height=10, wrap=WORD) self.outbox.pack(fill=BOTH, expand=1) self.inputbox.bind('<Key>', self.reevaluate) def select_all(event=None): event.widget.tag_add(SEL, 1.0, 'end-1c') event.widget.mark_set(INSERT, 1.0) event.widget.see(INSERT) return 'break' self.inputbox.bind('<Control-Key-a>', select_all) self.outbox.bind('<Control-Key-a>', select_all) self.inputbox.bind('<Control-Key-/>', lambda event: 'break') self.outbox.bind('<Control-Key-/>', lambda event: 'break') self.outbox.config(state=DISABLED) def reevaluate(self, event=None): if event is not None: if event.char == '': return if self.dynamic_var.get(): text = self.inputbox.get(1.0, END)[:-1] if len(text) < 10: return text = text.replace('\n \n', '\n\n') mode = self.showvar.get() assert mode in ('decode', 'encode'), 'Bad mode!' if mode == 'encode': # Encode Plaintext try: # Evaluate the plaintext characters plain = self.plain_entry.get() if plain: PC = eval(self.plain_entry.get()) else: PC = '' self.plain_entry.delete(0, END) self.plain_entry.insert(0, '""') # Evaluate the word size size = self.size_entry.get() if size: XD = int(size) while grid_size(text, XD, PC) > 1 << 20: XD -= 1 else: XD = 0 grid = 0 while grid <= 1 << 20: grid = grid_size(text, XD, PC) XD += 1 XD -= 1 # Correct the size and encode self.size_entry.delete(0, END) self.size_entry.insert(0, str(XD)) cyphertext, key, prime = encrypt_str(text, XD, PC) except: traceback.print_exc() else: buffer = '' for block in key: buffer += repr(block)[2:-1] + '\n' buffer += repr(prime)[2:-1] + '\n\n' + cyphertext self.outbox.config(state=NORMAL) self.outbox.delete(1.0, END) self.outbox.insert(END, buffer) self.outbox.config(state=DISABLED) else: # Decode Cyphertext try: header, cypher = text.split('\n\n', 1) lines = header.split('\n') for index, item in enumerate(lines): try: lines[index] = eval('b"' + item + '"') except: lines[index] = eval("b'" + item + "'") plain = decrypt_str(cypher, tuple(lines[:-1]), lines[-1]) except: traceback.print_exc() else: self.outbox.config(state=NORMAL) self.outbox.delete(1.0, END) self.outbox.insert(END, plain) self.outbox.config(state=DISABLED) else: text = self.inputbox.get(1.0, END)[:-1] text = text.replace('\n \n', '\n\n') mode = self.showvar.get() assert mode in ('decode', 'encode'), 'Bad mode!' if mode == 'encode': try: XD = int(self.size_entry.get()) PC = eval(self.plain_entry.get()) size = grid_size(text, XD, PC) assert size except: pass else: buffer = 'Grid size will be:\n' + convert(size) self.outbox.config(state=NORMAL) self.outbox.delete(1.0, END) self.outbox.insert(END, buffer) self.outbox.config(state=DISABLED)
class MarkovDemo(Frame): "MarkovDemo(master=None, **kw) -> MarkovDemo instance" TEXT = dict(height=2, width=46, wrap=WORD) # Text Options GRID = dict(padx=5, pady=5) # Grid Options # Initialize a MarkovDemo instance with a GUI for interaction. def __init__(self, master=None, **kw): "Initialize the MarkovDemo instance's widgets and settings." super().__init__(master, **kw) self.build_widgets() self.place_widgets() self.setup_widgets() self.grid_rowconfigure(2, weight=1) self.grid_rowconfigure(3, weight=1) self.grid_columnconfigure(0, weight=1) self.key = self.primer = None def build_widgets(self): "Build the various widgets that will be used in the program." # Create processing frame widgets. self.processing_frame = LabelFrame(self, text='Processing Mode:') self.mode_var = StringVar(self, 'encode') self.decode_button = Radiobutton(self.processing_frame, text='Decode Cipher-Text', command=self.handle_radiobuttons, value='decode', variable=self.mode_var) self.encode_button = Radiobutton(self.processing_frame, text='Encode Plain-Text', command=self.handle_radiobuttons, value='encode', variable=self.mode_var) self.freeze_var = BooleanVar(self, False) self.freeze_button = Checkbutton(self.processing_frame, text='Freeze Key & Primer', command=self.handle_checkbutton, offvalue=False, onvalue=True, variable=self.freeze_var) # Create encoding frame widgets. self.encoding_frame = LabelFrame(self, text='Encoding Options:') self.chain_size_label = Label(self.encoding_frame, text='Chain Size:') self.chain_size_entry = Entry(self.encoding_frame) self.plain_text_label = Label(self.encoding_frame, text='Plain-Text:') self.plain_text_entry = Entry(self.encoding_frame) # Create input frame widgets. self.input_frame = LabelFrame(self, text='Input Area:') self.input_text = ScrolledText(self.input_frame, **self.TEXT) # Create output frame widgets. self.output_frame = LabelFrame(self, text='Output Area:') self.output_text = ScrolledText(self.output_frame, **self.TEXT) def place_widgets(self): "Place the widgets where they belong in the MarkovDemo frame." # Locate processing frame widgets. self.processing_frame.grid(sticky=EW, **self.GRID) self.decode_button.grid(row=0, column=0, **self.GRID) self.encode_button.grid(row=0, column=1, **self.GRID) self.freeze_button.grid(row=0, column=2, **self.GRID) # Locate encoding frame widgets. self.encoding_frame.grid(sticky=EW, **self.GRID) self.chain_size_label.grid(row=0, column=0, sticky=W, **self.GRID) self.chain_size_entry.grid(row=0, column=1, sticky=EW, **self.GRID) self.plain_text_label.grid(row=1, column=0, sticky=W, **self.GRID) self.plain_text_entry.grid(row=1, column=1, sticky=EW, **self.GRID) self.encoding_frame.grid_columnconfigure(1, weight=1) # Locate input frame widgets. self.input_frame.grid(sticky=NSEW, **self.GRID) self.input_text.grid(sticky=NSEW, **self.GRID) self.input_frame.grid_rowconfigure(0, weight=1) self.input_frame.grid_columnconfigure(0, weight=1) # Locate output frame widgets. self.output_frame.grid(sticky=NSEW, **self.GRID) self.output_text.grid(sticky=NSEW, **self.GRID) self.output_frame.grid_rowconfigure(0, weight=1) self.output_frame.grid_columnconfigure(0, weight=1) def setup_widgets(self): "Setup each widget's configuration for the events they handle." self.input_text.bind('<Key>', self.handle_key_events) self.input_text.bind('<Control-Key-a>', self.handle_control_a) self.input_text.bind('<Control-Key-/>', lambda event: 'break') self.output_text['state'] = DISABLED self.output_text.bind('<Control-Key-a>', self.handle_control_a) self.output_text.bind('<Control-Key-/>', lambda event: 'break') ######################################################################## # Take care of any special event needing dedicated processing. def handle_radiobuttons(self): "Change the interface based on the encoding / decoding setting." if self.encrypting: self.freeze_button.grid() if not self.freeze_var.get(): self.encoding_frame.grid() else: self.freeze_button.grid_remove() if not self.freeze_var.get(): self.encoding_frame.grid_remove() self.handle_key_events(None) def handle_checkbutton(self): "Change the interface based on the key / primer freeze setting." if self.freeze_var.get(): self.encoding_frame.grid_remove() else: self.encoding_frame.grid() def handle_key_events(self, event): "Schedule refreshing the output area after an input area event." if event is None or event.char and event.state | 0o11 == 0o11: self.after_idle(self.refresh) @staticmethod def handle_control_a(event): "Select all text in the widget associated with the given event." event.widget.tag_add(SEL, 1.0, END + '-1c') return 'break' ######################################################################## # Handle interface's updates when either encoding or decoding. def refresh(self): "Refresh the output based on the value of the input." text = self.input_text.get(1.0, END + '-1c') if not text: self.output = text elif self.encrypting: self.encode(text) else: self.decode(text) def output(self, value): "Set the text in the output area to the string value." self.output_text['state'] = NORMAL self.output_text.delete(1.0, END) self.output_text.insert(END, value) if self.encrypting and self.freeze_var.get(): self.output_text.see(END) self.output_text['state'] = DISABLED output = property(fset=output, doc='Output area property.') @property def chain_size(self): "Chain size for the Markov chains used when encrypting." try: value = ast.literal_eval(self.chain_size_entry.get()) assert isinstance(value, int) and 2 <= value <= 256 return value except: self.chain_size_entry.delete(0, END) self.chain_size_entry.insert(0, '2') return 2 @property def plain_text(self): "Plain text or ignored characters in encryption process." try: value = self.repr_to_obj(self.plain_text_entry.get(), '') assert isinstance(value, str) return value except: self.plain_text_entry.delete(0, END) return '' ######################################################################## # Encrypt a string for display in the interface's output area. def encode(self, string): "Encode the string and show the cipher-text in the output." try: cipher = self.build_cipher(string) except ValueError: self.output = '' except: self.output = traceback.format_exc() else: self.output = self.build_header() + '\n\n' + cipher def build_cipher(self, string): "Build cipher-text based on plain-text and return answer." if self.key and self.freeze_var.get(): cipher, primer = me.encrypt_str(string, self.key, self.primer) else: args = string, self.chain_size, self.plain_text cipher, self.key, self.primer = me.auto_encrypt_str(*args) return cipher def build_header(self): "Build header from key and primer values in current use." header = '\n'.join(map(self.bytes_to_repr, self.key.data)) header += '\n' + self.bytes_to_repr(self.primer.data) return header ######################################################################## # Decrypt a string for display in the interface's output area. def decode(self, string): "Decode encrypted message and display plain-text in output." try: cipher = self.extract_keys(string) text = self.extract_text(cipher) except ValueError: self.output = '' except: self.output = traceback.format_exc() else: self.output = text def extract_keys(self, string): "Extract keys to decryption and return the cipher-text area." header, cipher = string.split('\n\n', 1) *key, primer = map(self.repr_to_obj, header.split('\n')) self.key, self.primer = me.Key(tuple(key)), me.Primer(primer) return cipher def extract_text(self, string): "Extract text message from string using built key and primer." text, primer = me.decrypt_str(string, self.key, self.primer) return text ######################################################################## # Provide some special methods to simplify the program's code. @property def encrypting(self): "Encrypting boolean stating current operations mode." return {'encode': True, 'decode': False}[self.mode_var.get()] @staticmethod def bytes_to_repr(obj): "Convert bytes object into suitable representation." if not isinstance(obj, bytes): raise TypeError('Object must be a bytes instance!') return repr(obj)[2:-1] @staticmethod def repr_to_obj(string, prefix='b'): "Convert representation into an equivalent object." for template in '{}"{}"', "{}'{}'": try: return ast.literal_eval(template.format(prefix, string)) except: pass raise ValueError('Cannot convert {!r} to object!'.format(string)) @classmethod def main(cls): "Create context for demo and run a test instance." NoDefaultRoot() root = Tk() root.minsize(420, 330) root.title('Markov Demo 2') test = cls(root) test.grid(sticky=NSEW) root.grid_rowconfigure(0, weight=1) root.grid_columnconfigure(0, weight=1) root.mainloop()
class ExpressQuery(Frame): def __init__(self, master): Frame.__init__(self, master) self.root = master self.root.bind_all('<F5>', self.update_all_posts) self.root.bind_all('<Escape>', self.clear_input) self.all_posts = {} # 运单列表 self.root.title('快递助手 v1.2') self.root.iconbitmap('logo.ico') self.root.resizable(width=False, height=False) self.auto_company_url = 'http://www.kuaidi100.com/autonumber/autoComNum?text=' self.query_url = 'http://www.kuaidi100.com/query?' with open('company_codes.json', 'r', encoding='utf-8') as f: self.company_codes = json.loads(f.read()) self.company_names = dict((v, k) for k, v in self.company_codes.items()) with open('state.json', 'r', encoding='utf-8') as f: self.state = json.loads(f.read()) parent_frame = Frame(self.root) parent_frame.grid(padx=10, pady=10, stick=E + W + N + S) add_post_group = Frame(parent_frame) post_id_label = Label(add_post_group, text='运单号:') self.post_id_var = tkinter.StringVar() # 运单号 self.post_id_field = Entry(add_post_group, width=20, textvariable=self.post_id_var) self.post_id_field.bind('<Return>', self.handle_add_post) post_note_label = Label(add_post_group, text='备注:') self.post_note_var = tkinter.StringVar() # 运单注释 post_note_field = Entry(add_post_group, width=20, textvariable=self.post_note_var) post_note_field.bind('<Return>', self.handle_add_post) post_company_label = Label(add_post_group, text='公司:') self.post_company_name_var = tkinter.StringVar() self.post_company_field = Combobox(add_post_group, textvariable=self.post_company_name_var, values=list(self.company_names.values()), width=12) post_add_button = Button(add_post_group, text='添加', width=10, command=self.handle_add_post) clear_input_button = Button(add_post_group, text='清空', width=10, command=self.clear_input) post_id_label.grid(row=0, column=0) self.post_id_field.grid(row=0, column=1) post_note_label.grid(row=0, column=2) post_note_field.grid(row=0, column=3) post_company_label.grid(row=0, column=4) self.post_company_field.grid(row=0, column=5) post_add_button.grid(row=0, column=6, padx=5) clear_input_button.grid(row=0, column=7, padx=5) self.post_id_field.focus_set() show_posts_group = Frame(parent_frame) self.posts = Treeview(show_posts_group, height=10, selectmode='browse', columns=('note', 'company_name', 'state', 'last_update')) # 运单列表框 self.x_scrollbar = Scrollbar(show_posts_group, orient=tkinter.HORIZONTAL, command=self.posts.xview) self.y_scrollbar = Scrollbar(show_posts_group, orient=tkinter.VERTICAL, command=self.posts.yview) self.posts.config(xscroll=self.x_scrollbar.set, yscroll=self.y_scrollbar.set) self.posts.column('#0', width=130) self.posts.heading('#0', text='运单号') self.posts.column('note', width=130) self.posts.heading('note', text='备注') self.posts.column('company_name', width=80) self.posts.heading('company_name', text='公司名称') self.posts.column('state', width=180) self.posts.heading('state', text='运单状态') self.posts.column('last_update', width=150) self.posts.heading('last_update', text='最后更新') self.posts.bind('<<TreeviewSelect>>', self.show_post_detail) self.posts.bind('<Delete>', self.remove_post) self.post_detail = ScrolledText(show_posts_group, bg='white', width=92, height=16, state=tkinter.DISABLED) self.posts.grid(row=0, column=0, sticky=W + N + S) self.x_scrollbar.grid(row=1, column=0, sticky=E + W) self.y_scrollbar.grid(row=0, column=1, sticky=N + S) self.post_detail.grid(row=2, column=0, sticky=W + N + S, padx=(0, 10)) status_label = Label(parent_frame, text='F5 更新全部运单动态') add_post_group.grid(row=0, column=0) show_posts_group.grid(row=1, column=0) status_label.grid(row=2, column=0) self.get_history() # 获取历史记录 def get_history(self): try: with open('history.json', 'r', encoding='utf-8') as f: self.all_posts = json.loads(f.read()) for post_id in self.all_posts: self.posts.insert('', 0, post_id, text=post_id, values=(self.all_posts[post_id]['note'], self.all_posts[post_id]['company_name'], self.state[self.all_posts[post_id]['state']], self.all_posts[post_id]['last_update'])) except ValueError: with open('history.json', 'w', encoding='utf-8') as f: json.dump(self.all_posts, f) print('No history record found') # 保存运单记录 def save_history(self): with open('history.json', 'w', encoding='utf-8') as f: json.dump(self.all_posts, f) # 新增运单 def handle_add_post(self, event=None): if self.post_id_var.get() == '': return if self.post_company_name_var.get(): company_code = self.company_codes[self.post_company_name_var.get()] else: try: with request.urlopen(self.auto_company_url + self.post_id_var.get()) as response: company_code = json.loads(response.read().decode())['auto'][0]['comCode'] except IndexError: return post = { 'post_id': self.post_id_var.get(), 'company_code': company_code, 'company_name': self.company_names[company_code], 'note': self.post_note_var.get()} self.all_posts[post['post_id']] = post try: self.posts.index(post['post_id']) except tkinter.TclError: self.posts.insert('', 0, self.post_id_var.get(), text='%s' % self.post_id_var.get()) handle_add_post = threading.Thread(target=self.handle_add_post_thread, args=(post,)) handle_add_post.start() self.clear_input() def handle_add_post_thread(self, post): self.update_post_detail_thread(post) self.posts.selection_set(post['post_id']) self.save_history() # 清空输入框 def clear_input(self, event=None): self.post_id_var.set('') self.post_note_var.set('') self.post_company_name_var.set('') self.post_id_field.focus_set() # 移除运单 def remove_post(self, event=None): self.all_posts.pop(self.posts.selection()[0]) self.posts.delete(self.posts.selection()[0]) self.post_detail.config(state=tkinter.NORMAL) self.post_detail.delete('1.0', tkinter.END) self.post_detail.config(state=tkinter.DISABLED) self.save_history() self.clear_input() # 更新全部运单动态 def update_all_posts(self, event=None): update_all_posts = threading.Thread(target=self.update_all_posts_thread) update_all_posts.start() def update_all_posts_thread(self): pool = ThreadPool(4) posts = list(self.all_posts.values()) pool.map(self.update_post_detail, posts) pool.close() pool.join() self.save_history() # 更新单个运单状态 def update_post_detail(self, post=None): update_post_detail = threading.Thread(target=self.update_post_detail_thread) update_post_detail.start() def update_post_detail_thread(self, post=None): if not post: post = self.all_posts[self.posts.selection()[0]] with request.urlopen(self.query_url + 'type=' + post['company_code'] + '&postid=' + post['post_id'])\ as response: obj = json.loads(response.read().decode()) self.all_posts[post['post_id']]['status'] = obj['status'] if obj['status'] == '200': self.all_posts[post['post_id']]['data'] = obj['data'] self.all_posts[post['post_id']]['state'] = obj['state'] self.all_posts[post['post_id']]['last_update'] = obj['data'][0]['time'] else: self.all_posts[post['post_id']]['data'] = [{'time': '快递公司参数异常', 'context': '单号不存在或者已经过期'}] self.all_posts[post['post_id']]['state'] = '-1' self.all_posts[post['post_id']]['last_update'] = '' self.posts.item(post['post_id'], values=(post['note'], post['company_name'], self.state[post['state']], post['last_update'])) # 显示运单详情 def show_post_detail(self, event=None): selected_post = self.all_posts[self.posts.selection()[0]] self.post_id_var.set(selected_post['post_id']) self.post_note_var.set(selected_post['note']) self.post_company_name_var.set(selected_post['company_name']) self.post_detail.config(state=tkinter.NORMAL) # 允许编辑消息记录文本框 self.post_detail.delete('1.0', tkinter.END) for x in selected_post['data']: self.post_detail.insert('end', x['time'] + '\t' + x['context'] + '\n') self.post_detail.config(state=tkinter.DISABLED) # 禁止编辑消息记录文本框
class SshPanel(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.scrolltext = ScrolledText(self, width = 120, font = ("", 14, "normal"), height = 30) self.scrolltext.config(state = "disable") f = Frame(self) self.entry = Entry(f, width = 75, font = ("", 15, "normal")) # self.entry.grab_set() self.entry.focus_set() self.entry.grid(row = 0, column = 0) self.entry.bind("<Return>", lambda event, frame = self: frame._runCommand()) self.button1 = Button(f, text = "sumbmit", font = ("", 15, "normal"), command = lambda frame = self: frame._runCommand()) self.button1.grid(row = 0, column = 1, padx = 4, pady = 2) self.button2 = Button(f, text = "clear", font = ("", 15, "normal"), command = lambda frame = self: frame._deleteText()) self.button2.grid(row = 0, column = 2, padx = 4, pady = 2) f.grid(row = 1, column = 0) self.scrolltext.grid(row = 0, column = 0) with shelve.open("userconfigdb") as db: keys = tuple(db.keys()) if not keys: configButtonCmd() with shelve.open("userconfigdb") as db: self.sshIP = db[tuple(db.keys())[0]].hostaddress self._configButtonCmd() def _deleteText(self): self.scrolltext.config(state = "normal") self.scrolltext.delete("1.0", END) self.scrolltext.config(state = "disable") def _fetch(self, root, vars): attrs = [] for var in vars: t = var.get() if not t: return attrs.append(t) self.username = attrs[0] self.passwd = attrs[1] root.destroy() def _configButtonCmd(self): popwin = PopupWindow("User Config") popwin.grab_set() popwin.focus() form = Frame(popwin) left = Frame(form) right = Frame(form) bottom = Frame(popwin) form.pack(fill = X) left.pack(side = LEFT) right.pack(side = RIGHT, expand = YES, fill = X) # bottom.pack(side = LEFT) fields = ("username", "password") variables = [] for field in fields: lab = Label(left, width = 10, text = field) ent = Entry(right) lab.pack(side = TOP) ent.pack(side = TOP, fill = X) var = StringVar() ent.config(textvariable = var) variables.append(var) Button(popwin, text = "Ok", font = ("", 15, "normal"), command = (lambda vars = variables, root = popwin: self._fetch(root, vars))).pack() def _runCommand(self): command = self.entry.get() self.entry.delete(0, END) self.scrolltext.config(state = "normal") if command != "": ssh = paramiko.SSHClient() try: ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # print(self.username, self.passwd) ssh.connect(self.sshIP, 22, self.username, self.passwd, timeout = 10) stdin,stdout,stderr = ssh.exec_command(command) out = stdout.readlines() err = stderr.readlines() for r in out: self.scrolltext.insert(END, " " + r) for r in err: self.scrolltext.insert(END, " " + r) except: pass finally: ssh.close() self.scrolltext.insert(END, "---------------------------------\n") self.scrolltext.config(state = "disable") self.scrolltext.see("end")
class Application(tk.Frame): def __init__(self, master=None): super().__init__(master) self.master = master self.pack(fill="both", expand=1) self.filenames = list() self.create_widgets() def create_widgets(self): bfont = Font(family="Helvetica", size=10) self.flist = ScrolledText(self, height=12, width=80) self.flist["font"] = bfont self.flist.pack(side="left", fill="both", expand=1) self.flist.insert(tk.END, "PDF Paths Listed Here:\n\n") self.flist.config(state="disabled") self.right = tk.Frame(self) self.right.pack(side="right", padx=20) self.browse = tk.Button(master=self.right) self.browse["text"] = "Add a PDF" self.browse["command"] = self.get_file self.browse["font"] = bfont self.browse.configure(bg="light gray") self.browse.pack(pady=20, ipadx=5, ipady=5) self.merge = tk.Button(master=self.right) self.merge["text"] = "Merge" self.merge["command"] = self.merge_files self.merge["font"] = bfont self.merge.configure(bg="light gray") self.merge.pack(side="bottom", pady=35, ipadx=18, ipady=10) self.clear = tk.Button(master=self.right) self.clear["text"] = "Clear List" self.clear["command"] = self.clear_list self.clear["font"] = bfont self.clear.configure(bg="light gray") self.clear.pack(side="bottom", ipadx=5, ipady=5) def say_hi(self): print("hi there, everyone!") def get_file(self): filename = askopenfilename(title="Select PDFs", filetypes=(("PDF files", "*.pdf"), ("All Files", "*.*"))) if filename != "": self.flist.config(state="normal") self.flist.insert( tk.END, str(self.filenames.__len__() + 1) + ". " + filename + "\n") self.filenames.append(filename) self.flist.config(state="disabled") def merge_files(self): if len(self.filenames) == 0: messagebox.showerror(title="Error", message="Plese select at least one file.") else: filename = asksaveasfilename(filetypes=(("PDF files", "*.pdf"), ("All Files", "*.*")), defaultextension=".pdf") if filename != "": merger(filename, self.filenames) self.clear_list() self.flist.config(state="normal") self.flist.insert(1.0, "Merge saved to: " + filename + "\n") self.flist.config(state="disabled") def clear_list(self): self.flist.config(state="normal") del self.filenames[:] self.flist.delete(1.0, tk.END) self.flist.insert(tk.END, "PDF Paths Listed Here:\n\n") self.flist.config(state="disabled")
class App(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self.initUI() self.bmm = BMMSegment(4) self.mp = MaxProbabilitySegment() self.tagger = HMM_Viterbi_POS_TAGGER() self.parser = TopDownParser() self.cykParser = CYKParser() def initUI(self): self.parent.title("双向最大匹配分词") self.pack(fill=BOTH, expand=1) self.columnconfigure(0, weight=3) self.columnconfigure(1, weight=3) self.columnconfigure(2, pad=7) self.rowconfigure(1, weight=3) self.rowconfigure(5, weight=3) self.menubar = Menu(self.parent) self.fileMenu = Menu(self.menubar, tearoff=0) self.fileMenu.add_command(label="读入规则文件", command=self.onLoadRules_CYK) self.fileMenu.add_separator() self.fileMenu.add_command(label="退出", command=self.parent.quit) self.menubar.add_cascade(label="文件", menu=self.fileMenu) self.parent.config(menu=self.menubar) self.label1 = Label(self, text="请输入PCFG语法规则或加载规则文件(如:S -> NP VP 0.1)") self.label1.grid(sticky=W, pady=4, padx=5) self.inputText = ScrolledText(self) self.inputText.grid(row=1, column=0, columnspan=2, rowspan=3, padx=5, sticky=E+W+N) self.inputText.tag_config('highlight', background='yellow') self.label2 = Label(self, text='请输入文本:') self.label2.grid(row=4, column=0, sticky=W, pady=4, padx=5) self.outputText = ScrolledText(self) self.outputText.grid(row=5, column=0, columnspan=2, rowspan=3, padx=5, sticky=E+S+W) self.rightFrame = Frame(self) self.rightFrame.grid(row=1, column=3, rowspan=7) self.bmmBtn = Button(self.rightFrame, text="双向最大匹配", command=self.onBMM) self.bmmBtn.pack(side="top", expand=True, pady=8) self.mpBtn = Button(self.rightFrame, text="最大概率分词", command=self.onMP) self.mpBtn.pack(side="top", expand=True, pady=8) self.hmmBtn = Button(self.rightFrame, text='HMM词性标注', command=self.onHMM) self.hmmBtn.pack(side="top", expand=True, pady=8) self.parseBtn = Button(self.rightFrame, text='语法分析', command=self.onTopdownParse) self.parseBtn.pack(side="top", expand=True, pady=8) self.cykBtn = Button(self.rightFrame, text='PCFG语法分析', command=self.onCYK) self.cykBtn.pack(side="top", expand=True, pady=8) self.reBtn = Button(self.rightFrame, text='RegEx提取信息', command=self.onRE) self.reBtn.pack(side="top", expand=True, pady=8) # HINT: Place additional button here self.quitBtn = Button(self.rightFrame, text="退出", command=self.onQuit) self.quitBtn.pack(side="top", expand=True, pady=8) def onQuit(self): self.quit() ############################## BMM Segmentation ######################################### def onBMM(self): self.outputText.delete('1.0', END) inStr = self.inputText.get('1.0', END).strip() start = time.clock() result = self.bmm.BMM(inStr, self.inputText) self.outputText.insert(INSERT, result) elapsed = time.clock() - start if result != '': self.label2['text'] = '分词结果 耗时: ' + '{0:.1f} ms'.format(elapsed*1000) ######################### Maximum Probability Segmentation ############################### def onMP(self): self.outputText.delete('1.0', END) inStr = self.inputText.get('1.0', END).strip() start = time.clock() result = self.mp.MaxProbability(inStr) self.outputText.insert(INSERT, result) elapsed = time.clock() - start if result != '': self.label2['text'] = '分词结果 耗时: ' + '{0:.1f} ms'.format(elapsed*1000) ############################## HMM Pos-tagging ########################################## def onHMM(self): self.outputText.delete('1.0', END) inStr = self.inputText.get('1.0', END).strip() if inStr == '': return start = time.clock() segmented = self.mp.MaxProbability(inStr) obs = [w.strip('/') for w in segmented.split()] result = self.tagger.Viterbi(obs) elapsed = time.clock() - start self.outputText.insert(INSERT, result) if result != '': self.label2['text'] = '词性标注结果 耗时: ' + '{0:.1f} ms'.format(elapsed*1000) ############################## Top-down parsing ######################################### def onTopdownParse(self): inStr = self.outputText.get('1.0', END).strip() if inStr == '': sentence = ['the', 'old', 'man', 'cried'] self.outputText.insert(INSERT, ' '.join(sentence)) else: sentence = inStr.strip().split() start = time.clock() succeed = self.parser.parse(sentence) elapsed = time.clock() - start if succeed: self.label2['text'] = '语法分析完成 结果:成功 耗时:' + '{0:.1f} ms'.format(elapsed*1000) newWindow = Toplevel(self) newWindow.title('自顶向下语法分析') self.textbox = Entry(newWindow) self.textbox.pack(fill=X, expand=1) self.tree = Treeview(newWindow) self.tree.heading('#0', text='语法树', anchor='w') self.tree.pack(fill=BOTH, expand=1) parseString = self.parser.printParseTree() self.textbox.insert(INSERT, parseString) self.buildParseTree_TopDown('', 'S', self.parser.rules, self.parser.choices) else: self.label2['text'] = '语法分析完成 结果:失败 耗时:' + '{0:.1f} ms'.format(elapsed*1000) def onLoadRules_TopDown(self): fname = askopenfilename(initialdir='./data', initialfile='rules.txt') if fname != '': self.inputText.delete('1.0', END) with open(fname) as f: self.inputText.insert(INSERT, f.read()) self.parser.loadRules(fname) def buildParseTree_TopDown(self, parent, symbol, rules, choices): if choices[symbol] == -1: newNode = self.tree.insert(parent, 'end', text=symbol, open=True) self.tree.insert(newNode, 'end', text=' | '.join(rules[symbol][0])) else: c = choices[symbol] newParent = self.tree.insert(parent, 'end', text=symbol, open=True) for symbl in rules[symbol][c]: self.buildParseTree_TopDown(newParent, symbl, rules, choices) ############################## CYK-PCFG parsing ######################################### def onLoadRules_CYK(self): fname = askopenfilename(initialdir='./data', initialfile='rules_pcfg.txt') if fname != '': self.inputText.delete('1.0', END) with open(fname) as f: self.inputText.insert(INSERT, f.read()) self.parser.loadRules(fname) def buildParseTree_CYK(self, parent, beg, end, symbol_id): backPt = self.cykParser.BP[beg][end][symbol_id] symbol = self.cykParser.id2symb[symbol_id] if backPt.s == -1: newNode = self.tree.insert(parent, 'end', text=symbol, open=True) self.tree.insert(newNode, 'end', text=self.cykParser.words[beg-1], open=True) else: newParent = self.tree.insert(parent, 'end', text=symbol, open=True) self.buildParseTree_CYK(newParent, beg, backPt.s, backPt.Y) self.buildParseTree_CYK(newParent, backPt.s+1, end, backPt.Z) def onCYK(self): inStr = self.outputText.get('1.0', END).strip() if inStr == '': sentence = 'fish people fish tanks' self.outputText.insert(INSERT, sentence) else: sentence = inStr start = time.clock() parseString, prob = self.cykParser.parse(sentence) elapsed = time.clock() - start self.label2['text'] = 'PCFG语法分析完成 结果:成功 耗时:' + '{0:.1f} ms'.format(elapsed*1000) newWindow = Toplevel(self) newWindow.title('PCFG语法分析') self.textbox = Entry(newWindow) self.textbox.pack(fill=X, expand=1) self.tree = Treeview(newWindow) self.tree.heading('#0', text='语法树 (概率:{0:.8f})'.format(prob), anchor='w') self.tree.pack(fill=BOTH, expand=1) self.textbox.insert(INSERT, parseString) self.buildParseTree_CYK('', 1, len(self.cykParser.words), self.cykParser.symb2id['S']) def onRE(self): window = Toplevel(self) window.title('正则表达式信息提取') label = Label(window) label.pack() result = ScrolledText(window) result.pack(fill=BOTH, expand=1) htmlFile = 'data/凤凰网.html' start = time.clock() titles = regex.fetchTitles(htmlFile) links = regex.fetchLinks(htmlFile) elapsed = time.clock() - start label['text'] = '耗时: {0:.1f} ms'.format(elapsed*1000) result.insert(INSERT, 'Titles:\n') result.insert(INSERT, '\n'.join(titles)) result.insert(INSERT, '\n\nLinks:\n') result.insert(INSERT, '\n'.join(links))
class Editor(Tk): def __init__(self, fname, *args, **kwargs): # This is a tangled mess. I am sorry. Tk.__init__(self, *args, **kwargs) for x in range(1): Grid.columnconfigure(self, x, weight=1) Grid.rowconfigure(self, x, weight=1) self.fname = fname self.opened = None self.tree = ttk.Treeview(self) self.ysb = ttk.Scrollbar(self, orient='vertical', command=self.tree.yview) self.tree.configure(yscroll=self.ysb.set) self.tree.heading('#0', text='Path', anchor='w') self.data = classes.Folder() self.data.load(open(self.fname).read()) self.iidmap = {} self.root_node = self.tree.insert('', 'end', text='/', open=True) self.updatetree() self.st = ScrolledText() self.st.grid(row=1, column=1, sticky=N+E+S+W) self.meta = Frame() self.namel = Label(self.meta) self.namee = Entry(self.meta) self.namel.grid(row=0, column=0) self.namee.grid(row=0, column=1) self.tree.grid(rowspan=2, row=0, column=0, sticky=N+S+E+W) self.meta.grid(row=2, column=1) self.bind('<Control-s>', self.save) self.mb = Menu() self.fm = Menu() self.fm.add_command(label='Save', accelerator='Ctrl+S', command=self.save) self.mb.add_cascade(menu=self.fm, label='Savefile') self.dm = Menu() self.dm.add_command(label='New file', command=self.newfile) self.mb.add_cascade(menu=self.dm, label='Files') self.config(menu=self.mb) def loadf(self, event=None): self.st.delete(1.0, END) self.namee.delete(0, END) if self.data[self.opened]: self.st.insert(1.0, self.data[self.opened].content) self.namee.insert(1, self.data[self.opened].name) def updatetree(self): self.tree.delete(self.root_node) self.root_node = self.tree.insert('', 'end', text='/', open=True) for f in self.data: item = self.tree.insert(self.root_node, 'end', text=f, open=False) self.iidmap[item] = f self.tree.bind('<Double-1>', self.openitem) def openitem(self, event=None): item = self.tree.identify('item', event.x, event.y) if item: self.opened = self.iidmap[item] self.loadf() def save(self, event=None): self.update_fs() open(self.fname, 'w').write(json.dumps(self.data.dump())) def update_fs(self, event=None): self.data[self.opened].write(self.st.get(1.0, END)) self.data[self.opened].rename(self.namee.get()) def newfile(self, event=None): name = input('Filename: ') self.opened = name self.data.create_file(name) self.updatetree()
class App(Frame): def __init__(self, parent, *args, **kwargs): Frame.__init__(self, parent, *args, **kwargs) self.root = parent self.init_gui() def init_gui(self): self.root.title('HR Analytics Tool') self.grid(column=0, row=0) ttk.Label(self, text='naneB Tool').grid(column=0, row=0, columnspan=10) ############ self.plot_frame = ttk.LabelFrame(self, text='Plot', height=100) self.plot_frame.grid(column=0, row=1, columnspan=4, sticky='nesw') self.plot_frame.grid_configure(padx=5, pady=5) self.draw_button = ttk.Button(self.plot_frame, text='Draw', command=lambda: self.plotDrawOk()) self.draw_button.grid(column=0, row=4, columnspan=4) ttk.Label(self.plot_frame, text='X').grid(column=0, row=1) ttk.Label(self.plot_frame, text='Y').grid(column=2, row=1) ttk.Label(self.plot_frame, text='Left').grid(column=3, row=1) self.combobox = ttk.Combobox(self.plot_frame) self.combobox.grid(column=0, row=2) self.combobox['values'] = columns_names self.combobox.set('satisfaction_level') self.combobox2 = ttk.Combobox(self.plot_frame) self.combobox2.grid(column=2, row=2) self.combobox2['values'] = columns_names self.combobox2.set('satisfaction_level') self.comboboxLeft = ttk.Combobox(self.plot_frame) self.comboboxLeft.grid(column=3, row=2) self.comboboxLeft['values'] = [0, 1] self.comboboxLeft.set(0) self.combobox3 = ttk.Combobox(self.plot_frame) self.combobox3.bind("<<ComboboxSelected>>", self.comboUpdate) self.combobox3.grid(row=3, column=0, columnspan=4) self.combobox3['values'] = plotNames self.combobox3.set('plot') self.checkCmd = IntVar() self.hueCheck = Checkbutton(self.plot_frame, variable=self.checkCmd, onvalue=1, offvalue=0, text="Hue=left") self.hueCheck.grid(column=3, row=4) self.hueCheck.configure(state="disabled") ############ self.heatmap_frame = ttk.LabelFrame(self, text='HeatMap', height=100) self.heatmap_frame.grid(column=0, row=2, columnspan=4, sticky='nesw') self.heatmap_frame.grid_configure(padx=5, pady=5) self.heatmap_button = ttk.Button(self.heatmap_frame, text='HeatMap', command=lambda: self.heatMapOk()) self.heatmap_button.place(relx=0.5, rely=0.5, anchor=CENTER) ########### self.cube_frame = ttk.LabelFrame(self, text='Cube', height=100) self.cube_frame.grid(column=0, row=3, columnspan=4, sticky='nesw') self.cube_frame.grid_configure(padx=5, pady=5) self.cube_button = ttk.Button(self.cube_frame, text='Cube', command=lambda: self.cubeOk()) self.cube_button.grid(column=1, row=4, columnspan=2, sticky='nesw') self.comboboxCube = ttk.Combobox(self.cube_frame) self.comboboxCube.grid(column=0, row=2) self.comboboxCube['values'] = columns_names self.comboboxCube.set('satisfaction_level') self.comboboxCube2 = ttk.Combobox(self.cube_frame) self.comboboxCube2.grid(column=2, row=2) self.comboboxCube2['values'] = columns_names self.comboboxCube2.set('satisfaction_level') self.comboboxCube3 = ttk.Combobox(self.cube_frame) self.comboboxCube3.grid(row=2, column=3, columnspan=4) self.comboboxCube3['values'] = columns_names self.comboboxCube3.set('satisfaction_level') ########### self.histogram_frame = ttk.LabelFrame(self, text='Histogram', height=100) self.histogram_frame.grid(column=0, row=4, columnspan=4, sticky='nesw') self.histogram_frame.grid_configure(padx=5, pady=5) self.comboboxHistogram = ttk.Combobox(self.histogram_frame) self.comboboxHistogram.grid(column=0, row=0) self.comboboxHistogram['values'] = columns_names self.comboboxHistogram.set('satisfaction_level') ttk.Label(self.histogram_frame, text='Bin').grid(column=1, row=0) self.textBoxHistogram = Text(self.histogram_frame, height=1, width=20) self.textBoxHistogram.grid(column=2, row=0) self.histogram_button = ttk.Button(self.histogram_frame, text='Histogram', command=lambda: self.histogramOk()) self.histogram_button.grid(column=1, row=1, columnspan=2, sticky='nesw') ############ self.kmeans_frame = ttk.LabelFrame(self, text='KMeans', height=100) self.kmeans_frame.grid(column=0, row=5, columnspan=4, sticky='nesw') self.kmeans_frame.grid_configure(padx=5, pady=5) self.comboboxKmeans = ttk.Combobox(self.kmeans_frame) self.comboboxKmeans.grid(column=0, row=0) self.comboboxKmeans['values'] = columns_names self.comboboxKmeans.set('satisfaction_level') self.comboboxKmeans2 = ttk.Combobox(self.kmeans_frame) self.comboboxKmeans2.grid(column=1, row=0) self.comboboxKmeans2['values'] = columns_names self.comboboxKmeans2.set('satisfaction_level') ttk.Label(self.kmeans_frame, text='n').grid(column=3, row=0) self.textBox = Text(self.kmeans_frame, height=1, width=10) self.textBox.grid(column=4, row=0) self.kmeans_button = ttk.Button(self.kmeans_frame, text='KMeans', command=lambda: self.kmenasOk()) self.kmeans_button.grid(column=1, row=4, columnspan=2, sticky='nesw') ############# self.cluster_frame = ttk.LabelFrame(self, text='Classification', height=100) self.cluster_frame.grid(column=4, row=1, columnspan=4, sticky='nesw') self.cluster_button = ttk.Button(self.cluster_frame, text='Classification', command=lambda: self.classification()) self.cluster_button.grid(column=0, row=0, sticky='nesw') ############# self.fiter_frame = ttk.LabelFrame(self, text='Filter Data', height=100) self.fiter_frame.grid(column=4, row=2, columnspan=4, sticky='nesw') self.filter_button = ttk.Button(self.fiter_frame, text='Filter', command=lambda: self.filterData()) self.filter_button.grid(column=0, row=0, sticky='nesw') ############# self.orange_frame = ttk.LabelFrame(self, text='Run Orange Tool', height=100) self.orange_frame.grid(column=4, row=3, columnspan=4, sticky='nesw') self.orange_button = ttk.Button(self.orange_frame, text='Run', command=lambda: self.runOrange()) self.orange_button.grid(column=0, row=0, sticky='nesw') ############# self.cross_frame = ttk.LabelFrame(self.cluster_frame, text='Cross Validation', height=100) self.cross_frame.grid_configure(padx=5, pady=5) self.cross_frame.grid(column=0, row=6, columnspan=4, sticky='nesw') self.cross_button = ttk.Button(self.cross_frame, text='Run', command=lambda: self.crossRun()) self.cross_button.grid_configure(padx=5, pady=5) self.cross_button.grid(column=0, row=0, sticky='nesw') ############# self.factor_analysis = ttk.LabelFrame(self, text='Factor Analysis', height=100) self.factor_analysis.grid_configure(padx=5, pady=5) self.factor_analysis.grid(column=0, row=6, columnspan=4, sticky='nesw') ttk.Label(self.factor_analysis, text='Component').grid(column=0, row=0) self.textBoxComponent = Text(self.factor_analysis, height=1, width=10) self.textBoxComponent.grid(column=1, row=0) ttk.Label(self.factor_analysis, text='Test Size').grid(column=0, row=1) self.textBoxTestSize = Text(self.factor_analysis, height=1, width=10) self.textBoxTestSize.grid(column=1, row=1) self.factor_button = ttk.Button(self.factor_analysis, text='Run', command=lambda: self.factorAnalysis()) self.factor_button.grid_configure(padx=5, pady=5) self.factor_button.grid(column=0, row=2, sticky='nesw') ############# for child in self.winfo_children(): child.grid_configure(padx=5, pady=5) for child2 in child.winfo_children(): child2.grid_configure(padx=5, pady=5) def plotDrawOk(self): self.selection = self.combobox.get() self.selection2 = self.combobox2.get() self.selection3 = self.combobox3.get() self.selectionLeft = self.comboboxLeft.get() window = Toplevel(self.plot_frame) if self.selection3 == 'plot': x = df[self.selection] y = df[self.selection2] self.fig, self.ax = plt.subplots(figsize=(8, 8)) self.canvas = FigureCanvasTkAgg(self.fig, window) self.canvas.get_tk_widget().pack(side='bottom', fill='both', expand=1) plt.plot(x[df.left == int(self.selectionLeft)], y[df.left == int(self.selectionLeft)], 'o', alpha=0.1) plt.ylabel(self.selection2) plt.title('Employees who left') plt.xlabel(self.selection) self.canvas.draw() if self.selection3 == 'countplot': self.fig, self.ax = plt.subplots(figsize=(15, 5)) self.canvas = FigureCanvasTkAgg(self.fig, window) self.canvas.get_tk_widget().pack(side='bottom', fill='both', expand=1) if self.checkCmd.get() == 1: sns.countplot(y=self.selection, hue='left', data=df).set_title('Employee ' + self.selection + ' Turnover Distribution') if self.checkCmd.get() == 0: sns.countplot(y=self.selection, data=df).set_title('Employee ' + self.selection + ' Turnover Distribution') if self.selection3 == 'barplot': self.fig, self.ax = plt.subplots(figsize=(15, 5)) self.canvas = FigureCanvasTkAgg(self.fig, window) self.canvas.get_tk_widget().pack(side='bottom', fill='both', expand=1) if self.checkCmd.get() == 1: sns.barplot(df[self.selection], df[self.selection2], hue=df.left) if self.checkCmd.get() == 0: sns.barplot(df[self.selection], df[self.selection2]) if self.selection3 == 'barplotPercentage': self.fig, self.ax = plt.subplots(figsize=(15, 5)) self.canvas = FigureCanvasTkAgg(self.fig, window) self.canvas.get_tk_widget().pack(side='bottom', fill='both', expand=1) if self.checkCmd.get() == 1: ax = sns.barplot(x=self.selection, y=self.selection, hue="left", data=df, estimator=lambda x: len(x) / len(df) * 100) if self.checkCmd.get() == 0: ax = sns.barplot(x=self.selection, y=self.selection, data=df, estimator=lambda x: len(x) / len(df) * 100) ax.set(ylabel="Percent") if self.selection3 == 'kdeplot': self.fig, self.ax = plt.subplots(figsize=(15, 5)) self.canvas = FigureCanvasTkAgg(self.fig, window) self.canvas.get_tk_widget().pack(side='bottom', fill='both', expand=1) ax = sns.kdeplot(df.loc[(df['left'] == 0), self.selection], color='b', shade=True, label='no turnover') ax = sns.kdeplot(df.loc[(df['left'] == 1), self.selection], color='r', shade=True, label='turnover') plt.title('Employee ' + self.selection + ' Distribution - Turnover V.S. No Turnover') if self.selection3 == 'distplot': self.fig, self.ax = plt.subplots(figsize=(7, 7)) self.canvas = FigureCanvasTkAgg(self.fig, window) self.canvas.get_tk_widget().pack(side='bottom', fill='both', expand=1) plt.xlabel(self.selection, fontsize=12) plt.ylabel('distribution', fontsize=12) sns.distplot(df[self.selection], kde=True) if self.selection3 == 'stripplot': self.fig, self.ax = plt.subplots(figsize=(7, 7)) self.canvas = FigureCanvasTkAgg(self.fig, window) self.canvas.get_tk_widget().pack(side='bottom', fill='both', expand=1) sns.stripplot(df[self.selection], df[self.selection2]) if self.selection3 == 'pointplot': self.fig, self.ax = plt.subplots(figsize=(7, 7)) self.canvas = FigureCanvasTkAgg(self.fig, window) self.canvas.get_tk_widget().pack(side='bottom', fill='both', expand=1) sns.pointplot(df[self.selection], df[self.selection2]) if self.selection3 == 'lvplot': self.fig, self.ax = plt.subplots(figsize=(7, 7)) self.canvas = FigureCanvasTkAgg(self.fig, window) self.canvas.get_tk_widget().pack(side='bottom', fill='both', expand=1) sns.lvplot(df[self.selection], df[self.selection2]) if self.selection3 == 'factorplot': self.fig, self.ax = plt.subplots(figsize=(7, 7)) self.canvas = FigureCanvasTkAgg(self.fig, window) self.canvas.get_tk_widget().pack(side='bottom', fill='both', expand=1) sns.factorplot(y=self.selection2, x=self.selection, data=df, kind="box", ax=self.ax) plt.tight_layout() plt.gcf().clear() def comboUpdate(self, event=None): if event.widget.get() == 'plot': self.combobox.configure(state="enabled") self.combobox2.configure(state="enabled") self.comboboxLeft.configure(state="enabled") self.hueCheck.configure(state="disabled") if event.widget.get() == 'barplot': self.combobox.configure(state="enabled") self.combobox2.configure(state="enabled") self.comboboxLeft.configure(state="disabled") self.hueCheck.configure(state="active") if event.widget.get() == 'barplotPercentage': self.combobox.configure(state="enabled") self.combobox2.configure(state="disabled") self.comboboxLeft.configure(state="disabled") self.hueCheck.configure(state="active") if event.widget.get() == 'countplot': self.combobox.configure(state="enabled") self.combobox2.configure(state="disabled") self.comboboxLeft.configure(state="disabled") self.hueCheck.configure(state="active") if event.widget.get() == 'kdeplot': self.combobox.configure(state="enabled") self.combobox2.configure(state="disabled") self.comboboxLeft.configure(state="disabled") self.hueCheck.configure(state="disabled") if event.widget.get() == 'distplot': self.combobox.configure(state="enabled") self.combobox2.configure(state="disabled") self.comboboxLeft.configure(state="disabled") self.hueCheck.configure(state="disabled") if event.widget.get() == 'stripplot': self.combobox.configure(state="enabled") self.combobox2.configure(state="enabled") self.comboboxLeft.configure(state="disabled") self.hueCheck.configure(state="disabled") if event.widget.get() == 'pointplot': self.combobox.configure(state="enabled") self.combobox2.configure(state="enabled") self.comboboxLeft.configure(state="disabled") self.hueCheck.configure(state="disabled") if event.widget.get() == 'lvplot': self.combobox.configure(state="enabled") self.combobox2.configure(state="enabled") self.comboboxLeft.configure(state="disabled") self.hueCheck.configure(state="disabled") if event.widget.get() == 'factorplot': self.combobox.configure(state="enabled") self.combobox2.configure(state="enabled") self.comboboxLeft.configure(state="disabled") self.hueCheck.configure(state="disabled") def cubeOk(self): self.selection = self.comboboxCube.get() self.selection2 = self.comboboxCube2.get() self.selection3 = self.comboboxCube3.get() window = Toplevel(self.plot_frame) self.fig = plt.figure() self.ax = self.fig.add_subplot(111, projection='3d') self.canvas = FigureCanvasTkAgg(self.fig, window) self.canvas.get_tk_widget().pack(side='bottom', fill='both', expand=1) x = df[self.selection] y = df[self.selection2] z = df[self.selection3] c = df['left'] _ = self.ax.scatter(xs=x, ys=y, zs=z, c=c) _ = self.ax.set_xlabel(self.selection) _ = self.ax.set_ylabel(self.selection2) _ = self.ax.set_zlabel(self.selection3) _ = plt.title( 'Plot 1: Multivariate Visualization with Number of Projects by Color' ) def heatMapOk(self): window = Toplevel(self.plot_frame) self.fig, self.ax = plt.subplots(figsize=(7, 7)) self.canvas = FigureCanvasTkAgg(self.fig, window) self.canvas.get_tk_widget().pack(side='bottom', fill='both', expand=1) correlation = df.corr() sns.heatmap(correlation, vmax=1, square=True, annot=True, cmap='cubehelix') plt.title('Correlation between different fearures') def histogramOk(self): self.selection = self.comboboxHistogram.get() window = Toplevel(self.plot_frame) self.fig, self.ax = plt.subplots(figsize=(7, 7)) self.canvas = FigureCanvasTkAgg(self.fig, window) self.canvas.get_tk_widget().pack(side='bottom', fill='both', expand=1) self.ax.hist(df[self.selection], bins=int(self.textBoxHistogram.get("1.0", END))) self.ax.set_xlabel(self.selection) self.ax.set_ylabel("Count") def kmenasOk(self): self.selection = self.comboboxKmeans.get() self.selection2 = self.comboboxKmeans2.get() window = Toplevel(self.plot_frame) self.fig, self.ax = plt.subplots(figsize=(7, 7)) self.canvas = FigureCanvasTkAgg(self.fig, window) self.canvas.get_tk_widget().pack(side='bottom', fill='both', expand=1) data_left = df[df["left"] == 1] kmeans = KMeans(n_clusters=int(self.textBox.get("1.0", END)), random_state=2) kmeans.fit(data_left[[self.selection, self.selection2]]) kmeans_colors = [ 'red' if c == 0 else 'orange' if c == 2 else 'blue' for c in kmeans.labels_ ] plt.scatter(x=self.selection, y=self.selection2, data=data_left, alpha=0.25, color=kmeans_colors) plt.xlabel(self.selection) plt.ylabel(self.selection2) plt.scatter(x=kmeans.cluster_centers_[:, 0], y=kmeans.cluster_centers_[:, 1], color="black", marker="X", s=100) plt.title("Clustering of the employed who left by Kmeans") def classification(self): classificationModule.classificationWindow(self.root) def filterData(self): window = Toplevel(self) self.filter_frame = ttk.LabelFrame(window, text='Filter Data', height=100) self.filter_frame.grid(column=0, row=0, columnspan=4, sticky='nesw') self.filter_frame.grid_configure(padx=5, pady=5) self.comboboxFilter = ttk.Combobox(self.filter_frame) self.comboboxFilter.bind("<<ComboboxSelected>>", self.comboUpdateFilter) self.comboboxFilter.grid(column=0, row=0) self.comboboxFilter['values'] = columns_names self.comboboxFilter.set('satisfaction_level') self.comboboxFilter2 = ttk.Combobox(self.filter_frame) self.comboboxFilter2.grid(column=0, row=1) self.comboboxFilter2['values'] = ['<', '>', '=='] self.comboboxFilter2.set(self.comboboxFilter2['values'][1]) self.comboboxFilter3 = ttk.Combobox(self.filter_frame) self.comboboxFilter3.grid(column=0, row=2) self.comboboxFilter3['values'] = df['satisfaction_level'].unique( ).tolist() self.comboboxFilter3.set('0.5') self.filterList = set() self.add_button = ttk.Button(self.filter_frame, text='Add Filter', command=lambda: self.addFilter()) self.add_button.grid(column=1, row=1, columnspan=2, sticky='nesw') self.add_button = ttk.Button(self.filter_frame, text='Remove Filter', command=lambda: self.removeFilter()) self.add_button.grid(column=1, row=2, columnspan=2, sticky='nesw') self.data = Listbox(self.filter_frame, width=22, height=10) self.data.grid(row=0, column=5, rowspan=3) self.add_button = ttk.Button(self.filter_frame, text='Apply Filter', command=lambda: self.applyFilter()) self.add_button.grid(column=0, row=3, columnspan=7, sticky='nesw') ttk.Label(self.filter_frame, text='Head of Data').grid(column=0, row=4, sticky=W) self.filterResult = ScrolledText(self.filter_frame, height=15, width=70) self.filterResult.grid(column=0, row=4, sticky=W, columnspan=10, rowspan=5) self.filterResult.config(state=DISABLED) for child in window.winfo_children(): for child2 in child.winfo_children(): child2.grid_configure(padx=5, pady=5) def comboUpdateFilter(self, event=None): value = event.widget.get() self.comboboxFilter3.configure(values=df[value].unique().tolist()) array = df[value].unique().tolist() self.comboboxFilter3.set(array[0]) def addFilter(self): self.selection = self.comboboxFilter.get() self.selection2 = self.comboboxFilter2.get() self.selection3 = self.comboboxFilter3.get() self.data.insert( END, str(self.selection + ":" + self.selection2 + ":" + self.selection3)) self.filterList.add(self.selection + ":" + self.selection2 + ":" + self.selection3) def removeFilter(self): self.selectionIndex = self.data.curselection() self.filterList.remove(self.data.get(self.selectionIndex[0])) self.data.delete(self.selectionIndex) def applyFilter(self): global df df = constantdf if self.filterList: for filter in self.filterList: tempList = filter.split(":") if tempList[0] != "salary" and tempList[0] != "sales": if tempList[1] == "<": df = df[df[tempList[0]] > float(tempList[2])] if tempList[1] == ">": df = df[df[tempList[0]] < float(tempList[2])] if tempList[1] == "==": df = df[df[tempList[0]] != float(tempList[2])] else: if tempList[1] == "==": df = df[df[tempList[0]] != tempList[2]] self.filterResult.config(state=NORMAL) self.filterResult.delete(1.0, END) self.filterResult.insert(END, df) self.filterResult.config(state=DISABLED) def showHead(self): tempDf = df.head() self.filterResult.config(state=NORMAL) self.filterResult.delete(1.0, END) self.filterResult.insert(END, tempDf) self.filterResult.config(state=DISABLED) def runOrange(self): import os os.system("orange-canvas") def crossRun(self): window = Toplevel(self) ttk.Label(window, text='Result').grid(column=0, row=0, sticky=W) self.crossResult = ScrolledText(window, height=15, width=70) self.crossResult.grid(column=0, row=1, sticky=W, columnspan=10, rowspan=5) self.crossResult.config(state=DISABLED) from sklearn.linear_model import LogisticRegression from sklearn.ensemble import RandomForestClassifier from sklearn.neighbors import KNeighborsClassifier as knn from sklearn.naive_bayes import GaussianNB as GB from sklearn.svm import SVC from sklearn.model_selection import cross_validate from sklearn.decomposition import PCA from sklearn.preprocessing import StandardScaler df_drop = df.drop(labels=['sales', 'salary'], axis=1) left_col = df_drop['left'] df_drop.drop(labels=['left'], axis=1, inplace=True) df_drop.insert(0, 'left', left_col) df_drop.head() X = df_drop.iloc[:, 1:8].values y = df_drop.iloc[:, 0].values X_std = StandardScaler().fit_transform(X) sklearn_pca = PCA(n_components=6) X_pca = sklearn_pca.fit_transform(X_std) models = [ "RandomForestClassifier", "Gaussian Naive Bays", "KNN", "Logistic_Regression", "Support_Vector" ] Classification_models = [ RandomForestClassifier(n_estimators=100), GB(), knn(n_neighbors=7), LogisticRegression(), SVC() ] Model_Accuracy = [] scoring = { 'acc': 'accuracy', 'f1': 'f1', 'precision': 'precision', 'recall': 'recall', 'roc_auc': 'roc_auc' } for model, model_name in zip(Classification_models, models): print(model_name) scores = cross_validate(model, X_pca, y, scoring=scoring, cv=10, return_train_score=True) Model_Accuracy.append(scores) self.crossResult.config(state=NORMAL) self.crossResult.delete(1.0, END) for i, m in zip(Model_Accuracy, models): self.crossResult.insert(END, "\n" + m) self.crossResult.insert(END, "\n--------\n") for j in i: self.crossResult.insert( END, str(j) + ": " + str(i[j].mean()) + "\n") self.crossResult.config(state=DISABLED) def factorAnalysis(self): self.componentSize = int(self.textBoxComponent.get("1.0", END)) self.testSize = float(self.textBoxTestSize.get("1.0", END)) from sklearn.decomposition import FactorAnalysis from sklearn.metrics import accuracy_score from sklearn.linear_model import LogisticRegression from sklearn.model_selection import train_test_split window = Toplevel(self) ttk.Label(window, text='Result').grid(column=0, row=0, sticky=W) self.factorResult = ScrolledText(window, height=15, width=70) self.factorResult.grid(column=0, row=1, sticky=W, columnspan=10, rowspan=5) self.factorResult.config(state=DISABLED) df1 = df y = df1['left'].values df1 = df1.drop(['left', 'sales', 'salary'], axis=1) X = df1.values factor = FactorAnalysis(n_components=self.componentSize).fit(X) X_ = factor.fit_transform(X) Xtrain, Xtest, ytrain, ytest = train_test_split( X_, y, test_size=self.testSize) log_reg = LogisticRegression() log_reg.fit(Xtrain, ytrain) y_val_l = log_reg.predict(Xtest) accuracy_score(ytest, y_val_l) m = factor.components_ n = factor.noise_variance_ m1 = m**2 m2 = np.sum(m1, axis=1) self.factorResult.config(state=NORMAL) self.factorResult.delete(1.0, END) for i in range(0, self.componentSize): pvar = (100 * m2[i]) / np.sum(m2) self.factorResult.insert(END, "pvar" + str(i) + ": " + str(pvar)) self.factorResult.insert(END, "\n")
class Application(ttk.Frame): def __init__(self, master=None): # ttk.Frame is an old-style class on 2.7 ttk.Frame.__init__(self, master) self._init_ui() self.pack() self.build = ProcessMonitor((sys.executable, 'util/build_modpack.py')) self.build.on_event = self._handle_build_event self.master.protocol('WM_DELETE_WINDOW', self._handle_close) self.after(100, self._check_queues) def _init_ui(self): wrapper = ttk.Frame(self) frame_mods = self._init_mod_frame(wrapper) frame_output = self._init_output_frame(wrapper) frame_mods.pack(pady=3) frame_output.pack(fill='x', pady=3) wrapper.pack() def _init_mod_frame(self, master): frame = ttk.LabelFrame(master, text='Mod Configuration') left = ttk.Frame(frame) middle = ttk.Frame(frame) right = ttk.Frame(frame) ttk.Label(left, text='Mods available:').pack() self.list_avail = ttk.Treeview(left, height=10, selectmode='browse') self.list_avail.bind('<<TreeviewSelect>>', lambda e: self._update_buttons()) self.list_avail.pack() self.mods_avail = [] ttk.Label(right, text='Mods enabled:').pack() self.list_enabled = ttk.Treeview(right, height=10, selectmode='browse') self.list_enabled.bind('<<TreeviewSelect>>', lambda e: self._update_buttons()) self.list_enabled.pack() self.mods_enabled = [] self.btn_add = ttk.Button(middle, text='=>', command=self._add_mod) self.btn_remove = ttk.Button(middle, text='<=', command=self._remove_mod) self.btn_up = ttk.Button(middle, text='Up', command=self._move_up) self.btn_down = ttk.Button(middle, text='Down', command=self._move_down) btn_rescan = ttk.Button(middle, text='Rescan', command=self._update_lists) for b in (self.btn_add, self.btn_remove, self.btn_up, self.btn_down, btn_rescan): b.pack() self._update_lists() left.pack(side='left') middle.pack(side='left') right.pack(side='right') return frame def _init_output_frame(self, master): frame = ttk.LabelFrame(master, text='Build Output') ttk.Button(frame, text='Start Build', command=self._start_build).pack() self.text_output = ScrolledText(frame, height=10, width=60) self.text_output.pack(fill='x') return frame def _update_lists(self): mods = sorted(m for m in os.listdir('mods') if os.path.isdir(os.path.join('mods', m))) old = self.mods_avail new = mods i = 0 j = 0 while i < len(old) and j < len(new): a = old[i] b = new[j] if a == b: i += 1 j += 1 elif a < b: self.list_avail.delete(a) i += 1 else: # a > b # Everything before the current element matches in the treeview # and in the new mod list. So insert at index `j`. self.list_avail.insert('', j, b, text=b) j += 1 while i < len(old): self.list_avail.delete(old[i]) i += 1 while j < len(new): self.list_avail.insert('', 'end', new[j], text=new[j]) j += 1 self.mods_avail = mods new_set = set(mods) new_mods_enabled = [] for m in self.mods_enabled: if m in new_set: new_mods_enabled.append(m) else: self.list_enabled.delete(m) self.mods_enabled = new_mods_enabled self._update_buttons() def _update_buttons(self): sel_avail = get_selection(self.list_avail) sel_enabled = get_selection(self.list_enabled) add_ok = sel_avail is not None and sel_avail not in self.mods_enabled remove_ok = sel_enabled is not None idx = self.list_enabled.index(sel_enabled) if sel_enabled is not None else None up_ok = idx is not None and idx > 0 down_ok = idx is not None and idx < len(self.mods_enabled) - 1 enable(self.btn_add, add_ok) enable(self.btn_remove, remove_ok) enable(self.btn_up, up_ok) enable(self.btn_down, down_ok) def _add_mod(self): mod = get_selection(self.list_avail) self.list_enabled.insert('', 'end', mod, text=mod) self.mods_enabled.append(mod) self._update_buttons() def _remove_mod(self): mod = get_selection(self.list_enabled) idx = self.list_enabled.index(mod) self.list_enabled.delete(mod) self.mods_enabled[idx : idx + 1] = [] self._update_buttons() def _move_up(self): mod = get_selection(self.list_enabled) idx = self.list_enabled.index(mod) self.list_enabled.move(mod, '', idx - 1) self._update_buttons() def _move_down(self): mod = get_selection(self.list_enabled) idx = self.list_enabled.index(mod) self.list_enabled.move(mod, '', idx + 1) self._update_buttons() def _start_build(self): self.text_output.delete('1.0', tk.END) append_text(self.text_output, 'Building...\n') self.build.start((','.join(self.mods_enabled),)) def _check_queues(self): self.build.poll() self.after(100, self._check_queues) def _handle_build_event(self, kind, data): if kind == 'output': append_text(self.text_output, data.decode()) elif kind == 'result': if data == 0: append_text(self.text_output, '\n\nBuild finished in %s' % (os.path.join(os.getcwd(), 'dist') + os.sep)) elif kind == 'error': append_text(self.text_output, '\n\nError collecting build output: %s' % data) def _handle_close(self): self.quit()
class LabGUI(tk.Frame): def __init__(self, parent): tk.Frame.__init__(self, parent) self.parent = parent parent.geometry('1450x700+50+50') parent.title('approximation') self.init_input_filename() self.init_label_filename() self.init_x_leng() self.init_choose_polynomial() self.init_create_pads() self.init_polynomial_degrees() self.init_function_weight() self.init_y_coord() self.init_run_button() self.init_default_checkbutton() self.init_y_checkbutton() self.init_all_labels() self.init_output_label() self.init_graph_canvas() self.first_run = True def init_label(self, text, column, row, columnspan=1, rowspan=1, height=1): label = tk.Label(self.parent, text=text, height=height) label.grid(column=column, row=row, columnspan=columnspan, rowspan=rowspan) def init_variable_label(self, variable, column, row, columnspan=1, rowspan=1): label = tk.Label(self.parent, textvariable=variable) label.grid(column=column, row=row, columnspan=columnspan, rowspan=rowspan) def init_entry(self, variable, text, column, row, columnspan=1, rowspan=1, width=4): entry = tk.Entry(self.parent, text=text, textvariable=variable, width=width) entry.grid(column=column, row=row, columnspan=columnspan, rowspan=rowspan, sticky=tk.W) def init_label_with_entry(self, text, column, row, variable, columnspan=1, rowspan=1, entry_width=4): self.init_label(text=text, column=column, row=row) self.init_entry(text=text, column=column + 1, row=row, variable=variable, width=entry_width) def init_radiobutton(self, text, column, row, variable, value, columnspan=1): rdbutton = tk.Radiobutton(self.parent, text=text, value=value, variable=variable) rdbutton.grid(row=row, column=column, columnspan=columnspan, sticky=tk.W) def init_pads(self, row=1, column=1, width=0, height=0): label = tk.Frame(self.parent, width=width, height=height) label.grid(column=column, row=row) def init_button(self, text, column, row, width, height, columnspan=1, rowspan=1, command=None): butt = tk.Button(self.parent, text=text, width=width, height=height, command=command) butt.grid(column=column, row=row, columnspan=columnspan, rowspan=rowspan) def init_checkbutton(self, text, column, row, columnspan=1, rowspan=1, variable=None): butt = tk.Checkbutton(self.parent, text=text, variable=variable) butt.grid(column=column, row=row, columnspan=columnspan, rowspan=rowspan) #Buttons def init_run_button(self): self.init_button(text='Розрахувати', width=10, height=1, column=11, row=6, rowspan=2, columnspan=2, command=self.run) def init_default_checkbutton(self): self.default_data = tk.BooleanVar(value=True) self.init_checkbutton(text='Стандартні значення', column=1, row=4, variable=self.default_data) def init_y_checkbutton(self): self.normalize_y = tk.BooleanVar(value=True) self.init_checkbutton(text='Нормалізувати y на графіку', column=11, row=5, variable=self.normalize_y) # Labels def init_create_pads(self): self.init_pads(column=2, width=35) self.init_pads(column=5, width=35) self.init_pads(column=7, width=20) self.init_pads(column=10, width=35) self.init_pads(row=7, height=30) self.init_pads(row=9, height=8) def init_all_labels(self): self.init_label(text='Ваги цільових функцій', column=11, row=0, columnspan=1, rowspan=2) self.init_label(text='Вибірка', column=0, row=0, columnspan=2, rowspan=2) self.init_label(text='Вектори', column=3, row=0, columnspan=2, rowspan=2) self.init_label(text='Поліноми', column=6, row=0, columnspan=4, height=2) self.init_label(text='Вид', column=6, row=1) self.init_label(text='Степінь', column=8, row=1) self.init_label(text='Результат', column=0, row=8, columnspan=6) self.init_label(text='Графік', column=7, row=8, columnspan=6) self.err_output = tk.StringVar(value='Значення похибки') self.init_variable_label(variable=self.err_output, column=8, row=11, columnspan=6) def init_output_label(self): self.scrolled_text = ScrolledText(master=self.parent, wrap='word', width=80, height=24, font=('TkDefaultFont', 11)) self.scrolled_text.grid(column=0, row=10, columnspan=7) self.set_output_text('Натисніть на кнопку "Розрахувати"') self.scrolled_text.config(state=tk.DISABLED) def init_graph_canvas(self): self.canvas_size = (700, 420) self.graph_canvas = tk.Canvas(self.parent, bg="#fff", height=self.canvas_size[1], width=self.canvas_size[0]) self.graph_canvas.grid(column=8, row=10, columnspan=6, sticky=tk.NW) # RadioButtons def init_choose_polynomial(self): self.polynomial_type = tk.StringVar(value='chebyshev_first') self.init_radiobutton(text='Чебишева 1-го порядку', row=2, column=6, value='chebyshev_first', variable=self.polynomial_type) self.init_radiobutton(text='Чебишева 2-го порядку', row=3, column=6, value='chebyshev_second', variable=self.polynomial_type) self.init_radiobutton(text='Лежандра', row=4, column=6, value='legendre', variable=self.polynomial_type) self.init_radiobutton(text='Лагерра', row=5, column=6, value='laguerre', variable=self.polynomial_type) self.init_radiobutton(text='Ерміта', row=6, column=6, value='hermite', variable=self.polynomial_type) def init_function_weight(self): self.weight_average = tk.BooleanVar() self.init_radiobutton(text='Через максимум і мінімум', row=2, column=11, columnspan=2, value=False, variable=self.weight_average) self.init_radiobutton(text='Середнє арифметичне', row=3, column=11, columnspan=2, value=True, variable=self.weight_average) # Labels with entries def init_samples_length(self): self.samples_length = tk.IntVar() self.init_label_with_entry(text='Розмір вибірки', column=0, row=2, variable=self.samples_length) def init_input_filename(self): self.input_filename = tk.StringVar(value='features.txt') self.init_label_with_entry(text='Файл зі значеннями x', column=0, row=2, variable=self.input_filename, entry_width=15) def init_label_filename(self): self.label_filename = tk.StringVar(value='labels.txt') self.init_label_with_entry(text='Файл зі значеннями y', column=0, row=3, variable=self.label_filename, entry_width=15) def init_x_leng(self): self.x_leng_var = [ tk.IntVar(value=def_value) for def_value in (3, 2, 2) ] for ind, var in enumerate(self.x_leng_var): self.init_label_with_entry(text='Розмірність x' + str(ind + 1), column=3, row=ind + 2, variable=var) def init_polynomial_degrees(self): self.polynomial_degrees = [tk.IntVar(value=3) for _ in range(3)] for ind, var in enumerate(self.polynomial_degrees): self.init_label_with_entry(text='Степінь x' + str(ind + 1), column=8, row=ind + 2, variable=var) def init_y_coord(self): self.y_coord = tk.IntVar(value=1) self.init_label_with_entry(text='Координата y', column=11, row=4, variable=self.y_coord) def set_output_text(self, output): self.scrolled_text.config(state=tk.NORMAL) self.scrolled_text.delete(1.0, tk.END) self.scrolled_text.insert(1.0, output) self.scrolled_text.config(state=tk.DISABLED) def update_graph(self): self.graph_image = ImageTk.PhotoImage( Image.open('graph.png').resize(self.canvas_size, Image.ANTIALIAS)) if self.first_run: self.canvas_image = self.graph_canvas.create_image( 0, 0, image=self.graph_image, anchor='nw') else: self.graph_canvas.itemconfigure(self.canvas_image, image=self.graph_image) def add_output(self, inp='', new_line=True): self.output += str(inp) if new_line: self.output += '\n' def run(self): self.output = '' self.polynomial_var = { 'chebyshev_first': 'T', 'chebyshev_second': 'U', 'legendre': 'P', 'hermite': 'H', 'laguerre': 'L' }.get(self.polynomial_type.get()) feature_lengths = () if self.default_data.get(): data = default_input() feature_lengths = (3, 2, 2) else: data = read_input_from_file(self.input_filename.get(), self.label_filename.get()) feature_lengths = [length.get() for length in self.x_leng_var] feature_ranges = get_ranges(feature_lengths) feature_amount = len(feature_lengths) polynomial_degree_values = np.array([ polynomial_degree.get() for polynomial_degree in self.polynomial_degrees ]) x, y = data y_variable = y[:, self.y_coord.get() - 1] x = normalize_data(x) print(y_variable[:10]) y_variable, norm_values = normalize_data(y_variable, min_max_data=True) b = np.empty(y.shape[0], dtype=np.float32) if self.weight_average: b = y.mean(axis=1) else: b = (y.min(axis=1) + y.max(axis=1)) / 2 A_full = create_equation_matrix_simult( x, polynomial_type=self.polynomial_type.get(), polynomial_degrees=polynomial_degree_values, feature_lengths=feature_lengths) lambda_matrix_full = np.linalg.lstsq(A_full, b)[0] err = np.max(np.abs(A_full @ lambda_matrix_full - b)) while err > 0.4: change = False for i in range(3): new_polynomial_degree_values = polynomial_degree_values.copy() new_polynomial_degree_values[i] += 1 A_full = create_equation_matrix_simult( x, polynomial_type=self.polynomial_type.get(), polynomial_degrees=new_polynomial_degree_values, feature_lengths=feature_lengths) lambda_matrix_full = np.linalg.lstsq(A_full, b)[0] err_new = np.max(np.abs(A_full @ lambda_matrix_full - b)) if (err - err_new) / err > 0.05: polynomial_degree_values = new_polynomial_degree_values err = err_new change = True if not change: break for polynomial_degree, value in zip(self.polynomial_degrees, polynomial_degree_values): polynomial_degree.set(value) A_full = create_equation_matrix_simult( x, polynomial_type=self.polynomial_type.get(), polynomial_degrees=polynomial_degree_values, feature_lengths=feature_lengths) lambda_matrix_full = np.linalg.lstsq(A_full, b)[0] save_graph(b, np.dot(A_full, lambda_matrix_full.T)) self.update_graph() new_output = print_equation_3(coeff_matrix=lambda_matrix_full, lengths=feature_lengths, degrees=polynomial_degree_values, coeff_name='λ', function_name='ψ', var_name=self.polynomial_var) self.add_output(new_output) phi_values_full = [] row_ind = 0 for feature_ind, (feature_length, polynomial_degree) in enumerate( zip(feature_lengths, polynomial_degree_values)): phi_values = [] for variable_ind in range(feature_length): A_part = A_full[:, row_ind:row_ind + polynomial_degree] lambda_part = lambda_matrix_full[row_ind:row_ind + polynomial_degree] row_ind = row_ind + polynomial_degree phi_values.append(np.dot(A_part, lambda_part)) phi_values = np.array(phi_values).T phi_values_full.append(phi_values) a_matrixes = [ np.linalg.lstsq(phi_values, y_variable)[0] for phi_values in phi_values_full ] new_output = print_equation_2(coeff_matrixes=a_matrixes, target_ind=self.y_coord.get()) self.add_output(new_output) new_output = output_diff(A=phi_values_full, b=y_variable, coeff=a_matrixes, on_array=True) self.add_output(new_output) F_values = np.array([ phi_values @ a_matrix.T for phi_values, a_matrix in zip(phi_values_full, a_matrixes) ]).T c_matrix = np.linalg.lstsq(F_values, y_variable)[0] new_output = print_equation_1(coeff_matrix=c_matrix, target_ind=self.y_coord.get()) self.add_output(new_output) new_output = output_diff(A=F_values, b=y_variable, coeff=c_matrix) self.add_output(new_output) #approx_values = F_values @ c_matrix.T lambda_matrix_y = np.linalg.lstsq(A_full, y_variable)[0] approx_values = np.dot(A_full, lambda_matrix_y.T) if not self.normalize_y.get(): y_variable = denormalize_data(y_variable, norm_values) print(y_variable[:10]) approx_values = denormalize_data(approx_values, norm_values) save_graph(y_variable, approx_values) self.update_graph() err_value = np.max(np.abs(y_variable - approx_values)) self.err_output.set('Значення похибки: {0:.5}'.format(err_value)) self.set_output_text(self.output) if self.first_run: self.first_run = False
class WbRunner(tk.Frame): def __init__(self, tool_name=None, master=None): if platform.system() == 'Windows': self.ext = '.exe' else: self.ext = '' exe_name = "whitebox_tools{}".format(self.ext) self.exe_path = path.dirname(path.abspath(__file__)) os.chdir(self.exe_path) for filename in glob.iglob('**/*', recursive=True): if filename.endswith(exe_name): self.exe_path = path.dirname(path.abspath(filename)) break wbt.set_whitebox_dir(self.exe_path) ttk.Frame.__init__(self, master) self.script_dir = os.path.dirname(os.path.realpath(__file__)) self.grid() self.tool_name = tool_name self.master.title("WhiteboxTools Runner") # widthpixels = 800 # heightpixels = 600 # self.master.geometry('{}x{}'.format(widthpixels, heightpixels)) # self.master.resizable(0, 0) # self.master.lift() if _platform == "darwin": os.system( '''/usr/bin/osascript -e 'tell app "Finder" to set frontmost of process "Python" to true' ''') self.create_widgets() self.working_dir = str(Path.home()) def create_widgets(self): toplevel_frame = ttk.Frame(self, padding='0.1i') (self.toolslist, selected_item) = self.get_tools_list() self.tools_frame = ttk.LabelFrame(toplevel_frame, text="{} Available Tools".format( len(self.toolslist)), padding='0.1i') self.toolnames = tk.StringVar(value=self.toolslist) self.tools_listbox = tk.Listbox( self.tools_frame, height=22, listvariable=self.toolnames) self.tools_listbox.bind("<<ListboxSelect>>", self.update_tool_help) self.tools_listbox.grid(row=0, column=0, sticky=tk.NSEW) self.tools_listbox.columnconfigure(0, weight=10) self.tools_listbox.rowconfigure(0, weight=1) s = ttk.Scrollbar(self.tools_frame, orient=tk.VERTICAL, command=self.tools_listbox.yview) s.grid(row=0, column=1, sticky=(tk.N, tk.S)) self.tools_listbox['yscrollcommand'] = s.set self.tools_frame.grid(row=0, column=0, sticky=tk.NSEW) self.tools_frame.columnconfigure(0, weight=10) self.tools_frame.columnconfigure(1, weight=1) self.tools_frame.rowconfigure(0, weight=1) overall_frame = ttk.Frame(toplevel_frame, padding='0.1i') # json_str = '{"default_value": null, "description": "Directory containing data files.", "flags": ["--wd"], "name": "Working Directory", "optional": true, "parameter_type": "Directory"}' # self.wd = FileSelector(json_str, overall_frame) # self.wd.grid(row=0, column=0, sticky=tk.NSEW) current_tool_frame = ttk.Frame(overall_frame, padding='0.1i') self.current_tool_lbl = ttk.Label(current_tool_frame, text="Current Tool: {}".format( self.tool_name), justify=tk.LEFT) # , font=("Helvetica", 12, "bold") self.current_tool_lbl.grid(row=0, column=0, sticky=tk.W) self.view_code_button = ttk.Button( current_tool_frame, text="View Code", width=12, command=self.view_code) self.view_code_button.grid(row=0, column=1, sticky=tk.E) current_tool_frame.grid(row=1, column=0, sticky=tk.NSEW) current_tool_frame.columnconfigure(0, weight=1) current_tool_frame.columnconfigure(1, weight=1) tool_args_frame = ttk.Frame(overall_frame, padding='0.0i') self.tool_args_frame = ttk.Frame(overall_frame, padding='0.0i') self.tool_args_frame.grid(row=2, column=0, sticky=tk.NSEW) self.tool_args_frame.columnconfigure(0, weight=1) # args_frame = ttk.Frame(overall_frame, padding='0.1i') # self.args_label = ttk.Label(args_frame, text="Tool Arguments:", justify=tk.LEFT) # self.args_label.grid(row=0, column=0, sticky=tk.W) # args_frame2 = ttk.Frame(args_frame, padding='0.0i') # self.args_value = tk.StringVar() # self.args_text = ttk.Entry(args_frame2, width=45, justify=tk.LEFT, textvariable=self.args_value) # self.args_text.grid(row=0, column=0, sticky=tk.NSEW) # self.args_text.columnconfigure(0, weight=1) # self.clearButton = ttk.Button(args_frame2, text="Clear", width=4, command=self.clear_args_box) # self.clearButton.pack(pady=10, padx=10) # self.clearButton.grid(row=0, column=1, sticky=tk.E) # self.clearButton.columnconfigure(0, weight=1) # args_frame2.grid(row=1, column=0, sticky=tk.NSEW) # args_frame2.columnconfigure(0, weight=10) # args_frame2.columnconfigure(1, weight=1) # args_frame.grid(row=2, column=0, sticky=tk.NSEW) # args_frame.columnconfigure(0, weight=1) # # Add the bindings # if _platform == "darwin": # self.args_text.bind("<Command-Key-a>", self.args_select_all) # else: # self.args_text.bind("<Control-Key-a>", self.args_select_all) buttonsFrame = ttk.Frame(overall_frame, padding='0.1i') self.run_button = ttk.Button( buttonsFrame, text="Run", width=8, command=self.run_tool) # self.run_button.pack(pady=10, padx=10) self.run_button.grid(row=0, column=0) self.quitButton = ttk.Button( buttonsFrame, text="Cancel", width=8, command=self.cancel_operation) self.quitButton.grid(row=0, column=1) buttonsFrame.grid(row=3, column=0, sticky=tk.E) output_frame = ttk.Frame(overall_frame, padding='0.1i') outlabel = ttk.Label(output_frame, text="Output:", justify=tk.LEFT) outlabel.grid(row=0, column=0, sticky=tk.NW) k = wbt.tool_help(self.tool_name) self.out_text = ScrolledText( output_frame, width=63, height=10, wrap=tk.NONE, padx=7, pady=7) self.out_text.insert(tk.END, k) self.out_text.grid(row=1, column=0, sticky=tk.NSEW) self.out_text.columnconfigure(0, weight=1) output_frame.grid(row=4, column=0, sticky=tk.NSEW) output_frame.columnconfigure(0, weight=1) # Add the binding if _platform == "darwin": self.out_text.bind("<Command-Key-a>", self.select_all) # self.out_text.bind("<Command-Key-A>", self.select_all) else: self.out_text.bind("<Control-Key-a>", self.select_all) progress_frame = ttk.Frame(overall_frame, padding='0.1i') self.progress_label = ttk.Label( progress_frame, text="Progress:", justify=tk.LEFT) self.progress_label.grid(row=0, column=0, sticky=tk.E, padx=5) self.progress_var = tk.DoubleVar() self.progress = ttk.Progressbar( progress_frame, orient="horizontal", variable=self.progress_var, length=200, maximum=100) self.progress.grid(row=0, column=1, sticky=tk.E) progress_frame.grid(row=5, column=0, sticky=tk.E) overall_frame.grid(row=0, column=1, sticky=tk.NSEW) overall_frame.columnconfigure(0, weight=1) toplevel_frame.columnconfigure(0, weight=1) toplevel_frame.columnconfigure(1, weight=4) # self.pack(fill=tk.BOTH, expand=1) # toplevel_frame.columnconfigure(0, weight=1) # toplevel_frame.rowconfigure(0, weight=1) toplevel_frame.grid(row=0, column=0, sticky=tk.NSEW) # Select the appropriate tool, if specified, otherwise the first tool self.tools_listbox.select_set(selected_item) self.tools_listbox.event_generate("<<ListboxSelect>>") self.tools_listbox.see(selected_item) menubar = tk.Menu(self) filemenu = tk.Menu(menubar, tearoff=0) filemenu.add_command(label="Set Working Directory", command=self.set_directory) filemenu.add_command( label="Locate WhiteboxTools exe", command=self.select_exe) filemenu.add_command(label="Refresh Tools", command=self.refresh_tools) filemenu.add_separator() filemenu.add_command(label="Exit", command=self.quit) menubar.add_cascade(label="File", menu=filemenu) editmenu = tk.Menu(menubar, tearoff=0) editmenu.add_command( label="Cut", command=lambda: self.focus_get().event_generate("<<Cut>>")) editmenu.add_command( label="Copy", command=lambda: self.focus_get().event_generate("<<Copy>>")) editmenu.add_command( label="Paste", command=lambda: self.focus_get().event_generate("<<Paste>>")) menubar.add_cascade(label="Edit ", menu=editmenu) helpmenu = tk.Menu(menubar, tearoff=0) helpmenu.add_command( label="About", command=self.help) helpmenu.add_command( label="License", command=self.license) menubar.add_cascade(label="Help ", menu=helpmenu) self.master.config(menu=menubar) # self.get_toolboxes() def help(self): self.print_to_output(wbt.version()) def license(self): self.print_to_output(wbt.license()) def set_directory(self): try: self.working_dir = filedialog.askdirectory( initialdir=self.exe_path) wbt.set_working_dir(self.working_dir) except: messagebox.showinfo( "Warning", "Could not find WhiteboxTools executable file.") def select_exe(self): try: filename = filedialog.askopenfilename(initialdir=self.exe_path) self.exe_path = path.dirname(path.abspath(filename)) wbt.set_whitebox_dir(self.exe_path) self.refresh_tools() except: messagebox.showinfo( "Warning", "Could not find WhiteboxTools executable file.") def run_tool(self): # wd_str = self.wd.get_value() wbt.set_working_dir(self.working_dir) # args = shlex.split(self.args_value.get()) args = [] for widget in self.tool_args_frame.winfo_children(): v = widget.get_value() if v: args.append(v) elif not widget.optional: messagebox.showinfo( "Error", "Non-optional tool parameter not specified.") return self.print_line_to_output("") # self.print_line_to_output("Tool arguments:{}".format(args)) # self.print_line_to_output("") # Run the tool and check the return value for an error if wbt.run_tool(self.tool_name, args, self.custom_callback) == 1: print("Error running {}".format(self.tool_name)) else: self.run_button["text"] = "Run" self.progress_var.set(0) self.progress_label['text'] = "Progress:" self.progress.update_idletasks() def print_to_output(self, value): self.out_text.insert(tk.END, value) self.out_text.see(tk.END) def print_line_to_output(self, value): self.out_text.insert(tk.END, value + "\n") self.out_text.see(tk.END) def cancel_operation(self): wbt.cancel_op = True self.print_line_to_output("Cancelling operation...") self.progress.update_idletasks() def view_code(self): webbrowser.open_new_tab(wbt.view_code(self.tool_name).strip()) def update_tool_help(self, event): selection = self.tools_listbox.curselection() self.tool_name = self.tools_listbox.get(selection[0]) self.out_text.delete('1.0', tk.END) for widget in self.tool_args_frame.winfo_children(): widget.destroy() k = wbt.tool_help(self.tool_name) self.print_to_output(k) j = json.loads(wbt.tool_parameters(self.tool_name)) param_num = 0 for p in j['parameters']: json_str = json.dumps( p, sort_keys=True, indent=2, separators=(',', ': ')) pt = p['parameter_type'] if 'ExistingFileOrFloat' in pt: ff = FileOrFloat(json_str, self, self.tool_args_frame) ff.grid(row=param_num, column=0, sticky=tk.NSEW) param_num = param_num + 1 elif ('ExistingFile' in pt or 'NewFile' in pt or 'Directory' in pt): fs = FileSelector(json_str, self, self.tool_args_frame) fs.grid(row=param_num, column=0, sticky=tk.NSEW) param_num = param_num + 1 elif 'FileList' in pt: b = MultifileSelector(json_str, self, self.tool_args_frame) b.grid(row=param_num, column=0, sticky=tk.W) param_num = param_num + 1 elif 'Boolean' in pt: b = BooleanInput(json_str, self.tool_args_frame) b.grid(row=param_num, column=0, sticky=tk.W) param_num = param_num + 1 elif 'OptionList' in pt: b = OptionsInput(json_str, self.tool_args_frame) b.grid(row=param_num, column=0, sticky=tk.W) param_num = param_num + 1 elif ('Float' in pt or 'Integer' in pt or 'String' in pt or 'StringOrNumber' in pt or 'StringList' in pt or 'VectorAttributeField' in pt): b = DataInput(json_str, self.tool_args_frame) b.grid(row=param_num, column=0, sticky=tk.NSEW) param_num = param_num + 1 else: messagebox.showinfo( "Error", "Unsupported parameter type: {}.".format(pt)) self.update_args_box() self.out_text.see("%d.%d" % (1, 0)) def update_args_box(self): s = "" self.current_tool_lbl['text'] = "Current Tool: {}".format( self.tool_name) # self.spacer['width'] = width=(35-len(self.tool_name)) for item in wbt.tool_help(self.tool_name).splitlines(): if item.startswith("-"): k = item.split(" ") if "--" in k[1]: value = k[1].replace(",", "") else: value = k[0].replace(",", "") if "flag" in item.lower(): s = s + value + " " else: if "file" in item.lower(): s = s + value + "='{}' " else: s = s + value + "={} " # self.args_value.set(s.strip()) def clear_args_box(self): self.args_value.set("") def args_select_all(self, event): self.args_text.select_range(0, tk.END) return 'break' def custom_callback(self, value): ''' A custom callback for dealing with tool output. ''' if "%" in value: try: str_array = value.split(" ") label = value.replace( str_array[len(str_array) - 1], "").strip() progress = float( str_array[len(str_array) - 1].replace("%", "").strip()) self.progress_var.set(int(progress)) self.progress_label['text'] = label except ValueError as e: print("Problem converting parsed data into number: ", e) except Exception as e: print(e) else: self.print_line_to_output(value) self.update() # this is needed for cancelling and updating the progress bar def select_all(self, event): self.out_text.tag_add(tk.SEL, "1.0", tk.END) self.out_text.mark_set(tk.INSERT, "1.0") self.out_text.see(tk.INSERT) return 'break' def get_tools_list(self): list = [] selected_item = -1 for item in wbt.list_tools().keys(): if item: value = to_camelcase(item) list.append(value) if value == self.tool_name: selected_item = len(list) - 1 if selected_item == -1: selected_item = 0 self.tool_name = list[0] return (list, selected_item) def get_toolboxes(self): toolboxes = set() for item in wbt.toolbox().splitlines(): # run wbt.toolbox with no tool specified--returns all if item: tb = item.split(":")[1].strip() toolboxes.add(tb) for v in sorted(toolboxes): # print(v) self.print_line_to_output(v) def refresh_tools(self): (self.toolslist, selected_item) = self.get_tools_list() self.tools_listbox.delete(0, len(self.toolslist)) for item in sorted(self.toolslist): self.tools_listbox.insert(len(self.toolslist), item) self.tools_frame["text"] = "{} Available Tools".format( len(self.toolslist))
class App08: def __init__(self): super().__init__() self.root = Tk() Centralizar.posicionar(self, self.root, 600, 300, False) Objetos.tela(self, self.root, 'App 08 - Python') Objetos.botoes(self, self.root, 'Analisar', lx=0.05, ly=0.585, largura=0.25, altura=0.15, comando=self.analisar) Objetos.botoes(self, self.root, 'Limpar', lx=0.05, ly=0.765, largura=0.25, altura=0.15, comando=self.limpar) Objetos.labels(self, self.root, 'Digite um Valor', lx=0.045, ly=0.225, largura=0.15, altura=0.15) self.textbox() self.root.mainloop() pass def textbox(self): self.txvalor = Entry(self.root, bd=1, relief='solid') self.txvalor.place(relx=0.05, rely=0.335, relwidth=0.25, relheight=0.065) self.txdados = ScrolledText(self.root, bd=1, relief='solid') self.txdados.place(relx=0.45, rely=0, relwidth=0.535, relheight=1) self.txdados['state'] = 'disabled' self.txvalor.focus() pass def analisar(self): if self.txvalor.get().strip() == '': messagebox.showwarning('Atenção', 'Favor preencher o campo!') self.txvalor.focus() else: try: num = float(self.txvalor.get().replace(',', '.')) mm = num * 10 km = num / 1000000 dam = num / 1000 m = num / 100 dm = num / 10 self.txdados['state'] = 'normal' self.txdados.insert( END, f'O valor de {num} convertido em:\n.Milímetro: {mm}\n.Quilômetro: {km}\n.Decametro: {dam}\n.Metro: {m}\n.Decimetro: {dm:.2f}' ) except: messagebox.showerror('Erro', 'Dados inseridos são invalidos') self.limpar(True) pass def limpar(self, status=False): if status == True: self.txdados['state'] = 'normal' self.txvalor.delete(0, END) self.txdados.delete('1.0', END) self.txvalor.focus() self.txdados['state'] = 'disabled' else: if self.txvalor.get().strip() != '' or self.txdados.get().strip( ) != '': resp = messagebox.askquestion('Pergunta', 'Deseja limpar os campos!') if resp == 'yes': self.txdados['state'] = 'normal' self.txvalor.delete(0, END) self.txdados.delete('1.0', END) self.txdados['state'] = 'disabled' self.txvalor.focus() pass pass
class ImportDialog(Frame): """Provides a frame for figure canvas and MPL settings""" def __init__(self, parent=None, filename=None): from .core import Table self.parent = parent self.filename = filename self.df = None self.main = Toplevel() self.master = self.main self.main.title('Text Import') self.main.protocol("WM_DELETE_WINDOW", self.quit) self.main.grab_set() self.main.transient(parent) delimiters = [',','\t',' ',';','/','&','|','^','+','-'] encodings = ['utf-8','ascii','iso8859_15','cp037','cp1252','big5','euc_jp'] grps = {'formats':['delimiter','decimal','comment'], 'data':['header','skiprows','index_col','skipinitialspace', 'skip_blank_lines','encoding','names'], 'other':['rowsperfile']} grps = OrderedDict(sorted(grps.items())) opts = self.opts = {'delimiter':{'type':'combobox','default':',', 'items':delimiters, 'tooltip':'seperator'}, 'header':{'type':'entry','default':0,'label':'header', 'tooltip':'position of column header'}, 'index_col':{'type':'entry','default':'','label':'index col', 'tooltip':''}, 'decimal':{'type':'combobox','default':'.','items':['.',','], 'tooltip':'decimal point symbol'}, 'comment':{'type':'entry','default':'#','label':'comment', 'tooltip':'comment symbol'}, 'skipinitialspace':{'type':'checkbutton','default':0,'label':'skip initial space', 'tooltip':'skip initial space'}, 'skiprows':{'type':'entry','default':0,'label':'skiprows', 'tooltip':'rows to skip'}, 'skip_blank_lines': {'type':'checkbutton','default':0,'label':'skip blank lines', 'tooltip':'do not use blank lines'}, 'encoding':{'type':'combobox','default':'utf-8','items':encodings, 'tooltip':'file encoding'}, #'prefix':{'type':'entry','default':None,'label':'prefix', # 'tooltip':''} 'rowsperfile':{'type':'entry','default':'','label':'rows per file', 'tooltip':'rows to read'}, 'names':{'type':'entry','default':'','label':'column names', 'tooltip':'col labels'}, } bf = Frame(self.main) bf.pack(side=LEFT,fill=BOTH) optsframe, self.tkvars, w = dialogFromOptions(bf, opts, grps, sticky='nwe', layout='vertical') self.m = PanedWindow(self.main, orient=VERTICAL) self.m.pack(side=LEFT,fill=BOTH,expand=1) self.textpreview = ScrolledText(self.main, width=80, height=10) self.m.add(self.textpreview, weight=3) tf = Frame(self.main) self.m.add(tf, weight=1) self.previewtable = Table(tf,rows=0,columns=0) self.previewtable.show() self.update() optsframe.pack(side=TOP,fill=BOTH) b = Button(bf, text="Update preview", command=self.update) b.pack(side=TOP,fill=X,pady=2) b = Button(bf, text="Import", command=self.doImport) b.pack(side=TOP,fill=X,pady=2) b = Button(bf, text="Cancel", command=self.quit) b.pack(side=TOP,fill=X,pady=2) self.main.wait_window() return def showText(self): """show text contents""" with open(self.filename, 'r') as stream: text = stream.read() self.textpreview.delete('1.0', END) self.textpreview.insert('1.0', text) return def update(self): """Reload previews""" kwds = {} other = ['rowsperfile'] for i in self.opts: if i in other: continue try: val = self.tkvars[i].get() except: val=None if val == '': val=None elif type(self.opts[i]['default']) != int: try: val=int(val) except: pass kwds[i] = val self.kwds = kwds self.showText() f = pd.read_csv(self.filename, chunksize=400, error_bad_lines=False, parse_dates=True, warn_bad_lines=False, **kwds) try: df = f.get_chunk() except pd.parser.CParserError: print ('parser error') df = pd.DataFrame() model = TableModel(dataframe=df) self.previewtable.updateModel(model) self.previewtable.showIndex() self.previewtable.redraw() return def doImport(self): """Do the import""" '''pw = Toplevel(self.main) pb = Progressbar(pw, orient='horizontal', mode='indeterminate') pb.pack(expand=True, fill=BOTH, side=TOP) pb.start(500)''' self.df = pd.read_csv(self.filename, **self.kwds) self.quit() return def quit(self): self.main.destroy() return
class Application(tkinter.Tk): def __init__(self): """Initialize widgets, methods.""" tkinter.Tk.__init__(self) self.grid() fontoptions = families(self) font = Font(family="Verdana", size=10) menubar = tkinter.Menu(self) fileMenu = tkinter.Menu(menubar, tearoff=0) editMenu = tkinter.Menu(menubar, tearoff=0) fsubmenu = tkinter.Menu(editMenu, tearoff=0) ssubmenu = tkinter.Menu(editMenu, tearoff=0) # adds fonts to the font submenu and associates lambda functions for option in fontoptions: fsubmenu.add_command(label=option, command = lambda: font.configure(family=option)) # adds values to the size submenu and associates lambda functions for value in range(1,31): ssubmenu.add_command(label=str(value), command = lambda: font.configure(size=value)) # adds commands to the menus menubar.add_cascade(label="File",underline=0, menu=fileMenu) menubar.add_cascade(label="Edit",underline=0, menu=editMenu) fileMenu.add_command(label="New", underline=1, command=self.new, accelerator="Ctrl+N") fileMenu.add_command(label="Open", command=self.open, accelerator="Ctrl+O") fileMenu.add_command(label="Save", command=self.save, accelerator="Ctrl+S") fileMenu.add_command(label="Exit", underline=1, command=exit, accelerator="Ctrl+Q") editMenu.add_command(label="Copy", command=self.copy, accelerator="Ctrl+C") editMenu.add_command(label="Cut", command=self.cut, accelerator="Ctrl+X") editMenu.add_command(label="Paste", command=self.paste, accelerator="Ctrl+V") editMenu.add_cascade(label="Font", underline=0, menu=fsubmenu) editMenu.add_cascade(label="Size", underline=0, menu=ssubmenu) editMenu.add_command(label="Color", command=self.color) editMenu.add_command(label="Bold", command=self.bold, accelerator="Ctrl+B") editMenu.add_command(label="Italic", command=self.italic, accelerator="Ctrl+I") editMenu.add_command(label="Underline", command=self.underline, accelerator="Ctrl+U") editMenu.add_command(label="Overstrike", command=self.overstrike, accelerator="Ctrl+T") editMenu.add_command(label="Undo", command=self.undo, accelerator="Ctrl+Z") editMenu.add_command(label="Redo", command=self.redo, accelerator="Ctrl+Y") self.config(menu=menubar) """Accelerator bindings. The cut, copy, and paste functions are not bound to keyboard shortcuts because Windows already binds them, so if Tkinter bound them as well whenever you typed ctrl+v the text would be pasted twice.""" self.bind_all("<Control-n>", self.new) self.bind_all("<Control-o>", self.open) self.bind_all("<Control-s>", self.save) self.bind_all("<Control-q>", self.exit) self.bind_all("<Control-b>", self.bold) self.bind_all("<Control-i>", self.italic) self.bind_all("<Control-u>", self.underline) self.bind_all("<Control-T>", self.overstrike) self.bind_all("<Control-z>", self.undo) self.bind_all("<Control-y>", self.redo) self.text = ScrolledText(self, state='normal', height=30, wrap='word', font = font, pady=2, padx=3, undo=True) self.text.grid(column=0, row=0, sticky='NSEW') # Frame configuration self.grid_columnconfigure(0, weight=1) self.resizable(True, True) """Command functions. *args is included because the keyboard bindings pass two arguments to the functions, while clicking in the menu passes only 1.""" def new(self, *args): """Creates a new window.""" app = Application() app.title('Python Text Editor') app.option_add('*tearOff', False) app.mainloop() def color(self): """Changes selected text color.""" try: (rgb, hx) = tkinter.colorchooser.askcolor() self.text.tag_add('color', 'sel.first', 'sel.last') self.text.tag_configure('color', foreground=hx) except TclError: pass def bold(self, *args): """Toggles bold for selected text.""" try: current_tags = self.text.tag_names("sel.first") if "bold" in current_tags: self.text.tag_remove("bold", "sel.first", "sel.last") else: self.text.tag_add("bold", "sel.first", "sel.last") bold_font = Font(self.text, self.text.cget("font")) bold_font.configure(weight="bold") self.text.tag_configure("bold", font=bold_font) except TclError: pass def italic(self, *args): """Toggles italic for selected text.""" try: current_tags = self.text.tag_names("sel.first") if "italic" in current_tags: self.text.tag_remove("italic", "sel.first", "sel.last") else: self.text.tag_add("italic", "sel.first", "sel.last") italic_font = Font(self.text, self.text.cget("font")) italic_font.configure(slant="italic") self.text.tag_configure("italic", font=italic_font) except TclError: pass def underline(self, *args): """Toggles underline for selected text.""" try: current_tags = self.text.tag_names("sel.first") if "underline" in current_tags: self.text.tag_remove("underline", "sel.first", "sel.last") else: self.text.tag_add("underline", "sel.first", "sel.last") underline_font = Font(self.text, self.text.cget("font")) underline_font.configure(underline=1) self.text.tag_configure("underline", font=underline_font) except TclError: pass def overstrike(self, *args): """Toggles overstrike for selected text.""" try: current_tags = self.text.tag_names("sel.first") if "overstrike" in current_tags: self.text.tag_remove("overstrike", "sel.first", "sel.last") else: self.text.tag_add("overstrike", "sel.first", "sel.last") overstrike_font = Font(self.text, self.text.cget("font")) overstrike_font.configure(overstrike=1) self.text.tag_configure("overstrike", font=overstrike_font) except TclError: pass def undo(self, *args): """Undo function""" try: self.text.edit_undo() except TclError: pass def redo(self, *args): """Redo function""" try: self.text.edit_redo() except TclError: pass def copy(self, *args): """Copy text""" self.clipboard_clear() self.clipboard_append(self.text.selection_get()) def cut(self, *args): """Cut text""" self.copy self.text.delete("sel.first", "sel.last") def paste(self, *args): """Paste text""" insertion = self.selection_get(selection = "CLIPBOARD") self.text.insert(0.0, insertion) def open(self, *args): """Opens a file dialog to open a plain text file.""" filename = tkinter.filedialog.askopenfilename() with open(filename) as f: text = f.read() self.text.delete("1.0", "end") self.text.insert('insert', text) def save(self, *args): try: """Opens a file dialog to save the text in plain text format.""" text = self.text.get("1.0", "end") filename = tkinter.filedialog.asksaveasfilename() with open(filename, 'w') as f: f.write(text) except FileNotFoundError: pass def exit(self, *args): """Exits the program.""" self.quit()