Tkinter-python 按钮在另一个函数的循环中没有响应
Tkinter-python button not responding when in a loop of another function
我有一个用于录制音频的 GUI。有两个按钮,开始和停止录制。
开始录制功能中有一个循环,我无法删除。当按下开始录制按钮时,停止按钮没有响应(由于开始循环,我出于某些原因无法删除)。我想知道是否有办法解决这个问题并让两个按钮响应,即使程序处于开始录制的循环中,这是一个无限的 loop.I' 使用 python2。代码如下所示,
class RecAUD:
def __init__(self, chunk=4000, frmat=pyaudio.paInt16, channels=1, rate=44100, py=pyaudio.PyAudio()):
# Start Tkinter and set Title
self.main = tk.Tk()
self.collections = []
self.var = StringVar()
self.var.set('READY')
self.main.geometry('1200x500')
self.main.title('Demo')
self.CHUNK = chunk
self.FORMAT = frmat
self.CHANNELS = channels
self.RATE = rate
self.p = py
self.st = 1
print("----------------------record device list---------------------")
info = self.p.get_host_api_info_by_index(0)
numdevices = info.get('deviceCount')
for i in range(0, numdevices):
if (self.p.get_device_info_by_host_api_device_index(0, i).get('maxInputChannels')) > 0:
print("Input Device id ", i, " - ", self.p.get_device_info_by_host_api_device_index(0, i).get('name'))
print("-------------------------------------------------------------")
self.index = int(input())
print("recording via index "+str(self.index))
self.stream = self.p.open(format=self.FORMAT, channels=self.CHANNELS, rate=self.RATE, input=True,input_device_index = self.index, frames_per_buffer=self.CHUNK)
self.buttons = tkinter.Frame(self.main, padx=1, pady=50)
self.buttons.pack(fill=tk.BOTH)
photo = PhotoImage(file = r"stt.png")
photoimage = photo.subsample(5, 5)
self.strt_rec = tkinter.Button(self.buttons, width=100, padx=8, pady=25, text='\n\n\n\nStart Recording', command=lambda: self.start_record(), bg='white', image = photoimage, compound = CENTER)
self.strt_rec.grid(row=0, column=0, columnspan=2, padx=50, pady=5)
self.stop_rec = tkinter.Button(self.buttons, width=100, padx=8, pady=25, text='\n\n\n\nStop Recording', command=lambda: self.stop_record(), bg='white', image = photoimage, compound = CENTER)
self.stop_rec.grid(row=0, column=1, columnspan=2, padx=450, pady=5)
self.op_text = Label(self.main,textvariable = self.var,foreground="green",font = "Times 30 bold italic")
self.op_text.place(x=350,y=100,anchor=NW)
self.op_text.pack()
tkinter.mainloop()
def start_record(self):
WAVE_OUTPUT_FILENAME = "recordedFile.wav"
while True:
data_frame = self.stream.read(self.CHUNK)
data_int16_frame = list(struct.unpack(str(self.CHUNK) + 'h', data_frame))
...
...
def stop_record(self):
self.stream.stop_stream()
self.stream.close()
self.p.terminate()
guiAUD = RecAUD()
我该如何解决这个问题,我应该在上面的代码中添加什么来使按钮随时响应?是否需要多线程?如果是,我如何为上面代码中的按钮引入它?非常感谢任何建议!提前致谢!
例如,您可以在 while True
中添加一个 update
来 kke GUI "alive"。
在下面的代码中,先按 OK,它进入 while True
循环,但使用 update
,当您按 KO
时,GUI 会做出反应:
import tkinter as tk
a = 0
def action():
global a
while True:
if a == 0:
b.configure(bg="red")
else:
b.configure(bg="blue")
w.update()
def reaction():
global a
a = 1
w = tk.Tk()
b = tk.Button(w, text="OK", command=action)
c = tk.Button(w, text="K0", command=reaction)
b.pack()
c.pack()
w.mainloop()
危险在于多次调用 action
,递归调用更糟……在这些情况下,您应该在启动回调中管理它。
您可以使用threading一个用于创建线程的模块
import threading
class cls():
def __init__():
self.thrun = True
def start_record(self):
WAVE_OUTPUT_FILENAME = "recordedFile.wav"
while self.thrun:
data_frame = self.stream.read(self.CHUNK)
data_int16_frame = list(struct.unpack(str(self.CHUNK) + 'h', data_frame))
def click(self):
self.th = threading.Thread(target=start_record)
def stop(self):
self.thrun = False
self.th.join()
我有一个用于录制音频的 GUI。有两个按钮,开始和停止录制。 开始录制功能中有一个循环,我无法删除。当按下开始录制按钮时,停止按钮没有响应(由于开始循环,我出于某些原因无法删除)。我想知道是否有办法解决这个问题并让两个按钮响应,即使程序处于开始录制的循环中,这是一个无限的 loop.I' 使用 python2。代码如下所示,
class RecAUD:
def __init__(self, chunk=4000, frmat=pyaudio.paInt16, channels=1, rate=44100, py=pyaudio.PyAudio()):
# Start Tkinter and set Title
self.main = tk.Tk()
self.collections = []
self.var = StringVar()
self.var.set('READY')
self.main.geometry('1200x500')
self.main.title('Demo')
self.CHUNK = chunk
self.FORMAT = frmat
self.CHANNELS = channels
self.RATE = rate
self.p = py
self.st = 1
print("----------------------record device list---------------------")
info = self.p.get_host_api_info_by_index(0)
numdevices = info.get('deviceCount')
for i in range(0, numdevices):
if (self.p.get_device_info_by_host_api_device_index(0, i).get('maxInputChannels')) > 0:
print("Input Device id ", i, " - ", self.p.get_device_info_by_host_api_device_index(0, i).get('name'))
print("-------------------------------------------------------------")
self.index = int(input())
print("recording via index "+str(self.index))
self.stream = self.p.open(format=self.FORMAT, channels=self.CHANNELS, rate=self.RATE, input=True,input_device_index = self.index, frames_per_buffer=self.CHUNK)
self.buttons = tkinter.Frame(self.main, padx=1, pady=50)
self.buttons.pack(fill=tk.BOTH)
photo = PhotoImage(file = r"stt.png")
photoimage = photo.subsample(5, 5)
self.strt_rec = tkinter.Button(self.buttons, width=100, padx=8, pady=25, text='\n\n\n\nStart Recording', command=lambda: self.start_record(), bg='white', image = photoimage, compound = CENTER)
self.strt_rec.grid(row=0, column=0, columnspan=2, padx=50, pady=5)
self.stop_rec = tkinter.Button(self.buttons, width=100, padx=8, pady=25, text='\n\n\n\nStop Recording', command=lambda: self.stop_record(), bg='white', image = photoimage, compound = CENTER)
self.stop_rec.grid(row=0, column=1, columnspan=2, padx=450, pady=5)
self.op_text = Label(self.main,textvariable = self.var,foreground="green",font = "Times 30 bold italic")
self.op_text.place(x=350,y=100,anchor=NW)
self.op_text.pack()
tkinter.mainloop()
def start_record(self):
WAVE_OUTPUT_FILENAME = "recordedFile.wav"
while True:
data_frame = self.stream.read(self.CHUNK)
data_int16_frame = list(struct.unpack(str(self.CHUNK) + 'h', data_frame))
...
...
def stop_record(self):
self.stream.stop_stream()
self.stream.close()
self.p.terminate()
guiAUD = RecAUD()
我该如何解决这个问题,我应该在上面的代码中添加什么来使按钮随时响应?是否需要多线程?如果是,我如何为上面代码中的按钮引入它?非常感谢任何建议!提前致谢!
例如,您可以在 while True
中添加一个 update
来 kke GUI "alive"。
在下面的代码中,先按 OK,它进入 while True
循环,但使用 update
,当您按 KO
时,GUI 会做出反应:
import tkinter as tk
a = 0
def action():
global a
while True:
if a == 0:
b.configure(bg="red")
else:
b.configure(bg="blue")
w.update()
def reaction():
global a
a = 1
w = tk.Tk()
b = tk.Button(w, text="OK", command=action)
c = tk.Button(w, text="K0", command=reaction)
b.pack()
c.pack()
w.mainloop()
危险在于多次调用 action
,递归调用更糟……在这些情况下,您应该在启动回调中管理它。
您可以使用threading一个用于创建线程的模块
import threading
class cls():
def __init__():
self.thrun = True
def start_record(self):
WAVE_OUTPUT_FILENAME = "recordedFile.wav"
while self.thrun:
data_frame = self.stream.read(self.CHUNK)
data_int16_frame = list(struct.unpack(str(self.CHUNK) + 'h', data_frame))
def click(self):
self.th = threading.Thread(target=start_record)
def stop(self):
self.thrun = False
self.th.join()