首页 > 解决方案 > kivymd 卡在循环的帮助下滚动列表项目?

问题描述

我正在开发一个移动应用程序,我想通过使用 for 循环创建多个 scoll 项目,但每当我使用时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()

有没有办法让它 看起来像这样

标签: pythonpython-3.xscrollkivykivymd

解决方案


问题是您试图image为每个MDCard. 任何小部件只能有一个父级。您只能使用该image小部件一次。image您可以通过在循环内移动小部件的创建来解决此问题。

此外,对于BoxLayouta 的孩子来说, a 是一个更好的选择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()

推荐阅读