From Vasilis.Vlachoudis at cern.ch Thu Apr 1 03:54:40 2021 From: Vasilis.Vlachoudis at cern.ch (Vasilis Vlachoudis) Date: Thu, 1 Apr 2021 07:54:40 +0000 Subject: [Tkinter-discuss] Exception protection to tk calls In-Reply-To: <20210331101042.633a537fa883b7e92c17fab3@web.de> References: <0BC70B5D93E054469872FFD0FE07220E0332B9C7FB@CERNXCHG54.cern.ch>, <20210331101042.633a537fa883b7e92c17fab3@web.de> Message-ID: <0BC70B5D93E054469872FFD0FE07220E0332BB330E@CERNXCHG53.cern.ch> Thank you Michael, >> grab_release() on a widget that has already been destroyed or, in the/ this is also my understanding, however the places that happens are on Dialog code(s) like import tkinter as tk class Dialog(tk.Toplevel): width = -1 height = -1 # ---------------------------------------------------------------------- def __init__(self, master, **kw): super().__init__(master, class_="MyDialog", **kw) self.transient(master) self.title("My title") frame = tk.Frame(self) frame.pack(side=tk.TOP, fill=tk.BOTH) # ... various widget+buttons creation #... #... self.protocol("WM_DELETE_WINDOW", self.close) if Dialog.width>0: self.geometry("%dx%d"%(Dialog.width, Dialog.height)) self.wait_visibility() self.focus_set() self.grab_set() self.wait_window() #----------------------------------------------------------------------- def close(self, event=None): Dialog.width = self.winfo_width() Dialog.height = self.winfo_height() self.grab_release() self.destroy() My impression is that on slow network connections (using remote X11 session), sometimes the dialog is displayed before the wait_visibility is being executed and if the user closes the window from the window manager, it arrives to the focus_set, grab_set or wait_window with a window that doesn't exist and then I get the error message. I've once got also the TclError on the "frame = tk.Frame(self)" command Maybe the self.geometry() is the culprit? This types of errors are not something frequent. They are rare, but they happen. We have several thousands active users around the world and I get an automatic report maybe once every a couple of weeks. Vasillis ________________________________________ From: Tkinter-discuss [tkinter-discuss-bounces+vasilis.vlachoudis=cern.ch at python.org] on behalf of Michael Lange [klappnase at web.de] Sent: Wednesday, March 31, 2021 10:10 To: tkinter-discuss at python.org Subject: Re: [Tkinter-discuss] Exception protection to tk calls Hi, On Wed, 31 Mar 2021 06:53:26 +0000 Vasilis Vlachoudis wrote: > Is there any recommendation which tkinter calls have to be protected > with an exception handling I occasionally receive traceback errors from > my users on various calls like: grab_current, grab_release, focus_get > most of the times I protect them with with a TclError handler catching > exceptions like_tkinter.TclError: bad window path name > > Also which type of exception has to be protected, this is the first > time I've got a KeyError from a tkinter call, which normally should be > innocent focus_get()" it is a bit hard to guess what's going on without a real code example. It seems like you get these errors when either calling for example grab_release() on a widget that has already been destroyed or, in the last example, calling focus_get() while a messagebox is being displayed (not sure how this can actually happen in real-world code, I was only able to reproduce that error message with a non-sensical example, like >>> def foo(): ... root.after(1000, lambda: print(root.focus_get())) ... messagebox.showinfo() ... ) . I know that this is not really an answer to your question, but my guess is that all of these situations may actually be caused by programming errors which, once they have been discovered, should rather be fixed properly than worked around with a try-except clause. For example, if the window on which grab_release() is called might no longer exist, something like if widget.winfo_exists(): widget.grab_release() might do the trick. If you want to use try-except protection anyway, I don't think that there is any general rule which methods should be protected with which exception type. I think the only way to find out is to examine the tkinter code and find out for yourself which exception(s) are likely to occur. For example with focus_get() I think the KeyError caused by nametowidget() is probably the only exception one might expect. Of course one could always play it safe with something like: try: focus = self.focus_get() except: focus = None Best regards Michael .-.. .. ...- . .-.. --- -. --. .- -. -.. .--. .-. --- ... .--. . .-. Death, when unnecessary, is a tragic thing. -- Flint, "Requiem for Methuselah", stardate 5843.7 _______________________________________________ Tkinter-discuss mailing list Tkinter-discuss at python.org https://mail.python.org/mailman/listinfo/tkinter-discuss From klappnase at web.de Thu Apr 1 05:21:11 2021 From: klappnase at web.de (Michael Lange) Date: Thu, 1 Apr 2021 11:21:11 +0200 Subject: [Tkinter-discuss] Exception protection to tk calls In-Reply-To: <0BC70B5D93E054469872FFD0FE07220E0332BB330E@CERNXCHG53.cern.ch> References: <0BC70B5D93E054469872FFD0FE07220E0332B9C7FB@CERNXCHG54.cern.ch> <20210331101042.633a537fa883b7e92c17fab3@web.de> <0BC70B5D93E054469872FFD0FE07220E0332BB330E@CERNXCHG53.cern.ch> Message-ID: <20210401112111.476a2023508592fef685a72a@web.de> Hi, On Thu, 1 Apr 2021 07:54:40 +0000 Vasilis Vlachoudis wrote: > Thank you Michael, > > >> grab_release() on a widget that has already been destroyed or, in > >> the/ > > this is also my understanding, however the places that happens are on > Dialog code(s) like > (...) > > My impression is that on slow network connections (using remote X11 > session), sometimes the dialog is displayed before the wait_visibility > is being executed and if the user closes the window from the window > manager, it arrives to the focus_set, grab_set or wait_window with a > window that doesn't exist and then I get the error message. if this is the case, maybe calling self.withdraw() early in the __init__ method and then calling protocol() before deiconify() might help? Just a guess, though. At least it sounds a bit like the users manage to press the "X" button from the window decorations before the protocol() has been applied. Best regards Michael .-.. .. ...- . .-.. --- -. --. .- -. -.. .--. .-. --- ... .--. . .-. Totally illogical, there was no chance. -- Spock, "The Galileo Seven", stardate 2822.3 From storchaka at gmail.com Sun Apr 4 17:57:24 2021 From: storchaka at gmail.com (Serhiy Storchaka) Date: Mon, 5 Apr 2021 00:57:24 +0300 Subject: [Tkinter-discuss] Unicode range In-Reply-To: <0BC70B5D93E054469872FFD0FE07220E0312E08B77@CERNXCHG51.cern.ch> References: <0BC70B5D93E054469872FFD0FE07220E0312E08B77@CERNXCHG51.cern.ch> Message-ID: 04.01.21 11:09, Vasilis Vlachoudis ????: > how can I "replace/strip" unicode characters that are out of the > accepted tk range before inserting them to Text()? > > ? File "/usr/lib/python3.6/tkinter/__init__.py", line 3272, in insert > ??? self.tk.call((self._w, 'insert', index, chars) + args) > _tkinter.TclError: character U+1c784 is above the range (U+0000-U+FFFF) > allowed by Tcl Upgrade Python. Since 3.7.6 Tkinter supports characters outside of the range U+0000-U+FFFF. From me at alandmoore.com Tue Apr 27 16:07:42 2021 From: me at alandmoore.com (alan moore) Date: Tue, 27 Apr 2021 15:07:42 -0500 Subject: [Tkinter-discuss] Binding custom events from a Menu on Windows Message-ID: <77d2f3ea-0e72-0d05-264f-839f17d6967e@alandmoore.com> Hello, I've recently stumbled on a problem while working with the Menu object on both Linux and Windows. I'm trying to create a loosely-coupled menu object, so rather than calling commands directly I'm generating custom events.? The main application object then binds callback methods to those custom events. This example shows the basic approach: **** EXAMPLE FOLLOWS **** import tkinter as tk root = tk.Tk() root.geometry('300x200') label = tk.Label(text='Test') label.grid() menu = tk.Menu(root) root.configure(menu=menu) submenu = tk.Menu(menu) menu.add_cascade(menu=submenu, label='Change Text') submenu.add_command( ??? label='Foo', ??? command=lambda: menu.event_generate('<>') ) submenu.add_command( ??? label='Bar', ??? command=lambda: menu.event_generate('<>') ) def setfoo(*_): ??? label.configure(text='Foo') def setbar(*_): ??? label.configure(text='Bar') menu.bind('<>', setfoo) menu.bind('<>', setbar) print(menu.bind()) root.mainloop() **** END EXAMPLE **** This code works as expected on Linux, but does not work at all on Windows.? The callback are never executed.? I suspect this has to do with the way menus are implemented on Windows; I know I can generate/bind events on the root window as a workaround, but should this work as-is? ( PS -- I posted this to stackoverflow, if anyone is interested in replying there:? https://stackoverflow.com/q/67289539/1454109 ) Regards, Alan Moore