4

I'm doing a proyect using kivy but i have a problem with the checkboxes. At first I'm trying to do the program like python coding (I know it is'nt clean, but I understand more) And i have a first screen with this coding:

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.uix.checkbox import CheckBox




class MainScreen(GridLayout):
    def __init__(self,**kwargs):
        e=[]
        super(MainScreen, self).__init__(**kwargs)
        self.cols=2
        def on_checkbox_active(checkbox, value):
            if value:
                e.append(value)
                print e
            else:
                print('The checkbox', checkbox, 'is inactive')

        self.add_widget(Label(text='Inserta assignatures desitjades',font_size=35))
        self.add_widget(Label(text=''))
        ch1 = CheckBox()
        self.add_widget(ch1)
        self.add_widget(Label(text='Termotecnia'))
        ch2 = CheckBox()
        self.add_widget(ch2)
        self.add_widget(Label(text='Termotecnia'))
        ch3 = CheckBox()
        self.add_widget(ch3)
        self.add_widget(Label(text='Termotecnia'))
        ch4 = CheckBox()
        self.add_widget(ch4)
        self.add_widget(Label(text='Termotecnia'))
        b1=Button(text='Exit',background_color=[0.7,0.7,1,1],font_size=24)  
        self.add_widget(b1)
        b2=Button(text='Next',font_size=24,font_color=[1,3,4,0],background_color=[1,2,3,6]) 
        self.add_widget(b2)
        ch1.bind(active=on_checkbox_active)
        ch2.bind(active=on_checkbox_active)
        b1.bind(on_press=exit)
        b2.bind(on_press=reloaded)
...

class SimpleKivy(App):
    def build(self):
        return MainScreen()


if __name__=='__main__':
    SimpleKivy().run()

I want to select two or three options for example, and save it for the next screen, like a type of selection. If anyone knows how to do it and save information for the next screen it woul help me a lot, because i have the code of the next screen for all the options, but i want to preselect in the first screen and then only use which i have selected. Also if anyone can help me, i want to know hoy to do the transition to another class (screen) when the button "Next" is pressed. I know this question are pretty simple but I'm new in kivy programming and some concepts are pretty difficult. Thanks.

Peter Badida
  • 11,310
  • 10
  • 44
  • 90
A.Piquer
  • 414
  • 9
  • 23

1 Answers1

1

What you want is accessing variables in other classes. Sometimes this can be annoying and you can do it either hard way with all __init__() and stuff, or... a simplier way comes along: it's get_running_app().

You can create a dictionary or something else, where you can store any value your other classes need to access. It's similar to using globals and it costs you less lines of code. For example in your case you could use a dictionary(or nested dictionaries, json, ...) to store for example 'checkboxes':'<names of checked ones>' and in each init you can loop over these values to make checkboxes active

Basically all you need is a = App.get_running_app() somewhere and something to access in main - App - class.

Example:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
Builder.load_string('''
<Root>:
    MainScreen:
        name: 'main'
    AnotherScreen:
        name: 'another'
<MainScreen>:
    BoxLayout:
        Button:
            text: 'next screen'
            on_release: root.parent.current='another'
        Button:
            text: 'ping!'
            on_release: root.ping()
<AnotherScreen>:
    BoxLayout:
        Button:
            text: 'previous screen'
            on_release: root.parent.current='main'
        Button:
            text: 'ping!'
            on_release: root.ping()
''')

class MainScreen(Screen):
    def __init__(self, **kw):
        super(MainScreen, self).__init__(**kw)
        self.a = App.get_running_app()
    def ping(self):
        print self.a.big_dict['hi']

class AnotherScreen(Screen):
    def ping(self):
        b = App.get_running_app()
        print b.big_dict['hi']

class Root(ScreenManager):
    pass
class SimpleKivy(App):
    big_dict={'hi':'hi there!'}
    def build(self):
        return Root()
SimpleKivy().run()

You can see there's no need to call __init__(), no need to write more lines of code if you really don't need to.

Peter Badida
  • 11,310
  • 10
  • 44
  • 90
  • But how it would be? I have the idea but i don't know how to save the information, because i have to know the last state of each checkbox. If i have 5 checkboxes and 1 is unselected, how i could save this information in a dictionary? – A.Piquer Mar 15 '16 at 15:09
  • Create a function which will run at each screen's change. Either store checkboxes' ids somwhere, or loop over every child of a class(checking if it's a checkbox) and saving its state to the dictionary. Either you can save it in the order the widgets were added to class(assuming you have same number of checkboxes), or the ids are the option here. For example `{:}` or nested one `{'chboxes':{:}}`. – Peter Badida Mar 15 '16 at 15:20
  • Okey, thanks. I have done all you have said and it's working. Now i would like to create a next screen based on the selection of the mainscreen, like a function. For example if i select the first checkbox and the last, the next screen will have a text input for the first and last. How can i make a program which can add automatically the widgets based en the selection of the previous screen? Sorry if i ask too much, i am very interested in kivy but i don't know too much. Thanks. – A.Piquer Mar 15 '16 at 15:58
  • Well, create basic structure of Screen and use `__init__()` to build your content from the inside. I'm not really sure if init is called when you call `add_widget(your_screen)`, but if not, then you'd need to call it manually after add_widget(). In the class you could set a list for example with `[0,0,0,0]` which you would update with init to `[1,0,0,1]` getting values from the dictionary, where you already have the states of checkboxes. Then you'd loop over the list and for each `1` add a `TextInput` instead of Checkbox(If you want to create the same screen with only two checkboxes replaced). – Peter Badida Mar 15 '16 at 16:35
  • Okey, I'll open another question because I have tried adding another screen but It can't work like a GridLayout, only as screen. I can do the iteration in python language but i don't know how to do it in kivy language. I'll link here the code of my program at the time. Thanks a lot. – A.Piquer Mar 15 '16 at 16:59
  • http://stackoverflow.com/questions/36018476/how-to-create-a-dynamic-kivy-app-with-checkboxes – A.Piquer Mar 15 '16 at 17:46