0

Basically im trying to create a tkinter UI together with a audio listening infinite loop. My problem is the after() method does not really work as your traditional infinite loop with an exit condition.

I would want to keep both tkinter's main loop and my own, so my infinite loop would be constantly listening until the exit condition is met then i break out the loop.

I was looking at multithreading but im not too sure how to do this with tkinter since im new to tkinter in general

Ultimately id want to do this

def listen(event):
   while 1:
       #listennnn
       #exit condition then break


root = Tk()
deploy = Button(root, text="Listen")
deploy.bind("<Button-1>", listen)

deploy.pack()
root.mainloop()
Reblochon Masque
  • 35,405
  • 10
  • 55
  • 80
  • Does this work for you? https://stackoverflow.com/questions/459083/how-do-you-run-your-own-code-alongside-tkinters-event-loop – Ted Brownlow Aug 24 '19 at 02:51
  • You are binding an endless function to the button. When you press it, the `listen` would run. Can you explain more what you want exactly? – Masoud Rahimi Aug 24 '19 at 03:22
  • Possible duplicate of [How do you run your own code alongside Tkinter's event loop?](https://stackoverflow.com/questions/459083/how-do-you-run-your-own-code-alongside-tkinters-event-loop) – stovfl Aug 24 '19 at 07:59

2 Answers2

0

You can use an exit condition with this construct:

def listen(event='dummy_event'):
    if exit_condition:
        return
    do_the_listening_thinghy()
    root.after(100, listen)


exit_condition = False

root = Tk()
deploy_btn = Button(root, text="Listen", command=listen)    
deploy_btn.pack()

root.mainloop()
Reblochon Masque
  • 35,405
  • 10
  • 55
  • 80
0

There are a couple of options.

Create your own event loop

Instead of calling root.mainloop(), write your own loop that does whatever audio capture you need and then calls root.update() to process Tkinter events.

This might need some careful tuning. You don't want to loose any audio, nor do you want the GUI to become unresponsive.

An similar alternative to this:

Integrate asyncio in your tkinter program

If you are familiar with the asyncio style, this might do very well. It also has support in the language.

Unfortunately asyncio is still kind of a work in progress. So the examples you'll find might be out of date and even unusable.

Use a separate process for audio

Launch a multiprocessing.Process to do the audio capture. Use a multiprocessing.Pipe to send commands to the process and to receive audio data (using after). You should probably create this process before creating the root window.

The biggest plusses of this method are:

  • it cannot interfere with the GUI process,
  • it can be tested separately from the GUI,
  • any audio processing can be done in the second process (or even a third process) without interfering with the GUI.

Using a separate thread for audio

Since audio involves I/O, this might be a good fit for threading.

It won't do if you also need to do CPU-intensive processing of the audio data. In CPython, only one thread at a time can be executing Python bytecode. So when the second thread crunching numbers, your GUI thread might be starved of run time.

Roland Smith
  • 42,427
  • 3
  • 64
  • 94