class ConfirmationWindow: """Class that initializes a toplevel window to confirm deletion of a recipe. """ def __init__(self, handle_return): """Constructor of class that keeps track of frame and necessary function to return to book window. Args: handle_return (function): Function _show_book() of class UI. """ self._frame = Toplevel() self._frame.title("") self._handle_return = handle_return self._initialize() def show(self): self._frame.deiconify() def destroy(self): self._frame.destroy() def _hide_confirmation_window(self): """Hides the confirmation window without deleting it. """ self._frame.withdraw() def _handle_delete(self): """Switches window to BookView() after deletion of recipe. """ cookbookapp_functions.delete_chosen_recipe() self._handle_return() def _initilize_message(self): """Constructs a label for confirmation window. """ message_label = ttk.Label( self._frame, text="Are you sure you want to delete this recipe?") message_label.grid(row=0, column=0, columnspan=2, padx=5, pady=5) def _initialize(self): """Initializes the window with necessary elements. """ cancel_button = ttk.Button(master=self._frame, text="Cancel", command=self._hide_confirmation_window) delete_button = ttk.Button(master=self._frame, text="Delete", command=self._handle_delete) self._initilize_message() cancel_button.grid(row=1, column=0, padx=5, pady=5) delete_button.grid(row=1, column=1, padx=5, pady=5)
class UpdatingStreamsWindow: def __init__(self, parent): self.window = Toplevel(parent.window) self.window.withdraw() self.window.protocol("WM_DELETE_WINDOW", self.noClose) self.parent = parent self.frame = Frame(self.window) self.frame.grid(row=0, sticky=NSEW, padx=4, pady=4) labelPleaseWait = Label(self.frame, text=MessageConstants.UPDATING_STREAMS) labelPleaseWait.grid(row=0, sticky=NSEW, padx=4, pady=4) WindowHelper.initializeWindow(self.window, self.parent, 300, 100, 30, 50, LabelConstants.UPDATE_IN_PROGRESS) self.window.deiconify() self.parent.window.attributes('-disabled', 0) self.parent.window.deiconify() self.window.update() def noClose(self): # Prevents closing the window while updating pass
def _change_position(self, event=None): '''Make widget sticky and set its position with respects to the other windows.''' pos = self._position.get() splash_supp = CONFIG.getboolean('General', 'splash_supported', fallback=True) try: for w in self.ewmh.getClientList(): if w.get_wm_name() == self.title(): self.ewmh.setWmState(w, 1, '_NET_WM_STATE_STICKY') self.ewmh.setWmState(w, 1, '_NET_WM_STATE_SKIP_TASKBAR') self.ewmh.setWmState(w, 1, '_NET_WM_STATE_SKIP_PAGER') if pos == 'above': self.attributes('-type', 'dock') self.ewmh.setWmState(w, 1, '_NET_WM_STATE_ABOVE') self.ewmh.setWmState(w, 0, '_NET_WM_STATE_BELOW') elif pos == 'below': self.attributes('-type', 'desktop') self.ewmh.setWmState(w, 0, '_NET_WM_STATE_ABOVE') self.ewmh.setWmState(w, 1, '_NET_WM_STATE_BELOW') else: if splash_supp: self.attributes('-type', 'splash') else: self.attributes('-type', 'toolbar') self.ewmh.setWmState(w, 0, '_NET_WM_STATE_BELOW') self.ewmh.setWmState(w, 0, '_NET_WM_STATE_ABOVE') self.ewmh.display.flush() if event is None and not splash_supp: Toplevel.withdraw(self) Toplevel.deiconify(self) except ewmh.display.error.BadWindow: pass
class Sobre: def __init__(self, master): self.master = master self.sobre_janela = Toplevel() self.sobre_janela.resizable(0, 0) self.sobre_janela.title("Sobre") self.sobre_janela.geometry("400x300") self.sobre_janela.protocol("WM_DELETE_WINDOW", self.on_close) self.sobre_janela.withdraw() self.sobre_janela.grid() self.sobre_janela.transient(self.master) self.sobre_janela.grab_set() sobre_frame = Frame(self.sobre_janela, relief=RAISED, borderwidth=1) sobre_frame.pack(fill=BOTH, expand=True) ok_btn = ttk.Button(self.sobre_janela, text="Ok", width=10, command=self.on_close) ok_btn.pack(side=RIGHT) # frame_kiri grid_frame = Frame(sobre_frame, bd=10) grid_frame.pack(fill=BOTH, expand=YES, side=LEFT) centro_(self.sobre_janela) self.sobre_janela.deiconify() self.master.wait_window(self.sobre_janela) def on_close(self): self.sobre_janela.destroy()
class ModalWindow(): def __init__(self, tab): self.toplevel = Toplevel(tab.tk) self.toplevel.transient(tab.tk) self.toplevel.withdraw() self.toplevel.grab_release() self.toplevel.protocol('WM_DELETE_WINDOW', self.hide) def show(self): self.centering() self.toplevel.deiconify() self.toplevel.tkraise() self.toplevel.grab_set() self.toplevel.focus_set() def hide(self): self.toplevel.grab_release() self.toplevel.withdraw() def centering(self): sw = self.toplevel.winfo_screenwidth() rw = self.toplevel.winfo_reqwidth() x = (sw - rw) // 2 sw = self.toplevel.winfo_screenheight() rw = self.toplevel.winfo_reqheight() y = (sw - rw) // 2 self.toplevel.wm_geometry('+%i+%i' % (x, y))
class MessageManagerWindow: def __init__(self, parent): self.master = Toplevel(parent) self.master.withdraw() self.master.geometry('+{x}+{y}'.format(x=parent.winfo_x(), y=parent.winfo_y())) self.master.wm_attributes("-topmost", 1) self.master.focus_force() self.master.wm_title("StreamTicker Message Manager") self.master.iconbitmap("imagefiles/stIcon.ico") self.master.resizable(False, False) self.master.grab_set() self.window = parent self.cancelMessages = deepcopy(self.window.messages) self.messages = sorted(self.window.messages, key=lambda x: x.sortOrder) self.mlFrame = MessageManagerListFrame(self) self.mlFrame.frame.grid(row=0, column=1, padx=(4, 4), pady=4) self.mbFrame = MessageButtonFrame(self) self.mbFrame.frame.grid(row=0, column=0, padx=(4, 0), pady=4) self.okFrame = MessageOkCancelFrame(self) self.okFrame.frame.grid(row=1, column=1, padx=4, pady=4, sticky=E) self.master.deiconify() self.master.mainloop()
def update_position(self): if self._position.get() == 'normal': if CONFIG.getboolean('General', 'splash_supported', fallback=True): self.attributes('-type', 'splash') else: self.attributes('-type', 'toolbar') if self.variable.get(): Toplevel.withdraw(self) Toplevel.deiconify(self)
class MessageModal(Toplevel): def __init__(self, root, time_label_var, modal_should_close): super().__init__(root, bg="green") self.modal_should_close = modal_should_close self.set_up_modal_attributes() self.create_widgets(time_label_var) self.bind_hide_events() self.hide() def set_up_modal_attributes(self): # settup the semitransparent background self.wm_attributes("-alpha", 0.3, "-fullscreen", True) self.wm_overrideredirect(True) # hide from taskbar # setting up the top layer in front of the background self.container = Toplevel(self, bg='magenta') self.container.wm_attributes("-fullscreen", True, "-alpha", 0.95, "-transparentcolor", 'magenta') self.container.overrideredirect(True) # hide from taskbar def create_widgets(self, time_label_var): frame_bg_color = "#111" self.frame = Frame(self.container, bg=frame_bg_color) self.frame.place(relx=.5, rely=.5, anchor="center", width=440, height=210) self.time_label = Label(self.frame, textvariable=time_label_var, bg=frame_bg_color, foreground="white", font=("Cookie", 75)) self.time_label.place(relx=.5, rely=.43, anchor="center") caption = Label(self.frame, text="Time to take a break.", bg=frame_bg_color, foreground="white", font=("Century Gothic", 13)) caption.place(relx=.5, rely=.7, anchor="center") def bind_hide_events(self): hide = lambda _: self.hide() self.bind("<Escape>", hide) self.bind("<space>", hide) self.container.bind("<Escape>", hide) self.container.bind("<space>", hide) def show(self): self.focus_set() self.deiconify() self.container.deiconify() self.attributes("-topmost", True, "-topmost", False) self.container.attributes("-topmost", True) def hide(self): self.withdraw() self.container.withdraw()
class MessageComponentWindow: def __init__(self, parent, messagePart: MessagePart, index: int): self.parent = parent self.parentWindow = parent.window.master self.master = Toplevel(self.parentWindow) self.master.withdraw() self.existingMessagePart = messagePart self.messagePart = deepcopy(messagePart) self.index = index self.master.geometry('+{x}+{y}'.format( x=self.parentWindow.winfo_x() + 10, y=self.parentWindow.winfo_y() + 10)) self.master.wm_attributes("-topmost", 1) self.master.focus_force() self.master.wm_title("StreamTicker Message Component") self.master.iconbitmap("imagefiles/stIcon.ico") self.master.resizable(False, False) self.master.grab_set() self.master.protocol("WM_DELETE_WINDOW", self.deleteWindow) self.componentFrame = MessageComponentFrame(self) self.componentFrame.frame.grid(row=0, sticky=NSEW, padx=4, pady=4) self.okCancelFrame = MessageComponentOkCancelFrame(self) self.okCancelFrame.frame.grid(row=2, column=0, padx=4, pady=4, sticky=E) self.master.deiconify() self.master.mainloop() def deleteWindow(self): self.master.destroy() self.parentWindow.lift() self.parentWindow.wm_attributes("-topmost", 1) self.parentWindow.grab_set() def returnMessageComponent(self): if validate(self.componentFrame, self.master): if self.existingMessagePart: self.parent.messageMakerPartFrame.parent.message.parts[ self.index] = MessagePart( self.componentFrame.componentType.get(), self.index, self.componentFrame.getValue()) else: self.existingMessagePart = MessagePart( self.componentFrame.componentType.get(), self.index, self.componentFrame.getValue()) self.parent.messageMakerPartFrame.parent.message.parts.append( self.existingMessagePart) self.parent.populateListbox( self.parent.messageMakerPartFrame.parent.message.parts) self.deleteWindow()
class EntryOptionsWindow: def __init__(self, ls: str, tk: Tk, select_path=False) -> None: self.select_path = select_path self.List = ls self.Tk = tk self.Root = Toplevel(self.Tk) self.Root.withdraw() self.Frame = Frame(self.Root) self.Box = Listbox(self.Frame, selectmode='extended', width=54, height=24) for i in globals()[self.List]: self.Box.insert(END, i) self.Scroll = Scrollbar(self.Frame, command=self.Box.yview) self.Entry = Entry(self.Frame) self.ButtonAdd = Button(self.Frame, text='Добавить', command=self.__add_item) self.ButtonDel = Button(self.Frame, text='Удалить', command=self.__del_item) self.ButtonDone = Button(self.Frame, text='Готово', command=self.__save_list) self.ButtonExit = Button(self.Frame, text='Отмена', command=self.Root.destroy) def __add_item(self) -> None: if self.select_path: text = filedialog.askdirectory() else: text = self.Entry.get() if text: self.Box.insert(END, text) self.Entry.delete(0, END) def __del_item(self) -> None: select = list(self.Box.curselection()) select.reverse() for i in select: self.Box.delete(i) def __save_list(self) -> None: globals()[self.List] = list(self.Box.get(0, END)) self.Root.destroy() def main(self) -> None: center_win(self.Root, '500x400') self.Root.deiconify() self.Root.title(f'Editing {self.List}') self.Box.pack(side='left', expand=True) self.Scroll.pack(side='left', fill='y') self.Box.config(yscrollcommand=self.Scroll.set) self.Frame.pack(side='left', padx=10) if not self.select_path: self.Entry.pack(anchor='n') self.ButtonAdd.pack(fill='x') self.ButtonDel.pack(fill='x') self.ButtonDone.pack(fill='x') self.ButtonExit.pack(fill='x') self.Root.mainloop()
class MainWindow: def __init__(self): global root self.master = Toplevel(root) self.master.withdraw() self.master.protocol('WM_DELETE_WINDOW', root.destroy) self.master.iconbitmap(imgdir) self.master.geometry("400x150") self.master.resizable(False, False) self.master.title("Adb & Fastboot Installer - By @Pato05") estyle = Style() estyle.element_create("plain.field", "from", "clam") estyle.layout("White.TEntry", [('Entry.plain.field', {'children': [( 'Entry.background', {'children': [( 'Entry.padding', {'children': [( 'Entry.textarea', {'sticky': 'nswe'})], 'sticky': 'nswe'})], 'sticky': 'nswe'})], 'border': '4', 'sticky': 'nswe'})]) estyle.configure("White.TEntry", background="white", foreground="black", fieldbackground="white") window = Frame(self.master, relief=FLAT) window.pack(padx=10, pady=5, fill=BOTH) Label(window, text='Installation path:').pack(fill=X) self.syswide = IntVar() self.instpath = StringVar() self.e = Entry(window, state='readonly', textvariable=self.instpath, style='White.TEntry') self.e.pack(fill=X) self.toggleroot() Label(window, text='Options:').pack(pady=(10, 0), fill=X) inst = Checkbutton(window, text="Install Adb and Fastboot system-wide?", variable=self.syswide, command=self.toggleroot) inst.pack(fill=X) self.path = IntVar(window, value=1) Checkbutton(window, text="Put Adb and Fastboot in PATH?", variable=self.path).pack(fill=X) Button(window, text='Install', command=self.install).pack(anchor='se') self.master.deiconify() def toggleroot(self): if self.syswide.get() == 0: self.instpath.set(installpaths['user']) elif self.syswide.get() == 1: self.instpath.set(installpaths['system']) def install(self): self.app = InstallWindow(setpath=self.path.get( ), installpath=self.instpath.get(), systemwide=self.syswide.get()) self.master.destroy()
def get_top_level(frames, kwargs=None): master = kwargs.pop('master') title = kwargs.pop('title') width = kwargs.get('width') height = kwargs.get('height') frames_kwargs = None if 'frames_kwargs' in kwargs.keys(): frames_kwargs = kwargs.pop('frames_kwargs') top_level = Toplevel(master=master, **kwargs) # Hide the toplevel top_level.withdraw() top_level.geometry( center_tk_window(window=top_level, height=width, width=height)) # Create main container frame that will hold all other frames top_level.grid_rowconfigure(0, weight=1) top_level.grid_columnconfigure(0, weight=1) container = ttk.Frame(top_level) container.grid(column=0, row=0, sticky="nsew") container.grid_rowconfigure(0, weight=1) container.grid_columnconfigure(0, weight=1) top_level.__setattr__('container', container) # Render all the other frames top_level_frames = {} for frame in frames: _frame = frame(parent=container, controller=top_level, kwargs=frames_kwargs[frame] if frames_kwargs else None) top_level_frames[frame] = _frame _frame.grid(row=0, column=0, sticky='nsew') top_level.__setattr__('frames', top_level_frames) # Define the title if title: top_level.title(title) # Raise the first frame top_level_frames[frames[0]].tkraise() # Make the toplevel visible again top_level.deiconify() return top_level
class UninstallWindow: def __init__(self, installpath, installtype): global root self.installpath = installpath self.installtype = installtype self.master = Toplevel(root) self.master.withdraw() self.master.iconbitmap(imgdir) self.master.protocol('WM_DELETE_WINDOW', root.destroy) self.master.title('Adb & Fastboot uninstaller - By @Pato05') self.master.resizable(False, False) self.master.geometry('400x100+100+100') frame = Frame(self.master, relief=FLAT) frame.pack(padx=10, pady=5, fill=BOTH) Label(frame, text='Found an installation of Adb & Fastboot.', font=('Segoe UI', 12)).pack(fill=X) Label(frame, text='What do you want to do?', font=('Segoe UI', 12)).pack(fill=X) btnframe = Frame(frame, relief=FLAT) btnframe.pack(fill=X, pady=(10, 0)) Button(btnframe, text='Uninstall', command=self.uninstall).pack( side=LEFT, anchor='w', expand=1) Button(btnframe, text='Update', command=self.update).pack( side=RIGHT, anchor='e', expand=1) self.master.deiconify() def uninstall(self): self.app = FinishWindow(True, self.remove(True), None, 'uninstall') self.master.destroy() def remove(self, removePath=True): from subprocess import call as subcall subcall([os.path.join(self.installpath, "adb.exe"), 'kill-server'], creationflags=0x00000008) rmtree(self.installpath) if removePath: return clearPath(self.installpath, self.installtype == 'system') else: return True def update(self): self.remove(False) self.app = InstallWindow( False, self.installpath, self.installtype == 'system', 'update') self.master.destroy()
class SettingsWindow: def __init__(self, parent): self.master = Toplevel(parent) self.master.withdraw() self.master.geometry('+{x}+{y}'.format(x=parent.winfo_x(), y=parent.winfo_y())) self.master.wm_attributes("-topmost", 1) self.master.focus_force() self.master.wm_title("StreamTicker Settings") self.master.iconbitmap("imagefiles/stIcon.ico") self.master.resizable(False, False) self.master.grab_set() self.parent = parent self.fields = SettingsGUIFields() self.mFrame = SettingsMessageFrame(self.master, self.fields) self.mFrame.frame.grid(row=0, column=0, rowspan=3, sticky=NSEW, padx=4, pady=4) self.bgFrame = SettingsBackgroundFrame(self, self.fields) self.bgFrame.frame.grid(row=0, column=1, sticky=NSEW, padx=4, pady=4) self.sFrame = SettingsWindowFrame(self.master, self.fields) self.sFrame.frame.grid(row=1, column=1, sticky=NSEW, padx=4, pady=4) self.okFrame = OkCancelFrame(self) self.okFrame.frame.grid(row=2, column=1, sticky=SE, padx=4, pady=4) self.fields.loadSettings(self.master, self.parent, self.mFrame, self.bgFrame) self.master.deiconify() self.master.mainloop()
class FinishWindow: def __init__(self, setpath, pathres, installpath, type='install'): global root self.master = Toplevel(root) self.master.withdraw() self.master.protocol('WM_DELETE_WINDOW', root.destroy) self.master.iconbitmap(imgdir) self.master.title('Adb & Fastboot installer - By @Pato05') self.master.resizable(False, False) frame = Frame(self.master, relief=FLAT) frame.pack(padx=10, pady=5, fill=BOTH) Label(frame, text=('Adb & Fastboot were successfully %s!' % ( 'updated' if type == 'update' else type+'ed')), font=('Segoe UI', 15)).pack(fill=X) if installpath is not None: Label(frame, text='Installation path: %s' % installpath, font=('Segoe UI', 12)).pack(fill=X) if setpath == 1 and pathres: Label(frame, text='You might need to restart applications to update PATH.', font=( 'Segoe UI', 12)).pack(fill=X) elif setpath == 1 and not pathres: Style().configure('Red.TLabel', foreground='red') Label(frame, text='Failed to put Adb & Fastboot into path.', font=('Segoe UI', 12), style='Red.TLabel').pack(fill=X) self.master.deiconify()
class UpdatingTwitchTagsWindow: def __init__(self, parent): self.window = Toplevel(parent.window) self.window.withdraw() self.window.protocol("WM_DELETE_WINDOW", self.noClose) self.parent = parent self.tags = deepcopy(parent.tags) self.frame = Frame(self.window) self.frame.grid(row=0, sticky=NSEW, padx=4, pady=4) labelPleaseWait = Label(self.frame, text=MessageConstants.UPDATING_TWITCH_TAGS) labelPleaseWait.grid(row=0, sticky=NSEW, padx=4, pady=4) WindowHelper.initializeWindow(self.window, self.parent, 300, 100, 30, 50, LabelConstants.UPDATE_IN_PROGRESS) self.window.deiconify() self.parent.window.attributes('-disabled', 0) self.parent.window.deiconify() self.window.update() beforeLen = len(self.tags) self.tags = updateTwitchTags(self.parent.parent.credentials.oauth, self.tags, True) afterLen = len(self.tags) messagebox.showinfo( LabelConstants.UPDATE_COMPLETE, MessageConstants.TAGS_ADDED.format(afterLen - beforeLen)) self.parent.tags = self.tags self.window.destroy() def noClose(self): # Prevents closing the window while updating pass
class ReportBug(object): def __init__(self, interface_idioma, master, design, idioma, icon): self.__bt_report = None self.__image_bug = None self.__bt_cancel = None self.__fr_botoes = None self.__lb_label3 = None self.__lb_label2 = None self.__lb_label1 = None self.__tp_princi = None self.interface_idioma = interface_idioma self.master = master self.design = design self.idioma = idioma self.icon = icon def __acessar_site_reporte(self): website_forms = "https://forms.gle/J4kE2Li8c58fz4hh6" self.__bt_report.configure( text=self.interface_idioma["abrir_formulario"][self.idioma]) t = Thread(target=lambda event=None: webbrowser_open(website_forms)) t.start() self.__destruir_interface() def __destruir_interface(self): self.__bt_report.destroy() self.__bt_cancel.destroy() self.__fr_botoes.destroy() self.__lb_label3.destroy() self.__lb_label2.destroy() self.__lb_label1.destroy() self.__tp_princi.destroy() def bug_carregar_tela(self): self.__image_bug = PhotoImage(file="imagens/bug.png") self.__image_bug = self.__image_bug.subsample(4) self.__tp_princi = Toplevel( self.master, bd=10, bg=self.design.dic["bug_lb1_encontrou_bug"]["bg"]) self.__tp_princi.resizable(False, False) self.__tp_princi.title( self.interface_idioma["titulo_reporte_bug"][self.idioma]) self.__tp_princi.tk.call('wm', 'iconphoto', self.__tp_princi._w, self.icon) self.__tp_princi.withdraw() try: self.__tp_princi.wm_attributes('-type', 'splash') except Exception as erro: print("Erro ao remover barra de titulos => ", erro) self.__lb_label1 = Label(self.__tp_princi) self.__lb_label2 = Label(self.__tp_princi) self.__lb_label3 = Label(self.__tp_princi) self.__lb_label1.configure(self.design.dic["bug_lb1_encontrou_bug"]) self.__lb_label2.configure(self.design.dic["bug_lb2_encontrou_bug"]) self.__lb_label3.configure(self.design.dic["bug_lb3_encontrou_bug"]) self.__lb_label1.configure( text=self.interface_idioma["encontrou_bug"][self.idioma]) self.__lb_label2.configure(image=self.__image_bug) self.__lb_label3.configure( text=self.interface_idioma["texto_reportar_bug"][self.idioma]) self.__fr_botoes = Frame(self.__tp_princi, self.design.dic["bug_fr_bt_encontrou_bug"]) self.__bt_cancel = Button( self.__fr_botoes, self.design.dic["bug_bt_canc_encontrou_bug"], text=self.interface_idioma["texto_depois"][self.idioma], relief=FLAT) self.__bt_report = Button( self.__fr_botoes, self.design.dic["bug_bt_report_encontrou_bug"], text=self.interface_idioma["texto_reporte_bug"][self.idioma], relief=FLAT) self.__tp_princi.grid_columnconfigure(1, weight=1) self.__fr_botoes.grid_columnconfigure(1, weight=1) self.__fr_botoes.grid_columnconfigure(2, weight=1) self.__bt_cancel.configure( command=lambda event=None: self.__destruir_interface()) self.__bt_report.configure( command=lambda event=None: self.__acessar_site_reporte()) self.__lb_label1.grid(row=1, column=1, sticky=NSEW) self.__lb_label2.grid(row=2, column=1, sticky=NSEW) self.__lb_label3.grid(row=3, column=1, sticky=NSEW) self.__fr_botoes.grid(row=4, column=1, sticky=NSEW) self.__bt_cancel.grid(row=1, column=1) self.__bt_report.grid(row=1, column=2) self.__tp_princi.update() self.__tp_princi.deiconify()
class Relat: #Guarda o ID do projeto aberto projeto_aberto = 0 #Janela prncipal def __init__(self, parent, db): self.parent = parent self.db = db self.parent.title("Relat") self.parent.geometry("700x450") self.parent.protocol("WM_DELETE_WINDOW", self.fechar_janela_ctrl) main_frame = Frame(self.parent) main_frame.pack(fill=BOTH, expand=YES) # TOOLBAR toolbar = Frame(main_frame) toolbar.pack(side=TOP, fill=X) self.projeto_img = tk.PhotoImage(file="./imagens/projetos.png") self.lista_projetos_btn = ttk.Button(toolbar, image=self.projeto_img, command=self.lista_projetos) self.lista_projetos_btn.pack(side=LEFT, padx=2, pady=2) self.iniciar_img = tk.PhotoImage(file="./imagens/iniciar.png") self.iniciar_btn = ttk.Button(toolbar, image=self.iniciar_img, command=self.iniciar_ctrl) self.iniciar_btn.state(['disabled']) # set the disabled flag, disabling the button self.iniciar_btn.pack(side=LEFT, pady=1) self.cancelar_img = tk.PhotoImage(file="./imagens/stop.png") self.cancelar_btn = ttk.Button(toolbar, image=self.cancelar_img, command=self.cancelar_ctrl) self.cancelar_btn.state(['disabled']) # set the disabled flag, disabling the button # self.cancelar_btn.state(['!disabled']) self.cancelar_btn.pack(side=LEFT, pady=1) self.sair_img = tk.PhotoImage(file="./imagens/sair.png") self.sair_btn = ttk.Button(toolbar, image=self.sair_img, command=self.fechar_janela_ctrl) self.sair_btn.pack(side=LEFT, pady=1) status_bar = Frame(main_frame) status_bar.pack(side=BOTTOM, fill=X) self.text_status_bar = Label(status_bar, text="www.KlinikPython.Wordpress.Com", relief=SUNKEN, bd=1) self.text_status_bar.pack(side=LEFT, fill=X, expand=True) frame_central = ttk.Notebook(main_frame) grid_frame = Frame(frame_central, bd=10) grid_frame.pack(fill=BOTH, expand=YES, side=LEFT) self.dataCols = ('nome', 'ultima_atualizacao') self.relatorios_grid = ttk.Treeview(grid_frame, selectmode='browse', columns=self.dataCols) self.relatorios_grid.bind("<Double-1>", self.alterar_relatorio_click) #self.relatorios_grid.bind("<Button-1>", self.habilita_btn_relat) scroll_y = ttk.Scrollbar(grid_frame, orient=VERTICAL, command=self.relatorios_grid.yview) scroll_x = ttk.Scrollbar(grid_frame, orient=HORIZONTAL, command=self.relatorios_grid.xview) self.relatorios_grid['yscroll'] = scroll_y.set self.relatorios_grid['xscroll'] = scroll_x.set scroll_y.configure(command=self.relatorios_grid.yview) scroll_y.pack(side=RIGHT, fill=Y) scroll_x.configure(command=self.relatorios_grid.xview) scroll_x.pack(side=BOTTOM, fill=X) # setup column headings self.relatorios_grid['show'] = 'headings' self.relatorios_grid.heading('nome', text='Nome', anchor=W) self.relatorios_grid.column('nome', stretch=0, width=200) self.relatorios_grid.heading('ultima_atualizacao', text='Última Atualização', anchor=W) # self.projetos_grid.column('ultima_atualizacao', stretch=0, width=100) self.relatorios_grid.pack(fill=BOTH, side=LEFT, expand=True) self.relatorios_grid.bind("<Double-1>", self.alterar_relatorio_click) frame_central.add(grid_frame, text="Relatórios") frame_central.add(Frame(), text="Configurações") frame_central.pack(side=LEFT, fill=BOTH, expand=1) frame_botoes = Frame(main_frame, width=200, padx=20, pady=30) frame_botoes.pack(side=RIGHT, fill=Y) self.novo_relatorio_img = tk.PhotoImage(file="./imagens/incluir.png") self.novo_relatorio_btn = ttk.Button(frame_botoes, width=20, text="Incluir", image=self.novo_relatorio_img, compound=LEFT, command=lambda: self.form_relatorio('novo')) self.novo_relatorio_btn.state(['disabled']) self.novo_relatorio_btn.pack(side=TOP, pady=2) self.alterar_relatorio_img = tk.PhotoImage(file="./imagens/alterar.png") self.alterar_relatorio_btn = ttk.Button(frame_botoes, width=20, text="Alterar", image=self.alterar_relatorio_img, compound=LEFT, command=lambda: self.form_relatorio('alterar')) self.alterar_relatorio_btn.state(['disabled']) self.alterar_relatorio_btn.pack(side=TOP, pady=2) self.excluir_relatorio_img = tk.PhotoImage(file="./imagens/excluir.png") self.excluir_relatorio_btn = ttk.Button(frame_botoes, width=20, text="Excluir", image=self.excluir_relatorio_img, compound=LEFT, command=self.excluir_relatorio_ctrl) self.excluir_relatorio_btn.state(['disabled']) self.excluir_relatorio_btn.pack(side=TOP, pady=2) self.move_up_img = tk.PhotoImage(file="./imagens/up.png") self.move_up_btn = ttk.Button(frame_botoes, width=20, text="Mover para cima", image=self.move_up_img, compound=LEFT, command=self.move_up_ctrl) self.move_up_btn.state(['disabled']) self.move_up_btn.pack(side=TOP, pady=2) self.move_down_img = tk.PhotoImage(file="./imagens/down.png") self.move_down_btn = ttk.Button(frame_botoes, width=20, text="Mover para baixo", image=self.move_down_img, compound=LEFT, command=self.move_down_ctrl) self.move_down_btn.state(['disabled']) self.move_down_btn.pack(side=TOP, pady=2) menu_bar = tk.Menu(main_frame) projeto_menu = tk.Menu(menu_bar, tearoff=0) projeto_menu.add_command(label="Projetos", command=self.lista_projetos) projeto_menu.add_command(label="Fechar Projeto", command=self.fechar_projeto_ctrl) projeto_menu.add_separator() projeto_menu.add_command(label="Sair", command=self.fechar_janela_ctrl) menu_bar.add_cascade(label="Projetos", menu=projeto_menu) ajuda_menu = tk.Menu(menu_bar, tearoff=0) ajuda_menu.add_command(label="Ajuda", command=self.sobre_ctrl) ajuda_menu.add_command(label="Licença", command=self.sobre_ctrl) ajuda_menu.add_separator() ajuda_menu.add_command(label="Sobre", command=self.sobre_ctrl) menu_bar.add_cascade(label="Sobre", menu=ajuda_menu) self.parent.config(menu=menu_bar) def lista_projetos(self): self.projeto_janela = Toplevel(self.parent) self.projeto_janela.title("Projetos") self.projeto_janela.geometry("400x400") self.projeto_janela.protocol("WM_DELETE_WINDOW", self.fechar_projeto_janela_ctrl) self.projeto_janela.withdraw() self.projeto_janela.grid() self.projeto_janela.transient(self.parent) self.projeto_janela.grab_set() projeto_frame = Frame(self.projeto_janela) projeto_frame.pack(fill=BOTH, expand=True) fechar_proj_btn = ttk.Button(self.projeto_janela, text="Fechar", width=10, command=self.fechar_projeto_janela_ctrl) fechar_proj_btn.pack(side=RIGHT, padx=5, pady=5) self.excluir_proj_btn = ttk.Button(self.projeto_janela, text="Excluir", width=10, command=self.excluir_projeto_ctrl) self.excluir_proj_btn.pack(side=RIGHT, padx=5, pady=5) self.excluir_proj_btn.state(["disabled"]) self.abrir_proj_btn = ttk.Button(self.projeto_janela, text="Abrir", width=10, command=self.abrir_projeto_ctrl) self.abrir_proj_btn.pack(side=RIGHT) self.abrir_proj_btn.state(["disabled"]) self.alterar_proj_btn = ttk.Button(self.projeto_janela, text="Alterar", width=10, command=lambda: self.form_projeto('alterar')) self.alterar_proj_btn.pack(side=RIGHT) self.alterar_proj_btn.state(["disabled"]) novo_proj_btn = ttk.Button(self.projeto_janela, text="Novo", width=10, command=lambda: self.form_projeto('novo')) novo_proj_btn.pack(side=RIGHT, padx=5, pady=5) grid_frame = Frame(projeto_frame, bd=10) grid_frame.pack(fill=BOTH, expand=YES, side=LEFT) self.dataCols = ('nome', 'ultima_atualizacao') self.projetos_grid = ttk.Treeview(grid_frame, selectmode='browse', columns=self.dataCols) self.projetos_grid.bind("<Double-1>", self.abrir_projeto_click) self.projetos_grid.bind("<Button-1>", self.habilita_btn_proj) scroll_y = ttk.Scrollbar(grid_frame, orient=VERTICAL, command=self.projetos_grid.yview) scroll_x = ttk.Scrollbar(grid_frame, orient=HORIZONTAL, command=self.projetos_grid.xview) self.projetos_grid['yscroll'] = scroll_y.set self.projetos_grid['xscroll'] = scroll_x.set scroll_y.configure(command=self.projetos_grid.yview) scroll_y.pack(side=RIGHT, fill=Y) scroll_x.configure(command=self.projetos_grid.xview) scroll_x.pack(side=BOTTOM, fill=X) # setup column headings self.projetos_grid['show'] = 'headings' self.projetos_grid.heading('nome', text='Nome', anchor=W) self.projetos_grid.column('nome', stretch=0, width=200) self.projetos_grid.heading('ultima_atualizacao', text='Última Atualização', anchor=W) # self.projetos_grid.column('ultima_atualizacao', stretch=0, width=100) self.projetos_grid.pack(fill=BOTH, side=LEFT, expand=True) centro_(self.projeto_janela) self.lista_projetos_ctrl() self.projeto_janela.deiconify() self.parent.wait_window(self.projeto_janela) def lista_projetos_ctrl(self): self.projetos_grid.delete(*self.projetos_grid.get_children()) dados = ProjetosDb(self.db).listar_projetos() for row in dados: formato = '{%d/%m/%Y %H:%M:%S}' #datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M") self.projetos_grid.insert('', END, row[0], values=(row[1], row[12])) def form_projeto(self, acao): self.form_projeto_janela = Toplevel(self.parent) self.form_projeto_janela.resizable(0, 0) if acao == 'novo': self.form_projeto_janela.title("Novo Projeto") else: self.form_projeto_janela.title("Alterar Projeto") self.form_projeto_janela.geometry("700x400") self.form_projeto_janela.protocol("WM_DELETE_WINDOW", self.fechar_form_projeto_ctrl) self.form_projeto_janela.withdraw() self.form_projeto_janela.grid() self.form_projeto_janela.transient(self.parent) self.form_projeto_janela.grab_set() projeto_frame = Frame(self.form_projeto_janela) projeto_frame.pack(fill=BOTH, expand=True) cancelar_btn = ttk.Button(self.form_projeto_janela, text="Cancelar", width=10, command=self.fechar_form_projeto_ctrl) cancelar_btn.pack(side=RIGHT, padx=5, pady=5) salvar_btn = ttk.Button(self.form_projeto_janela, text="Salvar", width=10, command=lambda: self.salvar_projeto_ctrl(acao)) salvar_btn.pack(side=RIGHT) info_frame = Frame(projeto_frame, bd=10) info_frame.pack(fill=BOTH, expand=YES, side=RIGHT) group_info = ttk.LabelFrame(info_frame, text="Informações", padding=(6, 6, 12, 12)) group_info.grid(row=0, column=0, sticky='nsew') ttk.Label(group_info, text='Nome', width=10).grid(row=0, column=0, sticky=W) self.nome = ttk.Entry(group_info, width=25) self.nome.grid(row=0, column=1, sticky=W, pady=2) ttk.Label(group_info, text='Descrição', width=10).grid(row=1, column=0, sticky=W) self.descricao = Text(group_info, height=4, width=25) self.descricao.configure(font=font.Font(font=self.nome['font'])) self.descricao.grid(row=1, column=1, sticky=W, pady=2) ttk.Label(group_info, text='Autor', width=10).grid(row=2, column=0, sticky=W) self.autor = ttk.Entry(group_info, width=25) self.autor.grid(row=2, column=1, sticky=W, pady=2) group_db = ttk.LabelFrame(info_frame, text="Acesso ao banco", padding=(6, 6, 12, 12)) group_db.grid(row=1, column=0, sticky=NSEW) ttk.Label(group_db, text='Tipo', width=10).grid(row=0, column=0, sticky=W) self.bd_tipo_value = tk.StringVar() self.bd_tipo = ttk.Combobox(group_db, textvariable=self.bd_tipo_value, state="readonly", width=22) self.bd_tipo['values'] = ('', 'Oracle', 'Mysql', 'PostgreSql') self.bd_tipo.current(0) self.bd_tipo.grid(row=0, column=1, sticky=W, pady=2) ttk.Label(group_db, text='Servidor', width=10).grid(row=1, column=0, sticky=W) self.bd_servidor = ttk.Entry(group_db, width=25) self.bd_servidor.grid(row=1, column=1, sticky=W, pady=2) ttk.Label(group_db, text='Porta', width=10).grid(row=2, column=0, sticky=W) self.bd_porta = ttk.Entry(group_db, width=15) self.bd_porta.grid(row=2, column=1, sticky=W, pady=2) ttk.Label(group_db, text='Banco', width=10).grid(row=3, column=0, sticky=W) self.bd_banco = ttk.Entry(group_db, width=25) self.bd_banco.grid(row=3, column=1, sticky=W, pady=2) ttk.Label(group_db, text='Usuário', width=10).grid(row=4, column=0, sticky=W) self.bd_usuario = ttk.Entry(group_db, width=25) self.bd_usuario.grid(row=4, column=1, sticky=W, pady=2) ttk.Label(group_db, text='Senha', width=10).grid(row=5, column=0, sticky=W) self.bd_senha = ttk.Entry(group_db, show="*", width=25) self.bd_senha.grid(row=5, column=1, sticky=W, pady=2) centro_(self.form_projeto_janela) if acao == 'alterar': self.alterar_projeto_ctrl() self.form_projeto_janela.deiconify() self.parent.wait_window(self.form_projeto_janela) def alterar_projeto_ctrl(self): projeto_id = self.projetos_grid.selection()[0] projeto = ProjetosDb(self.db).localizar_projeto(projeto_id) self.nome.insert(0, projeto[1]) self.descricao.insert(END, projeto[2]) self.autor.insert(0, projeto[3]) self.bd_tipo.current(projeto[4]) self.bd_servidor.insert(0, projeto[5]) self.bd_porta.insert(0, projeto[6]) self.bd_banco.insert(0, projeto[7]) self.bd_usuario.insert(0, projeto[9]) self.bd_senha.insert(0, projeto[10]) def salvar_projeto_ctrl(self, acao): arr = [] arr.append(self.nome.get()) arr.append(self.descricao.get("1.0", END)) arr.append(self.autor.get()) bd_tipo = self.bd_tipo.current() arr.append(bd_tipo) arr.append(self.bd_servidor.get()) arr.append(self.bd_porta.get()) arr.append(self.bd_banco.get()) # if (bd_tipo == 1) # conexao = oracle+cx_oracle://user:pass@host:port/dbname arr.append(self.bd_usuario.get()) arr.append(self.bd_senha.get()) arr.append("conexao") #Novo Projeto if acao == 'novo': #data de criação arr.append(datetime.now().isoformat(" ")) retorno = ProjetosDb(self.db).novo_projeto(arr) # if retorno.isnumeric: # self.projetos_grid.insert('', END, arr[0], values=(row[1], row[9])) self.fechar_form_projeto_ctrl() self.fechar_projeto_janela_ctrl() self.habilita_btn_abrir_proj() #Alterar projeto else: projeto_id = self.projetos_grid.selection()[0] # id do projeto arr.append(projeto_id) retorno = ProjetosDb(self.db).alterar_projeto(arr) # if retorno.isnumeric: # self.projetos_grid.insert('', END, arr[0], values=(row[1], row[9])) self.lista_projetos_ctrl() self.fechar_form_projeto_ctrl() def excluir_projeto_ctrl(self): if deleteBox("Excluir", "Deseja realmente excluir o projeto selecionado?"): item = self.projetos_grid.selection()[0] self.projetos_grid.delete(item) ProjetosDb(self.db).excluirProjeto(item) print("Projeto excluído: ", item) def indica_porta_bd(self, event): current = self.db_tipo.current() if current != -1: if current == 'Oracle': self.porta def fechar_janela_ctrl(self): self.parent.destroy() def fechar_projeto_ctrl(self): for child in self.relatorios_grid.get_children(): print(self.relatorios_grid.item(child)["values"]) #self.projetos_grid.delete(item) self.iniciar_btn.state(["disabled"]) self.cancelar_btn.state(["disabled"]) self.novo_relatorio_btn.state(["disabled"]) self.alterar_relatorio_btn.state(["disabled"]) self.excluir_relatorio_btn.state(["disabled"]) self.move_up_btn.state(["disabled"]) self.move_down_btn.state(["disabled"]) #Limpar a lista de relatórios self.relatorios_grid.delete(*self.relatorios_grid.get_children()) def fechar_projeto_janela_ctrl(self): self.projeto_janela.destroy() def fechar_form_projeto_ctrl(self): self.form_projeto_janela.destroy() def abrir_projeto_ctrl(self): projeto_id = self.projetos_grid.selection()[0] self.projeto_aberto = projeto_id relatorios_lista = RelatoriosDb(self.db).listar_relatorios(projeto_id) #print(relatorios_lista) self.lista_relatorios_ctrl(relatorios_lista) self.fechar_projeto_janela_ctrl() self.habilita_btn_abrir_proj() def abrir_projeto_click(self, event): projeto_id = self.projetos_grid.selection()[0] relatorios_lista = RelatoriosDb(self.db).listar_relatorios(projeto_id) #print(relatorios_lista) self.lista_relatorios_ctrl(relatorios_lista) self.fechar_projeto_janela_ctrl() self.habilita_btn_abrir_proj() def habilita_btn_proj(self, event): self.alterar_proj_btn.state(["!disabled"]) self.abrir_proj_btn.state(["!disabled"]) self.excluir_proj_btn.state(["!disabled"]) def habilita_btn_abrir_proj(self): self.novo_relatorio_btn.state(["!disabled"]) self.iniciar_btn.state(["!disabled"]) def iniciar_ctrl(self): self.lista_projetos_btn.state(["disabled"]) self.sair_btn.state(["disabled"]) self.novo_relatorio_btn.state(["disabled"]) self.alterar_relatorio_btn.state(["disabled"]) self.excluir_relatorio_btn.state(["disabled"]) self.move_up_btn.state(["disabled"]) self.move_down_btn.state(["disabled"]) self.iniciar_btn.state(["disabled"]) self.cancelar_btn.state(["!disabled"]) def cancelar_ctrl(self): self.lista_projetos_btn.state(["!disabled"]) self.sair_btn.state(["!disabled"]) self.novo_relatorio_btn.state(["!disabled"]) self.iniciar_btn.state(["!disabled"]) self.cancelar_btn.state(["disabled"]) def form_relatorio(self, acao): print('Projeto aberto:', self.projeto_aberto) self.form_relatorio_janela = Toplevel() self.form_relatorio_janela.resizable(0, 0) if acao == 'incluir': self.form_relatorio_janela.title("Novo Relatório") else: self.form_relatorio_janela.title("Alterar Relatório") self.form_relatorio_janela.geometry("500x300") self.form_relatorio_janela.protocol("WM_DELETE_WINDOW", self.fechar_form_relatorio_ctrl) self.form_relatorio_janela.withdraw() self.form_relatorio_janela.grid() self.form_relatorio_janela.transient(self.parent) self.form_relatorio_janela.grab_set() relatorio_frame = Frame(self.form_relatorio_janela, relief=RAISED, borderwidth=1) relatorio_frame.pack(fill=BOTH, expand=True) relatorio_tab = ttk.Notebook(relatorio_frame) relatorio_tab.pack(fill=BOTH, expand=True) cancelar_btn = ttk.Button(self.form_relatorio_janela, text="Cancelar", width=10, command=self.fechar_form_relatorio_ctrl) cancelar_btn.pack(side=RIGHT, padx=5, pady=5) ok_btn = ttk.Button(self.form_relatorio_janela, text="Incluir", width=10, command=self.alterar_relatorio_ctrl) ok_btn.pack(side=RIGHT) info_frame = Frame(relatorio_tab, bd=10) info_frame.pack(fill=BOTH, expand=YES, side=RIGHT) group_info = ttk.LabelFrame(info_frame, text="Informações", padding=(6, 6, 12, 12)) group_info.grid(row=0, column=0, sticky='nsew') ttk.Label(group_info, text='Nome', width=10).grid(row=0, column=0, sticky=W) self.nome_relatorio = ttk.Entry(group_info, width=25) self.nome_relatorio.grid(row=0, column=1, sticky=W, pady=2) ttk.Label(group_info, text='Descrição', width=10).grid(row=1, column=0, sticky=W) self.descricao_relatorio = Text(group_info, height=4, width=25) self.descricao_relatorio.configure(font=font.Font(font=self.nome_relatorio['font'])) self.descricao_relatorio.grid(row=1, column=1, sticky=W, pady=2) ttk.Label(group_info, text='Autor', width=10).grid(row=2, column=0, sticky=W) self.autor_relatorio = ttk.Entry(group_info, width=25) self.autor_relatorio.grid(row=2, column=1, sticky=W, pady=2) consulta_frame = ttk.Frame(relatorio_tab) sql_frame = ttk.LabelFrame(consulta_frame, text="Sql", padding=(6, 6, 12, 12)) sql_frame.grid(row=0, column=0, sticky=NSEW) self.consulta = Text(sql_frame, height=4, width=25) self.consulta.configure(font=font.Font(font=self.nome_relatorio['font'])) self.consulta.grid(row=0, column=0, sticky=W, pady=2) colunas_frame = ttk.LabelFrame(consulta_frame, text="Colunas", padding=(6, 6, 12, 12)) colunas_frame.grid(row=0, column=0, sticky=NSEW) self.dataCols = ('nome', 'complemento') self.colunas_grid = ttk.Treeview(colunas_frame, selectmode='browse', columns=self.dataCols) self.colunas_grid.bind("<Double-1>", self.abrir_projeto_click) self.colunas_grid.bind("<Button-1>", self.habilita_btn_proj) scroll_y = ttk.Scrollbar(colunas_frame, orient=VERTICAL, command=self.colunas_grid.yview) scroll_x = ttk.Scrollbar(colunas_frame, orient=HORIZONTAL, command=self.colunas_grid.xview) self.colunas_grid['yscroll'] = scroll_y.set self.colunas_grid['xscroll'] = scroll_x.set scroll_y.configure(command=self.colunas_grid.yview) scroll_y.pack(side=RIGHT, fill=Y) scroll_x.configure(command=self.colunas_grid.xview) scroll_x.pack(side=BOTTOM, fill=X) # setup column headings self.colunas_grid['show'] = 'headings' self.colunas_grid.heading('nome', text='Nome', anchor=W) self.colunas_grid.column('nome', stretch=0, width=200) self.colunas_grid.heading('complemento', text='Última Atualização', anchor=W) self.colunas_grid.pack(fill=BOTH, side=LEFT, expand=True) frame_botoes = Frame(relatorio_tab, width=200, padx=20, pady=30) frame_botoes.pack(side=RIGHT, fill=Y) self.novo_relatorio_img = tk.PhotoImage(file="./imagens/incluir.png") self.novo_relatorio_btn = ttk.Button(frame_botoes, width=20, text="Incluir", image=self.novo_relatorio_img, compound=LEFT, command=lambda: self.form_relatorio('novo')) self.novo_relatorio_btn.state(['disabled']) self.novo_relatorio_btn.pack(side=TOP, pady=2) self.alterar_relatorio_img = tk.PhotoImage(file="./imagens/alterar.png") self.alterar_relatorio_btn = ttk.Button(frame_botoes, width=20, text="Alterar", image=self.alterar_relatorio_img, compound=LEFT, command=lambda: self.form_relatorio('alterar')) self.alterar_relatorio_btn.state(['disabled']) self.alterar_relatorio_btn.pack(side=TOP, pady=2) f3 = ttk.Frame(relatorio_tab) # second page relatorio_tab.add(info_frame, text='Informações') relatorio_tab.add(consulta_frame, text='Consulta') relatorio_tab.add(f3, text='Configuração') centro_(self.form_relatorio_janela) self.form_relatorio_janela.deiconify() self.parent.wait_window(self.form_relatorio_janela) def alterar_relatorio_ctrl(self): relatorio_id = self.relatorios_grid.selection()[0] relatorio = RelatoriosDb(self.db).localizar_relatorio(relatorio_id) self.nome.insert(0, projeto[1]) self.descricao.insert(END, projeto[2]) self.autor.insert(0, projeto[3]) self.bd_tipo.current(projeto[4]) self.bd_servidor.insert(0, projeto[5]) self.bd_porta.insert(0, projeto[6]) self.bd_banco.insert(0, projeto[7]) self.bd_usuario.insert(0, projeto[9]) self.bd_senha.insert(0, projeto[10]) def salvar_relatorio_ctrl(self, acao): arr = [] arr.append(self.nome.get()) arr.append(self.descricao.get("1.0", END)) arr.append(self.autor.get()) tipo_operacao = self.tipo_operacao.current() arr.append(bd_tipo) arr.append(self.bd_servidor.get()) arr.append(self.bd_porta.get()) arr.append(self.bd_banco.get()) arr.append(self.bd_usuario.get()) arr.append(self.bd_senha.get()) #Novo Relatorio if acao == 'novo': #data de criação arr.append(datetime.now().isoformat(" ")) retorno = RelatoriosDb(self.db).novo_relatorio(arr) # if retorno.isnumeric: # self.projetos_grid.insert('', END, arr[0], values=(row[1], row[9])) self.fechar_form_relatorio_ctrl() #Alterar relatorio else: relatorio_id = self.relatorios_grid.selection()[0] # id do projeto arr.append(relatorio_id) retorno = RelatoriosDb(self.db).alterar_relatorio(arr) # if retorno.isnumeric: # self.projetos_grid.insert('', END, arr[0], values=(row[1], row[9])) self.fechar_form_relatorio_ctrl() def lista_relatorios_ctrl(self, relatorios): self.relatorios = relatorios for row in self.relatorios: self.relatorios_grid.insert("", END, row[0], values=(row[2], row[8])) def fechar_form_relatorio_ctrl(self): self.form_relatorio_janela.destroy() def habilita_btn_relat(self, event): self.alterar_relatorio_btn.state(["!disabled"]) self.excluir_relatorio_btn.state(["!disabled"]) self.move_up_btn.state(["!disabled"]) self.move_down_btn.state(["!disabled"]) def alterar_relatorio_click(self, event): self.form_relatorio('alterar') def excluir_relatorio_ctrl(self, db): if deleteBox("Excluir", "Deseja realmente excluir o relatório selecionado?"): relatorio_id = self.relatorios_grid.selection() self.relatorios_grid.delete(relatorio_id) RelatoriosDb(self.db).excluir_relatorio(relatorio_id) print("Relatório excluído: ", relatorio_id) def move_up_ctrl(self): relatorio = self.relatorios_grid.selection() print("item: ", relatorio) for i in relatorio: self.relatorios_grid.move(i, self.relatorios_grid.parent(i), self.relatorios_grid.index(i) - 1) def move_down_ctrl(self): leaves = self.relatorios_grid.selection() for i in leaves: self.relatorios_grid.move(i, self.relatorios_grid.parent(i), self.relatorios_grid.index(i) + 1) def sobre_ctrl(self): app = Sobre(self.parent)
class ToolTipManager: label = None window = None active = 0 def __init__(self): self.tag = None def getcontroller(self, widget): if self.tag is None: self.tag = "ui_tooltip_%d" % id(self) widget.bind_class(self.tag, "<Enter>", self.enter) widget.bind_class(self.tag, "<Leave>", self.leave) # pick suitable colors for tooltips try: self.bg = "systeminfobackground" self.fg = "systeminfotext" widget.winfo_rgb(self.fg) # make sure system colors exist widget.winfo_rgb(self.bg) except: self.bg = "#ffffe0" self.fg = "black" return self.tag def register(self, widget, text): widget.ui_tooltip_text = text tags = list(widget.bindtags()) tags.append(self.getcontroller(widget)) widget.bindtags(tuple(tags)) def unregister(self, widget): tags = list(widget.bindtags()) tags.remove(self.getcontroller(widget)) widget.bindtags(tuple(tags)) # event handlers def enter(self, event): widget = event.widget if not self.label: # create and hide balloon help window self.popup = Toplevel(bg=self.fg, bd=1) self.popup.overrideredirect(1) self.popup.withdraw() self.label = Label(self.popup, fg=self.fg, bg=self.bg, bd=0, padx=2, justify=LEFT) self.label.pack() self.active = 0 self.xy = event.x_root + 16, event.y_root + 10 self.event_xy = event.x, event.y self.after_id = widget.after(200, self.display, widget) def display(self, widget): if not self.active: # display balloon help window text = widget.ui_tooltip_text if callable(text): text = text(widget, self.event_xy) self.label.config(text=text) self.popup.deiconify() self.popup.lift() self.popup.geometry("+%d+%d" % self.xy) self.active = 1 self.after_id = None def leave(self, event): widget = event.widget if self.active: self.popup.withdraw() self.active = 0 if self.after_id: widget.after_cancel(self.after_id) self.after_id = None
class AutoSearchCombobox(Entry): def __init__(self, master: Widget, values: Optional[Iterable[str]] = None, height: Optional[int]=None, **kwargs): super().__init__(master, **kwargs) self._tl = Toplevel(self, takefocus=False, relief=GROOVE, borderwidth=1) self._tl.wm_overrideredirect(True) self._lb = ScrolledListbox(self._tl, width=kwargs.pop('width', None), height=height, selectmode=SINGLE) self.values = values self._lb.pack(expand=True, fill=BOTH) self._hide_tl() self.winfo_toplevel().focus_set() self.bind('<KeyRelease>', self._handle_keyrelease) self.bind('<FocusOut>', self._handle_focusout) self.bind('<KeyPress>', self._handle_keypress) #toplevel bindings cfg_handler = self.winfo_toplevel().bind('<Configure>', self._handle_configure, add="+") self.bind('<Destroy>', lambda __, cfg_handler=cfg_handler: self._unbind_my_configure(cfg_handler)) def _unbind_my_configure(self, cfg_handler): """Internal function. Allows for JUST this widget's associated callback. Getting around tkinter bug""" root_tl = self.winfo_toplevel() if not cfg_handler: root_tl.tk.call('bind', self._w, '<Configure>', '') return func_callbacks = root_tl.tk.call( 'bind', root_tl._w, '<Configure>', None).split('\n') new_callbacks = [ l for l in func_callbacks if l[6:6 + len(cfg_handler)] != cfg_handler] root_tl.tk.call('bind', root_tl._w, '<Configure>', '\n'.join(new_callbacks)) root_tl.deletecommand(cfg_handler) @property def values(self): """ Gets the values """ try: return self.__values except AttributeError: self.values = () return self.values @values.setter def values(self, values: Optional[Iterable]): """ Sorts and sets the values """ self.__values = tuple(sorted(values)) if values is not None else tuple() self._lb.insert(END, *self.values) self._lb.selection_clear(0, END) self._lb.selection_set(0) self._lb.activate(0) @property def _lb_current_selection(self) -> str: """ Returns the current selection in the listbox """ try: sel = self._lb.curselection()[0] except IndexError: return None return self._lb.get(sel) def _set_lb_index(self, index): self._lb.selection_clear(0, END) self._lb.selection_set(index) self._lb.activate(index) self._lb.see(index) @property def text_after_cursor(self) -> str: """ Gets the entry text after the cursor """ contents = self.get() return contents[self.index(INSERT):] @property def dropdown_is_visible(self): return self._tl.winfo_ismapped() def _handle_keypress(self, event: Event): if 'Left' in event.keysym: if self.dropdown_is_visible: self._hide_tl() return 'break' else: return elif (('Right' in event.keysym and self.text_after_cursor == '') or event.keysym in ['Return', 'Tab']) and self.dropdown_is_visible: #Completion and block next action self.delete(0, END) self.insert(0, self._lb_current_selection) self._hide_tl() return 'break' def _handle_keyrelease(self, event: Event): if 'Up' in event.keysym and self.dropdown_is_visible: previous_index = self._lb.index(ACTIVE) new_index = max(0, self._lb.index(ACTIVE) - 1) self._set_lb_index(new_index) if previous_index == new_index: self._hide_tl() return if 'Down' in event.keysym: if self.dropdown_is_visible: current_index = self._lb.index(ACTIVE) new_index = min(current_index + 1, self._lb.size() - 1) self._set_lb_index(new_index) return 'break' if not self.dropdown_is_visible and self._lb.size() > 0: self._show_tl() if len(event.keysym) == 1 or ('Right' in event.keysym and self.text_after_cursor == '') or event.keysym in ['BackSpace']: if self.get() != '': new_values = [value for value in self.values if value.lower( ).startswith(self.get().lower())] else: new_values = self.values self._lb.delete(0, END) self._lb.insert(END, *new_values) self._set_lb_index(0) if self._lb.size() < 1 or self.get() == self._lb_current_selection: self._hide_tl() else: self._show_tl() def _handle_focusout(self, event: Event): def cf(): if self.focus_get() != self._tl and self.focus_get() != self._lb: self._hide_tl() else: self.focus_set() self.after(1, cf) def _handle_configure(self, event: Event): if self._tl.winfo_ismapped(): self._update_tl_pos() def _show_tl(self) -> None: if self._tl.winfo_ismapped() == False: self._update_tl_pos() self._tl.deiconify() self._tl.attributes("-topmost", True) def _update_tl_pos(self) -> None: self._tl.geometry('+{}+{}'.format(self.winfo_rootx(), self.winfo_rooty() + self.winfo_height() - 1)) def _hide_tl(self) -> None: self._tl.withdraw()
class Idioma(): def __init__(self, tela, design, idioma, interface_idioma, icon): self.icon = icon self.idioma = idioma self.interface_idioma = interface_idioma self.design = design self.tela = tela self.base = "imagens/" self.tp_interface_idioma = None self.bt_idioma = None self.lb1 = None self.dic_imgs = None def selecionar_idioma(self, dic_imgs): self.dic_imgs = dic_imgs self.tp_interface_idioma = Toplevel(self.tela, self.design.dic["idioma_tp"]) self.tp_interface_idioma.withdraw() self.tp_interface_idioma.tk.call('wm', 'iconphoto', self.tp_interface_idioma._w, self.icon) self.tp_interface_idioma.grid_columnconfigure(1, weight=1) self.tp_interface_idioma.title('Escolha de Idioma') self.fr_top_idioma = Frame(self.tp_interface_idioma, self.design.dic["idioma_fr"]) self.fr_top_idioma.grid_columnconfigure(1, weight=1) self.fr_top_idioma.grid(row=1, column=1, sticky=NSEW) self.lb1 = Label( self.fr_top_idioma, self.design.dic['idioma_lb'], text=self.interface_idioma["texto_atualizacao"][self.idioma]) self.lb1.grid(row=1, column=1, sticky=NSEW) self.fr_idionas = Frame(self.tp_interface_idioma, self.design.dic['idioma_fr2']) self.fr_idionas.grid(row=2, column=1) # Carregar as imagens self.imgs = [] for k, v in self.dic_imgs.items(): self.imgs.append(PhotoImage(file=self.base + v)) # Carregar os botões x = 0 self.lista_botoes = [] for k, v in self.dic_imgs.items(): if self.idioma == k: self.fr_bt = Frame(self.fr_idionas, self.design.dic['idioma_fr3']) self.bt_bt = Button( self.fr_bt, self.design.dic['idioma_bt'], relief=GROOVE, image=self.imgs[x], ) self.lb_bt = Label( self.fr_bt, self.design.dic['idioma_lb2'], relief=GROOVE, text=k, ) else: self.fr_bt = Frame(self.fr_idionas, self.design.dic['idioma_fr4']) self.bt_bt = Button( self.fr_bt, self.design.dic['idioma_bt2'], relief=GROOVE, image=self.imgs[x], ) self.lb_bt = Label(self.fr_bt, self.design.dic['idioma_lb3'], relief=GROOVE, text=k) self.bt_bt[ "command"] = lambda bt_bt=self.bt_bt, dic=self.dic_imgs: self.marcar_opcao_idioma( bt_bt, dic) self.lista_botoes.append([self.fr_bt, self.bt_bt, self.lb_bt]) self.fr_bt.grid(row=1, column=x) self.bt_bt.grid(row=1, column=x) self.lb_bt.grid(row=2, column=x) x += 1 self.tp_interface_idioma.update() t_width = self.tela.winfo_screenwidth() t_heigth = self.tela.winfo_screenheight() j_heigth = self.tp_interface_idioma.winfo_screenmmheight() j_width = self.tp_interface_idioma.winfo_screenmmwidth() self.tp_interface_idioma.geometry("+{}+{}".format( j_width, j_heigth, int(t_width / 2 - (j_width / 2)), int(t_heigth / 2 - (j_heigth / 2)))) self.tp_interface_idioma.deiconify() def marcar_opcao_idioma(self, botao, dic_imgs): self.dic_imgs = dic_imgs self.tp_interface_idioma.withdraw() for bandeira in self.lista_botoes: if bandeira[1] == botao: self.idioma = bandeira[2]["text"] self.ic_idioma = PhotoImage( file="imagens/{}".format(self.dic_imgs[self.idioma])) self.ic_idioma = self.ic_idioma.subsample(4, 4) funcoes.arquivo_de_configuracoes_interface( "idioma", self.idioma) #self.lb1.configure(text=self.interface_idioma["texto_atualizacao"][self.idioma]) self.tp_interface_idioma.destroy() del bandeira self.selecionar_idioma(self.dic_imgs) else: pass return 10, 20
class SnakeListView: """View class for a window containing a scrollable list of snakes. Each snake should be selectable. Double clicking a snake triggers a callback in any observers.""" def __init__(self, title): self.snakes = [] self.window = Toplevel(padx=5, pady=5) self.window.title(title) self.window.withdraw() self.window.protocol("WM_DELETE_WINDOW", self.on_close) self.window.resizable(width=False, height=False) self.listeners = [] self.create_info_label() self.create_snake_list() def create_info_label(self): infotext = "Click on any snake to view its simulation and encoding" self.info_label = Label(self.window, text=infotext) self.info_label.grid(row=0, column=0, columnspan=1, sticky=N + E + S + W) def create_snake_list(self): self.snake_listview_scrollbar = Scrollbar(self.window, orient=VERTICAL) self.snake_listview_scrollbar.grid(row=1, column=1, sticky=N + E + S + W) self.snake_listbox = Listbox(self.window) self.snake_listbox.grid(row=1, column=0, sticky=N + E + S + W) self.snake_listview_scrollbar.config(command=self.snake_listbox.yview) self.snake_listbox.config( yscrollcommand=self.snake_listview_scrollbar.set) self.snake_listbox.bind('<Double-1>', self.click_snake) def set_title(self, title): self.window.title(title) def set_snakes(self, snakes): self.snake_listbox.delete(0, END) self.snakes = snakes for snake in self.snakes: self.snake_listbox.insert(END, snake.score) def add_listener(self, listener): self.listeners.append(listener) def show(self): self.window.deiconify() def hide(self): self.window.withdraw() def on_close(self): for listener in self.listeners: listener.on_close_snakelist_window(self) def click_snake(self, event): selections = self.snake_listbox.curselection() if len(selections) > 0: snake = self.snakes[int(selections[0])] for listener in self.listeners: listener.on_click_snake(snake)
class DateChooserPopup: def __init__(self, parent=None, firstweekday=6, startdate=None ): """ Args: parent (Widget): The parent widget; the popup is displayed to the bottom-right of the parent widget. startdate (datetime): The date to be in focus when the calendar is displayed. Current date is default. firstweekday (int): Specifies the first day of the week. ``0`` is Monday, ``6`` is Sunday (the default). **kw: """ self.parent = parent self.root = Toplevel() self.firstweekday = firstweekday self.startdate = startdate self.date_selected = startdate or datetime.today() self.date = startdate or self.date_selected self.calendar = calendar.Calendar(firstweekday=firstweekday) self.cframe = ttk.Frame(self.root, padding=0, borderwidth=1, relief='raised') self.xframe = ttk.Frame(self.cframe, style='primary.TFrame') self.tframe = ttk.Frame(self.cframe, style='primary.TFrame') self.wframe = ttk.Frame(self.cframe) self.dframe = None self.titlevar = StringVar(value=f'{self.date.strftime("%B %Y")}') self.datevar = IntVar() self.setup() self.root.grab_set() self.root.wait_window() def define_style(self): pass def draw_calendar(self): self.titlevar.set(f'{self.date.strftime("%B %Y")}') self.monthdays = self.calendar.monthdayscalendar(self.date.year, self.date.month) self.monthdates = self.calendar.monthdatescalendar(self.date.year, self.date.month) self.dframe = ttk.Frame(self.cframe) self.dframe.pack(fill='both', expand='yes') self.set_geometry() # calendar days for row, wk in enumerate(self.monthdays): for col, day in enumerate(wk): self.dframe.columnconfigure(col, weight=1) if day == 0: lbl = ttk.Label(self.dframe, text=self.monthdates[row][col].day, anchor='center') lbl.configure(style='secondary.TLabel', padding=(0, 0, 0, 10)) lbl.grid(row=row, column=col, sticky='nswe') else: if all([ day == self.date_selected.day, self.date.month == self.date_selected.month, self.date.year == self.date_selected.year ]): day_style = 'success.Toolbutton' else: day_style = 'calendar.primary.Outline.Toolbutton' rb = ttk.Radiobutton(self.dframe, variable=self.datevar, value=day, text=day, style=day_style) rb.configure(padding=(0, 0, 0, 10), command=lambda x=row, y=col: self.on_date_selected([x, y])) rb.grid(row=row, column=col, sticky='nswe') def draw_titlebar(self): """Create the title bar""" # previous month button self.btn_prev = ttk.Button(self.tframe, text='«', style='primary.TButton', command=self.on_prev_month) self.btn_prev.configure(style='chevron.primary.TButton') self.btn_prev.pack(side='left') # month and year title self.title_label = ttk.Label(self.tframe, textvariable=self.titlevar, anchor='center') self.title_label.configure(style='primary.Inverse.TLabel', font='helvetica 11') self.title_label.pack(side='left', fill='x', expand='yes') # next month button self.btn_next = ttk.Button(self.tframe, text='»', style='primary.TButton', command=self.on_next_month) self.btn_next.configure(style='chevron.primary.TButton') self.btn_next.pack(side='left') # days of the week header for wd in self.weekday_header(): wd_lbl = ttk.Label(self.wframe, text=wd, anchor='center', padding=(0, 5, 0, 10)) wd_lbl.configure(style='secondary.Inverse.TLabel') wd_lbl.pack(side='left', fill='x', expand='yes') def on_date_selected(self, index): row, col = index self.date_selected = self.monthdates[row][col] self.root.destroy() def on_next_month(self): year, month = calendar._nextmonth(self.date.year, self.date.month) self.date = datetime(year=year, month=month, day=1).date() self.dframe.destroy() self.draw_calendar() def on_prev_month(self): year, month = calendar._prevmonth(self.date.year, self.date.month) self.date = datetime(year=year, month=month, day=1).date() self.dframe.destroy() self.draw_calendar() def set_geometry(self): """Adjust the window size based on the number of weeks in the month""" w = 226 h = 255 if len(self.monthdates) == 5 else 285 # this needs to be adjusted if I change the font size. if self.parent: xpos = self.parent.winfo_rootx() + self.parent.winfo_width() ypos = self.parent.winfo_rooty() + self.parent.winfo_height() self.root.geometry(f'{w}x{h}+{xpos}+{ypos}') else: xpos = self.root.winfo_screenwidth()//2 - w ypos = self.root.winfo_screenheight() //2 - h self.root.geometry(f'{w}x{h}+{xpos}+{ypos}') def setup(self): """Setup the calendar widget""" self.cframe.pack(fill='both', expand='yes') self.xframe.pack(fill='x') self.tframe.pack(fill='x') self.wframe.pack(fill='x') # setup the top level window self.root.withdraw() # hide the window until setup is complete self.root.transient(self.parent) self.root.overrideredirect(True) self.root.resizable(False, False) self.cframe.update_idletasks() # actualize the geometry # create the visual components ttk.Button(self.xframe, text="⨉", command=self.root.destroy, style='exit.primary.TButton').pack(side='right') self.draw_titlebar() self.draw_calendar() self.root.deiconify() # make the window visible. self.root.attributes('-topmost', True) def weekday_header(self): """Returns a list of weekdays to be used as a header in the calendar based on the firstweekday""" weekdays = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'] return weekdays[self.firstweekday:] + weekdays[:self.firstweekday]
def click_add(self): '''点击新增按钮,创建模态对话框''' dialog_add = Toplevel() #弹出对话框 dialog_add.wm_transient(self.window) #与父窗口关联,窗口管理器不会当成独立窗口 dialog_add.focus_set() #焦点切换到对话框 dialog_add.grab_set() #事件不会传入父窗口(父窗口无法点击) dialog_add.withdraw() #隐藏窗口(等到窗口宽高位置设定好后再显示) dialog_add.title('添加经期开始/结束') #窗口标题 frame_add = Frame( dialog_add, padx=self.window_width / 20, pady=self.window_width / 20, bg='#FFF0F5' #lavenderblush ) frame_add.pack() def add(): '''点击对话框中的添加记录按钮''' yyyy = int(box_yyyy.get()) #从下拉选项框获取数据 mm = int(box_mm.get()) dd = int(box_dd.get()) self.main.add(yyyy, mm, dd) #添加经期开始/结束 if self.main.add_error: #添加记录异常 messagebox.showinfo(message=self.main.error_msg, parent=dialog_add) else: #添加记录成功 dialog_add.destroy() #关闭对话框 self.refresh() #刷新页面相关信息 messagebox.showinfo(message='添加记录成功!') #添加记录的按钮 btn_add_enter = Button( frame_add, bd=2, relief='groove', bg='#FFFFFF', #white fg='#FF1493', #deeppink activebackground='#FFFFFF', activeforeground='#FF1493', command=add) btn_add_enter.pack(side='bottom', anchor='s') if self.main.ongoing_date is None: btn_add_enter.configure(text='添加经期开始日期') else: btn_add_enter.configure(text='添加经期结束日期') box_yyyy = Combobox(frame_add, width=4, state='readonly') #年选项框 box_yyyy['value'] = tuple(range(2000, date.today().year + 1)) box_yyyy.current(date.today().year - 2000) #默认值为今天 box_yyyy.pack(side='left', anchor='n') label_year = Label(frame_add, text='年 ', bg='#FFF0F5') label_year.pack(side='left', anchor='n') box_mm = Combobox(frame_add, width=2, state='readonly') #月选项框 box_mm['value'] = tuple(range(1, 13)) box_mm.current(date.today().month - 1) #默认值为今天 box_mm.pack(side='left', anchor='n') label_month = Label(frame_add, text='月 ', bg='#FFF0F5') label_month.pack(side='left', anchor='n') box_dd = Combobox(frame_add, width=2, state='readonly') #日选项框 box_dd['value'] = tuple(range(1, 32)) box_dd.current(date.today().day - 1) #默认值为今天 box_dd.pack(side='left', anchor='n') label_day = Label(frame_add, text='日\n\n', bg='#FFF0F5') label_day.pack(side='left', anchor='n') dialog_add.update_idletasks() #手动更新显示,以获得布局后的窗口宽高来设置窗口位置 dialog_add_x = int( (dialog_add.winfo_screenwidth() * self.scale_factor - dialog_add.winfo_width()) / 2) dialog_add_y = int( (dialog_add.winfo_screenheight() * self.scale_factor - dialog_add.winfo_height()) / 2) dialog_add.geometry('+{}+{}'.format(dialog_add_x, dialog_add_y)) #设置窗口位置 dialog_add.resizable(False, False) #锁定窗口大小 dialog_add.deiconify() #显示窗口
def finalizeWindow(window: Toplevel, parent): window.deiconify() parent.window.wait_window(window) parent.window.attributes('-disabled', 0) parent.window.deiconify()
class Atualizar(): def __init__(self, tela, design, idioma, interface_idioma, icon): self.icon = icon self.interface_idioma = interface_idioma self.tp_atualizacao = None self.idioma = idioma self.design = design self.tela = tela # Destino dos Downloads e Backups data = str(datetime.now()).split('.')[0] data = data.replace(' ', '-') data = data.replace(':', '-') dest_download = os_path.join(os_getcwd(), 'AtualizarSafira') dest_backup = os_path.join(os_getcwd(), 'backups', data) # Instância de Upgrades self.up = Upgrade.Upgrade(dest_download, dest_backup) def verificar_versao(self, primeira_vez=False): """Verifica se existe uma versão mais recente disponível """ try: baixada = VERSAO_ATUAL # Obter todas as versões dic_versoes = self.up.obter_informacoes_versao() if dic_versoes.get('erro'): print(dic_versoes['erro']) messagebox.showinfo( "Erro ao buscar versões", "Aconteceu um erro quando a Safira tentou buscar as versões disponíveis. Este foi o erro: {}" .format(dic_versoes['erro'])) else: # Obter ultima versão recente = max(dic_versoes.keys()) if float(VERSAO_ATUAL["versao"]) < float(recente): print('A versão {} disponível, deseja atualizar?'.format( recente)) self.aviso_versao(baixada, recente) else: # Não é necessário avisar que está atualizado # Se a interface estiver iniciando if not primeira_vez: self.aviso_versao_atualizada(baixada) except Exception as erro: if not primeira_vez: messagebox.showinfo( "ops", self.interface_idioma["erro_generico"][self.idioma] + str(erro)) def aviso_versao(self, baixada, recente): """ Aviso, existe uma nova versão disponível """ self.tp_atualizacao = Toplevel( self.tela, self.design.dic["aviso_versao_top_level"]) self.tp_atualizacao.withdraw() self.tp_atualizacao.focus_force() self.tp_atualizacao.resizable(False, False) self.tp_atualizacao.tk.call('wm', 'iconphoto', self.tp_atualizacao._w, self.icon) self.tp_atualizacao.grid_columnconfigure(1, weight=1) self.tp_atualizacao.title( self.interface_idioma["titulo_aviso_atualizacao"][self.idioma]) # Tentar remover a barra de rolagem #try: # self.tp_atualizacao.wm_attributes('-type', 'splash') #except Exception as erro: # print("Erro ao remover barra de titulos => ", erro) # Objetos da interface fr_atualizaca = Frame(self.tp_atualizacao) lb_versao_dev = Label( fr_atualizaca, text=self.interface_idioma["versao_nova_disponivel"][self.idioma]) lb_versao_tex = Message( fr_atualizaca, text='{}'.format(self.interface_idioma["texto_update_disponivel"][ self.idioma]).format(recente)) fr_botoes = Frame(fr_atualizaca) bt_cancela = Button( fr_botoes, text=self.interface_idioma["versao_nao_quero"][self.idioma]) bt_atualiza = Button( fr_botoes, text=self.interface_idioma["atualizar_agora"][self.idioma]) # Configurações de desingn fr_atualizaca.configure(self.design.dic["aviso_versao_fr_atualizacao"]) lb_versao_dev.configure(self.design.dic["aviso_versao_lb_dev"]) lb_versao_tex.configure(self.design.dic["aviso_versao_ms"]) fr_botoes.configure(self.design.dic["aviso_versao_btn"]) bt_cancela.configure(self.design.dic["aviso_versao_btn_cancela"], relief=FLAT) bt_atualiza.configure(self.design.dic["aviso_versao_btn_atualiza"], relief=FLAT) # Eventos bt_atualiza.configure( command=lambda rec=recente: self.aviso_aguarde_instalando(rec)) bt_cancela.configure( command=lambda event=None: self.tp_atualizacao.destroy()) # Posicionamento de itens fr_atualizaca.grid_columnconfigure(1, weight=1) fr_botoes.grid_columnconfigure(1, weight=1) fr_botoes.grid_columnconfigure(2, weight=1) fr_atualizaca.grid(row=1, column=1, sticky=NSEW) lb_versao_dev.grid(row=1, column=1) lb_versao_tex.grid(row=2, column=1, sticky=NSEW) fr_botoes.grid(row=3, column=1, sticky=NSEW) bt_cancela.grid(row=1, column=1) bt_atualiza.grid(row=1, column=2) # Posicionando a tela j_width = self.tp_atualizacao.winfo_reqwidth() j_height = self.tp_atualizacao.winfo_reqheight() t_width = self.tela.winfo_screenwidth() t_heigth = self.tela.winfo_screenheight() self.tp_atualizacao.geometry("+{}+{}".format( int(t_width / 2) - int(j_width / 2), int(t_heigth / 2) - int(j_height / 2))) self.tp_atualizacao.deiconify() self.tp_atualizacao.update() def aviso_aguarde_instalando(self, recente): """ Realizando a atualização """ if self.tp_atualizacao is not None: self.tp_atualizacao.destroy() self.tp_atualizacao = Toplevel(None) self.tp_atualizacao.withdraw() self.tp_atualizacao.focus_force() self.tp_atualizacao.resizable(False, False) self.tp_atualizacao.tk.call('wm', 'iconphoto', self.tp_atualizacao._w, self.icon) self.tp_atualizacao.configure( self.design.dic["aviso_versao_top_level"]) self.tp_atualizacao.grid_columnconfigure(1, weight=1) self.tp_atualizacao.title('Atualizando.... Não feche a Safira!') #try: # self.tp_atualizacao.wm_attributes('-type', 'splash') #except Exception as erro: # print("Erro ao remover barra de titulos => ", erro) fr_atualizaca = Frame(self.tp_atualizacao) lb_versao_dev = Label(fr_atualizaca, text='{:^30}'.format('Aguarde Atualizando!')) lb_versao_tex = Message(fr_atualizaca, text=' ' * 50, width=200) fr_botoes = Frame(fr_atualizaca) bt_atualiza = Button(fr_botoes) fr_atualizaca.configure(self.design.dic["aviso_versao_fr_atualizacao"]) lb_versao_dev.configure(self.design.dic["aviso_versao_lb_dev"]) lb_versao_tex.configure(self.design.dic["aviso_versao_ms"]) fr_botoes.configure(self.design.dic["aviso_versao_btn"]) bt_atualiza.configure(self.design.dic["aviso_versao_btn_atualiza"], relief=FLAT) fr_atualizaca.grid_columnconfigure(1, weight=1) fr_botoes.grid_columnconfigure(1, weight=1) fr_botoes.grid_columnconfigure(2, weight=1) fr_atualizaca.grid(row=1, column=1, sticky=NSEW) lb_versao_dev.grid(row=1, column=1) lb_versao_tex.grid(row=2, column=1, sticky=NSEW) fr_botoes.grid(row=3, column=1, sticky=NSEW) j_width = self.tp_atualizacao.winfo_reqwidth() j_height = self.tp_atualizacao.winfo_reqheight() t_width = self.tela.winfo_screenwidth() t_heigth = self.tela.winfo_screenheight() self.tp_atualizacao.geometry("+{}+{}".format( int(t_width / 2) - int(j_width / 2), int(t_heigth / 2) - int(j_height / 2))) self.tp_atualizacao.deiconify() self.tp_atualizacao.update() th = Thread( target=lambda ver=recente, lb=lb_versao_tex, bt_at=bt_atualiza, lb_2=lb_versao_dev: self.aplica_versao(ver, lb, bt_at, lb_2)) th.start() def log(self, label, texto): label['text'] = label['text'] + '\n{}'.format(texto) def aplica_versao(self, versao, lb_versao_tex, bt_atualiza, lb_versao_dev): """Baixa, faz o download e atualiza a Safira""" self.log(lb_versao_tex, "Baixando Versão {}".format(versao)) atualizar = self.up.baixar_versao(versao) sucesso, msg, arquivo = atualizar # Baixou com sucesso if sucesso: self.log(lb_versao_tex, msg) self.log(lb_versao_tex, "Extraindo: {}".format(self.up.dest_download)) # Extraiu com sucesso sucesso, msg = self.up.extrair_versao(arquivo) if sucesso: self.log(lb_versao_tex, msg) self.log(lb_versao_tex, "Fazendo Backup") # Backup da versão atual sucesso_bkup, msg_bpk = self.up.fazer_backup_versao() if sucesso_bkup: self.log(lb_versao_tex, msg_bpk) self.log(lb_versao_tex, "Atualizando Versão") # Atualizar a versão sucesso_atualizar, msg_atualizar = self.atualizar_arquivos( versao) if sucesso_atualizar: self.log(lb_versao_tex, msg_atualizar) self.log(lb_versao_tex, "Sucesso!") lb_versao_dev.configure( text='{:^30}'.format('Atualizado com sucesso!'), fg='green') self.tp_atualizacao.title('Safira Atualizada!') else: self.log(lb_versao_tex, msg_atualizar) self.log(lb_versao_tex, "\nRestaurando") sucesso_restaurar, msg_restaurar = self.restaurar_versao( ) self.log(lb_versao_tex, sucesso_restaurar[1]) lb_versao_dev.configure(text='{:^30}'.format( sucesso_restaurar[1]), fg='orange') self.tp_atualizacao.title('Safira Não Atualizada!') else: self.log(lb_versao_tex, msg_bpk) lb_versao_dev.configure( text='{:^30}'.format('Erro ao fazer Backup'), fg='orange') self.tp_atualizacao.title('Safira Não Atualizada!') else: self.log(lb_versao_tex, msg) lb_versao_dev.configure( text='{:^30}'.format('Erro ao Extrair os arquivos'), fg='orange') self.tp_atualizacao.title('Safira Não Atualizada!') else: self.log(lb_versao_tex, msg) lb_versao_dev.configure( text='{:^30}'.format('Erro ao fazer Baixar Safira'), fg='orange') self.tp_atualizacao.title('Safira Não Atualizada!') bt_atualiza.configure(command=lambda event=None: self.fechar_tudo()) bt_atualiza['text'] = 'Reinicie a Safira!' bt_atualiza.grid(row=1, column=2) def fechar_tudo(self): self.tela.destroy() def abrir_site(self, url): self.tp_atualizacao.destroy() th = Thread(target=lambda url=url: webbrowser_open(url)) th.start() def aviso_versao_atualizada(self, baixada): self.tp_atualizacao = Toplevel( self.tela, self.design.dic["aviso_versao_tp_atualizada"]) self.tp_atualizacao.withdraw() self.tp_atualizacao.focus_force() self.tp_atualizacao.resizable(False, False) self.tp_atualizacao.tk.call('wm', 'iconphoto', self.tp_atualizacao._w, self.icon) #try: # self.tp_atualizacao.wm_attributes('-type', 'splash') #except Exception as erro: # print("Erro ao remover barra de titulos => ", erro) self.tp_atualizacao.grid_columnconfigure(1, weight=1) j_width = self.tp_atualizacao.winfo_reqwidth() j_height = self.tp_atualizacao.winfo_reqheight() t_width = self.tela.winfo_screenwidth() t_heigth = self.tela.winfo_screenheight() self.tp_atualizacao.title( self.interface_idioma["titulo_aviso_atualizado"][self.idioma]) fr_atualizaca = Frame(self.tp_atualizacao) lb_versao_dev = Label( fr_atualizaca, text=self.interface_idioma["atualizado_versao_ultima"][ self.idioma]) lb_versao_tex = Message( fr_atualizaca, text='{}'.format( self.interface_idioma["texto_atualizado"][self.idioma]).format( baixada["versao"]), relief=FLAT) fr_botoes = Frame(fr_atualizaca) bt_cancela = Button( fr_botoes, text=self.interface_idioma["texto_nao_quero"][self.idioma], relief=FLAT) bt_facebook = Button( fr_botoes, self.design.dic["aviso_versao_bt_facebook_atualizada"], text=self.interface_idioma["atualizado_facebook"][self.idioma], relief=FLAT) bt_blogger_ = Button( fr_botoes, self.design.dic["aviso_versao_bt_blog_atualizada"], text=self.interface_idioma["atualizado_blog"][self.idioma], relief=FLAT) # Configurações de desingn fr_atualizaca.configure(self.design.dic["aviso_versao_fr_atualizacao"]) lb_versao_dev.configure(self.design.dic["aviso_versao_lb_dev"]) lb_versao_tex.configure(self.design.dic["aviso_versao_ms"]) fr_botoes.configure(self.design.dic["aviso_versao_btn"]) bt_cancela.configure(self.design.dic["aviso_versao_btn_cancela"], relief=FLAT) #bt_atualiza.configure(self.design.dic["aviso_versao_btn_atualiza"], relief=FLAT) bt_cancela.configure( command=lambda event=None: self.tp_atualizacao.destroy()) bt_facebook.configure(command=lambda event=None: self.abrir_site( "https://www.facebook.com/safiralang/")) bt_blogger_.configure(command=lambda event=None: self.abrir_site( "https://safiralang.blogspot.com/")) fr_atualizaca.grid_columnconfigure(1, weight=1) fr_botoes.grid_columnconfigure(1, weight=1) fr_botoes.grid_columnconfigure(2, weight=1) fr_botoes.grid_columnconfigure(3, weight=1) fr_atualizaca.grid(row=1, column=1, sticky=NSEW) lb_versao_dev.grid(row=1, column=1) lb_versao_tex.grid(row=2, column=1, sticky=NSEW) fr_botoes.grid(row=3, column=1, sticky=NSEW) bt_cancela.grid(row=1, column=1) bt_facebook.grid(row=1, column=2) bt_blogger_.grid(row=1, column=3) self.tp_atualizacao.geometry("+{}+{}".format( int(t_width / 2) - int(j_width / 2), int(t_heigth / 2) - int(j_height / 2))) self.tp_atualizacao.update() self.tp_atualizacao.deiconify()
class Relat: #Janela prncipal def __init__(self, parent, db): self.parent = parent self.db = db self.parent.title("Relat") self.parent.geometry("700x450") self.parent.protocol("WM_DELETE_WINDOW", self.fechar_janela_ctrl) main_frame = Frame(self.parent) main_frame.pack(fill=BOTH, expand=YES) # TOOLBAR toolbar = Frame(main_frame) toolbar.pack(side=TOP, fill=X) self.projeto_img = tk.PhotoImage(file="./imagens/projetos.png") self.lista_projetos_btn = ttk.Button(toolbar, image=self.projeto_img, command=self.lista_projetos) self.lista_projetos_btn.pack(side=LEFT, padx=2, pady=2) self.iniciar_img = tk.PhotoImage(file="./imagens/iniciar.png") self.iniciar_btn = ttk.Button(toolbar, image=self.iniciar_img, command=self.iniciar_ctrl) self.iniciar_btn.state( ['disabled']) # set the disabled flag, disabling the button self.iniciar_btn.pack(side=LEFT, pady=1) self.cancelar_img = tk.PhotoImage(file="./imagens/stop.png") self.cancelar_btn = ttk.Button(toolbar, image=self.cancelar_img, command=self.cancelar_ctrl) self.cancelar_btn.state( ['disabled']) # set the disabled flag, disabling the button # self.cancelar_btn.state(['!disabled']) self.cancelar_btn.pack(side=LEFT, pady=1) self.sair_img = tk.PhotoImage(file="./imagens/sair.png") self.sair_btn = ttk.Button(toolbar, image=self.sair_img, command=self.fechar_janela_ctrl) self.sair_btn.pack(side=LEFT, pady=1) status_bar = Frame(main_frame) status_bar.pack(side=BOTTOM, fill=X) self.text_status_bar = Label(status_bar, text="www.KlinikPython.Wordpress.Com", relief=SUNKEN, bd=1) self.text_status_bar.pack(side=LEFT, fill=X, expand=True) self.id_status_bar = Label(status_bar, text="") self.id_status_bar.pack(side=RIGHT) frame_central = ttk.Notebook(main_frame) grid_frame = Frame(frame_central, bd=10) grid_frame.pack(fill=BOTH, expand=YES, side=LEFT) self.dataCols = ('nome', 'ultima_atualizacao') self.relatorios_grid = ttk.Treeview(grid_frame, selectmode='browse', columns=self.dataCols) self.relatorios_grid.bind("<Double-1>", self.alterar_relatorio_click) self.relatorios_grid.bind("<Button-1>", self.habilita_btn_relat) scroll_y = ttk.Scrollbar(grid_frame, orient=VERTICAL, command=self.relatorios_grid.yview) scroll_x = ttk.Scrollbar(grid_frame, orient=HORIZONTAL, command=self.relatorios_grid.xview) self.relatorios_grid['yscroll'] = scroll_y.set self.relatorios_grid['xscroll'] = scroll_x.set scroll_y.configure(command=self.relatorios_grid.yview) scroll_y.pack(side=RIGHT, fill=Y) scroll_x.configure(command=self.relatorios_grid.xview) scroll_x.pack(side=BOTTOM, fill=X) # setup column headings self.relatorios_grid['show'] = 'headings' self.relatorios_grid.heading('nome', text='Nome', anchor=W) self.relatorios_grid.column('nome', stretch=0, width=200) self.relatorios_grid.heading('ultima_atualizacao', text='Última Atualização', anchor=W) # self.projetos_grid.column('ultima_atualizacao', stretch=0, width=100) self.relatorios_grid.pack(fill=BOTH, side=LEFT, expand=True) self.relatorios_grid.bind("<Double-1>", self.alterar_relatorio_click) frame_central.add(grid_frame, text="Relatórios") frame_central.add(Frame(), text="Configurações") frame_central.pack(side=LEFT, fill=BOTH, expand=1) frame_botoes = Frame(main_frame, width=200, padx=20, pady=30) frame_botoes.pack(side=RIGHT, fill=Y) self.novo_relatorio_img = tk.PhotoImage(file="./imagens/incluir.png") self.novo_relatorio_btn = ttk.Button(frame_botoes, width=20, text="Incluir", image=self.novo_relatorio_img, compound=LEFT, command=self.novo_relatorio) self.novo_relatorio_btn.state(['disabled']) self.novo_relatorio_btn.pack(side=TOP, pady=2) self.alterar_relatorio_img = tk.PhotoImage( file="./imagens/alterar.png") self.alterar_relatorio_btn = ttk.Button( frame_botoes, width=20, text="Alterar", image=self.alterar_relatorio_img, compound=LEFT, command=self.alterar_relatorio) self.alterar_relatorio_btn.state(['disabled']) self.alterar_relatorio_btn.pack(side=TOP, pady=2) self.excluir_relatorio_img = tk.PhotoImage( file="./imagens/excluir.png") self.excluir_relatorio_btn = ttk.Button( frame_botoes, width=20, text="Excluir", image=self.excluir_relatorio_img, compound=LEFT, command=self.excluir_relatorio_ctrl) self.excluir_relatorio_btn.state(['disabled']) self.excluir_relatorio_btn.pack(side=TOP, pady=2) self.move_up_img = tk.PhotoImage(file="./imagens/up.png") self.move_up_btn = ttk.Button(frame_botoes, width=20, text="Mover para cima", image=self.move_up_img, compound=LEFT, command=self.move_up_ctrl) self.move_up_btn.state(['disabled']) self.move_up_btn.pack(side=TOP, pady=2) self.move_down_img = tk.PhotoImage(file="./imagens/down.png") self.move_down_btn = ttk.Button(frame_botoes, width=20, text="Mover para baixo", image=self.move_down_img, compound=LEFT, command=self.move_down_ctrl) self.move_down_btn.state(['disabled']) self.move_down_btn.pack(side=TOP, pady=2) menu_bar = tk.Menu(main_frame) projeto_menu = tk.Menu(menu_bar, tearoff=0) projeto_menu.add_command(label="Projetos", command=self.lista_projetos) projeto_menu.add_command(label="Fechar Projeto", command=self.fechar_projeto_ctrl) projeto_menu.add_separator() projeto_menu.add_command(label="Sair", command=self.fechar_janela_ctrl) menu_bar.add_cascade(label="Projetos", menu=projeto_menu) ajuda_menu = tk.Menu(menu_bar, tearoff=0) ajuda_menu.add_command(label="Ajuda", command=self.sobre_ctrl) ajuda_menu.add_command(label="Licença", command=self.sobre_ctrl) ajuda_menu.add_separator() ajuda_menu.add_command(label="Sobre", command=self.sobre_ctrl) menu_bar.add_cascade(label="Sobre", menu=ajuda_menu) self.parent.config(menu=menu_bar) def lista_projetos(self): self.projeto_janela = Toplevel(self.parent) self.projeto_janela.title("Projetos") self.projeto_janela.geometry("400x400") self.projeto_janela.protocol("WM_DELETE_WINDOW", self.fechar_projeto_janela_ctrl) self.projeto_janela.withdraw() self.projeto_janela.grid() self.projeto_janela.transient(self.parent) self.projeto_janela.grab_set() projeto_frame = Frame(self.projeto_janela) projeto_frame.pack(fill=BOTH, expand=True) fechar_proj_btn = ttk.Button(self.projeto_janela, text="Fechar", width=10, command=self.fechar_projeto_janela_ctrl) fechar_proj_btn.pack(side=RIGHT, padx=5, pady=5) self.excluir_proj_btn = ttk.Button(self.projeto_janela, text="Excluir", width=10, command=self.excluir_projeto_ctrl) self.excluir_proj_btn.pack(side=RIGHT, padx=5, pady=5) self.excluir_proj_btn.state(["disabled"]) self.abrir_proj_btn = ttk.Button(self.projeto_janela, text="Abrir", width=10, command=self.abrir_projeto_ctrl) self.abrir_proj_btn.pack(side=RIGHT) self.abrir_proj_btn.state(["disabled"]) self.alterar_proj_btn = ttk.Button(self.projeto_janela, text="Alterar", width=10, command=self.alterar_projeto) self.alterar_proj_btn.pack(side=RIGHT) self.alterar_proj_btn.state(["disabled"]) novo_proj_btn = ttk.Button(self.projeto_janela, text="Novo", width=10, command=self.novo_projeto) novo_proj_btn.pack(side=RIGHT, padx=5, pady=5) grid_frame = Frame(projeto_frame, bd=10) grid_frame.pack(fill=BOTH, expand=YES, side=LEFT) self.dataCols = ('nome', 'ultima_atualizacao') self.projetos_grid = ttk.Treeview(grid_frame, selectmode='browse', columns=self.dataCols) self.projetos_grid.bind("<Double-1>", self.abrir_projeto_click) self.projetos_grid.bind("<Button-1>", self.habilita_btn_proj) scroll_y = ttk.Scrollbar(grid_frame, orient=VERTICAL, command=self.projetos_grid.yview) scroll_x = ttk.Scrollbar(grid_frame, orient=HORIZONTAL, command=self.projetos_grid.xview) self.projetos_grid['yscroll'] = scroll_y.set self.projetos_grid['xscroll'] = scroll_x.set scroll_y.configure(command=self.projetos_grid.yview) scroll_y.pack(side=RIGHT, fill=Y) scroll_x.configure(command=self.projetos_grid.xview) scroll_x.pack(side=BOTTOM, fill=X) # setup column headings self.projetos_grid['show'] = 'headings' self.projetos_grid.heading('nome', text='Nome', anchor=W) self.projetos_grid.column('nome', stretch=0, width=200) self.projetos_grid.heading('ultima_atualizacao', text='Última Atualização', anchor=W) # self.projetos_grid.column('ultima_atualizacao', stretch=0, width=100) self.projetos_grid.pack(fill=BOTH, side=LEFT, expand=True) dados = ProjetosDb(self.db).listar_projetos() for row in dados: self.projetos_grid.insert('', END, row[0], values=(row[1], row[9])) centro_(self.projeto_janela) self.projeto_janela.deiconify() self.parent.wait_window(self.projeto_janela) def novo_projeto(self): self.novo_projeto_janela = Toplevel(self.parent) self.novo_projeto_janela.resizable(0, 0) self.novo_projeto_janela.title("Novo Projeto") self.novo_projeto_janela.geometry("700x400") self.novo_projeto_janela.protocol("WM_DELETE_WINDOW", self.fechar_novo_projeto_ctrl) self.novo_projeto_janela.withdraw() self.novo_projeto_janela.grid() self.novo_projeto_janela.transient(self.parent) self.novo_projeto_janela.grab_set() projeto_frame = Frame(self.novo_projeto_janela) projeto_frame.pack(fill=BOTH, expand=True) cancelar_btn = ttk.Button(self.novo_projeto_janela, text="Cancelar", width=10, command=self.fechar_novo_projeto_ctrl) cancelar_btn.pack(side=RIGHT, padx=5, pady=5) ok_btn = ttk.Button(self.novo_projeto_janela, text="Salvar", width=10, command=self.incluir_projeto_ctrl) ok_btn.pack(side=RIGHT) info_frame = Frame(projeto_frame, bd=10) info_frame.pack(fill=BOTH, expand=YES, side=RIGHT) group_info = ttk.LabelFrame(info_frame, text="Informações", padding=(6, 6, 12, 12)) group_info.grid(row=0, column=0, sticky='nsew') ttk.Label(group_info, text='Nome', width=10).grid(row=0, column=0, sticky=W) self.nome = ttk.Entry(group_info, width=25) self.nome.grid(row=0, column=1, sticky=W, pady=2) ttk.Label(group_info, text='Descrição', width=10).grid(row=1, column=0, sticky=W) self.descricao = Text(group_info, height=4, width=19) self.descricao.grid(row=1, column=1, sticky=W, pady=2) ttk.Label(group_info, text='Autor', width=10).grid(row=2, column=0, sticky=W) self.autor = ttk.Entry(group_info, width=25) self.autor.grid(row=2, column=1, sticky=W, pady=2) group_db = ttk.LabelFrame(info_frame, text="Acesso ao banco", padding=(6, 6, 12, 12)) group_db.grid(row=1, column=0, sticky=NSEW) ttk.Label(group_db, text='Tipo', width=10).grid(row=0, column=0, sticky=W) self.box_value = tk.StringVar() self.box = ttk.Combobox(group_db, textvariable=self.box_value, width=22) self.box['values'] = ('', 'Oracle', 'Mysql', 'PostgreSql') self.box.current(0) self.box.grid(row=0, column=1, sticky=W, pady=2) ttk.Label(group_db, text='Servidor', width=10).grid(row=1, column=0, sticky=W) self.servidor = ttk.Entry(group_db, width=25) self.servidor.grid(row=1, column=1, sticky=W, pady=2) ttk.Label(group_db, text='Porta', width=10).grid(row=2, column=0, sticky=W) self.porta = ttk.Entry(group_db, width=15) self.porta.grid(row=2, column=1, sticky=W, pady=2) ttk.Label(group_db, text='Banco', width=10).grid(row=3, column=0, sticky=W) self.senha = ttk.Entry(group_db, width=25) self.senha.grid(row=3, column=1, sticky=W, pady=2) ttk.Label(group_db, text='Usuário', width=10).grid(row=4, column=0, sticky=W) self.usuario = ttk.Entry(group_db, width=25) self.usuario.grid(row=4, column=1, sticky=W, pady=2) ttk.Label(group_db, text='Senha', width=10).grid(row=5, column=0, sticky=W) self.senha = ttk.Entry(group_db, show="*", width=25) self.senha.grid(row=5, column=1, sticky=W, pady=2) centro_(self.novo_projeto_janela) self.novo_projeto_janela.deiconify() self.parent.wait_window(self.novo_projeto_janela) def alterar_projeto(self): self.alterar_projeto_janela = Toplevel(self.parent) self.alterar_projeto_janela.resizable(0, 0) self.alterar_projeto_janela.title("Novo Projeto") self.alterar_projeto_janela.geometry("700x500") self.alterar_projeto_janela.protocol("WM_DELETE_WINDOW", self.fechar_alterar_projeto_ctrl) self.alterar_projeto_janela.withdraw() self.alterar_projeto_janela.grid() self.alterar_projeto_janela.transient(self.parent) self.alterar_projeto_janela.grab_set() projeto_frame = Frame(self.alterar_projeto_janela, relief=RAISED, borderwidth=1) projeto_frame.pack(fill=BOTH, expand=True) cancelar_btn = ttk.Button(self.alterar_projeto_janela, text="Cancelar", width=10, command=self.fechar_alterar_projeto_ctrl) cancelar_btn.pack(side=RIGHT, padx=5, pady=5) ok_btn = ttk.Button(self.alterar_projeto_janela, text="Salvar", width=10, command=self.salvar_projeto_ctrl) ok_btn.pack(side=RIGHT) info_frame = Frame(projeto_frame, bd=10) info_frame.pack(fill=BOTH, expand=YES, side=RIGHT) group_info = ttk.LabelFrame(info_frame, text="Informações", padding=(6, 6, 12, 12)) group_info.grid(row=0, column=0, sticky='nsew') ttk.Label(group_info, text='Nome', width=10).grid(row=0, column=0, sticky=W) self.nome = ttk.Entry(group_info, width=25) self.nome.grid(row=0, column=1, sticky=W, pady=2) ttk.Label(group_info, text='Descrição', width=10).grid(row=1, column=0, sticky=W) self.descricao = Text(group_info, height=4, width=19) self.descricao.grid(row=1, column=1, sticky=W, pady=2) ttk.Label(group_info, text='Autor', width=10).grid(row=2, column=0, sticky=W) self.autor = Text(group_info, height=4, width=19) self.autor.grid(row=2, column=1, sticky=W, pady=2) group_db = ttk.LabelFrame(info_frame, text="Acesso ao banco", padding=(6, 6, 12, 12)) group_db.grid(row=1, column=0, sticky='nsew') ttk.Label(group_db, text='Tipo', width=10).grid(row=0, column=0, sticky=W) self.bancos_value = tk.StringVar() self.bancos = ttk.Combobox(group_db, textvariable=self.box_value, width=22) self.bancos['values'] = ('', 'Oracle', 'Mysql', 'PostgreSql') self.bancos.current(0) self.bancos.grid(row=0, column=1, sticky=W, pady=2) ttk.Label(group_db, text='Servidor', width=10).grid(row=1, column=0, sticky=W) self.servidor = ttk.Entry(group_db, width=25) self.servidor.grid(row=2, column=0, sticky=W, pady=2) ttk.Label(group_db, text='Porta', width=10).grid(row=1, column=0, sticky=W) self.porta = ttk.Entry(group_db, width=25) self.usuario.grid(row=2, column=1, sticky=W, pady=2) ttk.Label(group_db, text='Banco', width=10).grid(row=3, column=0, sticky=W) self.senha = ttk.Entry(group_db, width=25) self.senha.grid(row=3, column=1, sticky=W, pady=2) ttk.Label(group_db, text='Usuário', width=10).grid(row=4, column=0, sticky=W) self.usuario = ttk.Entry(group_db, width=25) self.usuario.grid(row=4, column=1, sticky=W, pady=2) ttk.Label(group_db, text='Senha', width=10).grid(row=5, column=0, sticky=W) self.usuario = ttk.Entry(group_db, show="*", width=25) self.usuario.grid(row=5, column=1, sticky=W, pady=2) centro_(self.alterar_projeto_janela) self.alterar_projeto_janela.deiconify() self.parent.wait_window(self.projeto_janela) def salvar_projeto_ctrl(self): arr = [] arr.append(self.nome.get()) arr.append(self.descricao.get()) arr.append(self.autor.get()) arr.append(self.bancos.get()) arr.append(self.nome.get()) arr.append(self.usuario.get()) arr.append(self.senha.get()) retorno = ProjetosDb(self.db).incluir_projeto(arr) if retorno.isnumeric: self.projetos_grid.insert('', END, arr[0], values=(row[1], row[9])) self.fechar_projeto_janela_ctrl() def excluir_projeto_ctrl(self): if deleteBox("Excluir", "Deseja realmente excluir o projeto selecionado?"): item = self.projetos_grid.selection()[0] self.projetos_grid.delete(item) ProjetosDb(self.db).excluirProjeto(item) print("Projeto excluído: ", item) def fechar_janela_ctrl(self): self.parent.destroy() def fechar_projeto_ctrl(self): for child in self.relatorios_grid.get_children(): print(self.relatorios_grid.item(child)["values"]) #self.projetos_grid.delete(item) self.iniciar_btn.state(["disabled"]) self.cancelar_btn.state(["disabled"]) self.novo_relatorio_btn.state(["disabled"]) self.alterar_relatorio_btn.state(["disabled"]) self.excluir_relatorio_btn.state(["disabled"]) self.move_up_btn.state(["disabled"]) self.move_down_btn.state(["disabled"]) #Limpar a lista de relatórios self.relatorios_grid.delete(*self.relatorios_grid.get_children()) def fechar_projeto_janela_ctrl(self): self.projeto_janela.destroy() def fechar_novo_projeto_ctrl(self): self.novo_projeto_janela.destroy() def fechar_alterar_projeto_ctrl(self): self.alterar_projeto_janela.destroy() def iniciar_ctrl(self): self.lista_projetos_btn.state(["disabled"]) self.sair_btn.state(["disabled"]) self.novo_relatorio_btn.state(["disabled"]) self.alterar_relatorio_btn.state(["disabled"]) self.excluir_relatorio_btn.state(["disabled"]) self.move_up_btn.state(["disabled"]) self.move_down_btn.state(["disabled"]) self.iniciar_btn.state(["disabled"]) self.cancelar_btn.state(["!disabled"]) def cancelar_ctrl(self): self.lista_projetos_btn.state(["!disabled"]) self.sair_btn.state(["!disabled"]) self.novo_relatorio_btn.state(["!disabled"]) self.iniciar_btn.state(["!disabled"]) self.cancelar_btn.state(["disabled"]) def abrir_projeto_ctrl(self): projeto_id = self.projetos_grid.selection()[0] relatorios_lista = RelatoriosDb(self.db).listar_relatorios(projeto_id) #print(relatorios_lista) self.lista_relatorios_ctrl(relatorios_lista) self.fechar_projeto_janela_ctrl() self.habilita_btn_abrir_proj() def abrir_projeto_click(self, event): projeto_id = self.projetos_grid.selection()[0] relatorios_lista = RelatoriosDb(self.db).listar_relatorios(projeto_id) #print(relatorios_lista) self.lista_relatorios_ctrl(relatorios_lista) self.fechar_projeto_janela_ctrl() self.habilita_btn_abrir_proj() def habilita_btn_proj(self, event): self.alterar_proj_btn.state(["!disabled"]) self.abrir_proj_btn.state(["!disabled"]) self.excluir_proj_btn.state(["!disabled"]) def habilita_btn_abrir_proj(self): self.novo_relatorio_btn.state(["!disabled"]) self.iniciar_btn.state(["!disabled"]) def novo_relatorio(self): self.novo_relatorio_janela = Toplevel() self.novo_relatorio_janela.resizable(0, 0) self.novo_relatorio_janela.title("Novo Relatório") self.novo_relatorio_janela.geometry("500x300") self.novo_relatorio_janela.protocol("WM_DELETE_WINDOW", self.fechar_novo_relatorio_ctrl) self.novo_relatorio_janela.withdraw() self.novo_relatorio_janela.grid() self.novo_relatorio_janela.transient(self.parent) self.novo_relatorio_janela.grab_set() relatorio_frame = Frame(self.novo_relatorio_janela, relief=RAISED, borderwidth=1) relatorio_frame.pack(fill=BOTH, expand=True) self.relatorio_tab = ttk.Notebook(relatorio_frame) self.relatorio_tab.pack(fill=BOTH, expand=True) cancelar_btn = ttk.Button(self.novo_relatorio_janela, text="Cancelar", width=10, command=self.fechar_novo_relatorio_ctrl) cancelar_btn.pack(side=RIGHT, padx=5, pady=5) ok_btn = ttk.Button(self.novo_relatorio_janela, text="Incluir", width=10, command=self.salvar_relat_ctrl) ok_btn.pack(side=RIGHT) frame_informacaoes = ttk.Frame(self.relatorio_tab) frame_informacaoes.pack(side=BOTTOM, expand=YES) informacoes_bas = ttk.LabelFrame(frame_informacaoes) frame_informacaoes.pack(side=BOTTOM, expand=YES) # data Nomor ttk.Label(frame_informacaoes, text='Nomor Urut').grid(row=0, column=0, sticky=W) self.entNomor = ttk.Entry(frame_informacaoes) self.entNomor.grid(row=0, column=1) # data Nama ttk.Label(frame_informacaoes, text='Nama Lengkap').grid(row=1, column=0, sticky=W) self.entNama = ttk.Entry(frame_informacaoes) self.entNama.grid(row=1, column=1) # data Alamat ttk.Label(frame_informacaoes, text='Alamat').grid(row=2, column=0, sticky=W) self.entAlamat = ttk.Entry(frame_informacaoes) self.entAlamat.grid(row=2, column=1) # data NoTelp ttk.Label(frame_informacaoes, text='No. Telp').grid(row=3, column=0, sticky=W) self.entTelp = ttk.Entry(frame_informacaoes) self.entTelp.grid(row=3, column=1) # data Kelas ttk.Label(frame_informacaoes, text='Kelas').grid(row=4, column=0, sticky=W) self.entKelas = ttk.Entry(frame_informacaoes) self.entKelas.grid(row=4, column=1) f2 = ttk.Frame(self.relatorio_tab) # second page f3 = ttk.Frame(self.relatorio_tab) # second page self.relatorio_tab.add(frame_informacaoes, text='Informações') self.relatorio_tab.add(f2, text='Consulta') self.relatorio_tab.add(f3, text='Configuração') centro_(self.novo_relatorio_janela) self.novo_relatorio_janela.deiconify() self.parent.wait_window(self.novo_relatorio_janela) def alterar_relatorio(self): self.alterar_relatorio_janela = Toplevel() self.alterar_relatorio_janela.resizable(0, 0) self.alterar_relatorio_janela.title("Alterar Relatório") self.alterar_relatorio_janela.geometry("500x300") self.alterar_relatorio_janela.protocol( "WM_DELETE_WINDOW", self.fechar_alterar_relatorio_ctrl) self.alterar_relatorio_janela.withdraw() self.alterar_relatorio_janela.grid() self.alterar_relatorio_janela.transient(self.parent) self.alterar_relatorio_janela.grab_set() relatorio_frame = Frame(self.alterar_relatorio_janela, relief=RAISED, borderwidth=1) relatorio_frame.pack(fill=BOTH, expand=True) self.relatorio_tab = ttk.Notebook(relatorio_frame) self.relatorio_tab.pack(fill=BOTH, expand=True) cancelar_btn = ttk.Button(self.alterar_relatorio_janela, text="Cancelar", width=10, command=self.fechar_alterar_relatorio_ctrl) cancelar_btn.pack(side=RIGHT, padx=5, pady=5) ok_btn = ttk.Button(self.alterar_relatorio_janela, text="Incluir", width=10, command=self.salvar_relat_ctrl) ok_btn.pack(side=RIGHT) f1 = ttk.Frame(self.relatorio_tab ) # first page, which would get widgets gridded into it f1.pack(side=BOTTOM, expand=YES) f2 = ttk.Frame(self.relatorio_tab) # second page f3 = ttk.Frame(self.relatorio_tab) # second page self.relatorio_tab.add(f1, text='Informações') self.relatorio_tab.add(f2, text='Consulta') self.relatorio_tab.add(f3, text='Configuração') centro_(self.alterar_relatorio_janela) self.alterar_relatorio_janela.deiconify() self.parent.wait_window(self.alterar_relatorio_janela) def lista_relatorios_ctrl(self, relatorios): self.relatorios = relatorios for row in self.relatorios: self.relatorios_grid.insert("", END, row[0], values=(row[2], row[8])) def fechar_novo_relatorio_ctrl(self): self.novo_relatorio_janela.destroy() def fechar_alterar_relatorio_ctrl(self): self.alterar_relatorio_janela.destroy() def salvar_relat_ctrl(self): self.projeto_janela.destroy() def habilita_btn_relat(self, event): self.alterar_relatorio_btn.state(["!disabled"]) self.excluir_relatorio_btn.state(["!disabled"]) self.move_up_btn.state(["!disabled"]) self.move_down_btn.state(["!disabled"]) def novo_relatorio_ctrl(self): arr = [] arr.append(self.nome.get()) arr.append(self.descricao.get()) arr.append(self.autor.get()) arr.append(self.bancos.get()) arr.append(self.nome.get()) arr.append(self.usuario.get()) arr.append(self.senha.get()) retorno = ProjetosDb(self.db).incluir_projeto(arr) if retorno.isnumeric: self.projetos_grid.insert('', END, arr[0], values=(row[1], row[9])) self.fechar_novo_relatorio_ctrl() def alterar_relatorio_ctrl(self): item = self.relatorios_grid.selection()[0] print("you clicked on", self.relatorios_grid.item(item, "text")) def alterar_relatorio_click(self): item = self.relatorios_grid.selection()[0] print("you clicked on", self.relatorios_grid.item(item, "text")) def excluir_relatorio_ctrl(self, db): if deleteBox("Excluir", "Deseja realmente excluir o relatório selecionado?"): relatorio_id = self.relatorios_grid.selection() self.relatorios_grid.delete(relatorio_id) RelatoriosDb(self.db).excluirRelatorio(relatorio_id) print("Projeto excluído: ", relatorio_id) def move_up_ctrl(self): leaves = self.relatorios_grid.selection() print("item: ", leaves) for i in leaves: self.relatorios_grid.move(i, self.relatorios_grid.parent(i), self.relatorios_grid.index(i) - 1) def move_down_ctrl(self): leaves = self.relatorios_grid.selection() for i in leaves: self.relatorios_grid.move(i, self.relatorios_grid.parent(i), self.relatorios_grid.index(i) + 1) def sobre_ctrl(self): app = Sobre(self.parent)
class StartScreen(Tk): def __init__(self): try: Tk.__init__(self) except: log_err('no display, exit') exit(1) self.title(resource_pack.get_translation('start.title') % VERSION['str']) if settings['use-theme'] != 'ttk' and not sys.platform.startswith('win'): theme_path = os.path.dirname(os.path.abspath(__file__)) + '/theme/' + settings['use-theme'] self.tk.eval('lappend auto_path {%s}' % theme_path) ttk.Style().theme_use(settings['use-theme']) # 小部件 self.new_button = ttk.Button(self, text=resource_pack.get_translation('start.new'), command=self.new) self.start_button = ttk.Button(self, text=resource_pack.get_translation('start.start'), command=self.start_game) self.exit_button = ttk.Button(self, text=resource_pack.get_translation('start.exit'), command=lambda: exit()) self.game_item_list = Listbox(self, height=12) self.vscroll = ttk.Scrollbar(self, orient='vertical', command=self.game_item_list.yview) self.game_item_list.configure(yscrollcommand=self.vscroll.set) self.repair_button = ttk.Button(self, text=resource_pack.get_translation('start.multiplayer')) self.del_button = ttk.Button(self, text=resource_pack.get_translation('start.delete'), command=self.delete) self.rename_button = ttk.Button(self, text=resource_pack.get_translation('start.rename'), command=self.rename) # 显示 self.new_button.grid(column=0, row=0, padx=5, pady=5) self.start_button.grid(column=1, row=0, padx=5, pady=5) self.exit_button.grid(column=2, row=0, padx=5, pady=5) self.game_item_list.grid(column=0, columnspan=4, row=1, padx=3, pady=5, sticky='news') self.vscroll.grid(column=4, row=1, padx=2, pady=5, sticky='nes') self.repair_button.grid(column=0, row=2, padx=5, pady=5) self.del_button.grid(column=1, row=2, padx=5, pady=5) self.rename_button.grid(column=2, row=2, padx=5, pady=5) self.resizable(False, False) self.refresh() def delete(self, event=None): # 删除世界 if self.game_item_list.curselection() == (): select = self.game_item_list.get(0) else: select = self.game_item_list.get(self.game_item_list.curselection()[0]) if messagebox.askyesno(message=resource_pack.get_translation('start.dialog.text.delete') % select, title=resource_pack.get_translation('start.dialog.title.delete')): shutil.rmtree(os.path.join(saves_path, select)) self.refresh() def new(self, event=None): # 新的世界对话框 self.new_dialog = Toplevel(self) self.new_dialog.title(resource_pack.get_translation('start.dialog.title.new')) self.new_dialog_label_name = ttk.Label(self.new_dialog, text=resource_pack.get_translation('start.dialog.text.name')) self.new_dialog_entry_name = ttk.Entry(self.new_dialog) self.new_dialog_label_seed = ttk.Label(self.new_dialog, text=resource_pack.get_translation('general.seed')) self.new_dialog_entry_seed = ttk.Entry(self.new_dialog) self.new_dialog_label_type = ttk.Label(self.new_dialog, text=resource_pack.get_translation('start.dialog.text.type')) self.new_dialog_combobox_type = ttk.Combobox(self.new_dialog, values =resource_pack.get_translation('start.worldtype'), width=18) self.new_dialog_combobox_type.state(['readonly']) self.new_dialog_button_ok = ttk.Button(self.new_dialog, text=resource_pack.get_translation('start.dialog.text.ok'), command=self.new_world ) self.new_dialog_label_name.grid(column=0, row=0, padx=5, pady=5) self.new_dialog_entry_name.grid(column=1, row=0, columnspan=2, padx=5, pady=5) self.new_dialog_label_seed.grid(column=0, row=1, padx=5, pady=5) self.new_dialog_entry_seed.grid(column=1, row=1, columnspan=2, padx=5, pady=5) self.new_dialog_label_type.grid(column=0, row=2, padx=5, pady=5) self.new_dialog_combobox_type.grid(column=1, row=2, columnspan=2, padx=5, pady=5) self.new_dialog_button_ok.grid(column=2, row=3, padx=5, pady=5) self.new_dialog.resizable(False, False) self.new_dialog.geometry('+%d+%d' % (self.winfo_x() + 50, self.winfo_y() + 50)) self.new_dialog.transient(self) self.new_dialog.deiconify() self.new_dialog.grab_set() self.new_dialog.wait_window() def new_world(self, event=None): # 创建一个新的世界 name = self.new_dialog_entry_name.get() seed = self.new_dialog_entry_seed.get() if self.new_dialog_combobox_type.get() == resource_pack.get_translation('start.worldtype'): world_type = 'flat' else: world_type = 'random' if seed == '': seed = hash(time.ctime()) else: seed = hash(seed) is_valid_char = lambda c: any([c.isalpha(), c.isdigit(), c == '-', c == '_']) if not all([c for c in map(is_valid_char, name)]): log_err('invalid world name') else: if not os.path.isdir(os.path.join(saves_path, name)): if (('懒' in name) or ('懶' in name)) and ('zh' in settings['lang']): messagebox.showinfo(title=resource_pack.get_translation('start.egg.title'), message=resource_pack.get_translation('start.egg.message')) os.mkdir(os.path.join(saves_path, name)) world = open(os.path.join(saves_path, name, 'world.json'), 'w+') world.write('{}\n') world.close() world_level = {'data_version': VERSION['data'], 'seed': seed, 'type': world_type, 'time': 400, 'weather': {'now': 'clear', 'duration': 600}} json.dump(world_level, open(os.path.join(saves_path, name, 'level.json'), 'w+')) os.mkdir(os.path.join(saves_path, name, 'players')) player_info = {'position': '0', 'respawn': '0', 'now_block': 0} json.dump(player_info, open(os.path.join(saves_path, name, 'players', '%s.json' % player['id']), 'w+')) self.new_dialog.destroy() log_info('create world successfully') else: log_warn('Save existed') self.refresh() def refresh(self): # 刷新 self.game_item_list.delete(0, 'end') for item in [i for i in os.listdir(saves_path) if is_game_restore(i)]: self.game_item_list.insert('end', item) def rename(self): # 重命名对话框 self.rename_dialog = Toplevel(self) self.rename_dialog.title(resource_pack.get_translation('start.dialog.title.rename')) self.rename_dialog_label = ttk.Label(self.rename_dialog, style='TLabel', text=resource_pack.get_translation('start.dialog.text.name')) self.rename_dialog_entry = ttk.Entry(self.rename_dialog) name = self.game_item_list.curselection() name = self.game_item_list.get(0) if name == () else self.game_item_list.get(name) self.rename_dialog_entry.insert(0, name) def send_name(): self.rename_world(name) self.old = os.path.join(saves_path, self.rename_dialog_entry.get()) self.rename_dialog_button = ttk.Button(self.rename_dialog, text=resource_pack.get_translation('start.dialog.text.ok'), command=send_name) self.rename_dialog_label.grid(column=0, row=0, padx=5, pady=5) self.rename_dialog_entry.grid(column=1, row=0, columnspan=2, padx=5, pady=5) self.rename_dialog_button.grid(column=2, row=1, padx=5, pady=5) self.rename_dialog.resizable(False, False) self.rename_dialog.geometry('+%d+%d' % (self.winfo_x() + 50, self.winfo_y() + 50)) self.rename_dialog.transient(self) self.rename_dialog.deiconify() self.rename_dialog.grab_set() self.rename_dialog.wait_window() def rename_world(self, name): # 重命名世界 shutil.move(os.path.join(saves_path, name), os.path.join(saves_path, self.rename_dialog_entry.get())) self.rename_dialog.destroy() self.refresh() def start_game(self, event=None): # 启动游戏 select = self.game_item_list.curselection() if select == (): log_warn('no world selected') return select = self.game_item_list.get(select[0]) self.destroy() try: data = load_window() game = Game(width=max(data['width'], 800), height=max(data['height'], 600), caption='minecraft %s' % VERSION['str'], resizable=True) game.set_name(select) setup_opengl() pyglet.app.run() except SystemExit: pass except: name = time.strftime('error-%Y-%m-%d_%H.%M.%S.log') log_err('Catch error, saved in: log/%s' % name) with open(os.path.join(search_mcpy(), 'log', name), 'a+') as err_log: err_log.write('Minecraft version: %s\n' % VERSION['str']) err_log.write('python version: %s for %s\n' % ('.'.join([str(s) for s in sys.version_info[:3]]), sys.platform)) err_log.write('pyglet version: %s(OpenGL %s)\n' % (pyglet.version, gl_info.get_version())) err_log.write('time: %s\n' % time.ctime()) err_log.write('save: %s\n' % select) err_log.write('traceback:\n' + '=' * 34 + '\n') traceback.print_exc(file=err_log) err_log.write('=' * 34 + '\n') with open(os.path.join(search_mcpy(), 'log', 'error-latest.log'), 'w+') as latest_log: with open(os.path.join(search_mcpy(), 'log', name), 'r+') as err_log: latest_log.write(err_log.read()) exit(1)
class FilePane: def __init__(self, root, items=list(), on_selection=list(), on_close=list()): self.items = items self.item_count = len(items) self.on_selection = on_selection self.on_close = on_close self.window = Toplevel() self.window.title('Files') self.window.transient(root) self.window.protocol("WM_DELETE_WINDOW", self.on_window_close) self.menubar = Menu(self.window) self.menubar.add_command(label='Previous', command=self.previous) self.menubar.add_command(label='Next', command=self.next) # Display the menu self.window.config(menu=self.menubar) self.scrollbar = Scrollbar(self.window, orient='vertical') self.listbox = Listbox(self.window, yscrollcommand=self.scrollbar.set, exportselection=False) self.set_items(items) self.scrollbar.config(command=self.listbox.yview) self.scrollbar.pack(side='right', fill='y') self.listbox.pack(side='left', fill='both', expand=1) self.listbox.bind('<<ListboxSelect>>', self.on_select) def on_window_close(self): for callback in self.on_close: callback() self.window.withdraw() def hide(self): self.window.withdraw() def show(self): self.window.deiconify() def selected_item(self): return self.items[self.listbox.curselection()[0]] def select_index(self, index): self.listbox.selection_clear(0, END) # From https://stackoverflow.com/a/25451279/11628429 self.listbox.select_set( index) #This only sets focus on the first item. self.listbox.event_generate("<<ListboxSelect>>") def set_items(self, items): self.items = items self.item_count = len(items) self.listbox.delete(0, END) for item in items: item = path.split(item)[1] self.listbox.insert(END, item) self.select_index(0) def previous(self): index = self.listbox.curselection()[0] - 1 if index < 0: index = self.item_count - 1 self.select_index(index) def next(self): index = self.listbox.curselection()[0] + 1 if index >= self.item_count: index = 0 self.select_index(index) def on_select(self, event): if self.on_selection: for callback in self.on_selection: callback(self.selected_item())
class MessageMakerWindow: def __init__(self, listFrame, message: Message, index: int): self.master = Toplevel(listFrame.window.master) self.master.withdraw() self.listFrame = listFrame self.parent = listFrame.window.master self.parentWindow = listFrame.window self.message = deepcopy(message) if not self.message: self.isNewMessage = True self.message = Message() else: self.isNewMessage = False self.message.sortParts() self.index = index self.master.geometry('+{x}+{y}'.format(x=self.parent.winfo_x() + 10, y=self.parent.winfo_y() + 10)) self.master.wm_attributes("-topmost", 1) self.master.focus_force() self.master.wm_title("StreamTicker Message Maker") self.master.iconbitmap("imagefiles/stIcon.ico") self.master.resizable(False, False) self.master.grab_set() self.master.protocol("WM_DELETE_WINDOW", self.deleteWindow) self.fields = GlobalMessageSettings() self.setGlobalMessageSettings() self.mmFrame = MessageMakerFrame(self.master, self.message) self.mmFrame.frame.grid(row=0, column=0, sticky=NSEW, columnspan=2, padx=4, pady=4) self.partsFrame = MessageMakerPartFrame(self) self.partsFrame.frame.grid(row=1, column=0, sticky=NSEW, columnspan=2, padx=4, pady=4) self.globalMessageSettingsFrame = SettingsMessageFrame(self.master, self.fields) self.globalMessageSettingsFrame.frame.grid(row=2, column=1, sticky=NSEW, padx=(0, 4), pady=4) self.overrideFrame = OverrideFrame(self.master, self.globalMessageSettingsFrame, self.listFrame.window.window.settings) self.overrideFrame.frame.grid(row=2, column=0, sticky=NSEW, padx=4, pady=4) self.disableGlobalMessageFields() self.okCancelFrame = MessageMakerOkCancelFrame(self) self.okCancelFrame.frame.grid(row=3, column=0, columnspan=2, padx=4, pady=4, sticky=E) self.applyOverrides() self.master.deiconify() self.master.mainloop() def deleteWindow(self): self.master.destroy() self.parent.lift() self.parent.wm_attributes("-topmost", 1) self.parent.grab_set() def applyOverrides(self): overrides = self.message.overrides if overrides: if overrides.duration: self.fields.VAR_ENTRY_MESSAGE_DURATION.set(overrides.duration) self.overrideFrame.overrideDuration.set(True) self.overrideFrame.gmsFrame.ENTRY_MESSAGE_DURATION.configure(state=NORMAL) if overrides.intermission: self.fields.VAR_ENTRY_MESSAGE_INTERMISSION.set(overrides.intermission) self.overrideFrame.overrideIntermission.set(True) self.overrideFrame.gmsFrame.ENTRY_MESSAGE_INTERMISSION.configure(state=NORMAL) if overrides.scrollSpeed: self.fields.VAR_ENTRY_MOVE_ALL_ON_LINE_DELAY.set(overrides.scrollSpeed) self.overrideFrame.overrideScrollSpeed.set(True) self.overrideFrame.gmsFrame.entryMoveAllOnLineDelay.configure(state=NORMAL) if overrides.font: self.fields.VAR_FONT_COMBO_BOX.set(overrides.font) self.overrideFrame.overrideFont.set(True) self.overrideFrame.gmsFrame.FONT_COMBO_BOX.configure(state="readonly") if overrides.fontColor: self.fields.VAR_LABEL_MESSAGE_COLOR_FOREGROUND = overrides.fontColor self.fields.VAR_LABEL_MESSAGE_COLOR_TEXT.set(overrides.fontColor) self.overrideFrame.overrideFontColor.set(True) self.overrideFrame.gmsFrame.BUTTON_MESSAGE_COLOR.config(state=NORMAL) self.globalMessageSettingsFrame.CANVAS_MESSAGE_COLOR.itemconfig(self.globalMessageSettingsFrame.RECTANGLE_MESSAGE_COLOR, fill=self.fields.VAR_LABEL_MESSAGE_COLOR_FOREGROUND) if overrides.fontSize: self.fields.VAR_ENTRY_NORMAL_FONT_SIZE.set(overrides.fontSize) self.overrideFrame.overrideFontSize.set(True) self.overrideFrame.gmsFrame.ENTRY_NORMAL_FONT_SIZE.configure(state=NORMAL) if overrides.arrival: self.fields.VAR_ARRIVAL.set(overrides.arrival) self.overrideFrame.overrideArrival.set(True) self.overrideFrame.gmsFrame.ARRIVAL_COMBO_BOX.config(state="readonly") if overrides.departure: self.fields.VAR_DEPARTURE.set(overrides.departure) self.overrideFrame.overrideDeparture.set(True) self.overrideFrame.gmsFrame.DEPARTURE_COMBO_BOX.config(state="readonly") if overrides.bold: self.fields.VAR_FONT_IS_BOLD.set(overrides.bold) self.overrideFrame.overrideFontStyle.set(True) self.configureFontStyleFields() if overrides.italic: self.fields.VAR_FONT_IS_ITALIC.set(overrides.italic) self.overrideFrame.overrideFontStyle.set(True) self.configureFontStyleFields() if overrides.overstrike: self.fields.VAR_FONT_IS_OVERSTRIKE.set(overrides.overstrike) self.overrideFrame.overrideFontStyle.set(True) self.configureFontStyleFields() if overrides.alignment: self.fields.VAR_ALIGNMENT.set(overrides.alignment) self.overrideFrame.overrideAlignment.set(True) self.overrideFrame.gmsFrame.ALIGNMENT_COMBO_BOX.config(state="readonly") def configureFontStyleFields(self): self.overrideFrame.gmsFrame.checkButtonBold.config(state=NORMAL) self.overrideFrame.gmsFrame.checkButtonItalic.config(state=NORMAL) self.overrideFrame.gmsFrame.checkButtonOverstrike.config(state=NORMAL) def setGlobalMessageSettings(self): gmSettings = self.listFrame.window.window.settings.messageSettings wSettings = self.listFrame.window.window.settings.windowSettings self.fields.VAR_ENTRY_MESSAGE_DURATION.set(gmSettings.duration) self.fields.VAR_ENTRY_MESSAGE_INTERMISSION.set(gmSettings.intermission) self.fields.VAR_FONT_COMBO_BOX.set(gmSettings.fontFace) self.fields.VAR_LABEL_MESSAGE_COLOR_FOREGROUND = gmSettings.color self.fields.VAR_LABEL_MESSAGE_COLOR_TEXT.set(gmSettings.color) self.fields.VAR_ENTRY_NORMAL_FONT_SIZE.set(gmSettings.fontSize) self.fields.VAR_ENTRY_MOVE_ALL_ON_LINE_DELAY.set(wSettings.moveAllOnLineDelay) self.fields.VAR_ARRIVAL.set(gmSettings.arrival) self.fields.VAR_DEPARTURE.set(gmSettings.departure) self.fields.VAR_FONT_IS_BOLD.set(gmSettings.bold) self.fields.VAR_FONT_IS_ITALIC.set(gmSettings.italic) self.fields.VAR_FONT_IS_OVERSTRIKE.set(gmSettings.overstrike) self.fields.VAR_ALIGNMENT.set(gmSettings.alignment) def disableGlobalMessageFields(self): for child in self.globalMessageSettingsFrame.frame.winfo_children(): if child.winfo_class() in ('Entry', 'Button', 'TCombobox', 'Checkbutton'): child.configure(state='disable') if child.winfo_class() == 'Frame': for grandchild in child.winfo_children(): if grandchild.winfo_class() in ('Entry', 'Button', 'TCombobox', 'Checkbutton'): grandchild.configure(state='disable') def updateMessage(self): if validateMessageMessageMaker(self.fields, self.master) and validateFontsMessageMaker(self.fields, self.master) and validate(self): override = Override() if self.overrideFrame.overrideDuration.get(): override.duration = self.globalMessageSettingsFrame.fields.VAR_ENTRY_MESSAGE_DURATION.get() if self.overrideFrame.overrideIntermission.get(): override.intermission = self.globalMessageSettingsFrame.fields.VAR_ENTRY_MESSAGE_INTERMISSION.get() if self.overrideFrame.overrideScrollSpeed.get(): override.scrollSpeed = self.globalMessageSettingsFrame.fields.VAR_ENTRY_MOVE_ALL_ON_LINE_DELAY.get() if self.overrideFrame.overrideFont.get(): override.font = self.globalMessageSettingsFrame.fields.VAR_FONT_COMBO_BOX.get() if self.overrideFrame.overrideFontSize.get(): override.fontSize = self.globalMessageSettingsFrame.fields.VAR_ENTRY_NORMAL_FONT_SIZE.get() if self.overrideFrame.overrideFontColor.get(): override.fontColor = self.globalMessageSettingsFrame.fields.VAR_LABEL_MESSAGE_COLOR_TEXT.get() if self.overrideFrame.overrideArrival.get(): override.arrival = self.globalMessageSettingsFrame.fields.VAR_ARRIVAL.get() if self.overrideFrame.overrideDeparture.get(): override.departure = self.globalMessageSettingsFrame.fields.VAR_DEPARTURE.get() if self.overrideFrame.overrideFontStyle.get(): override.bold = self.globalMessageSettingsFrame.fields.VAR_FONT_IS_BOLD.get() override.italic = self.globalMessageSettingsFrame.fields.VAR_FONT_IS_ITALIC.get() override.overstrike = self.globalMessageSettingsFrame.fields.VAR_FONT_IS_OVERSTRIKE.get() if self.overrideFrame.overrideAlignment.get(): override.alignment = self.globalMessageSettingsFrame.fields.VAR_ALIGNMENT.get() for part in self.message.parts: part.sortOrder = self.message.parts.index(part) + 1 newMessage = Message(self.mmFrame.nickname.get(), self.index, self.message.parts, override) if not self.isNewMessage: self.parentWindow.messages[self.index] = newMessage else: self.parentWindow.messages.append(newMessage) self.parentWindow.mlFrame.populateListbox(self.parentWindow.messages) self.master.destroy()