Bind kivy properties from one screen to another screen - python-2.7

newbie here trying to test my hand on something new.I'm trying to display slider value from one screen on another screen. The screen I want the value to be displayed in has multiple screens embedded in it. the first picture is the first screen.
home screen that contains multiple screens
below is the code for this screen:
<Thermostat>:
BoxLayout:
orientation: 'horizontal'
cols: 2
Label:
id: Thmo
font_size: "11sp"
text: "INSIDE: 50"
Label:
text: "More Info"
font_size: "11sp"
<Weather>:
BoxLayout:
orientation: 'horizontal'
cols: 2
Label:
id:Temp
text: "OUT TEMP: "+ root.checkWeather()
font_size: "11sp"
Label:
id: Locale
text: root.locale
font_size: "11sp"
The next screen which is the command screen is here below, i want the slider value from this screen to be updated in the home screen. I have tried using a global variable called TEMP but it did not work. any help would be appreciated.
command screen
below is the code for the command screen:
<Temperature>:
BoxLayout:
cols: 3
Label:
text: 'THERMOSTAT'
Slider:
id: temp_slider
min: 40
max: 100
value: 40
step: 1
on_value: app.TEMP = str(temp_slider.value)
Label:
id: value
text: str(temp_slider.value)
<Vent>:
BoxLayout:
size_hint_y: None
height: '48dp'
cols: 3
Label:
text: 'VENT'
Button:
id: state
text: 'Open'
on_press: root.Open(state)
Label:
id: cmdErr

from kivy.app import App
value = App.get_running_app().root.ids.SCREENCONTROLLER.get_screen('SCREENAMEHERE').ids.CHILDWIDGETID.
Basically, you do your usual id traveling but you start from the very top of the running app and work downwards.
'root' here is the widget that is returned in the Apps Build Method. You haven't provided that code, so I'm assuming you returned the Screen Controller.
Once you get to the screen controller, you can use its get_screen method by entering the string name you gave to the screen you want to go to, then from their you find it through ids as if you were on that screen.

Related

Kivy Spinner - Values Size

Is there a way to change the text size from the values argument within Spinner? I've found that I can change the height and width of the dropdown boxes and change the size of the "label" (Layer). But is there a way to change the text size of both heads and all?
Spinner:
id: spinner_lry
text: 'Layer'
values:['heads', 'all']
size_hint_y: None
height: 50
font_size: 20
Yes, the options in a Spinner are displayed using the SpinnerOption class (just a Button) by default. You can set a different class to display the options using option_cls atribute, and specify the font_size for that class, like this in your kv:
<MyOption#SpinnerOption>:
font_size: 50
Spinner:
id: spinner_lry
text: 'Layer'
option_cls: "MyOption"
values:['heads', 'all']
size_hint_y: None
height: 50
font_size: 20

Kivy Python 2.7 - Put a layout inside of another layout

I have been looking into this question for a while, and I cannot seem to find the solution anywhere. I want to put a table inside of this page I have in my app, the page is a FloatLayout and I was wondering if it was possible to put a table inside of the FloatLayout.
Yes, it is possible to put a table inside of the FloatLayout. In the following example, we have a GridLayout inside a FloatLayout. As for a table, you might want to use RecycleView.
Example
main.py
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
class RootWidget(FloatLayout):
pass
class TestApp(App):
title = "GridLayout Inside FloatLayout Demo"
def build(self):
return RootWidget()
if __name__ == "__main__":
TestApp().run()
test.kv
#:kivy 1.10.0
<RootWidget>:
size: 300, 300
GridLayout:
cols: 3
row_force_default: True
row_default_height: 40
Button:
text: "Row 1 Col 1"
size_hint_x: None
width: 100
Label:
text: "Row 1 Col 2"
size_hint_x: None
width: 100
Button:
text: "Row 1 Col 3"
Button:
text: "Row 2 Col 1"
size_hint_x: None
width: 100
Label:
text: "Row 2 Col 2"
size_hint_x: None
width: 100
Button:
text: "Row 2 Col 3"
Output

How to write a "ghost" (or non-passable) text for a Kivy TextInput?

In a kivy app, I have some text-input widgets, I would like to label it as a ghost text. By ghost text, I mean it passes no value to the number to be called later on.
For example, say, I have two text input entries in a kivy app.
TextInput:
text: '1st number'
id: first_id
input_filter: 'float'
multiline: False
TextInput:
text: '2nd number'
id: second_id
input_filter: 'float'
multiline: False
When the app is run, the first text input has a default text "1st number" and the second text input has a default text "2nd number". I am linking them to a function that add the two floating numbers together via a method. The problem is if users didn't enter anything and press the "run" button, it will break the app. Is there a way to make the text non-passable to the function?
And also, I want it to be in the background, so that users don't have to tap the text input and then delete the '1st number' writing before entering a number, any way to do that?
I think I have created a small example the creates the behavior you wanted. I created a new widget with a TextInput and a Label and its only showing the label if the value is empty...
a = Builder.load_string("""
<FloatInput#FloatLayout>:
empty_text: "Input a number"
value: float(txt.text or '0.0')
TextInput:
id: txt
input_filter: 'float'
Label:
center: txt.center
size: self.parent.size or (300,300)
text: "" if self.parent.value else self.parent.empty_text
font_size: txt.font_size
color: 0,0,0,1
BoxLayout:
FloatInput:
id: fi
Label:
text: "%s" % fi.value
""")
class SimpleApp(App):
def build(self):
return a
SimpleApp().run()
You may use this class as your input widget...

