【问题标题】:Kivy Progress-Bar will not update until after 100% completionKivy 进度条在 100% 完成后才会更新
【发布时间】:2019-05-14 19:36:12
【问题描述】:

只有在更新其内部值的功能完全完成(100% 完成)后,Kivy 的进度条才会以图形方式更新。我正在使用它来更新名称和值的数据库,并希望它显示更新的进度。

对于其他类似的问题,以下所有方法都已尝试并失败:

(Clock.schedule_interval,Clock.schedule_once,Clock.create_trigger,@mainthread,Clock.schedule_once(partial(func))

他们的残余可以在下面的注释部分看到

在我按下的另一个页面上有一个按钮可以触发 update_database()。 update_database 调用 updateLoadingScreen 来更改进度条上的值和完成的数字百分比标签。孤立地看,这个功能似乎有效。但是,在 update_database() 中运行它会导致 UI 更新冻结,直到它简单地输出 100% 完成。 Clock.schedule_interval 会暂停直到达到 100%,无论是在 update_database 函数内部还是外部,Clock.schedule_once 也会等到达到 100% 后再做任何事情。 Clock.create_trigger 似乎不调用任何东西,除非它被实例化。 Functools partial() 不会改变任何行为。 @mainthread 给出错误:'mainthread' 未定义。

这似乎不是时间问题,因为 0.2 秒足以让它在其他情况下更新值。但是,它确实似乎被锁定在进程中并且无法更新 UI,即使修改了 UI 参数也是如此。

from kivy.uix.label import Label
from kivy.uix.progressbar import ProgressBar
from functools import partial


class UpdatePage(GridLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        #This part puts the series into a pandas dataframe
        self.df=getAllSeries()
        self.allserieslen=len(self.df)

        self.progress_bar=ProgressBar(max=self.allserieslen-1,value=0)
        self.add_widget(self.progress_bar)

        self.progress_label=Label(text='0%')
        self.add_widget(self.progress_label)

        #self.update_progress_trigger = Clock.create_trigger(self.updateLoadingScreen(self.currentseries,self.serieslen),-1)


        #Clock.schedule_interval(lambda x:self.updateLoadingScreen(self.currentseries,self.serieslen),.2)
        #This works, in a vaccum



    def update_database(self):
        #screenupdate=Clock.schedule_interval(lambda x:self.updateLoadingScreen(self.currentseries,self.serieslen),.2)
        for rownum in range(self.serieslen):
            chapters,name=findSingleSeriesChapter(self.df.at[rownum, 'URL'])
            self.currentseries=rownum

            #failed ways to update the screen (including the schedule and unscedule above and below)
            self.updateLoadingScreen(self.currentseries,self.serieslen)
            #Clock.schedule_once(lambda x:self.updateLoadingScreen(self.currentseries,self.serieslen),0.2)
            #self.update_progress_trigger()
            #Clock.schedule_once(lambda x:partial(self.updateLoadingScreen(self.currentseries,self.serieslen)),0.2)
            print('loop done',self.currentseries)
        #Clock.unschedule(screenupdate)

    #@mainthread
    def updateLoadingScreen(self,rownum,serieslen):
        print("Event has been triggered")
        self.progress_bar.value=rownum
        #self.remove_widget(self.progress_bar)
        #self.add_widget(self.progress_bar)
        percentage=str(round((rownum)/(serieslen-1)*100,1))

        self.progress_label.text=f"{percentage}%"
        #self.remove_widget(self.progress_label)
        #self.add_widget(self.progress_label)

【问题讨论】:

  • 如果您的UI 冻结,这表明您的Update_database 方法正在主线程上运行。您应该在单独的线程中运行任何需要不重要时间的东西。

标签: python kivy progress-bar python-multithreading kivy-language


【解决方案1】:

更新 UI 的 Kivy 代码应该在主线程上运行,否则应用程序会“冻结”直到当前运行的操作完成。尝试将@mainthread 装饰器添加到您的进度条代码中

from kivy.clock import mainthread

【讨论】:

  • 原来我没有导入,所以这可以解释“未定义”错误。我已将 @mainthread 装饰器添加到 updateLoadingScreen 和 updateDatabase 中,并分别使用此装饰器运行它,但此装饰器和上述任何方法的组合似乎都无法解冻 UI
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-07
相关资源
最近更新 更多