Reputation: 163
When I click on the button I need the data from the code to be shown on different screen. Below code does what I need despite that Clock
adds widgets every second. I would like the TextInput
to be editable so when I type some value to the 'Row' it will stay as typed. I've tried to use Clock.schedule_once()
but then the widgets does not appear. I've even tried something like below:
clock = 1
def fill_with_data(self, dt)
if clock == 1:
for item ...
clock +=1
witch locks adding new widgets (ridicules I know) but when I go back to MainScreen
to show another data then it does not appear on the screen. Below you will find whole code.
from kivy.config import Config
Config.set('graphics', 'multisamples', '0')
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import Screen
from kivy.clock import Clock
kv = """
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
ScreenManager:
MainScreen:
ShowData:
<DataSwitch>
Button:
text: 'Data 1'
on_press: app.root.current = 'ShowData'
on_press: root.show_data1()
Button:
text: 'Data 2'
on_press: app.root.current = 'ShowData'
on_press: root.show_data2()
<Row>
TextInput:
id: text_input
size_hint_y: None
height: 30
<Rows>
orientation: 'vertical'
<MainScreen>
name: 'MainScreen'
DataSwitch:
<ShowData>:
name: 'ShowData'
Rows:
Button:
text: 'Go back'
size_hint_y: None
height: 20
on_press: app.root.current = 'MainScreen'
"""
class Row(BoxLayout):
text = ''
def __init__(self, **kwargs):
super(Row, self).__init__(**kwargs)
self.set_text()
def set_text(self):
print('set', self.text)
self.ids.text_input.text = self.text
class Rows(BoxLayout):
data =[]
def __init__(self, **kwargs):
super(Rows, self).__init__(**kwargs)
#self.fill_with_data()
Clock.schedule_interval(self.fill_with_data, 1)
#Clock.schedule_once(self.fill_with_data)
def fill_with_data(self, dt):
for item in self.data:
Row.text = item
row = Row()
self.add_widget(row)
#self._rows[str(self.row_id)] = weakref.ref(row)
class MainScreen(Screen):
pass
class DataSwitch(BoxLayout):
data1 = ['1', '2', '3', '4']
data2 = ['5', '6', '7', '8']
def __init__(self, **kwargs):
super(DataSwitch, self).__init__(**kwargs)
def show_data1(self):
print('data1', self.data1)
Rows.data = self.data1
Rows()
def show_data2(self):
Rows.data = self.data2
Rows()
class ShowData(Screen):
pass
sm = Builder.load_string(kv)
class TestApp(App):
def build(self):
return sm
if __name__ == '__main__':
TestApp().run()
Upvotes: 0
Views: 1688
Reputation: 16011
Running the app will produce the following:
Rows:
as per kv fileRows()
as per Python script in methods show_data1()
and show_data2()
. These Rows
instances created does not have an associated ModalView
.Button:
text: 'Data 1'
on_press: app.root.current = 'ShowData'
on_press: root.show_data1()
Button:
text: 'Data 2'
on_press: app.root.current = 'ShowData'
on_press: root.show_data2()
The following example is just an illustration.
id: rows
Add id: rows
to Rows:
in class rule, <ShowData>:
. This will be use to reference attributes or methods in class Rows()
.
fill_with_data()
Use on_pre_enter
event of Screen
and Clock.schedule_once()
function to invoke method fill_with_data()
Note:
Row
will be added each time, the screen is displayed. In other words, Row
widget will double each time. To prevent this, one might want to delete the widgets added in on_pre_leave
event.
<ShowData>:
name: 'ShowData'
on_pre_enter:
Clock.schedule_once(self.ids.rows.fill_with_data, 0.1)
Rows:
id: rows
class Rows()
app
using App.get_running_app()
ShowData
using Screen Manager's get_screen()
function e.g. root.get_screen('ShowData')
data
using ids.rows.data
def show_data1(self):
App.get_running_app().root.get_screen('ShowData').ids.rows.data = self.data1
def show_data2(self):
App.get_running_app().root.get_screen('ShowData').ids.rows.data = self.data2
from kivy.config import Config
Config.set('graphics', 'multisamples', '0')
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import Screen
kv = """
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
#:import Clock kivy.clock.Clock
ScreenManager:
MainScreen:
ShowData:
<DataSwitch>
Button:
text: 'Data 1'
on_press: root.show_data1()
on_press: app.root.current = 'ShowData'
Button:
text: 'Data 2'
on_press: root.show_data2()
on_press: app.root.current = 'ShowData'
<Row>:
TextInput:
id: text_input
size_hint_y: None
height: 30
<Rows>:
orientation: 'vertical'
<MainScreen>:
name: 'MainScreen'
DataSwitch:
<ShowData>:
name: 'ShowData'
on_pre_enter:
Clock.schedule_once(self.ids.rows.fill_with_data, 0.1)
Rows:
id: rows
Button:
text: 'Go back'
size_hint_y: None
height: 20
on_press: app.root.current = 'MainScreen'
"""
class Row(BoxLayout):
def __init__(self, text, **kwargs):
super(Row, self).__init__(**kwargs)
self.ids.text_input.text = text
class Rows(BoxLayout):
data = []
def fill_with_data(self, dt):
for item in self.data:
row = Row(text=str(item))
self.add_widget(row)
class MainScreen(Screen):
pass
class DataSwitch(BoxLayout):
data1 = ['1', '2', '3', '4']
data2 = ['5', '6', '7', '8']
def show_data1(self):
App.get_running_app().root.get_screen('ShowData').ids.rows.data = self.data1
def show_data2(self):
App.get_running_app().root.get_screen('ShowData').ids.rows.data = self.data2
class ShowData(Screen):
def on_pre_leave(self):
self.ids.rows.clear_widgets()
sm = Builder.load_string(kv)
class TestApp(App):
def build(self):
return sm
if __name__ == '__main__':
TestApp().run()
Upvotes: 2