python - 使用kivy时钟在执行前等待

标签 python kivy

我有一个从服务器获取的列表,这就是我想要做的

result = [1,7,0,0,2,4....]

def got_json(req, result):
    for i in result:
        if i is odd:
            wait for 5 seconds and call my_function
            now continue
        else:
            call my_function (now)

所以基本上我正在寻找更像 time.sleep() 但使用 time.sleep 只是卡住应用程序,我只是想暂停执行我的 for 循环在 got_json 方法中,而不是我认为 time.sleep 所做的所有其他内容。

我尝试使用 Clock.schedule_once 使用此代码

class MyWidget(BoxLayout):

    def onbuttonclick(self):
        my_list = range(10)
        for i in my_list:
            if (i%2 == 0) :
                Clock.schedule_once(self.my_callback, 5)
                continue

            print("Whatever")

    def my_callback(self,dt):
        print("called")

输出看起来确实在调度函数,但它没有停止 for 循环的执行,这正是我想要的 上述代码的输出

Whatever
Whatever
Whatever
Whatever
Whatever
called
called
called
called
called

我想要的输出

Whatever
**5 seconds**

called
Whatever
**5 seconds**

called 

等等...
如何使用 Clock 对象来执行我想要的操作?谢谢

最佳答案

这是一个有趣的问题。使用线程 - 通常是此类任务的最通用解决方案。但是,如果我们谈论这个具体案例,您可以使用 generator它是返回自己控制流并稍后使用 Clock.schedule_once 恢复执行的屈服点:

from functools import wraps

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.clock import Clock


def yield_to_sleep(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        gen = func()
        def next_step(*_):
            try:
                t = next(gen)  # this executes 'func' before next yield and returns control to you
            except StopIteration:
                pass
            else:
                Clock.schedule_once(next_step, t)  # having control you can resume func execution after some time
        next_step()
    return wrapper


@yield_to_sleep  # use this decorator to cast 'yield' to non-blocking sleep
def test_function():
    for i in range(10):
        if (i % 2 == 0):
            yield 5  # use yield to "sleep"
            print('Called')
        else:
            print('Whatever')


class TestApp(App):
    def build(self):
        test_function()
        return BoxLayout()


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

更新:

def func():
    yield 'STEP 1'
    yield 'STEP 2'


gen = func()
print('Result of calling generator-function is generator object:', gen, '\n')


res1 = next(gen)
print('''Calling next() on generator object executes original 
function to the moment of yield point and freeze it\'s state:\n''', res1, '\n')


print('''Look at line of code that prints this mesage:
It\'s not located inside func(), 
but we were able to call it "in the middle" of executing func():
We see msg "STEP 1", but we don't see "STEP 2" yet.
This is what makes generators so cool: we can execute part of it,
do anything we want and resume execution later.
In "yield_to_sleep" this resuming delegated to Clock.schedule_once
making generator being executed after some time and without freezing anything.''', '\n')


res2 = next(gen)
print('Another next() and we on next yield point inside func():\n', res2, '\n')


try:
    next(gen)
except StopIteration:
    print('''If no yield points left, another next() call will finish func()
and raise StopIteration exception. It\'s not error it\'s just way
to say to outer code that generator is done.''', '\n')

关于python - 使用kivy时钟在执行前等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47961043/

相关文章:

python - django-mptt:如何成功移动节点

android - 安卓上的Python

python - Kivy:是否可以用类级别(而不是实例)属性触发事件?

javascript - 使用请求登录到具有 javascript 登录表单的网站

python - Kivy 在按下时更改自定义按钮的颜色

python - 如何找到真实数据的概率分布和参数? (Python 3)

python - 以编程方式在 Accordion 中切换 "tab"

python-3.x - 尝试使用 PyInstaller 时出现权限错误

python - Kivy 理解 self.pos 和 self.size

python - 计算 pandas df 的滚动窗口内的重复行