如何将列表项的值插入 KivyMD 中的另一个屏幕

Posted

技术标签:

【中文标题】如何将列表项的值插入 KivyMD 中的另一个屏幕【英文标题】:How to insert value of List Item into another Screen in KivyMD 【发布时间】:2021-04-14 22:45:11 【问题描述】:

在我正在编码的应用程序中,单击屏幕右下角的按钮会出现一个弹出窗口。在“完成”上单击弹出窗口关闭(close_dialog 方法),并出现一个新的列表项。 List Item 的文本是从弹出窗口的 MDTextField 中获取的。在列表项上单击我们进入另一个屏幕<GroupScreen>goto_group 方法)。

所以我有两个问题:

    据我了解,如果我们创建多个列表项,它们都会导致<Group Screen> 的一个实例。我说的对吗? 我希望每个创建的列表项都指向其唯一的<GroupScreen> 实例。例如,我希望将列表文本复制到 MDLabel(而不是“欢迎”文本)。我该怎么做?

代码.py:

from kivy.lang import Builder
from kivy.core.window import Window
from kivymd.app import MDApp
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.scrollview import ScrollView
from kivymd.uix.button import MDFlatButton
from kivymd.uix.dialog import MDDialog
from kivymd.uix.textfield import MDTextField
from kivy.uix.textinput import TextInput
from kivy.uix.screenmanager import Screen, ScreenManager
from kivymd.uix.list import TwoLineAvatarListItem

Window.size = (288, 511)

sm = ScreenManager()

class GroupScreen(Screen):
    pass

class DialogContent(BoxLayout):
    pass

class MainScreen(Screen):
    dialog = None

    def show_dialog(self, *args):
        '''
        Create group creation popup
        '''
        if not self.dialog:
            self.dialog = MDDialog(
                title="Create new group",
                type="custom",
                content_cls=DialogContent(),
            )
        self.dialog.open()

    def close_dialog(self, *args):
        '''
        Close popup on Done click
        '''
        self.dialog.dismiss()
        self.new_window()

    def new_window(self, *args):
        '''
        Create new group button
        '''
        mylist = TwoLineAvatarListItem(text = self.dialog.content_cls.textfield.text,
            on_release = self.goto_group)
        self.mdlist.add_widget(mylist)

    def goto_group(self, *args):
        sm.current = 'group'

class grudget4App(MDApp):
    def build(self):
        sm.add_widget(MainScreen(name='main'))
        sm.add_widget(GroupScreen(name='group'))
        scroll = ScrollView()
        return sm

if __name__ == '__main__':
    grudget4App().run()

代码。千伏:

ScreenManager:
    MainScreen:
    GroupScreen:

<DialogContent>:
    textfield: textfield
    orientation: "vertical"
    spacing: "12dp"
    size_hint_y: None
    height: "120dp"

    MDTextField:
        id: textfield
        hint_text: "Group name"

    MDFlatButton:
        id: btn1
        text: "Done"
        text_color: self.theme_cls.primary_color
        on_release: app.root.get_screen('main').close_dialog()

<MainScreen>:
    name: 'main'
    mdlist: mdlist
    FloatLayout:
        size_hint: 1, 0.89
        ScrollView:
            MDList:
                id: mdlist
    MDFloatingActionButton:
        pos_hint: 'right': 0.95, 'y': 0.05
        icon: "icon.png"
        theme_text_color: "Custom"
        text_color: app.theme_cls.primary_color
        on_release:
            root.show_dialog()

<GroupScreen>:
    name: 'group'
    MDLabel:
        text: "Welcome" #app.root.ids["textfield"].text
        halign: 'center'
    MDRectangleFlatButton:
        text: 'Back'
        pos_hint: 'center_x': 0.5, 'center_y': 0.3
        on_release:
            root.manager.current = 'main'

【问题讨论】:

【参考方案1】:

来自documentation:

名字

在 ScreenManager 中必须是唯一的屏幕名称。

我没有看到任何创建新 GroupScreens 的代码,但无论您将该代码放在哪里,都必须为其添加一个唯一的 name="some_group_name"

根据我的经验,为了让ButtonsMDDialog 中运行,您必须在其声明中添加auto_dismiss=False

def show_dialog(self, *args):
    '''
    Create group creation popup
    '''
    if not self.dialog:
        self.dialog = MDDialog(
            text="Create new group",
            type="custom",
            auto_dismiss=False,  # needed to allow Buttons to operate
            content_cls=DialogContent(),
        )
    self.dialog.open()

然后,new_window() 方法可以创建新的GroupScreenButton

def new_window(self, *args):
    '''
    Create new group button
    '''
    group_name = self.dialog.content_cls.textfield.text
    mylist = TwoLineAvatarListItem(text=group_name,
        on_release = partial(self.goto_group, group_name))  # use partial to pass group name
    self.mdlist.add_widget(mylist)
    sm.add_widget(GroupScreen(name=group_name))  # actually create the new GroupScreen and add it

goto_group() 方法变为:

def goto_group(self, group_name, *args):
    sm.current = group_name  # switch current screen to the passed in group

App 声明可以是:

class grudget4App(MDApp):
    def build(self):
        sm.add_widget(MainScreen(name='main'))
        # sm.add_widget(GroupScreen(name='group'))
        # scroll = ScrollView()
        return sm

请注意上述对 Screens 的唯一 name 的要求。您应该注意用户不要创建重复的组名。

【讨论】:

以上是关于如何将列表项的值插入 KivyMD 中的另一个屏幕的主要内容,如果未能解决你的问题,请参考以下文章

如何在android中获取主屏幕小部件列表项的点击事件[重复]

如何在 kivymd 中添加多个屏幕?

如何在 KivyMD 的 .kv 文件中使用 kivy 中的数据表?

如何在 kivymd 的单个屏幕中添加多个布局

如何使用 kivymd 中的函数更改列表项图标?

kivymd 中的动态屏幕