我正在尝试构建实时数据图,同时在Label上打印,但标签不会更新,直到我按下开始按钮。
这是.py代码:
// import
def get_microphone_level(label_level, stream, store_bool, dt):
global levels
data = stream.read(chunk)
mx = audioop.rms(data, 2)
if store_bool:
if len(levels) >= 100:
levels = []
levels.append(mx)
label_level.text = str(mx)
# print mx
print label_level.text
class Logic(BoxLayout):
label_level = ObjectProperty(Spinner)
select_timer = ObjectProperty(Spinner)
timer = NumericProperty('0.0001')
stream = None
def __init__(self):
super(Logic, self).__init__()
self.plot = SmoothLinePlot(color=[1, 0, 0, 1])
self.stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=chunk)
Clock.schedule_interval(partial(get_microphone_level, self.label_level, self.stream, False), self.timer)
def start(self):
self.ids.graph.add_plot(self.plot)
Clock.schedule_interval(partial(get_microphone_level, self.label_level, self.stream, True), self.timer)
Clock.schedule_interval(self.update_graph, self.timer)
def stop(self):
Clock.unschedule(self.update_graph)
Clock.unschedule(get_microphone_level)
def update_graph(self, dt):
self.plot.points = [(i, j / 5) for i, j in enumerate(levels)]
def update_timer(self, text):
self.timer = float(text)
self.stop()
self.start()
class RealTimeMicrophone(App):
def build(self):
return Builder.load_file("look.kv")
if __name__ == "__main__":
chunk = 2048
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
p = pyaudio.PyAudio()
levels = []
RealTimeMicrophone().run()
这是.kv:
#:import SmoothLinePlot kivy.garden.graph.SmoothLinePlot
Logic:
select_timer: select_timer
label_level: label_level
BoxLayout:
orientation: "vertical"
BoxLayout:
size_hint_y: .8
Graph:
id: graph
xlabel: "Time (in Second)"
ylabel: "Level"
ymin: 0
ymax: 5000
y_ticks_major: 1
x_ticks_minor: 5
x_ticks_major: 25
BoxLayout:
size_hint_y: .2
orientation: "horizontal"
spacing: 10
BoxLayout:
orientation: "vertical"
spacing: 10
Button:
text: "START"
bold: True
on_press: root.start()
Button:
text: "STOP"
bold: True
on_press: root.stop()
BoxLayout:
orientation: "vertical"
spacing: 10
BoxLayout:
orientation: "horizontal"
Label:
text: 'Current Level:'
Label:
id: label_level
text: '0'
Spinner:
id: select_timer
text: 'Select Timer (in Seconds)'
values: ['0.1', '0.5', '1', '2', '5']
on_text: root.update_timer(self.text)
我为标签数据创建了三个时钟计划1,设置了计时器后的级别集合,一个用于图形更新。
从 init 调用Clock.schedule_interval是否有任何问题。
答案 0 :(得分:0)
label_level ,因此您最好将 self 发送到您的函数:
def __init__(self, **kw):
...
Clock.schedule_interval(partial(get_microphone_level, self, False), self.timer)
self.label_level, self.stream
def get_microphone_level(logic, store_bool, dt):
stream = logic.stream #now get your stuff back...
label_level = logic.label_level
... # continue as usual ...
这样你就不会修复错误的值,因为每次调用它的函数都会从 Logic 实例中获取label_level