I am new at Kivy and Python and I have difficulties with tying kv code and py code. Here I go from a splash screen to login menu. I ask for name and age of the child using TextInput in kv and try to print it in py code, but I get this mistake:
PrintData() takes 2 positional arguments but 3 were given
I think I made some kind of stupid mistake or chose a wrong way to organise code.
My code:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import StringProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
Builder.load_string('''
<RootScreen>:
transition: FadeTransition()
IntroScreen:
NameScreen:
<IntroScreen>:
AnchorLayout:
Image:
source: 'yCFD2.png'
size_hint: 1,1
Button:
background_color: [63, 191, 63, 0.0]
text: ''
on_press: root.manager.current = 'data'
<NameScreen>:
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: 'X6TF0.png'
FloatLayout:
TextInput:
id: ChildName
size_hint:.2, .2
pos_hint:{'x': 0.7, 'y': 0.4}
text: "Введи имя"
focus: True
multiline: False
TextInput:
id: ChildAge
size_hint:.2, .2
pos_hint:{'x': 0.7, 'y': 0.6}
text: "Введи возраст"
focus: True
multiline: False
Button:
size_hint:.2, .2
pos_hint:{'x': 0.7, 'y': 0.8}
background_color: [63, 191, 63, 0.3]
text: 'Добавить в базу'
on_press: root.PrintData(ChildName, ChildAge)
''')
class IntroScreen(Screen):
def intro(self):
pass
class NameScreen(Screen):
ChildName = StringProperty()
ChildAge = StringProperty()
def __init__(self, **kwargs):
super(NameScreen, self).__init__(**kwargs)
self.ChildName = ''
def __init__(self, **kwargs):
super(NameScreen, self).__init__(**kwargs)
self.ChildAge = ''
def PrintData(ChildName, ChildAge):
print(ChildName, ChildAge)
sm = ScreenManager()
sm.add_widget(IntroScreen(name='intro'))
sm.add_widget(NameScreen(name='data'))
class SampleApp(App):
def build(self):
return (sm)
if __name__ == "__main__":
SampleApp().run()
The first parameter that are passed to the on_<property_name> event or the function bound to the property is self, which is the instance of the class where this function is defined.
Please refer to the following snippets and example for the solution.
def PrintData(self, ChildName, ChildAge):
print(ChildName, ChildAge)
on_press: root.PrintData(ChildName.text, ChildAge.text)
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import StringProperty
class IntroScreen(Screen):
def intro(self):
pass
class NameScreen(Screen):
ChildName = StringProperty()
ChildAge = StringProperty()
def __init__(self, **kwargs):
super(NameScreen, self).__init__(**kwargs)
self.ChildName = ''
def __init__(self, **kwargs):
super(NameScreen, self).__init__(**kwargs)
self.ChildAge = ''
def PrintData(self, ChildName, ChildAge):
print(ChildName, ChildAge)
class RootScreen(ScreenManager):
pass
class SampleApp(App):
def build(self):
return RootScreen()
if __name__ == "__main__":
SampleApp().run()
#:kivy 1.10.0
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
<RootScreen>:
transition: FadeTransition()
IntroScreen:
name: 'intro'
NameScreen:
name: 'data'
<IntroScreen>:
AnchorLayout:
Image:
source: 'kivyLogo.png' # 'yCFD2.png'
size_hint: 1,1
Button:
background_color: [63, 191, 63, 0.0]
text: ''
on_press: root.manager.current = 'data'
<NameScreen>:
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: 'kivymd_logo.png' # 'X6TF0.png'
FloatLayout:
TextInput:
id: ChildName
size_hint:.2, .2
pos_hint:{'x': 0.7, 'y': 0.4}
text: "Введи имя"
focus: True
multiline: False
TextInput:
id: ChildAge
size_hint:.2, .2
pos_hint:{'x': 0.7, 'y': 0.6}
text: "Введи возраст"
focus: True
multiline: False
Button:
size_hint:.2, .2
pos_hint:{'x': 0.7, 'y': 0.8}
background_color: [63, 191, 63, 0.3]
text: 'Добавить в базу'
on_press: root.PrintData(ChildName.text, ChildAge.text)