I have a GUI that processes messages serially as they arrive and get queued up by several websockets. This function sets up a callback to itself using after_idle to perpetuate the process, like so:
def process_queue(self, flush=False):
'''
Check for new messages in the queue periodically.
Sets up callback to itself to perpetuate the process.
'''
if flush:
while not self.queue.empty():
self.get_msg()
else:
self.get_msg()
self.master.after_idle(self.process_queue)
I have an OptionMenu
widget on the GUI, which hangs and causes the program to crash when it is clicked:
self.plotind = tk.StringVar()
self.plotind.set('MACD')
options = ['MACD']
self.indopts = tk.OptionMenu(self.analysis_frame, self.plotind, *[option for option in options])
self.indopts.grid(row=1, column=1)
If I change the after_idle()
to just after()
, it works fine.
I assume this is because clicking on an OptionMenu
actually sets up its own after_idle()
call to open the menu, which is then competing with the one I have in process_queue()
.
I can certainly use after()
in my function if need be - it might not be optimally fast at processing the queue, but it's not the end of the world. But is there a more graceful way to handle this? Surely most GUIs should be able to handle having after_idle()
called somewhere when an OptionMenu
exists?