KivyMD RecycleView 具有低 FPS 和滞后
KivyMD RecycleView has low FPS & lags
我正在使用 Python 3.8.12、Kivy 2.0.0 和 KivyMD-0.104.2
我正在 运行 在 ASUS ROG STRIX GL503VD 上 PyCharm 在 Ubuntu 18.04 LTS 上安装我的应用程序。
我的问题是,每次我使用 for 循环在 KivyMD BottomNavgation 中使用 RecycleView 生成内容时,无论内容是什么(甚至可能是 for i in range(100)),应用程序开始移动得非常慢(手动调整大小时正确调整大小大约需要 10 秒)。此外,我在生成数据的选项卡上的 FPS 低于 50,而在空的选项卡中,我得到 @80 FPS。
当我 运行 在 Kivy 2.0.0 中说 for i in range(100) 时,问题似乎没有发生,但我更愿意坚持使用 KivyMD。
上周我一直在互联网上寻找解决方案,但没有成功,而且有点难以理解关于 RecycleView 的 kivy 文档。
下面是我的代码,如果我做了一些不符合“良好实践”的事情,请纠正我。我刚开始学习 Kivy,我是 Python(@1 年)的初学者。
非常感谢。
编辑:同样,当部署到 Android 时,它在小米 Redmi Note8 Pro 上的运行速度低于 30 FPS。
main.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
您实际上并没有使用 RecycleView
。要使用 RecycleView
,您必须有一个 RecycleLayout
作为其子项,一个 viewclass
,以及一个指示 RecycleLayout
中项目的 data
列表。
这是在 App
中使用 RecycleView
的一种方法。首先,修改 kv
以指示 RecycleLayout
和 viewclass
:
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()
我正在使用 Python 3.8.12、Kivy 2.0.0 和 KivyMD-0.104.2 我正在 运行 在 ASUS ROG STRIX GL503VD 上 PyCharm 在 Ubuntu 18.04 LTS 上安装我的应用程序。 我的问题是,每次我使用 for 循环在 KivyMD BottomNavgation 中使用 RecycleView 生成内容时,无论内容是什么(甚至可能是 for i in range(100)),应用程序开始移动得非常慢(手动调整大小时正确调整大小大约需要 10 秒)。此外,我在生成数据的选项卡上的 FPS 低于 50,而在空的选项卡中,我得到 @80 FPS。 当我 运行 在 Kivy 2.0.0 中说 for i in range(100) 时,问题似乎没有发生,但我更愿意坚持使用 KivyMD。
上周我一直在互联网上寻找解决方案,但没有成功,而且有点难以理解关于 RecycleView 的 kivy 文档。
下面是我的代码,如果我做了一些不符合“良好实践”的事情,请纠正我。我刚开始学习 Kivy,我是 Python(@1 年)的初学者。
非常感谢。
编辑:同样,当部署到 Android 时,它在小米 Redmi Note8 Pro 上的运行速度低于 30 FPS。
main.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
您实际上并没有使用 RecycleView
。要使用 RecycleView
,您必须有一个 RecycleLayout
作为其子项,一个 viewclass
,以及一个指示 RecycleLayout
中项目的 data
列表。
这是在 App
中使用 RecycleView
的一种方法。首先,修改 kv
以指示 RecycleLayout
和 viewclass
:
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()