From massimo.pozzoni at st.com Tue Sep 20 04:05:36 2022 From: massimo.pozzoni at st.com (Massimo POZZONI) Date: Tue, 20 Sep 2022 08:05:36 +0000 Subject: [Tkinter-discuss] TKinter ttk combobox Focusout event Message-ID: I find an issue with the Combobox events: The event is triggered also when the drop-down menu list is opened. (Basically it works as the FocusOut of the associated Entry, not of the ComboBox) The <> event is triggered only when a selection is done from the list, but not if something is written inside the associated Entry. My problem is that I need an event that is triggered when the overall combox widget is left, which is not the FocusOut, because when I open the drop-down menu I am still using the widget, and it is not the <> because if I left the widget after writing inside the associated Entry, the event is not triggered because no selection from list happens. Is there any way to have an event that is triggered when the overall combobox is left, but not when the drop-down list is opened? Thanks Massimo ST Restricted -------------- next part -------------- An HTML attachment was scrubbed... URL: From klappnase at web.de Wed Sep 21 19:26:10 2022 From: klappnase at web.de (Michael Lange) Date: Thu, 22 Sep 2022 01:26:10 +0200 Subject: [Tkinter-discuss] TKinter ttk combobox Focusout event In-Reply-To: References: Message-ID: <20220922012610.98822950f6d0aaed271d5429@web.de> Hi, On Tue, 20 Sep 2022 08:05:36 +0000 Massimo POZZONI via Tkinter-discuss wrote: (...) > My problem is that I need an event that is triggered when the overall > combox widget is left, which is not the FocusOut, because when I open > the drop-down menu I am still using the widget, and it is not the > <> because if I left the widget after writing inside > the associated Entry, the event is not triggered because no selection > from list happens. > > Is there any way to have an event that is triggered when the overall > combobox is left, but not when the drop-down list is opened? maybe a workaround might help. As far as I know there is no simple way to directly access ttk subwidgets from tkinter, but with a simple trick you could check if the focus went from the combobox's entry to the drop down list, as in this example: #################################################### from tkinter import * from tkinter import ttk root = Tk() b = Button(root, text='Hi') b.pack(padx=100, pady=30) v = StringVar(value='foo') # define a unique widget name for the combobox c = ttk.Combobox(root, name='unique_name', textvariable=v, values=('foo', 'bar', 'bla')) c.pack(pady=30) def do_something(): print('Doing something...') def on_focus_out(event): # check if the drop-down list has keyboard focus if 'unique_name.popdown' in str(root.tk.call('focus')): print('Drop-down list opened.') else: do_something() c.bind('', on_focus_out) root.mainloop() #################################################### Alternatively one could skip that uinque-name thing and use the fact that focus_get() crashes when the drop down list has focus, with a modified event callback: def on_focus_out(event): try: c.focus_get() do_something() except KeyError: pass Not sure about this one, maybe it might fail if the focus goes from the combobox directly to some other ttk subwidget? In the simplified example program above both versions seem to work. Have a nice day, Michael .-.. .. ...- . .-.. --- -. --. .- -. -.. .--. .-. --- ... .--. . .-. Every living thing wants to survive. -- Spock, "The Ultimate Computer", stardate 4731.3 From massimo.pozzoni at st.com Thu Sep 22 12:17:50 2022 From: massimo.pozzoni at st.com (Massimo POZZONI) Date: Thu, 22 Sep 2022 16:17:50 +0000 Subject: [Tkinter-discuss] Program continuing execution while tkinter window is open In-Reply-To: References: Message-ID: I'm wondering if there is any way to have a tkinter window running, while the main program is continuing its execution. I tried with threading but with no success. So far I always got the program to wait until the tkinter window is closed. Is there any way to have the python main program to continue the execution while a tkinter window is open? Massimo ST Restricted -------------- next part -------------- An HTML attachment was scrubbed... URL: From klappnase at web.de Thu Sep 22 19:03:31 2022 From: klappnase at web.de (Michael Lange) Date: Fri, 23 Sep 2022 01:03:31 +0200 Subject: [Tkinter-discuss] Program continuing execution while tkinter window is open In-Reply-To: References: Message-ID: <20220923010331.c4835954c64ab2660ce979c0@web.de> Hi, On Thu, 22 Sep 2022 16:17:50 +0000 Massimo POZZONI via Tkinter-discuss wrote: > > I'm wondering if there is any way to have a tkinter window running, > while the main program is continuing its execution. I tried with > threading but with no success. > > So far I always got the program to wait until the tkinter window is > closed. > > Is there any way to have the python main program to continue the > execution while a tkinter window is open? I am not sure what you actually want to achieve; when using threads you need to make sure that the Tcl interpreter (inside which the tkinter window is running) runs in the main program thread and that you must *never* do any calls to tkinter from within any of the child threads. For interaction between tkinter and the child threads you can for example use Lock or Condition objects to safely update some variable value from the child thread and an after() loop to query the variable value on the Tk side. Below a primitive example: ########################################## from tkinter import * from threading import Thread, Lock from time import sleep from signal import signal root = Tk() s = IntVar() s.set(0) Label(root, textvariable=s).pack(pady=30, padx=70) x = 0 run = True lock = Lock() def quit(*args): global run # make sure the child stops before we quit run = False root.quit() root.protocol('WM_DELETE_WINDOW', quit) # make sure keyboard interrupt is handled properly signal(2, quit) def poll(): lock.acquire() s.set(x) print('current value ->', x) lock.release() root.after(500, poll) poll() def incr(): global x while run: lock.acquire() x += 1 lock.release() sleep(1) print('child thread done') t = Thread(target=incr) t.start() root.mainloop() ########################################## Have a nice day, Michael .-.. .. ...- . .-.. --- -. --. .- -. -.. .--. .-. --- ... .--. . .-. Without facts, the decision cannot be made logically. You must rely on your human intuition. -- Spock, "Assignment: Earth", stardate unknown