Search code examples
pythonkivylabelids

How to keep displaying the changeable real-time data in label every second?


In my code, it uses pyaudio to get user's voice pitch and volume. It keeps showing the numeric values every second in terminal. enter image description here

The problem is when I use Stringproperty or ids method to display them in the label, it doesn't show anything. enter image description here

But, after the code breaks, then it shows the data which is the last volume and pitch in the label. enter image description here

How can I display the real-time data every second in the label?

Here is my sample code .py:

while True:
    
        data = stream.read(1024)
        samples = num.fromstring(data,
            dtype=aubio.float_type)
        pitch = pDetection(samples)[0]
        # Compute the energy (volume) of the
        # current frame.
        volume = num.sum(samples**2)/len(samples)
        # Format the volume output so that at most
        # it has six decimal numbers.
        volume = "{:.6f}".format(volume)
        print(pitch)
        print(volume)
        
        #self.ids.pitchs.text= str(pitch)
        self.ids.volumes.text= volume 
        self.pitchs1 = str(pitch) 
      
            
        if keyboard.is_pressed('1'):  # if key '1' is pressed 
                break  # finishing the[1] loop
        

here is .kv file:

<Genereate>
 GridLayout:
     cols: 1
 GridLayout:
     size: root.width, root.height
     cols:2
     Label:
         id: pitchs
         text: root.pitchs1
         color: 1,0,1,1
    
     Label:
         id: volumes
         text: "Volume"
         color: 1,0,1,1
 Button:
     text: "Submit"
     size_hint: .5, .6
     on_release: root.pitches() 

Solution

  • the problem is that the while loop will run very fast that the User will not note any changes the solution for the is using kivy clock module like following create a method to deal the calculations

    def streaming(self, *args):
        data = stream.read(1024)
        samples = num.fromstring(data,
                                 dtype=aubio.float_type)
        pitch = pDetection(samples)[0]
        # Compute the energy (volume) of the
        # current frame.
        volume = num.sum(samples ** 2) / len(samples)
        # Format the volume output so that at most
        # it has six decimal numbers.
        volume = "{:.6f}".format(volume)
        print(pitch)
        print(volume)
    
        # self.ids.pitchs.text= str(pitch)
        self.ids.volumes.text = volume
        self.pitchs1 = str(pitch
                
            
    
    

    and now you should use the clock method to call every one second or any other period

    
    def run_stream(self,):
        schedule=Clock.schedule_interval(streaming, 1)
        # you can stop the steaming like this 
        if keyboard.is_pressed('1'):  # if key '1' is pressed 
            schedule.cancle()