Kivy 简明教程

Kivy - Progress Bar

当 GUI 应用程序执行某个耗时过程时,应有一些机制让用户了解其进度。Kivy 框架中的 Progressbar 小部件显示了正在进行的任务进度的可视化表示。

Kivy 的进度条小部件只支持水平模式,并以增量进度显示在应用程序窗口上。

Progressbar 类被定义在 "kivy.uix.progressbar" 模块中。

from kivy.uix.progressbar import ProgressBar
pb = Progressbar(**kwargs)

Progressbar 控件是一个仅显示控件,并且没有任何互动元素,因为它不会引发和传播任何事件。

要创建 Progressbar 的实例,您需要设置其 max 属性。

from kivy.uix.progressbar import ProgressBar
pb = ProgressBar(max=1000)

该控件具有 value 属性。您可以将其分配给小于其 "max" 属性的任何数字。

pb.value=100

然而,由于 progressbar 类没有任何事件和事件处理程序,我们需要将 value 属性手动链接到某个进程。

可以通过周期性地读取渐进式任务的某个属性的瞬时值,进而更新进度条的 value 属性来完成此操作。

让我们说我们有一个长 for 循环,它每隔一秒就执行下一个迭代。

for i in range(1000):
   time.delay(1)
   print (i)

我们希望在进度条上显示 I 的增量。因此,我们安排了一个时钟事件,在每隔一秒后调用函数。

progev = Clock.schedule_interval(update_progress, 1.0)

在每秒之后,update_progesss() 函数将进度条的 value 属性更新为迭代计数器 i

def update_progress():
   pb.value = i

Example

让我们在下面的代码中实现此方法。GUI 设计中包含两个按钮和一个标签。当按下了启动按钮时,它将一个 mp3 文件加载到 Sound 对象中。声音文件的长度被用作 progressbar 的 max 属性。

self.sound = SoundLoader.load('sample.mp3')
self.length = self.sound.length

当调用 play() 方法时,我们如上所述安排了一个进度事件。

self.prog_ev = Clock.schedule_interval(self.update_progress, 1.0)

update_progress() 方法读取 Sound 对象的 pos 属性,并使用它来更新 progressbar 的 value 属性

def update_progress(self, dt):
   if self.sound.state=='play':
      if self.prg.value < self.length:
         self.progress += 1 # Update value.
         self.prg.value=self.progress

这是 complete code

from kivy.app import App
from kivy.clock import Clock
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.core.audio import SoundLoader
from kivy.uix.progressbar import ProgressBar
from kivy.properties import NumericProperty
from kivy.core.window import Window

Window.size = (720, 400)

class audiodemoapp(App):
   length = NumericProperty(0.0)
   progress = NumericProperty(0.0)

   def build(self):
      layout = GridLayout(cols=1, padding=10)
      self.prg = ProgressBar()
      layout.add_widget(self.prg)
      self.l1 = Label(
         text='Press Start to Play', font_size=40,
         color=[.8, .6, .4, 1]
      )
      layout.add_widget(self.l1)
      box = BoxLayout(orientation='horizontal')
      self.button1 = Button(text="Start", font_size=32)
      self.button2 = Button(
         text='Pause', font_size=32,
         disabled=True
      )
      box.add_widget(self.button1)
      box.add_widget(self.button2)
      layout.add_widget(box)
      self.button1.bind(on_press=self.start_stop)
      self.button2.bind(on_press=self.pause_resume)

      return layout

   def start_stop(self, event):
      if self.button1.text == 'Start':
         self.l1.text = 'Playing'
         self.button1.text = 'Stop'
         self.sound = SoundLoader.load('sample.mp3')
         self.length = self.sound.length
         self.pos = 0
         self.button2.disabled = False
         self.sound.play()
         self.prog_ev = Clock.schedule_interval(self.update_progress, 1.0)
      else:
         if self.button1.text == 'Stop':
            self.l1.text = 'Press Start to Play'
            self.sound.state = 'stop'
            self.button1.text = 'Start'
            self.sound.unload()
            self.button2.disabled = True
            self.pos = 0

   def pause_resume(self, event):
      if self.button2.text == 'Pause':
         self.button2.text = 'Resume'
         self.l1.text == 'Paused'
         self.pos = self.sound.get_pos()
         self.sound.stop()
      else:
         if self.button2.text == 'Resume':
            self.l1.text = 'Playing'
            self.button2.text = 'Pause'
            print(self.pos)
            self.sound.seek(self.pos)
            self.sound.play()
            self.prog_ev = Clock.schedule_interval(self.update_progress, 1.0)
   def update_progress(self, dt):
      if self.sound.state == 'play':
         if self.prg.value < self.length:
            self.progress += 1 # Update value
            self.prg.value = self.progress
         else: # End case.
            self.progress = 0 # Reset value
            self.prog_ev.cancel() # Stop updating

audiodemoapp().run()

Output

运行以上代码。按下启动按钮。顶部的进度条显示音乐文件的瞬时播放位置。

kivy progress bar