I have an app with an apply button with its ‘clicked’ signal connected to a method named on_apply
. The problem is that on_apply
method takes a few seconds to run and while it is running, the app becomes unresponsive.
To solve that problem, I wanted to show a modal window with a spinning circle so that the users know that work is being done. So, I thought why not do something like this
def on_apply(self, widget):
win = Adw.Window(modal=True, transient_for=main_window)
# Add some widgets to the window here
win.show()
# 'Apply' code goes here
win.close()
But that doesn’t work. The new window does not show up, probably because it was going to show up after the signal handler was finished but it got closed right before that.
So, then I tried using Python’s concurrent.futures
module like so
def on_apply(self, widget):
win = Adw.Window(modal=True, transient_for=main_window)
# Add some widgets to the window here
win.show()
def do_the_work():
# 'Apply' code goes here
win.close()
from concurrent.futures import ThreadPoolExecutor
executor = ThreadPoolExecutor(max_workers=1)
executor.submit(do_the_work)
It seemed to work initially but then I noticed that I got following warning sometimes which I do not want.
(gdm-settings:12289): Gdk-WARNING **: 15:25:10.858: gdk_gl_context_make_current() failed
My question: how to handle code inside a signal handler that takes multiple seconds to run?
TLDR;
The code I want to run inside a signal handler takes a few seconds to run. How do I make it run in the background and show a dialog or window to the user asking them to wait for it to finish?