繁体   English   中英

如何在python kivy中正确组合小部件?

[英]How to compose widgets correctly in python kivy?

我想这样做,以便我可以看到循环执行的进度,但是 ProgressBar 仅在执行此循环后才退出。 我怎样才能解决这个问题?

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.progressbar import ProgressBar

class MyApp(App):
    def build(self):
        self.wid = FloatLayout()
        self.prog_bar = ProgressBar(max=99999, pos = [0, -150])
        self.wid.add_widget(self.prog_bar)
        self.prog_bar.value = 0
        for i in range(0, 99999):
            self.prog_bar.value = i
            print(i/99999)
        
        return self.wid
if __name__ == '__main__':
    MyApp().run()

Kivy 使用您App的主线程来更新其小部件。 您正在主线程上运行循环,因此 Kivy 在该循环完成之前无法更新ProgressBar 解决方法是在另一个线程中执行循环:

class MyApp(App):
    def build(self):
        self.wid = FloatLayout()
        self.prog_bar = ProgressBar(max=99999, pos=[0, -150])
        self.wid.add_widget(self.prog_bar)
        self.prog_bar.value = 0
        threading.Thread(target=self.do_progress).start()

        return self.wid

    def do_progress(self):
        for i in range(0, 99999):
            self.prog_bar.value = i
            print(i / 99999)

这不是关于组合,而是关于多任务处理,问题是,如果你做这样的锁定循环,kivy 在循环完成之前不能更新任何东西(因为在函数运行时没有其他事情发生,没有更新 UI或处理任何事件)。 所以你想要做的是让循环“并发”运行到 kivy 事件循环。

有多种方法可以做这种事情,它们或多或少都适合不同的情况。

kivy Clock 允许安排一个函数稍后运行( schedule_once ),可能多次( schedule_interval ),所以你可以有一个更原子的函数,它只增加一次进度条的值(不是在循环中),并调用这个函数使用调度间隔。 问题是,如果您想在函数中进行实际工作,则可能需要足够长的时间才能使 UI 在进度条值的增量之间被明显阻塞。

如果这是您的情况,因为您尝试运行的函数很慢,那么您可能希望改为在线程中运行该函数,这样它就不会阻塞 kivy UI。 如有必要,您将能够从线程更新进度条的值,使用 Clock 来安排执行此操作的函数(您需要小心不要执行从线程更新 OpenGL 上下文的操作,由于 OpenGL 没有指定这种情况下的行为,因此某些图形卡/驱动程序可以使用它,但其他图形卡/驱动程序会导致程序崩溃,因此从线程更新 UI 的任何内容都必须使用时钟,提供了一个mainthread装饰器在时钟模块中)。

在某些情况下,您可以(因此希望)避免事先进行长时间的工作,并找到一种方法在每次需要时完成最少的工作,然后继续工作,该想法有一些抽象,例如RecycleView ,这避免了完全创建小部件,当您想要显示很长的项目列表时,只需事先创建数据,并让它根据需要处理小部件的创建/更新。 当然,这可能不适用于您的情况,但值得一提,以防万一。

简而言之:不要执行这样的循环,或者在线程中执行它们,如果您确实需要这样的循环,请认真思考,并在使用线程时使用时钟事件来更新您的 UI。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM