首页 > 解决方案 > kivyMD - 从值列表动态创建小部件

问题描述

我对 kivyMD 很陌生,我尝试用图片、图标和一些文本构建简单的 Carousel。

我希望使用 2 个值列表 - 图片和名称来动态执行此操作。

这是手动 kv 的外观

Carousel:
    id: train_carousel
    MDFloatLayout:
        MDCard:
            size_hint: 0.95, 0.7
            pos_hint: {"center_x": 0.5, "center_y": 0.65}
            AsyncImage:
                source: "https://www.smth.com/img.png"
        MDIconButton:
            icon: "train"
            user_font_size: "40sp"
            pos_hint: {"center_x": 0.2, "center_y": 0.2}
        MDLabel:
            text: "Thomas the Tank Engine"
            pos_hint: {"center_x": 0.8, "center_y": 0.2}
    MDFloatLayout:
        MDCard:
            size_hint: 0.95, 0.7
            pos_hint: {"center_x": 0.5, "center_y": 0.65}
            AsyncImage:
                source: "https://www.smth.com/img.png"
        MDIconButton:
            icon: "train"
            user_font_size: "40sp"
            pos_hint: {"center_x": 0.2, "center_y": 0.2}
        MDLabel:
            text: "Thomas the Tank Engine"
            pos_hint: {"center_x": 0.8, "center_y": 0.2}
    MDFloatLayout:
        MDCard:

这是我的python文件。

from kivy.lang import Builder
from kivymd.app import MDApp
from kivy.core.window import Window
from kivymd.uix.button import MDIconButton
from kivymd.uix.card import MDCard
from kivymd.uix.floatlayout import MDFloatLayout
from kivymd.uix.label import MDIcon, MDLabel

Window.size = (400, 500)


class MainApp(MDApp):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def on_start(self, *args):

        list_of_names = ["Thomas", "Percy", "James", "Rebecca"]
        list_of_pics = ["https://www.smth.com/img1.png", "https://www.smth.com/img2.png", "https://www.smth.com/img3.png", "https://www.smth.com/img4.png"]

        counter = 0
        while counter < len(list_of_names):
            tmp_name = list_of_names[counter]
            tmp_pic = list_of_pics[counter]
            counter += 1
            print(counter)
            self.train_builder(tmp_pic, tmp_name)

    def train_builder(self, name, pic):
        card = MDFloatLayout()
        card.add_widget(MDCard(icon="train"))
        card.add_widget(MDIconButton(icon="train"))
        # card.add_widget(AsyncImage(source=pic))
        card.add_widget(MDLabel(text=name))
        self.root.ids.train_carousel.add_widget(card)

    def build(self):
        return Builder.load_file("main.kv")


MainApp().run()

我注释掉 AsyncImage 因为我知道这不是正确的方法,但我仍然无法完成这项工作。

列表中的图片链接仅供示例,并非真实图片。

此外,列表比此示例要长得多。他们每个都有大约 100 个条目。

有人可以帮我弄这个吗 :)

先感谢您。

标签: pythonpython-3.xkivykivy-languagekivymd

解决方案


我设法找到了我的问题的答案,所以如果有人遇到类似的问题,那就是这里。

class MainApp(MDApp):
    def build(self):
        carousel = Carousel()

        df = pd.read_excel("trains.xlsx")
        list_of_names = df['Name']
        list_of_pics = df['Pic']
        list_of_links = df['Link']

        tmp_counter = 0
        # while tmp_counter < len(list_of_names):
        while tmp_counter < 10:
            train_name = list_of_names[tmp_counter]
            train_pic = list_of_pics[tmp_counter]
            train_link = list_of_links[tmp_counter]

            md_float_layout = MDFloatLayout()
            md_card = MDCard(size_hint=(0.95, 0.8), pos_hint={"center_x": 0.5, "center_y": 0.60})
            md_card.add_widget(AsyncImage(source=train_pic, allow_stretch=True, keep_ratio=True))

            md_float_layout.add_widget(md_card)
            md_float_layout.add_widget(MDIconButton(icon="train", pos_hint={"center_x": 0.5, "center_y": 0.08}))
            md_float_layout.add_widget(MDLabel(text=train_name, halign="center", pos_hint={"center_x": 0.5, "center_y": 0.9}, theme_text_color="Primary", font_style="H5"))
            md_float_layout.add_widget(MDLabel(text=train_link, halign="center", pos_hint={"center_x": 0.5, "center_y": 0.15}, theme_text_color="Primary", font_style="Body1"))
            # md_float_layout.add_widget(MDRaisedButton(text="Click to hear my name", pos_hint={"center_x": 0.5, "center_y": 0.15}, theme_text_color="Primary"))

            carousel.add_widget(md_float_layout)

            tmp_counter += 1

        return carousel


MainApp().run()

享受 :)


推荐阅读