Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

python - Terminate the Thread by using button in Tkinter

In my GUI code, I tried to run loop1 and loop2 at the same time by clicking one button. Thus, I used Thread to achieve this. But I also tried to stop it by clicking another button and I failed. After searching on stackoverflow, I found out that there was no directly way to kill Thread. Here is the part of code:

def loop1():
    while True:
        call (["raspivid -n -op 150 -w 640 -h 480 -b 2666666.67 -t 5000 -o test.mp4"],shell=True)
        call (["raspivid -n -op 150 -w 640 -h 480 -b 2666666.67 -t 5000 -o test1.mp4"],shell=True)

def loop2():
    while True:
        call (["arecord -D plughw:1 --duration=5 -f cd -vv rectest.wav"],shell=True)
        call (["arecord -D plughw:1 --duration=5 -f cd -vv rectest1.wav"],shell=True)

def combine():
    Thread(target = loop1).start()
    Thread(target = loop2).start()

def stop():
    Thread(target = loop1).terminate()
    Thread(target = loop2).terminate()

I tried to use these two buttons to control it.

btn1 = Button(tk, text="Start Recording", width=16, height=5, command=combine)
btn1.grid(row=2,column=0)
btn2 = Button(tk, text="Stop Recording", width=16, height=5, command=stop)
btn2.grid(row=3,column=0)

I want the loop1 and loop2 can be stopped button2. Apparently there is no terminate in Thread. So I used another method Process. Here is the code:

from subprocess import call
from multiprocessing import Process
def loop1():
    while True:
        call (["raspivid -n -op 150 -w 640 -h 480 -b 2666666.67 -t 5000 -o test.mp4"],shell=True)
        call (["raspivid -n -op 150 -w 640 -h 480 -b 2666666.67 -t 5000 -o test1.mp4"],shell=True)
def loop2():
    while True:
        call (["arecord -D plughw:1 --duration=5 -f cd -vv rectest.wav"],shell=True)
        call (["arecord -D plughw:1 --duration=5 -f cd -vv rectest1.wav"],shell=True)
if __name__ == '__main__':
    Process(target = loop1).start()
    Process(target = loop2).start()

But this program finished immediately after I ran it. I know there is terminate function in Process. But I don't know how to use it.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

A potential solution would use Events. Also, a good rule of thumb when making GUIs is to use objects.

from threading import Thread,Event
from subprocess import call

class Controller(object):
    def __init__(self):
        self.thread1 = None
        self.thread2 = None
        self.stop_threads = Event()

    def loop1(self):
        while not self.stop_threads.is_set():
            call (["raspivid -n -op 150 -w 640 -h 480 -b 2666666.67 -t 5000 -o test.mp4"],shell=True)
            call (["raspivid -n -op 150 -w 640 -h 480 -b 2666666.67 -t 5000 -o test1.mp4"],shell=True)

    def loop2(self):
        while not self.stop_threads.is_set():
            call (["arecord -D plughw:1 --duration=5 -f cd -vv rectest.wav"],shell=True)
            call (["arecord -D plughw:1 --duration=5 -f cd -vv rectest1.wav"],shell=True)

    def combine(self):
        self.stop_threads.clear()
        self.thread1 = Thread(target = self.loop1)
        self.thread2 = Thread(target = self.loop2)
        self.thread1.start()
        self.thread2.start()

    def stop(self):
        self.stop_threads.set()
        self.thread1.join()
        self.thread2.join()
        self.thread1 = None
        self.thread2 = None

This way your button calls would become something like:

control = Controller()
btn1 = Button(tk, text="Start Recording", width=16, height=5, command=control.combine)
btn1.grid(row=2,column=0)
btn2 = Button(tk, text="Stop Recording", width=16, height=5, command=control.stop)
btn2.grid(row=3,column=0)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...