【问题标题】:Python Kivy - Can't submit a TextInput value of a screen (ScreenManager) to another screen's listviewPython Kivy - 无法将屏幕(ScreenManager)的TextInput值提交到另一个屏幕的列表视图
【发布时间】:2018-05-16 22:03:05
【问题描述】:

我是 kivy 新手,需要有关 ListView 和 ScreenManager 的帮助。我设法在一个屏幕上使用 ListView,但我试图通过 ScreenManager 将它与两个屏幕一起使用: 我在 MainScreen 中有一个 ListView,并制作了一个导航到 ProfileScreen 的按钮,我将在 TextInput“abc”和“defe”中输入值并希望将它们提交到 ListView。 当我使用此代码运行 .py 文件时,它可以工作,但是当我在 ProfileScreen 上输入值并按“确定”时,它崩溃并说“ProfileScreen”没有属性“student_list”。如果我将 ProfileScreen(Screen) 的参数更改为 ProfileScreen(MainScreen) 它可以工作,但是 ProfileScreen 页面的内容是从 MainScreen 继承的,这是我不想要的。

我该如何解决这个问题?我将不胜感激任何形式的帮助,在此先感谢。

这是我的代码:

studentdb.py, 学生数据库.kv

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivy.uix.listview import ListItemButton
from kivy.uix.screenmanager import ScreenManager, Screen

class StudentListButton(ListItemButton):
    pass

class Manager(ScreenManager):
    main_screen = ObjectProperty()
    profile_screen = ObjectProperty()

class MainScreen(Screen):
    first_name_text_input= ObjectProperty()
    last_name_text_input= ObjectProperty()
    student_list = ObjectProperty()

    def submit_student(self):
        # Get the student name from the TextInputs
        student_name = self.first_name_text_input.text + " " + self.last_name_text_input.text

        # Add the student to the ListView
        self.student_list.adapter.data.extend([student_name])

        # Reset the ListView
        self.student_list._trigger_reset_populate()

    def delete_student(self, *args):
        if self.student_list.adapter.selection:

            # Get the text from the item selected
            selection = self.student_list.adapter.selection[0].text

            # Remove the matching item
            self.student_list.adapter.data.remove(selection)

            # Reset the ListView
            self.student_list._trigger_reset_populate()

    def replace_student(self, *args):
        # If a list item is selected
        if self.student_list.adapter.selection:

            # Get the text from the item selected
            selection = self.student_list.adapter.selection[0].text

            # Remove the matching item
            self.student_list.adapter.data.remove(selection)

            # Get the student name from the TextInputs
            student_name = self.first_name_text_input.text + " " + self.last_name_text_input.text

            # Add the updated data to the list
            self.student_list.adapter.data.extend([student_name])

            # Reset the ListView
            self.student_list._trigger_reset_populate()

class ProfileScreen(Screen):
    abc_text_input=ObjectProperty()
    def_text_input=ObjectProperty()

    def okay(self):
        abc_name = self.abc_text_input.text + " " + self.def_text_input.text

        # Add the student to the ListView
        self.student_list.adapter.data.extend([abc_name])

        # Reset the ListView
        self.student_list._trigger_reset_populate()

class StudentDBApp(App):
    def build(self):
        return Manager()

if __name__=="__main__":
    StudentDBApp().run()
------------------------------------------------------------------
#: import main studentdb
#: import ListAdapter kivy.adapters.listadapter.ListAdapter
#: import ListItemButton kivy.uix.listview.ListItemButton

<MainScreen>:
    first_name_text_input: first_name
    last_name_text_input: last_name
    student_list: student_list
    BoxLayout:
        orientation: "vertical"
        BoxLayout:
            Label:
                text:"First Name:"
            TextInput:
                id: first_name
            Label:
                text:"Last Name:"
            TextInput:
                id: last_name
        BoxLayout:
            Button:
                text:"Submit"
                on_release: root.submit_student()
            Button:
                text:"Delete"
                on_release: root.delete_student()
            Button:
                text:"Replace"
                on_release: root.replace_student()
            Button:
                text: "New"
                on_release: root.manager.current="profile_screen"
        ListView:
            id: student_list
            adapter:
                ListAdapter(data=['Doug Smith'], cls=main.StudentListButton)

<ProfileScreen>:
    abc_text_input: abc
    def_text_input: defe
    BoxLayout:
        orientation: "vertical"
        BoxLayout:
            Button:
                text:"Back"
                on_release: root.manager.current="main_screen"
        BoxLayout:
            Label:
                text:"abc"
            TextInput:
                id: abc
            Label:
                text: "def"
            TextInput:
                id: defe
        BoxLayout:
            Button:
                text: "Okay"
                on_release: root.okay()

<Manager>:
    id: screen_manager
    main_screen: main_screen
    profile_screen: profile_screen

    MainScreen:
        id: main_screen
        name:"main_screen"
        manager: screen_manager

    ProfileScreen:
        id: profile_screen
        name: "profile_screen"
        manager: screen_manager

【问题讨论】:

    标签: python python-3.x listview kivy


    【解决方案1】:

    你的错误是student_listMainScreen的属性而不是ProfileScreen所以你不能自己访问它,我建议阅读以下内容:What is the purpose of self?

    在您的情况下,解决方案是通过ScreenManager 访问正确的屏幕:

    def okay(self):
        abc_name = self.abc_text_input.text + " " + self.def_text_input.text
        main_screen = self.manager.get_screen('main_screen')
    
        # Add the student to the ListView
        main_screen.student_list.adapter.data.extend([abc_name])
    
        # Reset the ListView
        main_screen.student_list._trigger_reset_populate()
    

    【讨论】:

    • 非常感谢,我是 Python 和 Kivy 的新手,所以我很难处理这样的小细节。我现在更明白了,干杯:)
    【解决方案2】:

    由于您已经在 ScreenManager 中将屏幕连接到 ObjectProperty,因此解决方案是

    self.manager.main_screen...
    

    注意

    您可能想用 RecycleView 替换 ListView,因为 ListView 已被弃用。

    List View

    自 1.10.0 版起已弃用:ListView 已弃用,请使用 RecycleView 代替。

    片段

    def okay(self):
        abc_name = self.abc_text_input.text + " " + self.def_text_input.text
    
        # Add the student to the ListView
        self.manager.main_screen.student_list.adapter.data.extend([abc_name])
    
        # Reset the ListView
        self.manager.main_screen.student_list._trigger_reset_populate()
    

    输出

    【讨论】:

    • 感谢您的回复。似乎总是有多种方法可以解决编码中的问题 :) 好吧,我考虑过使用 RecycleView,尽管没有足够的指南和教程,而且 kivy 网站上的示例还不足以让我弄清楚,因为我我是 kivy 的新手,所以在那之前我宁愿尝试坚持当前的东西,直到我有更多的知识。我什至还不能正确使用 ListView,我正在尝试向 ListView 添加多个列以分隔值,但老实说我不知道​​该怎么做。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-25
    • 1970-01-01
    相关资源
    最近更新 更多