KivyMD RecycleView 的 FPS 和延迟较低

Posted

技术标签:

【中文标题】KivyMD RecycleView 的 FPS 和延迟较低【英文标题】:KivyMD RecycleView has low FPS & lags 【发布时间】:2022-01-16 21:06:26 【问题描述】:

我正在使用 Python 3.8.12、Kivy 2.0.0 和 KivyMD-0.104.2 我在华硕 ROG STRIX GL503VD 上的 Ubuntu 18.04 LTS 上的 PyCharm 上运行我的应用程序。 我的问题是,每次我使用 for 循环在 KivyMD BottomNavgation 中使用 RecycleView 生成内容时,无论是什么内容(甚至可能是 for i in range(100)),应用程序都开始变得非常缓慢(手动调整大小时)正确调整大小大约需要 10 秒)。此外,我在生成数据的选项卡上的 FPS 低于 50,而在空的选项卡中,我得到 @80 FPS。 当我在 Kivy 2.0.0 中运行 let say for i in range(100) 时,问题似乎没有发生,但我更愿意坚持使用 KivyMD。

上周我一直在互联网上寻找解决方案,但没有运气,并且有点难以理解有关 RecycleView 的 kivy 文档。

以下是我的代码,如果我出于“良好实践”做了一些事情,请纠正我。我刚开始学习 Kivy,我是 Python 的初学者(@1 年)。

非常感谢。

编辑:此外,当部署到 android 时,它在小米 Redmi Note8 Pro 上的运行速度低于 30 FPS。

ma​​in.py

from kivy.lang import Builder
from kivymd.app import MDApp as md
from kivymd.uix.list import TwoLineListItem

import json as js
#from kivy.utils import platform
from kivy.core.window import Window

'''
if platform == "android":
    try:
        from android.permissions import request_permissions, Permission
        request_permissions([Permission.READ_EXTERNAL_STORAGE, Permission.WRITE_EXTERNAL_STORAGE])
    except:
        pass
'''

class MainApp(md):
    def build(self):
        Window.size = (491, 1064)
        self.theme_cls.primary_palette = 'Red'
        self.theme_cls.primary_hue = '50'
        layouts = Builder.load_file("layouts.kv")
        return layouts
    def on_start(self):
        for key, value in self.read_list().items():
            self.root.ids.container1.add_widget(TwoLineListItem(text=f"key", secondary_text="Tests : ".format(len(value))))
        self.fps_monitor_start()
    def read_list(self):
        with open('tests.json', 'r') as read_test:
            #82 lines in test_list dict
            test_list = js.load(read_test)
        return test_list


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

layouts.kv

<MainLayout>
#:import get_color_from_hex kivy.utils.get_color_from_hex
MDGridLayout:
    cols: 3
    size_hint: 1, 1
    MDBottomNavigation:
        panel_color: get_color_from_hex("#008080")
        text_color_active: get_color_from_hex("#FFFFFF")
        MDBottomNavigationItem:
            name: 'Item1'
            text: 'item_1'
            icon: 'language-python'
            MDGridLayout:
                cols: 1
                RecycleView:
                    MDList:
                        id: container1

        MDBottomNavigationItem:
            name: 'Item2'
            text: 'item_2'
            icon: 'language-cpp'
            MDBoxLayout:
                RecycleView:
                    MDList:
                        id: container2


        MDBottomNavigationItem:
            name: 'Item3'
            text: 'item_3'
            icon: 'language-javascript'
            MDBoxLayout:
                RecycleView:
                    MDList:
                        id: container3


【问题讨论】:

【参考方案1】:

您实际上并未使用RecycleView。要使用RecycleView,您必须有一个RecycleLayout 作为其子级、一个viewclass 和一个指示RecycleLayout 中的项目的data 列表。

这是在App 中使用RecycleView 的一种方法。首先将kv修改为RecycleLayoutviewclass

MDGridLayout:
    cols: 3
    size_hint: 1, 1
    MDBottomNavigation:
        panel_color: get_color_from_hex("#008080")
        text_color_active: get_color_from_hex("#FFFFFF")
        MDBottomNavigationItem:
            name: 'Item1'
            text: 'item_1'
            icon: 'language-python'
            MDGridLayout:
                cols: 1
                RecycleView:
                    id: container1
                    viewclass: 'TwoLineListItem'
                    RecycleBoxLayout:
                        default_size: None, dp(75)
                        default_size_hint: 1, None
                        size_hint_y: None
                        height: self.minimum_height
                        orientation: 'vertical'

以上将container1 id 移动到RecycleView 并添加所需的属性以允许RecycleView 运行。

然后可以修改on_start()方法,为RecycleView创建data列表:

def on_start(self):
    data = []
    for key, value in self.read_list().items():
        data.append('text': f"key", 'secondary_text': "Tests : ".format(len(value)))
    self.root.ids.container1.data = data
    self.fps_monitor_start()

【讨论】:

像魅力一样工作!现在 FPS 很稳定,调整大小时几乎没有延迟。非常感谢!!!

以上是关于KivyMD RecycleView 的 FPS 和延迟较低的主要内容,如果未能解决你的问题,请参考以下文章

在 kivymd 屏幕中显示 opencv

郁闷:制作一个表格小部件

使用 KivyMD 库运行应用程序时出现错误 No module named 'kivymd.app'

KivyMD - 如何使用 KivyMD BottomNavigationItems 和屏幕本身内的按钮在屏幕上导航?

KivyMD 错误:ValueError:KivyMD:App 对象必须在加载根小部件之前进行初始化

.spec 文件中的“ModuleNotFoundError:没有名为 'kivymd' 的模块”