def __init__(self, master): """Create the Toplevel 'About arxivfeed'.""" Toplevel.__init__(self, master, class_=master.winfo_class(), padx=10) self.title(_("About {app_name}".format(app_name=APP_NAME))) self.image = PhotoImage(file=IMAGES['icon'], master=self) Label(self, image=self.image).grid(row=0, columnspan=2, pady=10) Label(self, text="{app_name} {version}".format(app_name=APP_NAME, version=__version__)).grid( row=1, columnspan=2) Label(self, text=_("PyTkEditor - Python IDE")).grid(row=2, columnspan=2, padx=10) Label(self, text="Copyright (C) Juliette Monsel 2018-2020").grid( row=3, columnspan=2) Label(self, text="*****@*****.**").grid(row=4, columnspan=2) b = Button(self, text=_("License"), command=self._license) b.grid(row=5, column=0, pady=20, padx=4, sticky='e') Button(self, text=_("Close"), command=self.exit).grid(row=5, column=1, pady=20, padx=4, sticky='w') self.protocol("WM_DELETE_WINDOW", self.exit) self.resizable(0, 0) b.focus_set() self.grab_set()
def __init__(self, parent, title, imageFile, body): super(DialogAbout, self).__init__(parent) self.parent = parent parentGeometry = re.match("(\d+)x(\d+)[+]?([-]?\d+)[+]?([-]?\d+)", parent.geometry()) dialogX = int(parentGeometry.group(3)) dialogY = int(parentGeometry.group(4)) self.transient(self.parent) self.title(title) frame = Frame(self) image = PhotoImage(file=imageFile) aboutImage = Label(frame, image=image) aboutBody = Label(frame, text=body, wraplength=500) okButton = Button(frame, text=_("OK"), command=self.ok) okButton.focus_set() aboutImage.grid(row=0, column=0, sticky=NW, pady=20, padx=16) aboutBody.grid(row=0, column=1, columnspan=2, sticky=EW, pady=3, padx=0) okButton.grid(row=1, column=2, sticky=EW, pady=3) frame.grid(row=0, column=0, sticky=(N,S,E,W)) frame.columnconfigure(1, weight=1) window = self.winfo_toplevel() window.columnconfigure(0, weight=1) self.geometry("+{0}+{1}".format(dialogX+200,dialogY+200)) self.bind("<Alt-u>", lambda *ignore: okButton.focus_set()) self.bind("<Return>", self.ok) self.bind("<Escape>", self.close) self.protocol("WM_DELETE_WINDOW", self.close) self.grab_set() self.wait_window(self)
def __init__(self, parent=None, title="", message="", button="Ok", image=None, **options): """ Create a message box with one button: parent: parent of the toplevel window title: message box title message: message box text button: message displayed on the button image: image displayed at the left of the message **options: other options to pass to the Toplevel.__init__ method """ Toplevel.__init__(self, parent, **options) self.transient(parent) self.resizable(False, False) self.title(title) if image: Label(self, text=message, wraplength=335, font="Sans 11", compound="left", image=image).grid(row=0, padx=10, pady=10) else: Label(self, text=message, wraplength=335, font="Sans 11").grid(row=0, padx=10, pady=10) b = Button(self, text=button, command=self.destroy) b.grid(row=1, padx=10, pady=10) self.grab_set() b.focus_set() self.wait_window(self)
def __init__(self, title="", message="", button="Ok", image=None, checkmessage="", style="clam", **options): """ Create a messagebox with one button and a checkbox below the button: parent: parent of the toplevel window title: message box title message: message box text button: message displayed on the button image: image displayed at the left of the message checkmessage: message displayed next to the checkbox **options: other options to pass to the Toplevel.__init__ method """ Tk.__init__(self, **options) self.resizable(False, False) self.title(title) s = Style(self) s.theme_use(style) if image: Label(self, text=message, wraplength=335, font="Sans 11", compound="left", image=image).grid(row=0, padx=10, pady=(10, 0)) else: Label(self, text=message, wraplength=335, font="Sans 11").grid(row=0, padx=10, pady=(10, 0)) b = Button(self, text=button, command=self.destroy) b.grid(row=2, padx=10, pady=10) self.var = BooleanVar(self) c = Checkbutton(self, text=checkmessage, variable=self.var) c.grid(row=1, padx=10, pady=0, sticky="e") self.grab_set() b.focus_set() self.wait_window(self)
def __init__(self, parent, title="", message="", image=None, button1=_("Yes"), button2=_("No"), button3=_("Cancel")): """ Create a messagebox with three buttons. Arguments: parent: parent of the toplevel window title: message box title message: message box text button1/2: message displayed on the first/second button image: image displayed at the left of the message """ Toplevel.__init__(self, parent, class_='MyNotes') self.transient(parent) self.resizable(False, False) self.title(title) self.columnconfigure(0, weight=1) self.rowconfigure(0, weight=1) self.columnconfigure(1, weight=1) self.columnconfigure(2, weight=1) self.result = None if isinstance(image, str): data = ICONS.get(image) if data: self.img = PhotoImage(master=self, data=data) else: self.img = PhotoImage(master=self, file=image) image = self.img frame = Frame(self) frame.grid(row=0, columnspan=3, sticky="ewsn") if image: Label(frame, image=image).pack(side="left", padx=(10, 4), pady=(10, 4)) Label(frame, text=message, font="TkDefaultFont 10 bold", wraplength=335).pack(side="left", padx=(4, 10), pady=(10, 4)) b1 = Button(self, text=button1, command=self.command1) b1.grid(row=1, column=0, padx=10, pady=10) Button(self, text=button2, command=self.command2).grid(row=1, column=1, padx=10, pady=10) Button(self, text=button3, command=self.destroy).grid(row=1, column=2, padx=10, pady=10) self.grab_set() b1.focus_set()
def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self.parent.title("Example Form") self.pack(fill=BOTH, expand=True) f = Frame(self) f.pack(fill=X) l = Label(f, text='First Name', width=10) l.pack(side=LEFT, padx=5, pady=5) self.firstName = Entry(f) self.firstName.pack(fill=X, padx=5, expand=True) f = Frame(self) f.pack(fill=X) l = Label(f, text='Last Name', width=10) l.pack(side=LEFT, padx=5, pady=5) self.lastName = Entry(f) self.lastName.pack(fill=X, padx=5, expand=True) f = Frame(self) f.pack(fill=X) l = Label(f, text='Full Name', width=10) l.pack(side=LEFT, padx=5, pady=5) self.fullName = Label(f, text='ALEX POOPKIN', width=10) self.fullName.pack(fill=X, padx=5, expand=True) f = Frame(self) f.pack(fill=X) l = Label(f, text='', width=10) l.pack(side=LEFT, padx=5, pady=0) self.errorMessage = Label(f, text='Invalid character int the name!', foreground='red', width=30) self.errorMessage.pack(fill=X, padx=5, expand=True) f = Frame(self) f.pack(fill=X) b = Button(f, text='Close', command=lambda : self.parent.quit()) b.pack(side=RIGHT, padx=5, pady=10) b['default'] = ACTIVE b.focus_set() self.clearButton = Button(f, text='Clear') self.clearButton.pack(side=RIGHT, padx=5, pady=10) self.clearButton['state'] = DISABLED self.sendButton = Button(f, text='Send') self.sendButton.pack(side=RIGHT, padx=5, pady=10)
def __init__(self, parent=None, title="", message="", button=_("Ok"), image=None): """ Create a message box with one button. Arguments: parent: parent of the toplevel window title: message box title message: message box text (that can be selected) button: message displayed on the button image: image displayed at the left of the message, either a PhotoImage or a string """ Toplevel.__init__(self, parent, class_='Scheduler') self.transient(parent) self.resizable(False, False) self.title(title) self.result = "" self.button = button if isinstance(image, str): data = ICONS.get(image) if data: self.img = PhotoImage(master=self, data=data) else: self.img = PhotoImage(master=self, file=image) image = self.img frame = Frame(self) frame.rowconfigure(0, weight=1) frame.columnconfigure(1, weight=1) l = len(message) w = max(1, min(l, 50)) h = 0 for line in message.splitlines(): h += 1 + len(line) // w if h < 3: w = min(l, 35) h = 0 for line in message.splitlines(): h += 1 + len(line) // w display = Text(frame, relief='flat', highlightthickness=0, font="TkDefaultFont 10 bold", bg=self.cget('bg'), height=h, width=w, wrap="word") display.configure(inactiveselectbackground=display.cget("selectbackground")) display.insert("1.0", message) display.configure(state="disabled") display.grid(row=0, column=1, pady=(10, 4), padx=4, sticky="ewns") display.bind("<Button-1>", lambda event: display.focus_set()) if image: Label(frame, image=image).grid(row=0, column=0, padx=4, pady=(10, 4)) b = Button(self, text=button, command=self.validate) frame.pack() b.pack(padx=10, pady=10) self.grab_set() b.focus_set()
def __init__(self, title="", message="", button="Ok", image=None, checkmessage="", **options): """ Create a messagebox with one button and a checkbox below the button: parent: parent of the toplevel window title: message box title message: message box text button: message displayed on the button image: image displayed at the left of the message checkmessage: message displayed next to the checkbox **options: other options to pass to the Toplevel.__init__ method """ Tk.__init__(self, **options) self.title(title) self.resizable(False, False) self.columnconfigure(1, weight=1) self.rowconfigure(0, weight=1) style = Style(self) style.theme_use(STYLE) self.img = None if isinstance(image, str): try: self.img = PhotoImage(file=image) except TclError: self.img = PhotoImage(data=image) elif image: self.img = image if self.img: Label(self, image=self.img).grid(row=0, column=0, padx=10, pady=(10, 0)) Label(self, text=message, wraplength=335, font="TkDefaultFont 10 bold").grid(row=0, column=1, padx=10, pady=(10, 0)) b = Button(self, text=button, command=self.destroy) b.grid(row=2, padx=10, pady=10, columnspan=2) self.var = BooleanVar(self) c = Checkbutton(self, text=checkmessage, variable=self.var) c.grid(row=1, padx=10, pady=4, sticky="e", columnspan=2) self.grab_set() b.focus_set()
def __init__(self, parentdir: str): """\ Parameters --------- parentdir (str): The path of the directory where the SymLink will be placed """ self.initDir = Path(parentdir) Tk.__init__(self) wd = 400 ht = 100 self.title("Create Symbolic Link") self.attributes('-topmost', 1) x = ((self.winfo_screenwidth() - wd) // 2) y = ((self.winfo_screenheight() - ht) // 2) self.geometry(f'{wd}x{ht}+{x}+{y}') self.bind_all('<Escape>', lambda _: self.destroy()) lbl1 = Label( master=self, font='Ebrima 12', text="Would you like to make a Symlink for a folder or a file?") lbl1.place(anchor='center', relx=0.5, rely=0.3) folder_btn = Button(master=self, text="Folder", underline=0, command=lambda: self.createLink('folder'), width=10) folder_btn.place(anchor='center', relx=0.25, rely=0.66) folder_btn.focus_set() self.bind_all('<Return>', lambda _: folder_btn.invoke()) file_btn = Button(master=self, text=" File ", command=lambda: self.createLink('file'), width=10) file_btn.place(anchor='center', relx=0.5, rely=0.66) cancel_btn = Button(master=self, text="Cancel", command=self.destroy, width=10) cancel_btn.place(anchor='center', relx=0.75, rely=0.66) self.mainloop()
def _license(self): """ affiche la licence dans une nouvelle fenêtre """ def close(): """ ferme la fenêtre """ self.focus_set() fen.destroy() fen = Toplevel(self, class_="BraceletGenerator") fen.title(_("License")) fen.transient(self) fen.protocol("WM_DELETE_WINDOW", close) fen.resizable(0, 0) fen.grab_set() fen.configure(bg=BG_COLOR) set_icon(fen) texte = Text(fen, width=50, height=18) texte.pack() texte.insert( "end", _("Bracelet Generator is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n\n" )) texte.insert( "end", _("Bracelet Generator is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n\n" )) texte.insert( "end", _("You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/." )) i = int(texte.index("5.end").split(".")[1]) texte.tag_add("link", "5.%i" % (i - 29), "5.%i" % (i - 1)) texte.tag_configure("link", foreground="#0000ff", underline=1) texte.tag_bind("link", "<Button - 1>", lambda event: webOpen("http://www.gnu.org/licenses/")) texte.tag_bind("link", "<Enter>", lambda event: texte.config(cursor="hand1")) texte.tag_bind("link", "<Leave>", lambda event: texte.config(cursor="")) texte.configure(state="disabled", wrap="word") b_close = Button(fen, text=_("Close"), command=close) b_close.pack(side="bottom") b_close.focus_set() fen.wait_window(fen)
def __init__(self, parent, title=None, text=None): self.had_focus = parent.focus_get() Toplevel.__init__(self, parent) if title: self.title(title) stext = ScrolledText(self, background="gray") stext.pack(padx=5, pady=5) if text is not None: stext.insert("end", text) stext["state"] = "disabled" separ = Separator(self, orient="horizontal") separ.pack(expand=1, fill="x") b = Button(self, text=_("OK"), width=10, command=self.destroy, default="active") self.bind("<Escape>", self.destroy) b.pack() self.protocol("WM_DELETE_WINDOW", self.destroy) b.focus_set() self.grab_set() self.wait_window()
def __init__(self, parent, title="", message="", button1="Yes", button2="No", image=None, **options): """ Create a messagebox with two buttons: parent: parent of the toplevel window title: message box title message: message box text button1/2: message displayed on the first/second button image: image displayed at the left of the message **options: other options to pass to the Toplevel.__init__ method """ Toplevel.__init__(self, parent, **options) self.transient(parent) self.resizable(False, False) self.title(title) self.columnconfigure(0, weight=1) self.columnconfigure(1, weight=1) self.rep = "" self.button1 = button1 self.button2 = button2 if image: Label(self, text=message, wraplength=335, font="Sans 11", compound="left", image=image).grid(row=0, padx=10, pady=10, columnspan=2) else: Label(self, text=message, wraplength=335, font="Sans 11").grid(row=0, padx=10, pady=10, columnspan=2) b1 = Button(self, text=button1, command=self.command1) b1.grid(row=1, column=0, padx=15, pady=10, sticky="e") Button(self, text=button2, command=self.command2).grid(row=1, column=1, padx=15, pady=10, sticky="w") self.grab_set() b1.focus_set() self.wait_window(self)
def _license(self): """ affiche la licence dans une nouvelle fenêtre """ def close(): """ ferme la fenêtre """ self.focus_set() fen.destroy() fen = Toplevel(self) fen.title(_("License")) fen.transient(self) fen.protocol("WM_DELETE_WINDOW", close) fen.resizable(0, 0) fen.grab_set() # set_icon(fen) texte = Text(fen, width=50, height=18) texte.pack() texte.insert("end", _("Sudoku-Tk is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n\n")) texte.insert("end", _("Sudoku-Tk is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n\n")) texte.insert("end", _("You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.")) i = int(texte.index("5.end").split(".")[1]) texte.tag_add("link", "5.%i" % (i - 29), "5.%i" % (i - 1)) texte.tag_configure("link", foreground="#0000ff", underline=1) texte.tag_bind("link", "<Button - 1>", lambda event: webOpen("http://www.gnu.org/licenses/")) texte.tag_bind("link", "<Enter>", lambda event: texte.config(cursor="hand1")) texte.tag_bind("link", "<Leave>", lambda event: texte.config(cursor="")) texte.configure(state="disabled", wrap="word") b_close = Button(fen, text=_("Close"), command=close) b_close.pack(side="bottom") b_close.focus_set() fen.wait_window(fen)
class About(Toplevel): ''' The About dialog Shows information about this application ''' WINDOW_WIDTH = 350 WINDOW_HEIGHT = 120 WINDOW_WIDTH_MIN = 350 WINDOW_HEIGHT_MIN = 100 WINDOW_WIDTH_OFFSET = 40 WINDOW_HEIGHT_OFFSET = 20 WINDOW_TITLE = "Brainfsck - About" def __init__(self, master, **kw): Toplevel.__init__(self, master, **kw) self.style = Style() self.withdraw() x = self.master.winfo_rootx() + self.WINDOW_WIDTH_OFFSET y = self.master.winfo_rooty() + self.WINDOW_HEIGHT_OFFSET loadIcon(self.tk, self, IIVLXICO) self.title(self.WINDOW_TITLE) self.geometry('{0:d}x{1:d}+{2:d}+{3:d}'.format( self.WINDOW_WIDTH, self.WINDOW_HEIGHT, x,y)) self.resizable(False, False) self.minsize(self.WINDOW_WIDTH_MIN, self.WINDOW_HEIGHT_MIN) #grid configure self.grid_columnconfigure(0, weight=1) self.grid_columnconfigure(1, weight=1) self.grid_rowconfigure(0, weight=1) self.grid_rowconfigure(1, weight=0) self.grid_rowconfigure(2, weight=0) self.grid_rowconfigure(3, weight=0) self.grid_rowconfigure(4, weight=1) # grab the current window #self.wait_visibility() self.transient(self.master) self.focus_set() self.grab_set() self.deiconify() # draw this window self.configureStyles() self.draw() # wait for the window to close and return to master self.wait_window() def configureStyles(self): self.style.configure('About.TButton', font='Segoe 8', anchor='center', height=0, width=10, padding=2) self.style.configure('About.TLabel', font='Segoe 10') self.style.configure('AboutBold.TLabel', font='Segoe 14 bold', anchor='center') self.style.configure('AboutBoldMed.TLabel', font='Segoe 11 bold', anchor='center') def draw(self): ''' Draw the About window ''' self.title_label = Label(self, text = "Brainfsck", justify=CENTER, style= 'AboutBold.TLabel') self.title_label.grid(row=0, column=0, columnspan=2, sticky='news') self.title_label_sub = Label(self, text = "Brainfsck Interpreter", style = "AboutBoldMed.TLabel") self.title_label_sub.grid(row=1, column=0, columnspan=2, sticky='news') self.about_label = Label(self, text = "Created by iivlx - [email protected]", style = "About.TLabel") self.about_label.grid(row=2, column=0, columnspan=2, padx=10, sticky='news') self.version_label = Label(self, text = "Version: {0:s}".format('.'.join(str(v) for v in __version__)), style = "About.TLabel") self.version_label.grid(row=3, column=0, columnspan=2, padx=10, sticky='news') self.close_button = Button(self, text = "Close", style = "About.TButton", command = lambda: self.close()) self.close_button.grid(row=4, column=1, padx=4, pady=4, sticky='nes') self.close_button.focus_set() def close(self): ''' Close this dialog and return to parent window ''' self.master.focus_set() self.destroy()
def __init__(self, notebook_page, caller): """ Create the and place the widgets in the frame for user Signal input interaction. :param notebook_page: Notebook page to contain this frame :param caller: class instantiating this class """ self.caller = caller # A set of arrays to manage the user selected modes, # and reported values and timestamps for each of the # 8 signals # an array of value entry controls that hold the returned values self.values = [] # an array of time stamp entry controls that hold the returned # timestamps self.time_stamps = [] # create the frame self.touch_inputs_frame = Frame(notebook_page, padding=10, relief=SUNKEN) # create the controls for each of the 8 signals for x in range(1, 5): # set the mode label with an associated signal channel number l = Label(self.touch_inputs_frame, text=('Touch ' + str(x) + ' Value')) l.grid(row=x, column=2, padx=[20, 5]) # create a read only entry field for each signal report # and set its value to 0 value = Entry(self.touch_inputs_frame, state='readonly', width=6) value.configure({'readonlybackground': 'white'}) self.values.append(value) value.grid(row=x, column=3, pady=3, padx=3) self.set_input_value(x - 1, '') # create a time stamp label for the timestamp entry field # and set its value to empty l = Label(self.touch_inputs_frame, text=' Time Stamp:') l.grid(row=x, column=4, padx=[20, 5]) # create a read only entry field for each time stamp time_stamp = Entry(self.touch_inputs_frame, state='readonly', width=20) time_stamp.configure({'readonlybackground': 'white'}) self.time_stamps.append(time_stamp) time_stamp.grid(row=x, column=5, pady=3, padx=3) self.set_time_stamp_value(x - 1, '') # add an enable touch button b = Button(self.touch_inputs_frame, text='Enable Touch', command=self.enable_touch) b.focus_set() b.grid(row=55, column=45, pady=[30, 5], padx=[0, 30]) # grid the label frame and sets its position self.touch_inputs_frame.grid(row=0, column=0, sticky='EW', columnspan=49, padx=[95, 10], pady=30)
def __init__(self, parent=None, title="", message="", traceback="", report_msg=False, button=_("Ok"), image="error"): """ Create an error messagebox. Arguments: parent: parent of the toplevel window title: message box title message: message box text (that can be selected) button: message displayed on the button traceback: error traceback to display below the error message report_msg: if True display a suggestion to report error image: image displayed at the left of the message, either a PhotoImage or a string """ Toplevel.__init__(self, parent, class_='Scheduler') self.transient(parent) self.resizable(False, False) self.title(title) self.result = "" self.button = button style = Style(self) style.configure("url.TLabel", foreground="blue") style.configure("txt.TFrame", background='white') if not parent: style.theme_use('clam') if isinstance(image, str): data = ICONS.get(image) if data: self.img = PhotoImage(master=self, data=data) else: self.img = PhotoImage(master=self, file=image) image = self.img frame = Frame(self) frame.rowconfigure(0, weight=1) frame.columnconfigure(1, weight=1) l = len(message) l2 = len(traceback) w = max(1, min(max(l, l2), 50)) h = 0 for line in message.splitlines(): h += 1 + len(line) // w h2 = 0 for line in traceback.splitlines(): h2 += 1 + len(line) // w if h + h2 < 3: w = min(l, 35) h = 0 for line in message.splitlines(): h += 1 + len(line) // w h2 = 0 for line in traceback.splitlines(): h2 += 1 + len(line) // w display = Text(frame, relief='flat', highlightthickness=0, font="TkDefaultFont 10 bold", bg=self.cget('bg'), height=h, width=w, wrap="word") display.configure(inactiveselectbackground=display.cget("selectbackground")) display.insert("1.0", message) display.configure(state="disabled") display.grid(row=0, column=1, pady=(10, 4), padx=4, sticky="ewns") display.bind("<Button-1>", lambda event: display.focus_set()) if image: Label(frame, image=image).grid(row=0, column=0, padx=4, pady=(10, 4)) frame2 = Frame(self) frame2.columnconfigure(0, weight=1) frame2.rowconfigure(0, weight=1) report_frame = Frame(self) if traceback: txt_frame = Frame(frame2, style='txt.TFrame', relief='sunken', borderwidth=1) error_msg = Text(txt_frame, width=w, wrap='word', font="TkDefaultFont 10", bg='white', height=8, highlightthickness=0) error_msg.bind("<Button-1>", lambda event: error_msg.focus_set()) error_msg.insert('1.0', traceback) error_msg.configure(state="disabled") scrolly = Scrollbar(frame2, orient='vertical', command=error_msg.yview) scrolly.grid(row=0, column=1, sticky='ns') scrollx = Scrollbar(frame2, orient='horizontal', command=error_msg.xview) scrollx.grid(row=1, column=0, sticky='ew') error_msg.configure(yscrollcommand=scrolly.set, xscrollcommand=scrollx.set) error_msg.pack(side='left', fill='both', expand=True) txt_frame.grid(row=0, column=0, sticky='ewsn') if report_msg: Label(report_frame, text=_("Please report this bug on ")).pack(side="left") url = Label(report_frame, style="url.TLabel", cursor="hand1", font="TkDefaultFont 10 underline", text="https://github.com/j4321/MyNotes/issues") url.pack(side="left") url.bind("<Button-1>", lambda e: url_open("https://github.com/j4321/MyNotes/issues")) b = Button(self, text=button, command=self.validate) frame.pack(fill='x') frame2.pack(fill='both', padx=4, pady=(4, 4)) report_frame.pack(fill="x", padx=4, pady=(4, 0)) b.pack(padx=10, pady=10) self.grab_set() b.focus_set()
class UpdateChecker(Toplevel): version_parser = VersionParser() def __init__(self, master, notify=False): Toplevel.__init__(self, master, class_="CheckMails") logging.info('Checking for updates') self.title(_("Update")) self.withdraw() self.rowconfigure(0, weight=1) self.columnconfigure(0, weight=1) self.columnconfigure(1, weight=1) self.protocol("WM_DELETE_WINDOW", self.quit) self.notify = notify self.img = PhotoImage(file=IM_QUESTION, master=self) frame = Frame(self) frame.grid(row=0, columnspan=2, sticky="ewsn") Label(frame, image=self.img).pack(side="left", padx=(10, 4), pady=(10, 4)) Label(frame, text=_("A new version of CheckMails is available.\ \nDo you want to download it?"), font="TkDefaultFont 10 bold", wraplength=335).pack(side="left", padx=(4, 10), pady=(10, 4)) self.b1 = Button(self, text=_("Yes"), command=self.download) self.b1.grid(row=1, column=0, padx=10, pady=10, sticky="e") Button(self, text=_("No"), command=self.quit).grid(row=1, column=1, padx=10, pady=10, sticky="w") self.ch = Checkbutton(self, text=_("Check for updates on startup.")) if CONFIG.getboolean("General", "check_update"): self.ch.state(("selected", )) self.ch.grid(row=2, columnspan=2, sticky='w') self.update = None self.thread = Thread(target=self.update_available, daemon=True) self.thread.start() self.after(1000, self.check_update) def check_update(self): if self.update is None: self.after(1000, self.check_update) elif self.update: self.deiconify() self.grab_set() self.lift() self.b1.focus_set() else: if self.notify: run([ "notify-send", "-i", IMAGE2, _("Update"), _("CheckMails is up-to-date.") ]) logging.info("CheckMails is up-to-date") self.destroy() def quit(self): CONFIG.set("General", "check_update", str("selected" in self.ch.state())) save_config() self.destroy() def download(self): webOpen("https://sourceforge.net/projects/checkmails/files") self.quit() def update_available(self): """ Check for updates online, return True if an update is available, False otherwise (and if there is no Internet connection). """ try: with request.urlopen( 'https://sourceforge.net/projects/checkmails') as page: latest_version = self.version_parser.feed(page.read().decode()) self.update = latest_version > __version__ except error.URLError as e: if e.reason.errno == -2: # no Internet connection self.update = False elif e.reason.errno == 104: # connection timed out self.update_available() else: raise e
class UpdateChecker(Toplevel): def __init__(self, master, notify=False): Toplevel.__init__(self, master, class_=APP_NAME) logging.info('Checking for updates') self.title(_("Update")) self.withdraw() self.rowconfigure(0, weight=1) self.columnconfigure(0, weight=1) self.columnconfigure(1, weight=1) self.protocol("WM_DELETE_WINDOW", self.quit) self.notify = notify self._version = __version__ self.img = PhotoImage(file=ICONS['question'], master=self) frame = Frame(self) frame.grid(row=0, columnspan=2, sticky="ewsn") Label(frame, image=self.img).pack(side="left", padx=(10, 4), pady=(10, 4)) Label(frame, text=_("A new version of {app_name} is available.\ \nDo you want to download it?").format(app_name=APP_NAME), font="TkDefaultFont 10 bold", wraplength=335).pack(side="left", padx=(4, 10), pady=(10, 4)) self.b1 = Button(self, text=_("Yes"), command=self.download) self.b1.grid(row=1, column=0, padx=10, pady=10, sticky="e") Button(self, text=_("No"), command=self.quit).grid(row=1, column=1, padx=10, pady=10, sticky="w") self.ch = Checkbutton(self, text=_("Check for updates on startup.")) if CONFIG.getboolean("General", "check_update"): self.ch.state(("selected", "!alternate")) else: self.ch.state(("!selected", "!alternate")) self.ch.grid(row=2, columnspan=2, sticky='w') self.update = None self.thread = Process(target=self.update_available, daemon=True) self.thread.start() self.after(1000, self.check_update) def check_update(self): if self.update is None: self.after(1000, self.check_update) elif self.update: logging.info("%s %s is available", APP_NAME, self._version) self.deiconify() self.grab_set() self.lift() self.b1.focus_set() else: if self.notify: run([ "notify-send", "-i", IM_ICON_SVG, _("Update"), _("{app_name} is up-to-date.").format(app_name=APP_NAME) ]) logging.info("%s is up-to-date", APP_NAME) self.destroy() def quit(self): CONFIG.set("General", "check_update", str("selected" in self.ch.state())) save_config() self.destroy() def download(self): webOpen("https://github.com/j4321/{app_name}/releases/tag/v{version}". format(app_name=APP_NAME, version=self._version)) self.quit() def update_available(self): """ Check for updates online, return True if an update is available, False otherwise (and if there is no Internet connection). """ feed = feedparser.parse( "https://github.com/j4321/{app_name}/releases.atom".format( app_name=APP_NAME)) try: # feed['entries'][0]['id'] is of the form 'tag:github.com,...:Repository/.../vx.y.z' self._version = os.path.split(feed['entries'][0]['id'])[1][1:] self.update = self._version > __version__ except IndexError: # feed['entries'] == [] because there is no Internet connection self.update = False