Kivy事件安排得太早了

问题描述 投票:0回答:1

Python 3.7 Kivy 1.11.1 OSX 10.14.6

[我正在编写25 fps的Kivy应用程序,该应用程序应具有10毫秒的快速事件循环。问题是循环几乎很快被称为much。有没有办法解决这个问题?这是我的测试代码:

from kivy.config import Config

Config.read("config.ini")
Config.set('graphics', 'maxfps', '25')
Config.set('kivy', 'kivy_clock', 'free_all')
Config.write()

from kivy.uix.relativelayout import RelativeLayout
from kivy.app import App
from time import time
from kivy.clock import Clock
from collections import deque
from numpy import median

class Screen(RelativeLayout):

    durations_ms = deque(maxlen=100)
    last_event_loop_time = time()
    counter = 1

    @staticmethod
    def event_loop(dt):
        duration_ms = (time() - Screen.last_event_loop_time) * 1000
        Screen.durations_ms.append(duration_ms)
        Screen.last_event_loop_time = time()
        if Screen.counter == 0:
            print("Interval time (ms) median: {0:.3f}, min: {1:.3f}, max: {2:.3f}"
                  .format(median(Screen.durations_ms), min(Screen.durations_ms), max(Screen.durations_ms)))
        Screen.counter = (Screen.counter + 1) % 100

    def __init__(self, **kwargs):
        super(Screen, self).__init__(**kwargs)
        Clock.schedule_interval_free(self.event_loop, 0.010)


class TestApp(App):

    def build(self):
        return Screen()

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

输出为:

Interval time (ms) median: 0.035, min: 0.030, max: 1.431
Interval time (ms) median: 0.061, min: 0.030, max: 0.408
Interval time (ms) median: 0.037, min: 0.031, max: 0.551
python kivy scheduler event-loop
1个回答
0
投票

您的问题激起了我的兴趣。我建议使用另一种方法来使用Python event_loop模块调度sched。这是执行此操作的代码的修改版本:

from kivy.config import Config

Config.read("config.ini")
Config.set('graphics', 'maxfps', '25')
Config.set('kivy', 'kivy_clock', 'free_all')
Config.write()

from kivy.uix.relativelayout import RelativeLayout
from kivy.app import App
import sched
from time import time, sleep
from collections import deque
from numpy import median

class Screen(RelativeLayout):

    durations_ms = deque(maxlen=100)
    last_event_loop_time = time()
    counter = 1
    s = sched.scheduler(time, sleep)  # create the scheduler

    def event_loop(self):
        duration_ms = (time() - Screen.last_event_loop_time) * 1000
        Screen.last_event_loop_time = time()
        Screen.durations_ms.append(duration_ms)
        if Screen.counter == 0:
            print("Interval time (ms) median: {0:.3f}, min: {1:.3f}, max: {2:.3f}"
                  .format(median(Screen.durations_ms), min(Screen.durations_ms), max(Screen.durations_ms)))
        Screen.counter = (Screen.counter + 1) % 100

        # enter the next call to event_loop into the scheduler
        Screen.s.enter(0.01, 1, self.event_loop)

    def __init__(self, **kwargs):
        super(Screen, self).__init__(**kwargs)

        # enter the first call to event_loop and start the scheduler
        Screen.s.enter(0.01, 1, self.event_loop)
        Screen.s.run()


class TestApp(App):

    def build(self):
        return Screen()

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

注意,这会在主线程上运行您的event_loop。如果您的event_loop正在进行GUI更新,则很好,否则非常糟糕。

© www.soinside.com 2019 - 2024. All rights reserved.