kivymd卡滚动列表项目与循环的帮助?



我正在一个移动应用程序上工作,我想通过使用for循环创建多个滚动项,但每当我使用for loop时,给我一些错误It has already parent widget。如何制作MDCard列表

我的应用程序:点击这里

我的代码:

from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.screenmanager import Screen, ScreenManager
from kivymd.uix.boxlayout import BoxLayout
from kivy.uix.image import AsyncImage
from kivymd.uix.card import MDCard
from kivymd.uix.label import MDLabel
Window.size = (450, 740)
kv = '''
ScreenManager:
Main:
<main>:
name: 'main'
video_list: video_list
BoxLayout:
orientation: 'vertical'
MDToolbar:
title: 'Video downloader'
ScrollView:
Screen:
id: video_list
'''
class Main(Screen):
pass
sm = ScreenManager()
sm.add_widget(Main(name='main'))
class Ytube(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.theme_cls.colors = 'Red'
self.theme_cls.primary_palette = "Red"
self.root = Builder.load_string(kv)
image = AsyncImage(
source='https://static.hub.91mobiles.com/wp-content/uploads/2020/05/How-to-download-youtube-videos.jpg', size_hint=(1, .7), )
screen_id = self.root.get_screen('main').ids.video_list
for i in range(1):
card = MDCard(orientation='vertical', pos_hint={
'center_x': .5, 'center_y': .7}, size_hint=(.9, .4))
card.add_widget(image)
card.add_widget(MDLabel(
text='Phishing attacks are SCARY easy to do!! (let me show you!)', size_hint=(.6, .2), ))
screen_id.add_widget(card)
def build(self):
return self.root
if __name__ == "__main__":
Ytube().run()

有没有办法让它像这样。

问题是您试图为每个MDCard使用相同的image小部件。任何小部件只能有一个父部件。您只能使用一次image小部件。您可以通过将image小部件的创建移动到循环中来解决这个问题。

另外,BoxLayout对于ScrollView的子对象来说是更好的选择,因为它有一个可以使用的minimum_height属性。下面是您的代码的修改版本,它应用了这两个建议:

from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.uix.image import AsyncImage
from kivymd.uix.card import MDCard
from kivymd.uix.label import MDLabel
Window.size = (450, 740)
kv = '''
ScreenManager:
Main:
<main>:
name: 'main'
video_list: video_list
BoxLayout:
orientation: 'vertical'
MDToolbar:
title: 'Video downloader'
ScrollView:
do_scroll_x: False
BoxLayout:
id: video_list
orientation: 'vertical'
size_hint_y: None
height: self.minimum_height
'''
class Main(Screen):
pass
sm = ScreenManager()
sm.add_widget(Main(name='main'))
class Ytube(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.theme_cls.colors = 'Red'
self.theme_cls.primary_palette = "Red"
self.root = Builder.load_string(kv)
screen_id = self.root.get_screen('main').ids.video_list
for i in range(5):
# Make a new image widget for each MDCard
image = AsyncImage(
source='https://static.hub.91mobiles.com/wp-content/uploads/2020/05/How-to-download-youtube-videos.jpg', size_hint=(1, .7), )
card = MDCard(orientation='vertical', pos_hint={
'center_x': .5, 'center_y': .7}, size_hint=(.9, None), height=200)
card.add_widget(image)
card.add_widget(MDLabel(
text='Phishing attacks are SCARY easy to do!! (let me show you!)', size_hint=(.6, .2), ))
screen_id.add_widget(card)
def build(self):
return self.root
if __name__ == "__main__":
Ytube().run()