I am trying to change the text of a label using an id, I tried it with stringProperty, with objectProperty without any properties. There has to be something I am missing in my code because it simply does not work whatever I try and any help would be greatly appreciated.
This bit of code is a simple screen with 2 buttons, one for going to the other screen and one for changing the label
from kivy.app import *
from kivy.uix.button import *
from kivy.graphics import *
from kivy.uix.widget import *
from kivy.uix.label import *
from kivy.uix.floatlayout import *
from kivy.uix.boxlayout import *
from kivy.uix.relativelayout import *
from kivy.uix.scrollview import ScrollView
from kivy.properties import ListProperty, StringProperty,ObjectProperty
from kivy.uix.screenmanager import ScreenManager,Screen
from kivy.core.window import Window
from kivy.lang import Builder
from kivy.uix.gridlayout import GridLayout
class WindowManager(ScreenManager):
pass
class Name(FloatLayout):
def __init__(self, **kwargs):
super(Name, self).__init__(**kwargs)
def changeName(self):
print(self.ids)
self.name = self.ids.nameOfSong.text
print(self.name)
self.ids.nameOfSong.text = 'name'
self.name = self.ids.nameOfSong.text
print(self.name)
class MainWindow(Screen):
def __init__(self, **kwargs):
super(MainWindow, self).__init__(**kwargs)
self.pos = (0, 0)
self.size = (1,1)
self.z = Name()
self.add_widget(self.z)
def swap(self):
Name().changeName()
class SecondWindow(Screen,BoxLayout):
def __init__(self, **kwargs):
super(SecondWindow, self).__init__(**kwargs)
class langApp(App):
def build(self):
sm = ScreenManager()
sm.add_widget(MainWindow(name='main'))
sm.add_widget(SecondWindow(name='second'))
return sm
Builder.load_file("kiv.kv")
if __name__ == '__main__':
langApp().run()
My kiv.kv file, most of it is not connected to the problem (I think)
#:kivy 1.11.1
WindowManager:
MainWindow:
SecondWindow:
<MainWindow>:
name: "main"
FloatLayout:
pos: 0,0
size: root.width,root.height
Button:
on_release:
root.manager.transition.direction = 'left'
app.root.current = "second"
text: 'Stop'
pos_hint: {'x':.45,'y':.1}
size_hint: .1,.1
Button:
on_press: root.swap()
text: 'Next'
pos_hint: {'x':.65,'y':.1}
size_hint: .1,.1
<SecondWindow>:
name: "second"
FloatLayout:
pos: 0,0
size: root.width,root.height
Button:
on_release:
root.manager.transition.direction = 'right'
app.root.current = "main"
text: 'Stop'
pos_hint: {'x':.45,'y':.1}
size_hint: .1,.1
<Name>:
Label:
text: nameOfSong
font_size: 20
size_hint: None, None
pos_hint: {'x': 0.435, 'y': 0.25}
A few problems with your code:
First, your code as posted dos not run. The line in your kv
:
text: nameOfSong
is illegal.
Second, the code:
def swap(self):
Name().changeName()
is creating a new instance of Name
and calling changeName()
on that new instance. However, that new instance is not the one that is displayed in your GUI.
To fix that, you just need to call changeName()
on the instance of Name
that is in your GUI. Conveniently, you have saved a reference to the correct instance with the line:
self.z = Name()
So, you can change the swap()
method to use that instance of Name
:
def swap(self):
self.z.changeName()
The other problem is that the changeName()
method tries to use a non-existent id nameOfSong
. To fix that (and to make your posted code runnable), just change the <Name>
rule in your kv to define that id
:
<Name>:
Label:
id: nameOfSong
text: 'Some Name'
font_size: 20
size_hint: None, None
pos_hint: {'x': 0.435, 'y': 0.25}
On an unrelated note, your code is building the App
GUI
twice. The line:
Builder.load_file("kiv.kv")
is building the GUI
from the lines:
WindowManager:
MainWindow:
SecondWindow:
and your python code is building it again here:
def build(self):
sm = ScreenManager()
sm.add_widget(MainWindow(name='main'))
sm.add_widget(SecondWindow(name='second'))
return sm
You can delete those three lines from your kv
file.