def history(self): from tkinter.scrolledtext import ScrolledText win = ScrolledText(Toplevel(), width=100) history = self.guicommander.gethistory() win.insert(END, history) win.pack(expand=1, fill=BOTH) win.focus_set()
def createNewEditor(self): new_tab_name = askstring('New Tab', 'Enter name of new tab') if new_tab_name: f_name, ext = os.path.splitext(new_tab_name) scrolled_text = ScrolledText(font=self.code_font, undo=True, tabs=('2c'), background='#282c34', insertbackground='#ffffff', foreground='#abb2a4') self.Editors.append(scrolled_text) self.Filenames[scrolled_text] = None try : lexer = self.lexer_selector[ext] except KeyError: lexer = None self.Lexers[scrolled_text] = lexer self.notebook.add(scrolled_text, image=self.langImg(ext), text=os.path.split(new_tab_name)[1], compound='left') self.notebook.select(scrolled_text) self.createTags() self.recolorize(None) self.setStatusText(self.getStatusText()) self.miscBindings(scrolled_text) scrolled_text.focus_set() scrolled_text.edit_reset()
def openFile(self): opened_file_name = fd.askopenfilename(initialdir=".", title="Select file", filetypes=(('all files', '*.*'),)) if not isinstance(opened_file_name, tuple): ext = os.path.splitext(opened_file_name)[1] scrolled_text = ScrolledText(font=self.code_font, undo=True, tabs=('2c'), background='#282c34', insertbackground='#ffffff', foreground='#abb2a4') self.Editors.append(scrolled_text) self.Filenames[scrolled_text] = opened_file_name self.notebook.add(scrolled_text, image=self.langImg(ext), text=os.path.split(opened_file_name)[1], compound='left') with open(opened_file_name) as f: file_text = f.read() f.close() scrolled_text.insert('end', file_text) self.notebook.select(scrolled_text) try : lexer = self.lexer_selector[ext] except KeyError: lexer = None self.Lexers[scrolled_text] = lexer self.createTags() self.recolorize(None) scrolled_text.focus_set() scrolled_text.edit_reset() self.miscBindings(scrolled_text) self.setStatusText(self.getStatusText())
def promptUserForCorrections(initialText,image=None): ''' promptUserForCorrections is a GUI that allows the user to modify the text string Parameters: - initialText - initial string of text Return: - finalText - updated string of text submitted by the user ''' # TODO: Better formatting of window, more descriptive labels, add some colors finalText = None colors = getDominantColorsFromImage(image) colorFG1 = colors[0] colorBG1 = colors[1] #TODO: Set colors to match poster def rgbfy(rgb): return "#%02x%02x%02x" % rgb master = tk.Tk() master.title("Spotify Playlist Generator") leftFrame = tk.Frame(master,width=300,height=400,bd=2,bg=rgbfy(colorBG1),\ highlightbackground=rgbfy(colorFG1), highlightcolor=rgbfy(colorFG1), highlightthickness=3) rightFrame = tk.Frame(master,width=900,height=400,bd=2,bg=rgbfy(colorBG1),\ highlightbackground=rgbfy(colorFG1), highlightcolor=rgbfy(colorFG1), highlightthickness=3) leftFrame.pack(side=tk.LEFT,expand=True,fill=tk.BOTH) rightFrame.pack(side=tk.RIGHT,expand=True,fill=tk.BOTH) L1 = tk.Label(leftFrame, text='List of Items',bg=rgbfy(colorBG1)) T1 = ScrolledText(leftFrame, width=40,borderwidth=2,bg=rgbfy(colorBG1)) T1.insert(tk.INSERT,initialText) image_resized = image.resize((800,800), Image.ANTIALIAS) photo_img = ImageTk.PhotoImage(image_resized) L3 = tk.Label(rightFrame, image=photo_img,relief=tk.RAISED,bg=rgbfy(colorBG1)) def callback(): nonlocal finalText finalText = T1.get(1.0,tk.END) master.destroy() B1 = tk.Button(leftFrame, width=30, text = "Submit Setlist",command=callback) L1.pack() T1.pack(expand=True,fill=tk.Y) L3.pack() B1.pack() T1.focus_set() tk.mainloop() return finalText
class mainWindow: def __init__(self, master=None): self.master = master self.set_app_title(None) self.font = Font(family="Verdana", size=10) self.text = ScrolledText(self.master, state='normal', height=400, width=400, wrap='word', font=self.font, pady=2, padx=3, undo=True, bg='white') self.text.pack(fill=tk.Y, expand=1) self.text.focus_set() self.menubar = tk.Menu(self.master, relief=tk.FLAT) self.selectedText = None '''configure events''' self.events() def build(self): self.fileMenu = file_menu.fileMenu(self.text, self.master, self) self.editMenu = edit_menu.editMenu(self.text, self.master, self) self.formatMenu = format_menu.formatMenu(self.text, self.master, self) self.helpMenu = help_menu.helpMenu(self.text, self.master, self) def events(self): self.text.bind("<<Selection>>", self.selected_text) self.master.bind("<Button-1>", self.mouse_click) self.menubar.bind("<Button-1>", self.mouse_click) def set_app_title(self, file_name): app_title = my_globals.BTTE_NAME() + '-' app_title += 'v' + my_globals.BTTE_VERSION() + '-' if not file_name: file_name = "Untitled" app_title += file_name self.master.title(app_title) '''EVENTS''' def selected_text(self, event): oldSelectedText = self.selectedText try: self.selectedText = self.text.get(tk.SEL_FIRST, tk.SEL_LAST) except: self.selectedText = None ''' update edit menu''' if oldSelectedText != self.selectedText: self.editMenu.update() def mouse_click(self, event): self.editMenu.rightClick.unpost()
def example(): root = Tk() root.title('输入框') root.geometry('500x500') stext = ScrolledText(root, bg='white', height=10, font=('Courier New', 13), fg='#333') stext.pack(fill='both', side='left', expand=True) stext.focus_set() stext.insert('insert', 'python') # 插入字符 # stext.delete(1.0, 'end) # 清空 root.mainloop()
def make_gui(cls, interactive=False): gui = cls() root = Tk() gui.root = root f = Frame(root) f.pack(side='top', expand=1, fill='both') gui.frame = f canvas = Canvas(f) canvas.bind("<Configure>", gui.configure_canvas) canvas.pack(side='top', expand=1, fill='both') gui.canvas = canvas screen = turtle.TurtleScreen(canvas) gui.screen = screen if interactive: output = ScrolledText(f, height=10, state='disabled') output.bind("<1>", lambda event: output.focus_set()) output.pack(side='top', expand=0, fill='x') gui.output = output text_input = Frame(f) prompt = Label(text_input, text="?") prompt.pack(side='left', expand=0) gui._prompt_label = prompt input_var = StringVar() gui.input_var = input_var entry = Entry(text_input, textvariable=input_var) entry.bind('<Return>', gui.handle_input) entry.bind('<Up>', gui.back_history) entry.bind('<Down>', gui.forward_history) entry.pack(side='left', expand=1, fill='x') text_input.pack(side='top', expand=0, fill='x') return gui
class TextFrame(ttk.LabelFrame): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._init_ui() def _init_ui(self): self.textbox = ScrolledText(self, width=70, height=10) self.textbox.bind("<1>", lambda event: self.textbox.focus_set()) self.textbox.pack(expand=True, fill='both')
def openFileByName(self, path): opened_file_name = path if opened_file_name[0] != '/': opened_file_name = os.path.dirname(os.path.abspath(__file__)) + '/' + path if not os.path.isdir(opened_file_name): ext = os.path.splitext(opened_file_name)[1] scrolled_text = ScrolledText(font=self.code_font, undo=True, tabs=('1.28c'), background='#282c34', insertbackground='#ffffff', foreground='#abb2a4') self.Editors.append(scrolled_text) self.Filenames[scrolled_text] = opened_file_name print(opened_file_name) self.notebook.add(scrolled_text, image=self.langImg(ext), text=os.path.split(opened_file_name)[1], compound='left') with open(opened_file_name) as f: file_text = f.read() f.close() scrolled_text.insert('end', file_text) self.notebook.select(scrolled_text) try: lexer = self.lexer_selector[ext] except KeyError: lexer = None self.Lexers[scrolled_text] = lexer self.createTags() self.recolorize(None) scrolled_text.focus_set() scrolled_text.edit_reset() self.miscBindings(scrolled_text) self.setStatusText(self.getStatusText())
def createWindow(): global window global Scroll global outscroll window = Tk() Scroll = ScrolledText(window, width=100, height=20) Scroll.grid() Scroll.focus_set() Translate = Button(window, width=10, height=5, text="Translate", command=translateFunc) Translate.grid() outscroll = ScrolledText(window, width=100, height=20) outscroll.grid() outscroll.focus_set() window.title("German to swissgerman translator") window.geometry("") window.mainloop()
def init_disp(self): """Output area""" disp_area = ScrolledText(master=self.frame, wrap=tk.WORD, width=60, height=10) disp_area.grid(padx=10, pady=10, row=3, column=0, columnspan=4, rowspan=4, sticky='nsew') disp_area.bind("<1>", lambda event: disp_area.focus_set()) disp_area.insert('end', '等待指示!') disp_area.configure(state='disabled') tk.Grid.rowconfigure(self.frame, 3, weight=1) tk.Grid.columnconfigure(self.frame, 0, weight=1) return disp_area
class Gui(): def __init__(self): self.file_path = None self.simulation_data = None # A ScriptOutput object self.root = tk.Tk() self.root.protocol("WM_DELETE_WINDOW", self.file_quit) self.set_title() self.scriptLabel = None self.scriptField = None self._create_widgets() self._assign_accelerators() self.root.mainloop() def _create_widgets(self): # The frame containing the widgets frame = tk.Frame(self.root) # The menu bar menu_bar = tk.Menu(self.root, tearoff=0) # The File menu file_menu = tk.Menu( menu_bar, tearoff=0) # tearoff = 0: can't be seperated from window file_menu.add_command(label="New", underline=0, command=self.file_new) # , accelerator="Ctrl+N") file_menu.add_command( label="Open...", underline=0, command=self.file_open) # , accelerator="Ctrl+O") file_menu.add_command( label="Save", underline=0, command=self.file_save) # , accelerator="Ctrl+S") file_menu.add_command(label="Save As...", underline=1, command=self.file_save_as) file_menu.add_separator() file_menu.add_command(label="Exit", underline=1, command=self.file_quit) menu_bar.add_cascade(label="File", underline=0, menu=file_menu) # The Run menu run_menu = tk.Menu( menu_bar, tearoff=0) # tearoff = 0: can't be seperated from window run_menu.add_command(label="Simulate and Plot", underline=0, command=self.simulate, accelerator="F5") run_menu.add_command(label="Plot", underline=0, command=self.plot) menu_bar.add_cascade(label="Run", underline=0, menu=run_menu) # The Edit menu edit_menu = tk.Menu( menu_bar, tearoff=0) # tearoff = 0: can't be seperated from window edit_menu.add_command(label="Undo", underline=0, command=self.undo, accelerator="Ctrl+Z") edit_menu.add_command(label="Redo", underline=0, command=self.redo, accelerator="Ctrl+Y") menu_bar.add_cascade(label="Edit", underline=0, menu=edit_menu) self.root.config(menu=menu_bar) # The label lbltxt = "Place your script in the box below or open a text file" # lbltxt = "Simulate: F5, Open: Ctrl+O, Save: Ctrl+S, New: Ctrl+N" scriptLabel = tk.Label(frame, text=lbltxt) scriptLabel.pack(side="top", anchor="w") # The Text widget self.scriptField = ScrolledText(frame) self.scriptField.pack(side="top", fill=BOTH, expand=YES) self.scriptField.config(undo=True) self.scriptField.focus_set() # self.scriptField.config( # borderwidth=0, # font="{Lucida Sans Typewriter} 12", # foreground="green", # background="black", # insertbackground="white", # cursor # selectforeground="green", # selection # selectbackground="#008000", # wrap=tk.WORD, # use word wrapping # width=64, # undo=True, # Tk 8.4 # ) # The Quit button # quitButton = tk.Button(frame, text="Quit", command=self.quit) # quitButton.pack(side="right") # The Close All button closefigButton = tk.Button(frame, text="Close All Figures", command=self.close_figs) closefigButton.pack(side="right") # The Simulate button simButton = tk.Button(frame, text="Simulate and Plot", command=self.simulate) simButton.pack(side="left") # The Plot button plotButton = tk.Button(frame, text="Plot", command=self.plot) plotButton.pack(side="left") frame.pack(fill=BOTH, expand=YES) def simulate(self, event=None): try: script = self.scriptField.get("1.0", "end-1c") script_obj = LsScript.LsScript(script) self.simulation_data = script_obj.run() script_obj.postproc(self.simulation_data) except Exception as ex: self.handle_exception(ex) def plot(self): try: if self.simulation_data is None: raise LsGuiException("No simulation data to plot.") script = self.scriptField.get("1.0", "end-1c") script_obj = LsScript.LsScript(script) script_obj.postproc(self.simulation_data) except Exception as ex: self.handle_exception(ex) def close_figs(self): plt.close("all") def handle_exception(self, ex): # err_msg = ex.args[0] err_msg = str(ex) # if len(ex.args) == 2: # err_msg = "{0} {1}".format(err_msg, ex.args[1]) # # err_msg = err_msg + ex.args[1] messagebox.showerror("Error", err_msg) print(traceback.format_exc()) # def file_open(self): # filename = filedialog.askopenfilename() # # filename = "C:/Python/Python36-32/_Markus/scriptexempel2.txt" # XXX # file = open(filename, "r") # self.scriptField.delete("1.0", "end-1c") # self.scriptField.insert("1.0", file.read()) # self.scriptField.mark_set("insert", "1.0") # file.close() # Make sure you close the file when done def save_changes(self): if self.scriptField.edit_modified(): msg = "This document has been modified. Do you want to save changes?" save_changes = messagebox.askyesnocancel("Save?", msg) if save_changes is None: # Cancel return False elif save_changes is True: # Yes self.file_save() return True def file_new(self, event=None): save_changes = self.save_changes() if not save_changes: return self.scriptField.delete(1.0, "end") self.scriptField.edit_modified(False) self.scriptField.edit_reset() self.file_path = None self.set_title() def file_open(self, event=None): # , filepath=None): save_changes = self.save_changes() if not save_changes: return # XXX initialdir = '.' if os.path.isdir('/home/markus/Dropbox/'): initialdir = '/home/markus/Dropbox/LearningSimulator/Scripts' filepath = filedialog.askopenfilename(filetypes=FILETYPES, initialdir=initialdir) if filepath is not None and len(filepath) != 0: with open(filepath, encoding="utf-8") as f: file_contents = f.read() # Set current text to file contents self.scriptField.delete(1.0, "end") self.scriptField.insert(1.0, file_contents) self.scriptField.edit_modified(False) self.scriptField.mark_set("insert", "1.0") self.file_path = filepath self.set_title() def file_save(self, event=None): self.file_save_as(filepath=self.file_path) def file_save_as(self, filepath=None, event=None): if filepath is None: filepath = filedialog.asksaveasfilename(filetypes=FILETYPES) if len( filepath ) == 0: # Empty tuple or empty string is returned if cancelled return # "cancelled" try: with open(filepath, 'wb') as f: text = self.scriptField.get(1.0, "end-1c") f.write(bytes(text, 'UTF-8')) self.scriptField.edit_modified(False) self.file_path = filepath self.set_title() return # "saved" except IOError as e: self.handle_exception(e) return # "cancelled" def file_quit(self, event=None): save_changes = self.save_changes() if not save_changes: return self.close_figs() self.root.destroy() # sys.exit(0) def set_title(self, event=None): if self.file_path is not None: # title = os.path.basename(self.file_path) title = os.path.abspath(self.file_path) else: title = "Untitled" self.root.title(title + " - " + TITLE) def undo(self, event=None): try: self.scriptField.edit_undo() except Exception as e: self.handle_exception(e) return "break" def redo(self, event=None): self.scriptField.edit_redo() return "break" def _assign_accelerators(self): # self.scriptField.bind("<Control-n>", self.file_new) # self.scriptField.bind("<Control-N>", self.file_new) # self.scriptField.bind("<Control-o>", self.file_open) # self.scriptField.bind("<Control-O>", self.file_open) # self.scriptField.bind("<Control-S>", self.file_save) # self.scriptField.bind("<Control-s>", self.file_save) self.scriptField.bind("<Control-y>", self.redo) self.scriptField.bind("<Control-Y>", self.redo) self.scriptField.bind("<Control-z>", self.undo) self.scriptField.bind("<Control-Z>", self.undo) # self.root.bind_class("Text", ",<Control-z>", self.undo) # self.root.bind_class("Text", ",<Control-Z>", self.undo) # self.root.bind_class("Text", ",<Control-y>", self.redo) # self.root.bind_class("Text", ",<Control-Y>", self.redo) self.scriptField.bind("<F5>", self.simulate)
class FormMain(tk.Frame): def __init__(self, master=None) -> None: super().__init__(master) self._init_widgets() self._images: List[PhotoImage] = [] # master master.title("QR Code") master.propagate(True) master.update() master.minsize(master.winfo_width(), master.winfo_height()) def _init_widgets(self): # event handler self._update_image_handler = lambda event: self.update_image(event) self._btn_save_handler = lambda event: self.on_btn_save_clicked(event) # self self.propagate(False) self.config(width=700, height=550) self.pack(expand=True, fill=tk.BOTH) # top_frame self._fra_top = self._create_top_frame() self._fra_top.pack(expand=True, fill=tk.BOTH, anchor=tk.S) # middle_frame self._fra_middle = self._create_middle_frame() self._fra_middle.pack(expand=False, fill=tk.BOTH, anchor=tk.S, padx=4, pady=4) # bottom_frame self._fra_bottom = self._create_bottom_frame() self._fra_bottom.pack(expand=False, fill=tk.X, anchor=tk.NW, padx=4, pady=4) def _create_top_frame(self) -> tk.Frame: frame = tk.Frame(self, bg="gray80", height=320) frame.propagate(False) return frame def _create_middle_frame(self) -> tk.Frame: frame = tk.Frame(self, bg="gray95", height=120) # lbl_data lbl_data = tk.Label(frame, text="Data :") lbl_data.pack(anchor=tk.W, padx=4) # txt_data self._txt_data = ScrolledText(frame, height=6) self._txt_data.pack(anchor=tk.NW, expand=True, fill=tk.X, padx=4) self._txt_data.focus_set() self._txt_data.bind("<KeyRelease>", self._update_image_handler) return frame def _create_bottom_frame(self) -> tk.Frame: pad = {"padx": 4, "pady": 4} frame = tk.Frame(self, bg="gray95", height=70) # lbl_ec_level lbl_ec_level = tk.Label(frame, text="Error Correction Level :") lbl_ec_level.grid(row=0, column=0, sticky=tk.W, cnf=pad) # cmb_ec_level self._cmb_ec_level_var = tk.StringVar() cmb_ec_level = ttk.Combobox(frame, state="readonly", width=4, textvariable=self._cmb_ec_level_var) cmb_ec_level["values"] = ["L", "M", "Q", "H"] cmb_ec_level.current(1) cmb_ec_level.grid(row=0, column=1, sticky=tk.W, cnf=pad) cmb_ec_level.bind("<<ComboboxSelected>>", self._update_image_handler) # lbl_max_ver lbl_max_ver = tk.Label(frame, text="Max Version :") lbl_max_ver.grid(row=1, column=0, sticky=tk.W, cnf=pad) # cmb_max_ver self._cmb_max_ver_var = tk.StringVar() cmb_max_ver = ttk.Combobox(frame, state="readonly", width=4, height=20, textvariable=self._cmb_max_ver_var) cmb_max_ver["values"] = [i + 1 for i in range(40)] cmb_max_ver.current(len(cmb_max_ver["values"]) - 1) cmb_max_ver.grid(row=1, column=1, sticky=tk.W, cnf=pad) cmb_max_ver.bind("<<ComboboxSelected>>", self._update_image_handler) # lbl_byte_enc lbl_byte_enc = tk.Label(frame, text="Byte mode Encoding :") lbl_byte_enc.grid(row=0, column=2, sticky=tk.W, cnf=pad) # cmb_byte_enc self._cmb_byte_enc_var = tk.StringVar() cmb_byte_enc = ttk.Combobox(frame, state="readonly", width=56, textvariable=self._cmb_byte_enc_var) cmb_byte_enc["values"] = ["Shift_JIS", "UTF-8"] cmb_byte_enc.current(0) cmb_byte_enc.grid(row=0, column=3, columnspan=2, sticky=tk.W, cnf=pad) cmb_byte_enc.bind("<<ComboboxSelected>>", self._update_image_handler) # chk_structured_append self._chk_structured_append_var = tk.BooleanVar(value=False) chk_structured_append = ttk.Checkbutton( frame, text="Structured Append", variable=self._chk_structured_append_var) chk_structured_append.grid(row=1, column=2, sticky=tk.W, cnf=pad) chk_structured_append.bind("<Button-1>", self._update_image_handler) # fra_module_size fra_module_size = tk.Frame(frame) fra_module_size.grid(row=1, column=3, sticky=tk.W) # lbl_module_size lbl_module_size = tk.Label(fra_module_size, text="Module Size :") lbl_module_size.pack(anchor=tk.W, side=tk.LEFT, cnf=pad) # spn_module_size self._spn_module_size_var = tk.IntVar(value=5) spn_module_size = tk.Spinbox(fra_module_size, from_=2, to_=100, width=4, state="readonly", textvariable=self._spn_module_size_var) spn_module_size.pack(anchor=tk.W, side=tk.LEFT, cnf=pad) spn_module_size.bind("<KeyPress-Up>", self._update_image_handler) spn_module_size.bind("<KeyPress-Down>", self._update_image_handler) # btn_save btn_save = ttk.Button(frame, text="Save", width=19) btn_save.grid(row=1, column=4, sticky=tk.E, cnf=pad) btn_save.bind("<ButtonRelease-1>", self._btn_save_handler) btn_save.bind("<Key-Return>", self._btn_save_handler) btn_save.bind("<Key-space>", self._btn_save_handler) return frame def create_symbols(self) -> Optional[qr.Symbols]: data = self._txt_data.get("1.0", tk.END + "-1c") if not data: return None ec_level = qr.ErrorCorrectionLevel.to_int(self._cmb_ec_level_var.get()) max_ver = int(self._cmb_max_ver_var.get()) structured_append = bool(self._chk_structured_append_var.get()) enc_mode = self._cmb_byte_enc_var.get() symbols = qr.Symbols(ec_level, max_ver, structured_append, enc_mode) try: symbols.append_text(data) except Exception as e: tkmsg.showwarning(message=e) return None return symbols def update_image(self, event) -> None: if self._fra_top.winfo_children(): for widget in self._fra_top.winfo_children(): widget.destroy() symbols = self.create_symbols() if not symbols: return self._images.clear() module_size = self._spn_module_size_var.get() for symbol in symbols: image = symbol.tk_photo_image(module_size) self._images.append(image) for image in self._images: qrcode = tk.Label(self._fra_top, image=image) qrcode.pack(expand=False, fill=tk.NONE, anchor=tk.NW, side=tk.LEFT) def on_btn_save_clicked(self, event): symbols = self.create_symbols() if not symbols: return filetypes = [("Monochrome Bitmap", "*.bmp"), ("Portable Pixmap", "*.ppm"), ("X11 Bitmap", "*.xbm"), ("SVG", "*.svg")] filename = tkfdlg.asksaveasfilename(defaultextension="bmp", filetypes=filetypes) (root, ext) = os.path.splitext(filename) ext = ext.lower() module_size = self._spn_module_size_var.get() for i, symbol in enumerate(symbols): if symbols.count == 1: path = root + ext else: path = root + "_" + str(i) + ext if ext == ".bmp": symbol.save_bitmap( path, module_size, True, ) if ext == ".ppm": symbol.save_ppm(path, module_size) if ext == ".xbm": symbol.save_xbm(path, module_size) if ext == ".svg": symbol.save_svg(path, module_size)
class Window(tk.Tk): """Show a Tk window with scrollable text from stdin. Checks stdin for a new line every one millisecond. If the line starts with a \`#', the rest of the line is used as a new title for the window. Otherwise, the line is appended to the textfield, including the newline character. """ def __init__(self): """Initialize the window. Creates a frame, holding a srollable textfield. Finally reading from stdin is initiated. """ super().__init__() self.font = Font(size=20) self.title('State Machine') self.frame = tk.Frame(self) self.frame.pack(fill='both', expand=True) self.text = ScrolledText(self.frame, wrap='word', font=self.font) self.text.configure(state='disabled') self.text.pack(side='top', fill='both', expand=True) self.text.bind('<1>', lambda ev: self.text.focus_set()) self.geometry('500x400') self.after(1, self.do_read) def do_read(self): """Try to read a line from stdin.""" line = sys.stdin.readline() if line is not None and line != '': self.process_line(line) self.after(1, self.do_read) def process_line(self, line): """Process a line for debug display. If a line starts with \`#', change the window's title. Otherwise, write the line to the textbox. Arguments: line: the line to be processed, including newline character """ if line[0] == '#': self.title(line[1:].rstrip('\n')) else: self.write_text(line) def write_text(self, text): """Write text to the end of the textfield. Arguments: text: the text to be added to the textfield. """ self.text.configure(state='normal') self.text.insert('end', text) # Only autoscroll when at end. if self.text.vbar.get()[1] == 1.0: self.text.pos = self.text.index('end - 1 char') self.text.yview_pickplace('end') self.text.configure(state='disabled')
menuFrame.grid( row=0, column=0, padx=10, pady=10, ) menuFrame.configure(bg="#3C0990") # open a file buttonOpenFile = Button(menuFrame, text="OpenFile", command=openfile) buttonOpenFile.grid(row=0, column=0, padx=5) buttonOpenFile.configure(bg="#1D0446") # create a file or save as buttonSaveAsFile = Button(menuFrame, text="SavaAs", command=saveasfile) buttonSaveAsFile.grid(row=0, column=1, padx=5) buttonSaveAsFile.configure(bg="#1D0446") # The A frame for the textarea textAreaFrame = Frame() textAreaFrame.grid(row=1, column=0, padx=10, pady=10) textAreaFrame.configure(bg="#170436") # textArea = Text(textAreaFrame) textArea = ScrolledText(textAreaFrame) textArea.grid(row=1, column=0, padx=10, pady=10) textArea.focus_set() textArea.configure(bg="#010014") mainloop()
def create_window(self): def translate_link(documnt_conent): if translate_link_chosen.get() == '百度翻译': translate_result = baidu_translate(text=documnt_conent, to=language.get()) print("baidu tranlate loading...") # 在翻译结果区域显示结果 trans_result_box.insert(END, translate_result) elif translate_link_chosen.get() == '谷歌翻译': translate_result = google_translate(text=documnt_conent, to_language=language.get()) print("google tranlate loading...") # 在翻译结果区域显示结果 trans_result_box.insert(END, translate_result) def documnt_translate(event): documnt_conent = type_content_box.get('1.0', 'end-1c') # 统计有多少字符 # print(type_content_box.count('1.0', END)) # 匹配五段,以换行为界限 pattern = re.compile(r'.*?\n.*?\n.*?\n.*?\n.*?\n') find_paragraphs = pattern.findall(documnt_conent) for find_paragraph in find_paragraphs: if type_content_box.count('1.0', END) > tuple([0]): translate_link(find_paragraph) finally_pattern = re.compile(find_paragraphs[-1] + '(.*?)') finally_paragraph = finally_pattern.search(documnt_conent) translate_link(find_paragraph) def boxconnent_translate(): documnt_conent = type_content_box.get('1.0', 'end-1c') if type_content_box.count('1.0', END) > tuple([0]): translate_link(documnt_conent) pass # 显示翻译结果 def show_trans_result(): # 运行结果按钮状态:正在翻译 trans_result_box.delete(1.0, END) run_after.config( text='正在翻译', bg='#ffffff', fg='#000000', ) # 翻译文档 事件绑定鼠标左键按下放开时,翻译文档 openfile_button.bind('ButtonRelease-1', documnt_translate) #直接翻译文本框里的内容 boxconnent_translate() # 运行结果按钮状态:运行结果 run_after.config(text='运行结果') def get_documnt(file_path): # 获取文档对象 file_path_ = file_path file = docx.Document(file_path_) #print("段落数:" + str(len(file.paragraphs))) # 段落数为13,每个回车隔离一段 # 输出段落编号及段落内容 type_content_box.delete(1.0, END) for i in range(len(file.paragraphs)): type_content_box.insert(END, file.paragraphs[i].text) type_content_box.insert(END, '\n') # 选择文件路径 def selectPath(): path_ = askdirectory() path.set(path_) def file_path(): filetypes = [("All Files", '*'), ("word 97-2003文档", '*.doc', 'TEXT'), ("word文档", '*.docx', 'TEXT')] filename = tkinter.filedialog.askopenfilename(filetypes=filetypes) if filename != '': openfile_lable.config(text=filename) get_documnt(filename) else: openfile_lable.config(text="您没有选择任何文件") def save_file(): text_value = trans_result_box.get('1.0', END).strip() if text_value: filename = tkinter.filedialog.asksaveasfile() #print(filename.name) if filename: filename.write(text_value + '\n') savefile_lable.config(text=filename.name) #打开文件标签 openfile_lable = Label(self.master, text='请选择word文档', width=47, bg='#6495ED', fg='#ffffff', relief='flat', font=('微软雅黑', 11)) openfile_lable.place(x=1, y=10) #保存文件标签 savefile_lable = Label(self.master, text='请选择保存路径', width=40, bg='#6495ED', fg='#ffffff', relief='flat', font=('微软雅黑', 11)) savefile_lable.place(x=510, y=10) # 打开文件按钮 openfile_button = Button(self.master, text="打开文件", command=lambda: file_path()) openfile_button.place(x=430, y=10) #保存按钮 save_button = Button(self.master, text="保存文件", command=lambda: save_file()) save_button.place(x=960 - 80, y=10) ############################################### # 自动检测语言 auto_language = Button( self.master, text=' 自动检测语言 ', state='disabled', relief='flat', bg='#ffffff', fg='#000000', font=('微软雅黑', 9), ) auto_language.place(x=1, y=50) # 选择语言 language = StringVar() language_chosen = Combobox( self.master, width=10, textvariable=language, ) #language_chosen = Combobox(self.master, width=10, ) language_chosen['values'] = ['中文', '英语', '日语'] # 设置下拉列表的值 language_chosen.place(x=25 * 7, y=50) language_chosen.current(0) # 选择百度或者google翻译,默认为百度翻译 translate_link_chosen = Combobox(self.master, width=10) translate_link_chosen['values'] = ['百度翻译', '谷歌翻译'] # 设置下拉列表的值 translate_link_chosen.place(x=40 * 7, y=50) translate_link_chosen.current(0) # 翻译按钮 translate_button = Button(self.master, text='翻 译', width=10, bg='#6495ED', fg='#ffffff', relief='flat', command=lambda: show_trans_result(), font=('微软雅黑', 9)) translate_button.place(x=60 * 7 + 5, y=50) # 运行结果按钮 run_after = Button( self.master, state=DISABLED, width=10, relief='flat', font=('微软雅黑', 9), ) run_after.place(x=72 * 7 + 4, y=50) ######################################################################### # 在窗口中创建输入子窗口 type_content_box = ScrolledText( self.master, width=55, height=15, font=('微软雅黑', 11), ) type_content_box.insert(END, '请在此处输入文字') type_content_box.focus_set() type_content_box.pack(side=LEFT, expand=True) # 结果窗口 trans_result_box = ScrolledText( self.master, width=55, height=15, font=('consolas', 11), ) trans_result_box.pack(side=RIGHT) ################################################ #帮助 help1 = Label( self.master, text=__help1__, font=('微软雅黑', 11), ) help1.place(x=1, y=480 - 90) help2 = Label( self.master, text=__help2__, font=('微软雅黑', 11), ) help2.place(x=1, y=480 - 70) help3 = Label( self.master, text=__help3__, font=('微软雅黑', 11), ) help3.place(x=1, y=480 - 50) # 底部版权信息 copyright = Label( self.master, text=__copyright_info__, font=('consolas', 11), ) copyright.place(x=(960 - len(__copyright_info__) * 7.5) / 2, y=480 - 22)
class App(Frame): """Гланое окно приложения""" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # screen_width = self.winfo_screenwidth() # print(screen_width, self.winfo_screenheight()) self.master.title(f'Mem-translate {__version__}') self.master.minsize(300, 200) menu = Menu(self.master) self.master.configure(menu=menu) menu_file = Menu(menu) menu_file.add_command(label='Импорт', command=self.on_import) menu.add_cascade(label='Файл', menu=menu_file) width = 73 self.text = ScrolledText(self, bg='white', height=31, width=width, undo=True, wrap='word') self.text['font'] = DEFAULT_FONT self.text.tag_configure(TAG_BLUE, background='#aaf') self.text.focus_set() self.text.bind('<Key>', self.on_key_text) self.text.grid_configure(row=0, column=0, rowspan=2) self.text_fuzz = ScrolledText(self, bg='white', height=15, width=width, wrap='word') self.text_fuzz['font'] = DEFAULT_FONT self.text_fuzz.tag_configure(TAG_BLUE, background='#afa') self.text_fuzz.bind('<Key>', lambda event: 'break') self.text_fuzz.grid_configure(row=0, column=1, sticky='n') self.text_tran = ScrolledText(self, bg='white', height=15, width=width, wrap='word') self.text_tran['font'] = DEFAULT_FONT self.text_tran.bind('<Key>', lambda event: 'break') self.text_tran.grid_configure(row=1, column=1, sticky='s') self.grid_configure() def destroy(self): # todo log.info('destroy') super().destroy() def on_import(self): """Обработчик кнопки Импорт""" filename = Open(initialdir='../you-can/source/', filetypes=(('Текст', '*.txt'),)).show() text_ls = do_import(filename) self.do_open(text_ls) def do_open(self, text_ls: List[str]): """Отрисовать текст""" for line in text_ls: self.text.insert('end', line) # добавляем немного подсветки # if not line.startswith(PREFIX_TRANSLATE) and line != PREFIX_CUT: if not line.startswith('>>>'): i = self.text.index('insert').split('.', 1)[0] self.text.tag_add(TAG_BLUE, f'{i}.0', f'{i}.{len(line)}') self.text.insert('end', '\n') log.debug(self.text.tag_ranges(TAG_BLUE)) def on_key_text(self, event): """Обработчик нажатий любой клавиши в главном textArea""" if event.keycode == 36: # Return self.do_enter() return 'break' log.debug(event) def do_enter(self): tag_range = self.text.tag_nextrange(TAG_BLUE, self.text.index('insert')) if not tag_range: return index1, index2 = tag_range # двигаем курсор index = int(index2.split('.')[0]) + 1 self.text.mark_set('insert', f'{index}.{len(PREFIX_TRANSLATE)}') self.text.see('insert') text: str = self.text.get(index1, index2) # переводим текст self.text_tran.delete('1.0', 'end') start_new_thread(self.thread_translate, (text,)) # ... self.text_fuzz.delete('1.0', 'end') start_new_thread(self.thread_fuzz, (text,)) def thread_translate(self, text: str): """Асинхронно запускаем машинный перевод""" try: text2 = translate_yandex(text) except BaseException as ex: text2 = str(ex) self.text_tran.insert('1.0', text2) def thread_fuzz(self, text: str): """Асинхронно ищем нечёткие совпадения""" # todo закешировать + парсить перевод + перенести в text.py ls: list = self.text.get('1.0', 'end').split('\n') ls.remove(text) choices = [f'{i + 1}: {line}' for i, line in enumerate(ls) if not line.startswith('>>>')] # result = [f'{line} ({p})' for line, p in extractBests(text, choices, score_cutoff=1, limit=7)] # result = [(line, fuzz.token_set_ratio(line, text)) for line in choices] ww = set(re.findall(r'\w{4,}', text)) - {'that', 'That', 'only', 'Only'} result = [] for line in choices: p = len(set(re.findall(r'\w{4,}', line)) & ww) if p > 0: result.append((line, p)) result = heapq.nlargest(7, result, key=lambda x: x[1]) result = [line for line, p in result] # self.text_fuzz.insert('1.0', '\n'.join(result)) for line in result: self.text_fuzz.insert('end', line) i = self.text_fuzz.index('insert').split('.', 1)[0] # for m in SequenceMatcher(None, line.lower(), text.lower()).get_matching_blocks(): # self.text_fuzz.tag_add(TAG_BLUE, f'{i}.{m.a}', f'{i}.{m.a + m.size}') for w in ww: for m in re.finditer(w, line): self.text_fuzz.tag_add(TAG_BLUE, f'{i}.{m.start()}', f'{i}.{m.end()}') self.text_fuzz.insert('end', '\n')
class EditorWindow: def __init__(self): self.root = Tk(className="EDITOR") self.python_files = PythonFiles(self) self.root.geometry("%dx%d+%d+%d" % ( self.root.winfo_screenwidth() * 0.5, self.root.winfo_screenheight() * 0.4, # self.root.winfo_screenwidth() * 0.1, self.root.winfo_screenheight() * 0.1 0, 0)) self.root.columnconfigure(0, weight=1) self.root.rowconfigure(0, weight=1) self.base_title = "PyEditor v%s" % __version__ self.root.title(self.base_title) self.text_frame = Frame(master=self.root) self.text = ScrolledText(master=self.root, background="white") self.text.bind("<Tab>", self.tab_event) self.text.grid(row=0, column=0, sticky=NSEW) #TODO: find a right height self.exec_output = ScrolledText(master=self.root, height=10, state=DISABLED, background="#dddddd") # for information text like load/save/run: self.exec_output.tag_config( "info", foreground="#0000ff", #background="#eeeeee" ) self.exec_output.grid(row=1, column=0, sticky=NSEW) self.text.focus_set() # self.script_list = ScriptList(self) p = Percolator(self.text) d = ColorDelegator() p.insertfilter(d) # add statusbar to window self.init_statusbar() # add menu to window self.init_menu() # Add special RPi/Minecraft features, if available self.rpi = MinecraftSpecials(self) if self.rpi.mcpi_available: # minecraft is available self.set_content(DEFAULT_MCPI_SCRIPT) if not self.rpi.is_running: self.rpi.startup_minecraft() else: # no minecraft available self.set_content(DEFAULT_SCRIPT) self.root.update() ########################################################################### # Status bar FILENAME_LABEL = "filename" def get_filename(self): filename = self.status_bar.get_textEntry(self.FILENAME_LABEL) return filename def set_filename(self, filename): filename = os.path.split(filename)[-1] self.status_bar.set_textEntry(self.FILENAME_LABEL, filename) def update_filename(self, event=None): filename = self.get_filename() if filename and not filename.endswith(".py"): filename = "%s.py" % filename self.set_filename(filename) def init_statusbar(self): self.status_bar = MyMultiStatusBar(self.root) if sys.platform == "darwin": # Insert some padding to avoid obscuring some of the statusbar # by the resize widget. self.status_bar.set_label('_padding1', ' ', side=RIGHT) self.status_bar.grid(row=2, column=0) self.text.bind("<<set-line-and-column>>", self.set_line_and_column) self.text.event_add("<<set-line-and-column>>", "<KeyRelease>", "<ButtonRelease>") self.text.after_idle(self.set_line_and_column) self.status_bar.new_textEntry(self.FILENAME_LABEL, 'unnamed.py', callback=self.update_filename) def set_line_and_column(self, event=None): line, column = self.text.index(INSERT).split('.') self.status_bar.set_label('column', 'Column: %s' % column) self.status_bar.set_label('line', 'Line: %s' % line) ########################################################################### # Menu def init_menu(self): self.menubar = Menu(self.root) filemenu = Menu(self.menubar, tearoff=0) self.menubar.add_command(label="Run", command=self.command_run) self.menubar.add_command(label="Load", command=self.command_load_file) # filemenu.add_command(label="Load", command=self.command_load_file) self.menubar.add_command(label="Save", command=self.command_save_file) self.menubar.add_command(label="Exit", command=self.root.quit) # # self.menubar.add_cascade(label="File", menu=filemenu) self.root.config(menu=self.menubar) def command_run(self): source_listing = self.get_content() self.exec_output.config(state=NORMAL) self.exec_output.delete("1.0", END) filename = self.get_filename() self.python_files.run_source_listing(source_listing, filename) log.debug("Adding to terminal out") #self.exec_output.insert(END, "Run Script") self.exec_output.config(state=DISABLED) def command_load_file(self): infile = askopenfile( parent=self.root, mode="r", title="Select a Python file to load", filetypes=DEFAULT_FILETYPES, initialdir=BASE_PATH, ) if infile is not None: source_listing = infile.read() infile.close() self.set_content(source_listing) self.set_filename(infile.name) # FIXME: insert only name! self.append_feedback_to_output("Script %r loaded." % infile.name) def command_save_file(self): self.update_filename() # FIXME: add .py if missing content = self.get_content() filename = self.get_filename() filepath = os.path.join(BASE_PATH, filename) if os.path.isfile(filepath): self.python_files.move_to_backup(filepath) with open(filepath, "w") as f: f.write(content) self.append_feedback_to_output("Save to: %r" % filepath) ########################################################################### def get_content(self): content = self.text.get("1.0", END) content = content.strip() return content def set_content(self, source_listing): self.text.delete("1.0", END) log.critical("insert %i Bytes listing.", len(source_listing)) self.text.insert(END, source_listing) self.text.mark_set(INSERT, '1.0') # Set cursor at start self.text.focus() def append_exec_output(self, text): self.exec_output.config(state=NORMAL) self.exec_output.insert(END, text) self.exec_output.config(state=DISABLED) def append_feedback_to_output(self, text): text = "%s\n" % text.rstrip() self.exec_output.config(state=NORMAL) self.exec_output.insert(END, text, "info") self.exec_output.config(state=DISABLED) ########################################################################### indent_pad = " " * 4 def tab_event(self, event): log.debug("Tab event") self.text.insert("insert", self.indent_pad) return BREAK
def create_window(self): # 输入区域窗口 type_content_box = ScrolledText( self.master, width=54, height=10, font=('微软雅黑', 12), ) type_content_box.insert( END, '在此处输入文字、网址 即可翻译', ) type_content_box.focus_set() type_content_box.pack(side=LEFT, expand=True) # 显示区域窗口 trans_result_box = ScrolledText( self.master, width=54, height=11, bg='#D3D3D3', font=('consolas', 11), ) trans_result_box.focus_set() trans_result_box.pack(side=RIGHT, expand=True) # 自动检测语言 auto_language = Button( self.master, text=' 自动检测语言 ', state='disabled', relief='flat', bg='#ffffff', fg='#000000', font=('微软雅黑', 11), ) auto_language.place(x=5, y=90) # 选择语言 language = StringVar() language_chosen = Combobox( self.master, width=12, textvariable=language, ) language_chosen['values'] = ['中文', '英语', '日语'] # 设置下拉列表的值 language_chosen.place(x=25 * 7, y=100) language_chosen.current(0) # 运行结果按钮 run_after = Button( self.master, state=DISABLED, width=10, relief='flat', font=('微软雅黑', 11), ) run_after.place(x=72 * 7 + 4, y=90) # 显示翻译结果 def show_trans_result(): global translate_result trans_result_box.delete('1.0', END) # 运行结果按钮状态:正在翻译 run_after.config( text='正在翻译', bg='#ffffff', fg='#000000', ) if type_content_box.count('1.0', END) > tuple([0]): translate_result = translate.baidu_translate( text=type_content_box.get('1.0', 'end-1c'), to=language.get()) # 在翻译结果区域显示结果 trans_result_box.insert(END, translate_result) # 运行结果按钮状态:运行结果 run_after.config(text='运行结果') # 翻译按钮 translate_button = Button( self.master, text='翻 译', width=10, bg='#6495ED', fg='#ffffff', relief='flat', command=lambda: show_trans_result(), font=('微软雅黑', 11), ) translate_button.place(x=55 * 7 + 5, y=90) # 底部版权信息 copyright = Label( self.master, text=__copyright_info__, font=('consolas', 11), ) copyright.place(x=(960 - len(__copyright_info__) * 7.5) / 2, y=480 - 22)
from tkinter import Tk,END from tkinter.scrolledtext import ScrolledText root = Tk() stext = ScrolledText(root,bg='white', height=10) stext.pack(fill="both", side="left", expand=True) stext.focus_set() root.mainloop()
text='Randomize') randomizedButton.grid(row=4, column=1) numCopiesLabel = Label(root, text='Choose how many tests you want created ' '(for random option ONLY):', wraplength=160) numCopiesLabel.grid(row=5, column=0, sticky=W, padx=(10, 0)) numOfCopiesChoices = [x for x in range(1, 41)] numOfCopies.set(1) numberOfCopiesMenu = OptionMenu(root, numOfCopies, *numOfCopiesChoices) numberOfCopiesMenu.grid(row=5, column=1) proceedButton = Button( root, text='Convert file', command=lambda: main(inputFile.get(), outfileEntry.get(), version.get( ), numOfCopies.get())) proceedButton.grid(row=6, column=2, sticky=SW, pady=(10, 20)) feedbackArea = ScrolledText(root, wrap=WORD, borderwidth=2, relief='groove') feedbackArea.grid(row=1, column=3, rowspan=4) feedbackArea.bind("<1>", lambda event: feedbackArea.focus_set()) feedbackArea.insert('end', ' Feedback Window:\n\n') feedbackArea.configure(state=DISABLED) root.mainloop()
class Logger: def __init__(self, root): self.printer = sys.stdout sys.stdout = self self.__root = root self.__is_open: bool = False self.__window: tkinter.Toplevel = None self.__text_view: tkinter.Text = None # 是否滚动到底部,默认滚动 self.__is_scroll_to_bottom = tkinter.IntVar() self.__is_scroll_to_bottom.set(1) self.__read_line = 0 def loop(self): if os.path.exists(log_file) and self.__is_open: with open(log_file, 'r+') as file: lines = file.readlines()[self.__read_line:] if lines: self.__read_line += len(lines) self.__text_view.config(state=tkinter.NORMAL) line = '' for text in lines: # if text.endswith('\r') or text.endswith('\n'): # self.__text_view.insert(tkinter.END, line + text + '\n') # line = '' # else: # line += text self.__text_view.insert(tkinter.END, text + '\n') self.__text_view.config(state=tkinter.DISABLED) if self.__is_scroll_to_bottom.get() == 1: self.__text_view.see('end') self.__root.after(100, self.loop) def open(self): if not self.__is_open: self.__window = tkinter.Toplevel(self.__root) self.__window.title('日志窗口') self.__window.geometry('500x500') self.__window.protocol("WM_DELETE_WINDOW", self.close) frame = ttk.Frame(self.__window) frame.pack(fill=tkinter.BOTH, expand=True) ttk.Button(frame, text='清空日志', command=lambda: self.clear()).pack() ttk.Checkbutton(frame, text='自动滚动到底部', variable=self.__is_scroll_to_bottom).pack() self.__text_view = ScrolledText(frame, state=tkinter.DISABLED) self.__text_view.pack(fill=tkinter.BOTH, expand=True) self.__text_view.bind("<1>", lambda event: self.__text_view.focus_set()) self.__is_open = True def close(self): self.__read_line = 0 self.__is_open = False try: self.__window.destroy() except: pass def write(self, args): args = str(args) self.printer.write(args) with open(log_file, 'a+') as file: file.write(args) def flush(self): pass def clear(self): self.printer.write('清空日志') self.__read_line = 0 with open(log_file, 'w') as file: file.write('') if self.__is_open: self.__text_view.config(state=tkinter.NORMAL) self.__text_view.delete(1.0, tkinter.END) self.__text_view.config(state=tkinter.DISABLED) def is_open(self): return self.__is_open
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 GetResourceApp(BaseWin): def __init__(self, tk_win): BaseWin.__init__(self, tk_win) self.input_url = StringVar() self.input_url.set('https://www.meijubie.com/movie/index44655.html') self.processing = False self.selectProcessor = StringVar() # 处理请求的个数 self.current_name = '' def set_init_window(self): self.tk_win.grid_rowconfigure(1, weight=1) self.tk_win.grid_columnconfigure(0, weight=1) labelframe = LabelFrame(text="输入") labelframe.grid_columnconfigure(1, weight=1) labelframe.grid(column=0, row=0, padx=10, pady=10, sticky=EW) Label(labelframe, text="目标网址", justify=LEFT, width=10).grid(row=0, column=0) entry = Entry(labelframe, textvariable=self.input_url) entry.grid(row=0, column=1, sticky=EW, padx=5) entry.bind('<Key-Return>', self.getResourceLink) self.button = Button(labelframe, text="获取", command=self.getResourceLink, width=10) self.button.grid(row=0, column=2, sticky=E, padx=5) Label(labelframe, text="处理器", justify=LEFT, width=10).grid(row=1, column=0) select_process = ttk.Combobox(labelframe, textvariable=self.selectProcessor, state="readonly", values=PROCESS_FUN_NAME_LIST, width=90) select_process.set("请选择网址处理器") select_process.grid(row=1, column=1, sticky=EW, columnspan=2, padx=5, pady=5) if len(PROCESS_FUN_NAME_LIST) > 0: select_process.set(PROCESS_FUN_NAME_LIST[0]) output_frame = LabelFrame(text="链接结果") output_frame.grid(column=0, row=1, sticky=NSEW, padx=10) self.copy_btn = Button(output_frame, text="复制到剪贴板", command=lambda: self.copy(self.output_txt)) self.copy_btn.config(state=DISABLED) self.copy_btn.pack() self.output_txt = ScrolledText(output_frame) self.output_txt.pack(side=TOP, expand=TRUE, fill=BOTH, padx=10, pady=10) self.output_txt.bind( "<Button-3>", lambda x: self.rightKey(x, self.output_txt)) # 绑定右键鼠标事件 self.output_txt.bind("<<Selection>>", self.on_text_selection) # 绑定选择事件 # self.output_txt.grid(column=0, columnspan=4) # self.vbar = ttk.Scrollbar(output_frame, orient=VERTICAL, command=self.output_txt.yview) # self.output_txt.configure(yscrollcommand=self.vbar.set) def on_text_selection(self, event=NONE): # try: # selection = self.output_txt.get(SEL_FIRST, SEL_LAST) # except Exception: # selection = NONE # if selection is not NONE and len(selection) > 0: if self.output_txt.tag_ranges("sel"): self.copy_btn.config(state=NORMAL) else: self.copy_btn.config(state=DISABLED) def getResourceLink(self, event=NONE): if self.processing: return self.processing = True # 创建进度条 self.gress_bar = GressBar() # 禁用按钮 self.button.state = DISABLED th = threading.Thread(target=self.doGetResourceLink) th.setDaemon(True) th.start() # 启动进度条 self.gress_bar.start() pass def doGetResourceLink(self): self.current_name = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) self.output_txt.insert( END, '#########################Begin:%s##########################\n' % self.current_name) request_url = self.input_url.get() if not request_url: self.output_txt.insert(END, '请求的网址为空\n') self.end_process() return self.output_txt.insert(END, request_url + '\n') self.output_txt.insert(END, '\n') processor = PROCESS_FUN_DICT[self.selectProcessor.get()] if processor is None: self.output_txt.insert(END, '未找到对应的网站处理器\n') self.end_process() return last_time = time.time_ns() try: results = processor.getDownloadLink(request_url) except Exception as e: self.output_txt.insert(END, '%s\n' % e.args) self.end_process() return index_start = self.output_txt.index("end-1c linestart") for item in results: self.output_txt.insert(END, item + '\n') index_end = self.output_txt.index("end-1c linestart") self.output_txt.insert( END, '\n耗时=%d毫秒\n' % ((time.time_ns() - last_time) / 1E6)) self.end_process(index_end, index_start) def end_process(self, index_end=END, index_start=END): self.output_txt.insert( END, '###########################End:%s##########################\n' % self.current_name) self.gress_bar.quit() self.button.state = NORMAL self.processing = False # 移除之前的选择 self.output_txt.tag_remove(SEL, '1.0', END) # 设置选中状态 print("\nstart=%s,end=%s\n" % (index_start, index_end)) self.output_txt.tag_add(SEL, index_start, index_end) self.output_txt.focus_set()
class FormOBNT: "Classe définissant le formulaire OBNT" def __init__(self, appli): "Constructeur de la fenêtre OBNT" self.root = appli # Référence à l'application racine # Création de la nouvelle fenêtre self.fenetre = Commun.nouvelleFenetre(self.root, "Message standard OBNT") # Fermeture par la case système self.fenetre.protocol("WM_DELETE_WINDOW", self.quitterOBNT) # Composants de la fenêtre self.dessineOBNT() self.bulleAide() # Initialisations self.razSaisie() # Gestion des raccourcis clavier self.fenetre.bind('<Alt-v>', self.validerOBNT) self.fenetre.bind('<Return>', self.validerOBNT) self.fenetre.bind('<Alt-n>', self.annulerOBNT) self.fenetre.bind('<Escape>', self.annulerOBNT) self.fenetre.bind('<Alt-q>', self.quitterOBNT) self.stMessage.bind( '<Return>', self.notReturn ) # On ne valide pas par <Entrée> sur la zone stMessage def dessineOBNT(self): # variables locales vLigne = 1 # N° de ligne pour le positionnement des composants vNomBouton = "" vIndice = 0 vFen = self.fenetre # Composants de la fenêtre Label(vFen, text="Informations transmission", fg="blue", bg="orange").grid(row=vLigne, column=0, columnspan=8, sticky=E + W) vLigne += 1 Label(vFen, text="Groupe Date/Heure : ").grid(row=vLigne, column=0, sticky=W) self.efGdh = Commun.gdhWidget(vFen, vFen) self.efGdh.grid(row=vLigne, column=1, sticky=W) self.iGdh = IntVar() self.ckGdh = Checkbutton( vFen, text="Recalculer le GDH lors de la validation", variable=self.iGdh) self.ckGdh.grid(row=vLigne, column=2, columnspan=2, sticky=W) vLigne += 1 Label(vFen, text="Emis par : ").grid(row=vLigne, column=0, sticky=W) self.cbEmetteur = Commun.indicatifWidget(vFen, vFen, self.root) self.cbEmetteur.grid(row=vLigne, column=1, sticky=W) Label(vFen, text="Reçu par : ").grid(row=vLigne, column=2, sticky=W) self.cbDestinataire = Commun.indicatifWidget(vFen, vFen, self.root) self.cbDestinataire.grid(row=vLigne, column=3, sticky=W) vLigne += 1 Label(vFen, text="Instructions particulières : ").grid(row=vLigne, column=0, sticky=W) self.eInstruc = Entry(vFen) self.eInstruc.grid(row=vLigne, column=1, columnspan=3, sticky=W + E) vLigne += 1 Label(vFen, text="Message OBNT", fg="blue", bg="orange").grid(row=vLigne, column=0, columnspan=8, sticky=E + W) vLigne += 1 Label(vFen, text="Entête du message", fg="blue", bg="cyan").grid(row=vLigne, column=0, columnspan=6, sticky=E + W) vLigne += 1 Label(vFen, text="Origine : ").grid(row=vLigne, column=0, sticky=W) self.efOrigine = Pmw.EntryField(vFen, validate=Commun.nonVideValidator) self.efOrigine.grid(row=vLigne, column=1, sticky=W) vLigne += 1 Label(vFen, text="Destinataires Action : ").grid(row=vLigne, column=0, sticky=W) self.efDestAction = Pmw.EntryField(vFen, validate=Commun.nonVideValidator) self.efDestAction.grid(row=vLigne, column=1, columnspan=2, sticky=E + W) Label(vFen, text="(utilisez le / comme séparateur)").grid(row=vLigne, rowspan=2, column=3, columnspan=2, sticky=W) vLigne += 1 Label(vFen, text="Destinataires Info : ").grid(row=vLigne, column=0, sticky=W) self.eDestInfo = Entry(vFen) self.eDestInfo.grid(row=vLigne, column=1, columnspan=2, sticky=E + W) vLigne += 1 Label(vFen, text="Degré d'Urgence : ").grid(row=vLigne, column=0, sticky=W) self.cbDegUrg = Commun.comboWidget(self.root, vFen, self.root.cfgListe['DegUrgOBNT']) self.cbDegUrg.grid(row=vLigne, column=1, columnspan=2, sticky=W) vLigne += 1 Label(vFen, text="Corps du message ", fg="blue", bg="cyan").grid(row=vLigne, column=0, columnspan=6, sticky=E + W) vLigne += 1 Label(vFen, text="Objet : ").grid(row=vLigne, column=0, sticky=W) self.efObjet = Pmw.EntryField(vFen, validate=Commun.nonVideValidator) self.efObjet.grid(row=vLigne, column=1, columnspan=3, sticky=E + W) vLigne += 1 Label(vFen, text="Référence : ").grid(row=vLigne, column=0, sticky=W) self.eRef = Entry(vFen) self.eRef.grid(row=vLigne, column=1, columnspan=2, sticky=E + W) vLigne += 1 Label(vFen, text="Message : ").grid(row=vLigne, column=0, sticky=W) self.stMessage = ScrolledText(vFen, wrap="word", height=12) self.stMessage.grid(row=vLigne, column=1, columnspan=4, sticky=E + W) vLigne += 12 Label(vFen, text="Final du message ", fg="blue", bg="cyan").grid(row=vLigne, column=0, columnspan=6, sticky=E + W) vLigne += 1 Label(vFen, text="GDH Dépôt/Rédaction : ").grid(row=vLigne, column=0, sticky=W) self.efGdhDep = Commun.gdhWidget(vFen, vFen) self.efGdhDep.grid(row=vLigne, column=1, sticky=W) self.rbACK = Pmw.RadioSelect( vFen, buttontype="radiobutton", labelpos=W, label_text="Demande Accusé de Réception : ") self.rbACK.grid(row=vLigne, column=3, columnspan=2, sticky=W) self.rbACK.add("Oui") self.rbACK.add("Non") vLigne += 1 Label(vFen, text="Fin de Message ", fg="blue", bg="orange").grid(row=vLigne, column=0, columnspan=8, sticky=E + W) vLigne += 1 Button(vFen, text="Valider", command=self.validerOBNT, fg="red", underline=0).grid(row=vLigne, column=0, padx=5, pady=5, sticky=E + W) Button(vFen, text="Annuler", command=self.annulerOBNT, fg="red", underline=1).grid(row=vLigne, column=2, padx=5, pady=5, sticky=E + W) Button(vFen, text="Quitter", command=self.quitterOBNT, fg="red", underline=0).grid(row=vLigne, column=4, padx=5, pady=5, sticky=E + W) # Définition des bulles d'aide sur la fenêtre def bulleAide(self): # ATTENTION, les message d'aide des Widgets GesADRA sont déjà gérés self.fenetre.bulle.bind( self.stMessage, "Texte du message, sur plusieurs lignes si besoin") # Action sur un bouton "Valider" def validerOBNT(self, evt=None): "Traitement du bouton 'Valider'" #Contrôle de la validité des données if self.controleSaisie() == False: # Si erreur, on stoppe le traitement return None # Recalcul des données variables (Gdh, N° message, etc...) if self.iGdh.get() == True: self.efGdh.setvalue("") vGdh = datetime.datetime.now().strftime("%d/%m/%y %H:%M") self.efGdh.setvalue(vGdh) # Rédaction du message self.redigerOBNT() # Impression if self.root.userData['IMPR_MSG'] == "OUI": os.startfile(Commun.getFullPath(self.root, self.vFicOBNT + ".TXT"), "print") else: tkMessageBox.showinfo('Message OBNT', 'Message créé : ' + self.vFicOBNT) self.fenetre.destroy() # Action sur le bouton "Annuler" def annulerOBNT(self, evt=None): "Traitement du bouton 'Annuler'" # Remise à Zéro de la saisie self.razSaisie() # Action sur le bouton "Quitter" def quitterOBNT(self, evt=None): "Traitement du bouton 'Quitter'" etesVousSur = tkMessageBox.askquestion("Fermeture du Formulaire", \ "Confirmez-vous la fermeture du Message OBNT ?") if etesVousSur == "yes": self.fenetre.destroy() else: self.fenetre.focus_set() # Traitement du bind <Return> spécifique def notReturn(self, evt=None): """Reproduire le comportement normal de la touche <Entrée> pour un ScrolledText""" self.stMessage.insert(self.stMessage.index(INSERT), "\n") return "break" # Remise à zéro de la saisie utilisateur def razSaisie(self): vGdh = datetime.datetime.now().strftime("%d/%m/%y %H:%M") self.efGdh.setvalue(vGdh) # Gdh transmission self.ckGdh.select() # Cocher pour recalculer le Gdh self.cbEmetteur.setentry("") self.cbDestinataire.setentry("") self.eInstruc.delete(0, END) self.efOrigine.setvalue("") self.efDestAction.setvalue("") self.eDestInfo.delete(0, END) self.cbDegUrg.selectitem(self.root.userData['URG_OBNT']) self.efObjet.setvalue("") self.eRef.delete(0, END) self.stMessage.delete(1.0, END) self.efGdhDep.setvalue(vGdh) # Gdh rédaction message self.rbACK.invoke("Non") # Demande Ack # Validation de la saisie utilisateur def controleSaisie(self): #Contrôle de saisie if not (self.efGdh.valid() and self.cbEmetteur.valid() and self.cbDestinataire.valid() and \ self.efOrigine.valid() and self.efDestAction.valid()and self.efObjet.valid() and \ self.efGdhDep.valid()): tkMessageBox.showwarning( 'Contrôle', 'Les champs en rouge sont absents ou incorrects') self.fenetre.focus_set() return False if self.stMessage.get(1.0, END).strip() == "": tkMessageBox.showwarning('Controle', 'Message vide') self.stMessage.focus_set() return False return True # Creation des fichiers message def redigerOBNT(self): # Nom du fichier self.vFicOBNT = Commun.getFicOBNT(self.root) # Fichier TXT self.txtFileOBNT() # Fichier XML self.xmlFileOBNT() # Ecriture d'une ligne dans la main courante vTexte = "Message " + self.vFicOBNT + \ " de " + self.efOrigine.getvalue() + " vers " + self.efDestAction.getvalue() infosMCI = Commun.InfosMCI(self.efGdh.getvalue(), self.cbEmetteur.get(), self.cbDestinataire.get(), \ self.cbDegUrg.get(), " ", vTexte) infosMCI.ecrire(self.root) def txtFileOBNT(self): fic = open(Commun.getFullPath(self.root, self.vFicOBNT + ".TXT"), 'w') fic.write(self.vFicOBNT + "\n\n") fic.write( '################################################################################\n' ) fic.write('- ' + (self.root.userData['ACTIVATION'] + ' - ') * 3 + '\n') fic.write( '--------------------------------------------------------------------------------\n' ) # Informations transmission fic.write("GDH Emission : " + self.efGdh.getvalue() + "\n") fic.write("Emis par : " + self.cbEmetteur.get() + "\n") fic.write("Recu par : " + self.cbDestinataire.get() + "\n") fic.write("Instructions : " + self.eInstruc.get() + "\n") fic.write( '================================================================================\n' ) # Entête du message fic.write("MESSAGE OBNT".center(80) + "\n") fic.write("Origine : " + self.efOrigine.getvalue() + "\n") fic.write("Dest. Action : " + self.efDestAction.getvalue() + "\n") fic.write("Dest. Info : " + self.eDestInfo.get() + "\n") fic.write("Urgence : " + self.cbDegUrg.get() + "\n") fic.write( '--------------------------------------------------------------------------------\n' ) # Corps du message fic.write("Objet : " + self.efObjet.get() + "\n") fic.write("Référence : " + self.eRef.get() + "\n") fic.write("Message : \n\n") # découpage des lignes du message for ligne in self.stMessage.get(1.0, END).split("\n"): if len(ligne) > 79: for ligne in textwrap.wrap(ligne, 79): fic.write(ligne + "\n") else: fic.write(ligne + "\n") fic.write( '--------------------------------------------------------------------------------\n' ) # Final du message fic.write("GDH Dépôt : " + self.efGdhDep.getvalue() + "\n") fic.write("Demande A.R. : " + self.rbACK.getvalue() + "\n") fic.write("FIN DE MESSAGE".center(80) + "\n") fic.write( '================================================================================\n' ) fic.write('- ' + (self.root.userData['ACTIVATION'] + ' - ') * 3 + '\n') fic.write( '################################################################################\n' ) fic.close() # def xmlFileOBNT(self): fic = open(Commun.getFullPath(self.root, self.vFicOBNT + ".XML"), 'w') fic.write( '<?xml version="1.0" encoding="iso-8859-15"?><?xml-stylesheet type="text/xsl" href="..\msgOBNT.XSL"?>\n' ) fic.write('<msg>\n') fic.write('<form>Message OBNT</form>\n') fic.write('<soft>' + self.root.userData['LOGICIEL'] + '</soft>\n') fic.write('<vers>' + self.root.userData['VERSION'] + '</vers>\n') fic.write('<mode>' + self.root.userData['ACTIVATION'] + '</mode>\n') fic.write('<trans>\n') fic.write('<gdh>' + self.efGdh.getvalue() + '</gdh>\n') fic.write('<emis>' + self.cbEmetteur.get() + '</emis>\n') fic.write('<recu>' + self.cbDestinataire.get() + "</recu>\n") fic.write("<instr>" + self.eInstruc.get() + "</instr>\n") fic.write('</trans>\n') fic.write("<top>\n") fic.write("<from>" + self.efOrigine.getvalue() + "</from>\n") fic.write("<to>" + self.efDestAction.getvalue() + "</to>\n") fic.write("<info>" + self.eDestInfo.get() + "</info>\n") fic.write("<urg>" + self.cbDegUrg.get() + "</urg>\n") fic.write('</top>\n') fic.write("<corps>\n") fic.write("<obj>" + self.efObjet.getvalue() + "</obj>\n") fic.write("<ref>" + self.eRef.get() + "</ref>\n") # découpage des lignes du message for ligne in self.stMessage.get(1.0, END).split("\n"): if len(ligne) > 79: for ligne in textwrap.wrap(ligne, 79): fic.write("<txt>" + ligne + "</txt>\n") else: fic.write("<txt>" + ligne + "</txt>\n") fic.write('</corps>\n') fic.write('<bot>\n') fic.write("<gdh>" + self.efGdhDep.getvalue() + "</gdh>\n") fic.write("<ack>" + self.rbACK.getvalue() + "</ack>\n") fic.write('</bot>\n') fic.write('</msg>\n') fic.close()
font_size_drop = tk.OptionMenu(menu_frame, font_size, *sizes, command=change_font) font_size_drop.config(width=2) font_size.set(sizes[2]) font_size_drop.grid(row=1, column=6, padx=5, pady=5) # Defining Font Stype Dropdown styles = ['Regular', 'Bold', 'Italic'] font_style = tk.StringVar() font_style_drop = tk.OptionMenu(menu_frame, font_style, *styles, command=change_font) font_style_drop.config(width=8) font_style.set(styles[0]) font_style_drop.grid(row=1, column=7, padx=5, pady=5) # Defining Text Frame Layout my_font = (font_family.get(), font_size.get()) input_text = ScrolledText(text_frame, bg=text_color, font=my_font, width=100, height=100) input_text.focus_set() input_text.pack() # Running Root Mainloop root.mainloop()
def showlicense(): from tkinter.scrolledtext import ScrolledText win = ScrolledText(Toplevel(),width=100) win.insert(END,license) win.pack(expand=1,fill=BOTH) win.focus_set()
class PageProg(tk.Frame): def __init__(self, parent, user, dept): ttk.Frame.__init__(self, parent) self.parent = parent self.user = user self.dept = dept self.statwosel = StringVar(parent, value="PEND") self.komponenProgress() self.komponenAtas() self.komponenTengah() self.komponenBawah() def komponenProgress(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, padx=10) ttk.Label(self.midFrame, text='').grid(row=0, column=0, padx=10) ttk.Label(self.botFrame, text='').grid(row=0, column=0, padx=10) ttk.Label(footer, text='').grid(row=0, column=0) def komponenAtas(self): entOne = ttk.Frame(self.topFrame) entOne.grid(row=1, column=1, sticky=W) self.progWo = ttk.Entry(entOne, width=10) self.progWo.grid(row=1, column=0, sticky=W) self.progIfca = ttk.Entry(entOne, width=15) self.progIfca.grid(row=1, column=1, sticky=W) ttk.Label(entOne, text=' ').grid(row=1, column=2, sticky=W, pady=5, padx=10) self.progUnit = ttk.Entry(entOne, width=12) self.progUnit.grid(row=1, column=3, sticky=W) entTwo = ttk.Frame(self.topFrame) entTwo.grid(row=2, column=1, sticky=W) self.progTgl = ttk.Entry(entTwo, width=15) self.progTgl.grid(row=1, column=0, sticky=W) self.progJam = ttk.Entry(entTwo, width=10) self.progJam.grid(row=1, column=1, sticky=W) ttk.Label(entTwo, text=' ').grid(row=1, column=2, sticky=W, pady=5, padx=10) self.progStaff = ttk.Entry(entTwo, width=12) self.progStaff.grid(row=1, column=3, sticky=W) self.progWorkReq = ScrolledText(self.topFrame, height=8, width=40) self.progWorkReq.grid(row=3, column=1, sticky=W) ttk.Label(self.topFrame, text=' ').grid(row=3, column=2, sticky=W, pady=5, padx=10) self.commitDetail = ScrolledText(self.topFrame, height=8, width=50) self.commitDetail.grid(row=3, column=3, sticky=W) entLeft = ttk.Frame(self.topFrame) entLeft.grid(row=2, column=3, sticky=W) self.commitdate = ttk.Entry(entLeft, width=20) self.commitdate.grid(row=1, column=0, sticky=W) ttk.Label(entLeft, text='By :').grid(row=1, column=1, sticky=W, pady=5, padx=5) self.commitby = ttk.Entry(entLeft, width=20) self.commitby.grid(row=1, column=2, sticky=W) self.btnPendAccp = ttk.Button(entLeft, text='Accept', command=self.onAccPending, width=10) self.btnPendAccp.grid(row=1, column=3, sticky=N, pady=10, padx=5) entBtnRight = ttk.Frame(self.topFrame) entBtnRight.grid(row=3, column=4, sticky=W) self.btnCommUpdate = ttk.Button(entBtnRight, text='Update', command=self.onProgCommUpd, width=10) self.btnCommUpdate.grid(row=1, column=0, sticky=N, pady=5, padx=5) self.btnCommReturn = ttk.Button(entBtnRight, text='Return', command=self.onReturnWO, width=10) self.btnCommReturn.bind("<Button-3>", self.onReturnWO) # percobaan tooltips self.btnCommReturn.grid(row=2, column=0, sticky=N, pady=5, padx=5) self.btnCommTake = ttk.Button(entBtnRight, text='Take', command=self.onTakeWO, width=10) self.btnCommTake.bind("<Button-3>", self.onTakeWO) # percobaan tooltips self.btnCommTake.grid(row=3, column=0, sticky=N, pady=5, padx=5) self.btnCommDone = ttk.Button(entBtnRight, text='Done', command=self.onSetDoneWO, width=10) # self.btnCommDone = Button(entBtnRight, text='Done',\ # command=self.onSetDoneWO, width=10,\ # relief=RAISED, bd=2, bg="#FC6042", fg="white",# # activebackground="#444",activeforeground="white" ) self.btnCommDone.bind("<Button-3>", self.onSetDoneWO) # percobaan tooltips self.btnCommDone.grid(row=4, column=0, sticky=N, pady=5, padx=5) def komponenTengah(self): btnselect = ttk.Frame(self.midFrame) btnselect.grid(row=1, column=1, sticky=W) ttk.Radiobutton(btnselect,text="PENDING",variable=self.statwosel,value="PEND",\ command=self.progress_refresh).grid(row=1,column=1,sticky=W) ttk.Radiobutton(btnselect,text="PROGRESS",variable=self.statwosel,value="PROG",\ command=self.progress_refresh).grid(row=1,column=3,sticky=W,padx=20) ttk.Radiobutton(btnselect,text="RETURN",variable=self.statwosel,value="RETU",\ command=self.progress_refresh).grid(row=1,column=5,sticky=W) ttk.Radiobutton(btnselect,text="TAKEN",variable=self.statwosel,value="TAKE",\ command=self.progress_refresh).grid(row=1,column=7,sticky=W,padx=20) ''' frcaridata = ttk.Frame(self.midFrame) frcaridata.grid(row=1,column=2,sticky=E) self.entcaridata = ttk.Entry(frcaridata, width=15) self.entcaridata.grid(row=1, column=1,sticky=E) self.btnRefProg = Button(frcaridata, text='Search',\ command='self.caridata', width=10,\ relief=RAISED, bd=2, bg="#667", fg="white",# activebackground="#444",activeforeground="white") self.btnRefProg.grid(row=1,column=2,pady=5,padx=5) ''' def komponenBawah(self): listprog = ttk.Frame(self.botFrame) listprog.grid(row=1, column=1, sticky=W) listcomm = ttk.Frame(self.botFrame) listcomm.grid(row=1, column=2, sticky=W, padx=20) self.tabelProg = ttk.Treeview(listprog, columns=kolomProgIfca, show='headings') self.tabelProg.bind("<Double-1>", self.progress_detail) sbVer = ttk.Scrollbar(listprog, orient='vertical', command=self.tabelProg.yview) sbVer.pack(side=RIGHT, fill=Y) sbHor = ttk.Scrollbar(listprog, orient='horizontal', command=self.tabelProg.xview) sbHor.pack(side=BOTTOM, fill=X) self.tabelProg.pack(side=TOP, fill=BOTH) self.tabelProg.configure(yscrollcommand=sbVer.set) self.tabelProg.configure(xscrollcommand=sbHor.set) self.tabelcomm = ttk.Treeview(listcomm, columns=kolomCommIfca, show='headings') self.tabelcomm.bind("<Double-1>", self.prog_comm_detail) sbVer = ttk.Scrollbar(listcomm, orient='vertical', command=self.tabelcomm.yview) sbVer.pack(side=RIGHT, fill=Y) sbHor = ttk.Scrollbar(listcomm, orient='horizontal', command=self.tabelcomm.xview) sbHor.pack(side=BOTTOM, fill=X) self.tabelcomm.pack(side=TOP, fill=BOTH) self.tabelcomm.configure(yscrollcommand=sbVer.set) self.tabelcomm.configure(xscrollcommand=sbHor.set) self.progress_refresh() def entrySet(self, opsi): # 3 progress entry clear if opsi == "progclear": self.progWo.config(state="normal") self.progIfca.config(state="normal") self.progUnit.config(state="normal") self.progTgl.config(state="normal") self.progJam.config(state="normal") self.progStaff.config(state="normal") self.progWorkReq.config(state="normal") self.commitdate.config(state="normal") self.commitby.config(state="normal") self.commitDetail.config(state="normal") self.progWo.delete(0, END) self.progIfca.delete(0, END) self.progUnit.delete(0, END) self.progTgl.delete(0, END) self.progJam.delete(0, END) self.progStaff.delete(0, END) self.commitdate.delete(0, END) self.commitby.delete(0, END) self.commitDetail.delete('1.0', 'end') self.progWorkReq.delete('1.0', 'end') elif opsi == "progread": self.progWo.config(state="readonly") self.progIfca.config(state="readonly") self.progUnit.config(state="readonly") self.progTgl.config(state="readonly") self.progJam.config(state="readonly") self.progStaff.config(state="readonly") self.progWorkReq.config(state="disable") # self.commitDetail.config(state="disable") elif opsi == "disablebtn": self.btnPendAccp.config(state="disable") self.btnCommUpdate.config(state="disable") self.btnCommReturn.config(state="disable") self.btnCommTake.config(state="disable") self.btnCommDone.config(state="disable") else: pass # 3 # def progress_table(self, opsi): ''' opsi = <status WO> ''' # sql = "SELECT * FROM logbook WHERE status_ifca LIKE %s" # sql = "SELECT no_wo, no_ifca, unit FROM logbook WHERE status_ifca LIKE %s OR status_ifca LIKE %s OR status_ifca LIKE %s" sql = "SELECT no_wo, no_ifca, unit FROM logbook WHERE status_ifca LIKE %s ORDER BY no_ifca DESC" val = ("%{}%".format(opsi), ) results = getdata_all(sql, val) self.tabelProg.delete( *self.tabelProg.get_children()) #refresh, hapus dulu tabel lama for kolom in kolomProgIfca: self.tabelProg.heading(kolom, text=kolom) # self.tabelProg.column("No", width=10,anchor="w") self.tabelProg.column("WO", width=50, anchor="w") self.tabelProg.column("IFCA", width=80, anchor="w") self.tabelProg.column("UNIT", width=80, anchor="w") i = 0 for dat in results: if (i % 2): baris = "genap" else: baris = "ganjil" #tampilkan hanya wo ifca unit # self.tabelProg.insert('', 'end', values=dat[1]+" "+dat[2]+" "+dat[4], tags=baris) self.tabelProg.insert('', 'end', values=dat, tags=baris) i += 1 self.tabelProg.tag_configure("ganjil", background="gainsboro") self.tabelProg.tag_configure("genap", background="floral white") def commited_table(self, data): # data = "no_ifca" # sql = "SELECT * FROM onprogress WHERE no_ifca LIKE %s" sql = "SELECT date_update,commit_update,auth_by,auth_dept \ FROM onprogress WHERE no_ifca LIKE %s ORDER BY date_update ASC" val = ("%{}%".format(data), ) results = getdata_all(sql, val) self.tabelcomm.delete( *self.tabelcomm.get_children()) #refresh, hapus dulu tabel lama for kolom in kolomCommIfca: self.tabelcomm.heading(kolom, text=kolom) # self.tabelcomm.column("No", width=10,anchor="w") self.tabelcomm.column("TANGGAL", width=110, anchor="w") self.tabelcomm.column("UPDATE", width=500, anchor="w") self.tabelcomm.column("OLEH", width=120, anchor="w") self.tabelcomm.column("DEPT", width=70, anchor="w") i = 0 for dat in results: if (i % 2): baris = "genap" else: baris = "ganjil" self.tabelcomm.insert('', 'end', values=dat, tags=baris) i += 1 self.tabelcomm.tag_configure("ganjil", background="gainsboro") self.tabelcomm.tag_configure("genap", background="floral white") def progress_detail(self, event): try: curItem = self.tabelProg.item(self.tabelProg.focus()) ifca_value = curItem['values'][1] self.entrySet("progclear") self.commited_table(ifca_value) self.progIfca.insert(END, ifca_value) # sql = "SELECT no_wo, no_ifca, date_create, unit, work_req, staff, work_act, time_create, status_ifca FROM logbook WHERE no_ifca = %s" sql = "SELECT no_wo,no_ifca,date_create,time_create,unit,\ work_req,staff,status_ifca FROM logbook WHERE no_ifca = %s" val = (ifca_value, ) data = getdata_one(sql, val) self.progWo.insert(END, data[0]) #TGL buat self.progTgl.insert(END, get_date(str(data[2]))) self.progJam.insert(END, data[3]) self.progUnit.insert(END, data[4]) self.progWorkReq.insert(END, data[5]) self.progStaff.insert(END, data[6]) self.entrySet("progread") self.commitdate.config(state="disable") if (self.dept == "ENG") or (self.dept == "CS"): if data[7] == "PENDING": self.btnCommUpdate.config(state="disable") self.btnPendAccp.config(state="normal") elif data[7] == "ONPROGRESS": self.btnCommUpdate.config(state="normal") self.btnCommReturn.config(state="normal") elif (data[7] == "RETURNED") and (self.dept == "ENG"): self.btnCommTake.config(state="normal") elif (data[7] == "TAKEN") and (self.dept == "ENG"): self.btnCommDone.config(state="normal") else: pass else: pass #fungsi diatas hanya untuk cs-eng self.commitby.focus_set() except: print('Tidak ada data di tabel') def prog_comm_detail(self, event): try: # detail by data from mysql ''' curItem = self.tabelcomm.item(self.tabelcomm.focus()) comDate = curItem['values'][0] valIfca = self.progIfca.get() sql = "SELECT * FROM onprogress WHERE no_ifca LIKE %s AND date_update = %s" val = (valIfca,comDate) data = getdata_one(sql,val) self.commitdate.config(state="normal") self.commitby.config(state="normal") self.commitDetail.config(state="normal") self.commitdate.delete(0, END) self.commitby.delete(0, END) self.commitDetail.delete('1.0', 'end') self.commitdate.insert(END,get_date(str(data[2]))) self.commitby.insert(END, data[4]) self.commitDetail.insert(END, data[3]) self.commitdate.config(state="readonly") self.commitby.config(state="readonly") self.commitDetail.config(state="disable") self.entrySet("disablebtn") ''' # detail by data from treeview curItem = self.tabelcomm.item(self.tabelcomm.focus()) self.commitdate.config(state="normal") self.commitby.config(state="normal") self.commitDetail.config(state="normal") self.commitdate.delete(0, END) self.commitby.delete(0, END) self.commitDetail.delete('1.0', 'end') self.commitdate.insert(END, get_date(str(curItem['values'][0]))) self.commitby.insert(END, curItem['values'][2]) self.commitDetail.insert(END, curItem['values'][1]) self.commitdate.config(state="readonly") self.commitby.config(state="readonly") self.commitDetail.config(state="disable") self.entrySet("disablebtn") except: print('Tidak ada data di tabel') def progress_refresh(self): self.entrySet("disablebtn") self.entrySet("progclear") tipe = str(self.statwosel.get()) if tipe == "PEND": self.progress_table("PENDING") elif tipe == "PROG": self.progress_table("ONPROGRESS") elif tipe == "RETU": self.progress_table("RETURNED") elif tipe == "TAKE": self.progress_table("TAKEN") else: pass self.tabelcomm.delete( *self.tabelcomm.get_children()) #refresh, hapus dulu tabel lama for kolom in kolomCommIfca: self.tabelcomm.heading(kolom, text=kolom) ######### ### baru sampe sini [PAGEPROG]Optimization def onProgCommUpd(self): try: db_config = read_db_config() con = mysql.connector.connect(**db_config) cur = con.cursor() getIfca = self.progIfca.get() getUsrUpd = self.commitby.get() getcommit = self.commitDetail.get(1.0, END) # ('1.0', 'end') accandusr = getUsrUpd.upper().strip() + "@" + self.user from datetime import datetime getTime = datetime.now() if len(getUsrUpd.strip() ) == 0: # .strip memastikan space/tab termasuk len 0 messagebox.showwarning(title="Peringatan", message="Siapa yang update commit?") self.commitby.focus_set() self.commitby.delete(0, END) elif len(getcommit.strip() ) == 0: # .strip memastikan space/tab termasuk len 0 messagebox.showwarning( title="Peringatan", message="Silahkan isi perubahan terlebih dahulu") self.commitDetail.focus_set() self.commitDetail.delete('1.0', 'end') else: sql = "INSERT INTO onprogress (no_ifca,date_update,commit_update,auth_by,auth_login,auth_dept)"+\ "VALUES(%s,%s,%s,%s,%s,%s)" cur.execute(sql, (getIfca, getTime, getcommit.strip(), accandusr, self.user, self.dept)) messagebox.showinfo( title="Informasi", message="Update telah tersimpan oleh {}.".format( getUsrUpd)) self.progress_detail(self) con.commit() cur.close() con.close() except mysql.connector.Error as err: messagebox.showerror(title="Error", \ message="SQL Log: {}".format(err)) def onAccPending(self): try: db_config = read_db_config() con = mysql.connector.connect(**db_config) cur = con.cursor() getIfca = self.progIfca.get() getAccBy = self.commitby.get() accandusr = getAccBy.upper().strip() + "@" + self.user from datetime import datetime getTimeAcc = datetime.now() autocom = "[WO OnProgress] diterima oleh {}.".format( getAccBy.upper()) setStatus = "ONPROGRESS" if len(getAccBy.strip()) == 0: messagebox.showwarning(title="Peringatan", message="Siapa yang menerima WO?") self.commitby.focus_set() self.commitby.delete(0, END) else: sql1 = "INSERT INTO onprogress (no_ifca,date_update,commit_update,auth_by,auth_login,auth_dept)"+\ "VALUES(%s,%s,%s,%s,%s,%s)" cur.execute(sql1, (getIfca, getTimeAcc, autocom, accandusr, self.user, self.dept)) sql2 = "UPDATE logbook SET status_ifca=%s WHERE no_ifca =%s" cur.execute(sql2, (setStatus, getIfca)) messagebox.showinfo( title="Informasi", message="WO sudah diterima oleh {}.".format(getAccBy)) self.progress_refresh() con.commit() cur.close() con.close() except mysql.connector.Error as err: messagebox.showerror(title="Error", \ message="SQL Log: {}".format(err)) def onReturnWO(self, event=None): if not event == None: print("event True =", Event) # percobaan tooltips return try: db_config = read_db_config() con = mysql.connector.connect(**db_config) cur = con.cursor() getIfca = self.progIfca.get() getAccBy = self.commitby.get() accandusr = getAccBy.upper().strip() + "@" + self.user from datetime import datetime getTimeAcc = datetime.now() autocom = "[WO Return] dikembalikan oleh {}.".format( getAccBy.upper()) setStatus = "RETURNED" cekaccp = "SELECT auth_dept FROM onprogress \ WHERE no_ifca = %s AND `commit_update` LIKE '%[WO OnProgress] diterima oleh%'" cur.execute(cekaccp, (getIfca, )) data = cur.fetchone() if len(getAccBy.strip()) == 0: messagebox.showwarning(title="Peringatan", message="Siapa yang mengembalikan WO?") self.commitby.focus_set() self.commitby.delete(0, END) elif self.dept != data[0]: messagebox.showerror( title="Error", message= "WO yang diterima oleh Dept. {0}, Tidak bisa dikembalikan oleh Dept. {1}.\r\n \ \r\nWO Hanya bisa dikembalikan oleh Dept. yang sama saat WO diterima." .format(data[0], self.dept)) elif messagebox.askokcancel('Return WO', 'WO akan dikembalikan?') == True: sql1 = "INSERT INTO onprogress (no_ifca,date_update,commit_update,auth_by,auth_login,auth_dept)"+\ "VALUES(%s,%s,%s,%s,%s,%s)" cur.execute(sql1, (getIfca, getTimeAcc, autocom, accandusr, self.user, self.dept)) sql2 = "UPDATE logbook SET status_ifca=%s WHERE no_ifca =%s" cur.execute(sql2, (setStatus, getIfca)) messagebox.showinfo( title="Informasi", message="WO Sudah dikembalikan oleh {}.".format(getAccBy)) self.progress_refresh() else: pass con.commit() cur.close() con.close() except mysql.connector.Error as err: messagebox.showerror(title="Error", \ message="SQL Log: {}".format(err)) def onTakeWO(self, event=None): if not event == None: print("event True =", Event) # percobaan tooltips return try: db_config = read_db_config() con = mysql.connector.connect(**db_config) cur = con.cursor() getIfca = self.progIfca.get() getAccBy = self.commitby.get() accandusr = getAccBy.upper().strip() + "@" + self.user from datetime import datetime getTimeAcc = datetime.now() autocom = "[WO Taken] diterima oleh {}.".format(getAccBy.upper()) setStatus = "TAKEN" if len(getAccBy.strip()) == 0: messagebox.showwarning(title="Peringatan", message="Siapa yang menerima WO?") self.commitby.focus_set() self.commitby.delete(0, END) elif messagebox.askokcancel('Take WO', 'WO sudah diterima?') == True: sql1 = "INSERT INTO onprogress (no_ifca,date_update,commit_update,auth_by,auth_login,auth_dept)"+\ "VALUES(%s,%s,%s,%s,%s,%s)" cur.execute(sql1, (getIfca, getTimeAcc, autocom, accandusr, self.user, self.dept)) sql2 = "UPDATE logbook SET status_ifca=%s WHERE no_ifca =%s" cur.execute(sql2, (setStatus, getIfca)) messagebox.showinfo( title="Informasi", message="WO Sudah diterima oleh {}.".format(getAccBy)) self.progress_refresh() else: pass con.commit() cur.close() con.close() except mysql.connector.Error as err: messagebox.showerror(title="Error", \ message="SQL Log: {}".format(err)) def onSetDoneWO(self, event=None): if not event == None: print("event True =", Event) # percobaan tooltips return try: db_config = read_db_config() con = mysql.connector.connect(**db_config) cur = con.cursor() getIfca = self.progIfca.get() getAccBy = self.commitby.get() accandusr = getAccBy.upper().strip() + "@" + self.user getcommit = self.commitDetail.get(1.0, END) # ('1.0', 'end') from datetime import datetime getRealTime = datetime.now() # autocom = "Status wo DONE oleh {}.".format(getAccBy) setStatus = "DONE" if len(getAccBy.strip()) == 0: messagebox.showwarning(title="Peringatan", message="Siapa staff yang handle WO?") self.commitby.focus_set() self.commitby.delete(0, END) elif len(getcommit.strip() ) == 0: # .strip memastikan space/tab termasuk len 0 messagebox.showwarning( title="Peringatan", message="Silahkan isi perubahan terlebih dahulu") self.commitDetail.focus_set() self.commitDetail.delete('1.0', 'end') else: setdate = PopupDateTime(self.parent) setdate.parent.wait_window(setdate.top) if len(setdate.value.strip()) > 0: getdate, gettime = setdate.value.split( ) #pisah tanggal dan jam sqllastcom = "INSERT INTO onprogress (no_ifca,date_update,commit_update,auth_by,auth_login,auth_dept)"+\ "VALUES(%s,%s,%s,%s,%s,%s)" cur.execute(sqllastcom, (getIfca, getRealTime, getcommit.strip(), accandusr, self.user, self.dept)) storedata = self.getDataComm(getIfca) sqlmain = "UPDATE logbook SET staff=%s,status_ifca=%s,date_done=%s,time_done=%s,work_act=%s WHERE no_ifca =%s" cur.execute( sqlmain, (getAccBy.upper(), setStatus, self.checktgl(getdate), gettime, storedata.strip(), getIfca)) messagebox.showinfo( title="Informasi", message="Update telah tersimpan oleh {}.".format( getAccBy)) self.progress_refresh() else: # output kosong, batalkan perintah DONE print("batalkan done") con.commit() cur.close() con.close() except mysql.connector.Error as err: messagebox.showerror(title="Error", \ message="SQL Log: {}".format(err)) def getDataComm(self, data): #PR: RAMPINGKAN DATA try: db_config = read_db_config() con = mysql.connector.connect(**db_config) cur = con.cursor() sql = "SELECT date_update,commit_update,auth_by,auth_dept \ FROM onprogress WHERE no_ifca LIKE %s" # data = "TN10020352" val = ("%{}%".format(data), ) cur.execute(sql, val) results = cur.fetchall() self.commitDetail.delete('1.0', 'end') for dat in results: #tampilkan mulai dari tanggal # nantinya kumpulkan dulu data progres selanjutnya store ke sql self.commitDetail.insert(END, dat) self.commitDetail.insert(END, "\r\n") getcom = self.commitDetail.get(1.0, END) self.commitDetail.delete('1.0', 'end') cur.close() con.close() return getcom except mysql.connector.Error as err: messagebox.showerror(title="Error", \ message="SQL Log: {}".format(err)) def checktgl(self, data): if len(str(data)) == 10: cHari = str(data)[0:2] cBulan = str(data)[3:5] cTahun = str(data)[6:] return datetime.date(int(cTahun), int(cBulan), int(cHari)) else: return None
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)