【问题标题】:KivyMD RecycleView has low FPS & lagsKivyMD RecycleView 的 FPS 和延迟较低
【发布时间】: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


【问题讨论】:

    标签: kivy kivy-language python-3.8 kivymd


    【解决方案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 很稳定,调整大小时几乎没有延迟。非常感谢!!!
    猜你喜欢
    • 1970-01-01
    • 2015-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-04
    • 1970-01-01
    • 2021-08-28
    • 2011-04-20
    相关资源
    最近更新 更多