Kivy: button on_press switch to next tab using kivy builder

I'm new to python and kivy so please be gentle :)
I have 3 tabs and want the app to show the next tab when I press button1 and button2, and to shutdown itself when button3 is pressed. I would like to use kivy builder to do this, if possible.
Please help :/
from kivy.app import App
from kivy.uix.tabbedpanel import TabbedPanel
from kivy.lang import Builder
class Root(TabbedPanel):
pass
Builder.load_string('''
<Root>
do_default_tab: False
size_hint: 1, 1
post_hint: {'center_x': .5, 'y': .5}
do_default_tab: False
TabbedPanelItem:
text: 'Step 1'
FloatLayout:
Button:
id: button1
size_hint: .10, .10
pos: 1350, 40
orientation: 'vertical'
text: 'Next!'
on_press: print("go to next step") #need help
TabbedPanelItem:
text: 'Step 2'
FloatLayout:
Button:
id: button2
size_hint: .10, .10
pos: 1350, 40
orientation: 'vertical'
text: 'Next!'
on_press: print("go to next step") #need help
TabbedPanelItem:
text: 'Step 3'
FloatLayout:
Button:
id: button3
size_hint: .10, .10
pos: 1350, 40
orientation: 'vertical'
text: 'The End.'
on_press: print("exiting") #need help
''')
class TabbedPanelApp(App):
def build(self):
return Root()
if __name__ == '__main__':
TabbedPanelApp().run()
TabbedPanel.switch_to seems pretty straightforward to me. Just use it like this in those three on_press:
root.switch_to(root.tab_list[1])
root.switch_to(root.tab_list[0])
root.switch_to(root.tab_list[2])
tab_list is in "reversed" order - the last added TabbedPanelItem is the first item in list.

Placing an image in the middle of the label in Kivy

I have the following Kivy language file, which should mimic a dialer app. Also in the middle underneath the digits it should display an icon (red rectangle). However it seems that in my implementation the parent, self and root objects all have the same properties. What's wrong in my code? Is there a better way to do it?
# File name: dialer.kv
#:kivy 1.9.0
<Button>:
color: .8,.9,0,.65
font_size: 32
<MyGridLayout>:
rows: 3
spacing: 10
GridLayout:
rows: 1
size_hint_y: .40
Label:
text: '12345678901231234567890'
size: self.texture_size
text_size: root.width, None
font_size: 44
halign: 'center'
valign: 'middle'
canvas.before:
Rectangle:
pos: self.parent.center_x - self.width / 2, self.parent.center_y - self.height / 2
source: 'bg.png'
GridLayout:
cols: 3
rows: 4
size_hint_y: .50
spacing: 10
Button:
text: '1'
Button:
text: '2'
Button:
text: '3'
Button:
text: '4'
Button:
text: '5'
Button:
text: '6'
Button:
text: '7'
Button:
text: '8'
Button:
text: '9'
Button:
text: '*'
Button:
text: '0'
Button:
text: '#'
GridLayout:
cols: 2
size_hint_y: .10
spacing: 10
Button:
text: 'Clear'
Button:
text: 'Dial'
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
# File name: main.py
import kivy
kivy.require('1.9.0')
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
class MyGridLayout(GridLayout):
pass
class DialerApp(App):
def build(self):
return MyGridLayout()
if __name__=="__main__":
DialerApp().run()
self variable you're using inside the canvas instructions is referencing to enclosing widget class (in this case it's a label), not a VertexInstruction like Rectangle. In your code self.parent.center_x is in fact the center of GridLayout and the self.width is the label width. To place your image in the middle of the label you can calculate the position manually:
<MyGridLayout>:
rows: 3
spacing: 10
GridLayout:
rows: 1
size_hint_y: .40
Label:
# ...
canvas.before:
Rectangle:
pos: self.center_x - 50, self.center_y - 50 # default size is 100x100
source: 'test.png'
# ...
You can also use Image widget as follows:
<MyGridLayout>:
rows: 3
spacing: 10
GridLayout:
rows: 1
size_hint_y: .40
Label:
# ...
Image:
center: self.parent.center
source: 'test.png'
# ...
Image is a Widget so now self refers to it and self.parent refers to the Label and we can use the center attribute to calculate the position automatically.