在指定时间后更新小部件

时间:2014-01-09 16:25:15

标签: python kivy

我无法理解如何更新kivy屏幕。 这是我的python文件:

import kivy
kivy.require('1.1.1')

from kivy.app import App
from kivy.uix.widget import Widget
import time


class PongGame(Widget):
    labe = ObjectProperty(None)

    def settext(self,x):
        self.labe.text = str(x)
        print "DONE"



class PongApp(App):

    def build(self):
        game = PongGame()
        game.settext(1)
        time.sleep(3)
        game.settext(5)
        time.sleep(3)
        game.settext(87)
        time.sleep(3)
        game.settext(5)
        return game


if __name__ == '__main__':
    PongApp().run()

这是我的kv文件

#:kivy 1.0.9
<PongGame>:
    labe:lab
    Label:
        id: lab
        font_size: 70  
        center_x: root.width / 4
        top: root.top - 50
        text: str("Hello")

当我运行它时它会冻结。然后我看到的只是一个5。 我怎样才能让其他人出现?

1 个答案:

答案 0 :(得分:3)

def build(self):
        game = PongGame()
        game.settext(1)
        time.sleep(3)
        game.settext(5)
        time.sleep(3)
        game.settext(87)
        time.sleep(3)
        game.settext(5)
        return game

你的问题是sleep阻止整个线程 - 你的整个程序在调用期间停止做任何事情。这包括已绘制的任何图形界面,它无法更新甚至接收输入,因为它在同一个线程中运行,并且在阻塞函数调用停止之前不会再次运行。

实际上,你也遇到了这样的问题:所有这些变化都是在绘制gui之前发生的(游戏只在从build返回后才显示在kivy窗口中)。

你必须考虑kivy的主循环和时钟 - 在后台kivy试图尽可能频繁地运行某些功能,如触摸检测和图形更新。如果你在这个循环中运行一些需要很长时间的代码,那么在你的代码终止之前,kivy的其余部分都无法工作。这在gui编程中是正常的,你必须小心不要阻止主程序循环。

kivy定期安排事情的最简单方法是创建一个函数并挂钩到这个事件循环,告诉时钟在一段时间后或每次重复一段时间后运行你的函数。在您的情况下,您希望每3秒更改一次文本。

以下是如何准确实现所需目标的简短示例:

from kivy.app import App
from kivy.uix.widget import Widget
import time
from kivy.properties import ObjectProperty

from functools import partial
from kivy.lang import Builder
from kivy.clock import Clock


Builder.load_string('''
<PongGame>:
    labe:lab
    Label:
        id: lab
        font_size: 70  
        center_x: root.width / 4
        top: root.top - 50
        text: str("Hello")
''')


class PongGame(Widget):
    labe = ObjectProperty(None)

    def settext(self, x, *args):
        self.labe.text = str(x)
        print "DONE"



class PongApp(App):

    def build(self):
        game = PongGame()
        game.settext(1)

        Clock.schedule_once(partial(game.settext, 5), 3)
        Clock.schedule_once(partial(game.settext, 87), 6)
        Clock.schedule_once(partial(game.settext, 5), 9)

        return game


if __name__ == '__main__':
    PongApp().run()

有一些重要的注意事项。一个是我使用functools.partial()因为您需要将函数传递给Clock.schedule_oncepartial从现有函数创建函数(此处为game.settext })和一些默认参数(这里是标签的数字)。将*args添加到PongGame.settext也很重要,因为时钟会自动传递一些我们不关心的额外参数。

如果您的意思不明确,请尝试使用这些参数来查看会发生什么。