标签未在Kivy中实时更新

时间:2016-12-17 19:14:03

标签: python python-2.7 kivy kivy-language

我正在尝试构建实时数据图,同时在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是否有任何问题。

1 个答案:

答案 0 :(得分:0)

__ init __ 中尚未设置

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