Kivy - How do I call a function from a ListView?

So, I am struggling with this little bit, where I cannot find a way to pass the value through the procedure when I click on the ListView element. The example below is a simpler version of what I want and how my main code will be installed. The goal is to see ChangeScreen (self.index) in the on_release hash tag: in the KV file. However, the problem is that I do not know how to successfully call ChangeScreen. Thank!

Kivy:

#: import main main
#: import ListAdapter kivy.adapters.listadapter.ListAdapter 

AppScreenManager:
    DemoScreen1:
        id: screen1
    DemoScreen2:
        id: screen2

<DemoScreen1>:
    name: "demoscreen1"
    BoxLayout:
        orientation: "vertical"
        ListView:
            adapter:
                ListAdapter(data=["Screen 1","Screen 2"], cls=main.ListButton)

<DemoScreen2>:
    name: "demoscreen2"
    orientation: "vertical"
    BoxLayout:
        orientation: "vertical"
        Label:
            id: labText
            text: "Hello World"

<ListButton>:
    height: self.texture_size[1]
    on_release: ### HOW DO I CALL THE ChangeScreen FUNCTION HERE

Python:

import kivy
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import StringProperty, ObjectProperty, ListProperty
from kivy.uix.listview import ListItemButton


class DemoScreen1(Screen):
    def ChangeScreen(self, option):
        if option == 0:
            print("Screen1")
            self.parent.ids.screen2.labelUpdater("Screen 1 was pressed")
        else:
            print("Screen2")
            self.parent.ids.screen2.labelUpdater("Screen 2 was pressed")
        self.parent.current = "demoscreen2"

class DemoScreen2(Screen):
    labText = StringProperty()
    def labelUpdater(self,newText):
        self.ids.labText.text = newText

class ListButton(ListItemButton):
    data = ListProperty()

class AppScreenManager(ScreenManager):
    pass
class Tester(App): 
    pass
if __name__ == '__main__':
    Tester().run() 
+4
source share
3 answers

alternative solution:

...
<ListButton>:
    height: self.texture_size[1]
    on_release: self.parent.parent.parent.parent.parent.ChangeScreen(self.index)

...

but just do it for events like on_press, on_releasenever for on_parent, because they don’t have a parent when this last event triggers a call

, , , self.parent.parent.parent ListView

,

+1

, , :

  • ChangeScreen ScreenManager: .

  • ListAdapter: list adapter - , , on_selection_change. , ListAdapter , ListItemButton.

  • , kvfile, (IMHO) : kvfile - , , ListAdapter. , ListAdapter.

  • ListAdapter ScreenManager ChangeScreen, ( EL3PHANTEN, ScreenManager , ).

, :

tester.kv

#: import main main

AppScreenManager:
    DemoScreen1:
        id: screen1
    DemoScreen2:
        id: screen2

<DemoScreen1>:
    name: "demoscreen1"
    BoxLayout:
        orientation: "vertical"
        ListView:
            adapter:
                main.MyListAdapter(
                data=["Screen 1","Screen 2"], 
                cls=main.MyListButton, 
                scr=root.parent
                )

<DemoScreen2>:
    name: "demoscreen2"
    orientation: "vertical"
    BoxLayout:
        orientation: "vertical"
        Label:
            id: labText
            text: "Hello World"

<MyListButton>:
    height: self.texture_size[1]

main.py

import kivy
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import StringProperty, ObjectProperty, ListProperty
from kivy.uix.listview import ListItemButton
from kivy.adapters.listadapter import ListAdapter


class DemoScreen1(Screen):
    pass


class DemoScreen2(Screen):
    labText = StringProperty()
    def labelUpdater(self,newText):
        self.ids.labText.text = newText


class MyListButton(ListItemButton):
    data = ListProperty()


class MyListAdapter(ListAdapter):
    scr = ObjectProperty()

    def on_selection_change(self, *args):
        self.scr.ChangeScreen(self.selection[0].index)


class AppScreenManager(ScreenManager):
    def ChangeScreen(self, option):
        if option == 0:
            print("Screen1")
            self.ids.screen2.labelUpdater("Screen 1 was pressed")
        else:
            print("Screen2")
            self.ids.screen2.labelUpdater("Screen 2 was pressed")
        self.current = "demoscreen2"


class Tester(App): 
    pass


if __name__ == '__main__':
    Tester().run() 
+1

Try putting the method changeScreenin a class ListButton.
Then do ScreenManageras an attribute in the class App. Thus, you can access it as app.smin kv.
Then you can pass to the app.smmethod changeScreento get the screens.
Here is your modified example:

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.listview import ListItemButton
from kivy.lang import Builder


class DemoScreen2(Screen):

    def labelUpdater(self,newText):
        self.ids.labText.text = newText


class ListButton(ListItemButton):
    data = ListProperty()

    def ChangeScreen(self, option, sm):
        if option == 0:
            print("Screen1")
            sm.ids.screen2.labelUpdater("Screen 1 was pressed")
        else:
            print("Screen2")
            sm.ids.screen2.labelUpdater("Screen 2 was pressed")
        sm.current = "demoscreen2"


class AppScreenManager(ScreenManager):
    pass


KV = """

#: import ListAdapter kivy.adapters.listadapter.ListAdapter
#: import Factory kivy.factory.Factory

<AppScreenManager>:
    DemoScreen1:
        id: screen1
    DemoScreen2:
        id: screen2

<DemoScreen1@Screen>:
    name: "demoscreen1"
    BoxLayout:
        orientation: "vertical"
        ListView:
            adapter:
                ListAdapter(data=["Screen 1","Screen 2"], cls=Factory.ListButton)

<DemoScreen2>:
    name: "demoscreen2"
    orientation: "vertical"
    BoxLayout:
        orientation: "vertical"
        Button:
            id: labText
            text: "Hello World"
            on_release:
                app.sm.current = "demoscreen1"

<ListButton>:
    height: self.texture_size[1]
    on_release: root.ChangeScreen(self.index,app.sm)

"""


class Tester(App):

    def build(self):
        Builder.load_string(KV)
        self.sm = AppScreenManager()
        return self.sm

if __name__ == '__main__':
    Tester().run()
0
source

Source: https://habr.com/ru/post/1690809/


All Articles