Add Toggle Buttons with if statement - python

Based on an input (0, 1, 2 or 3) the kv.file or py.file should add a group of Toggle Buttons to the already existing layout. I tried a lot but can't seem to figure it out and would love some advice, since it is all still a bit new to me.
So when self.reminder() = 0, no Toggle Buttons are shown.
When self.reminder() = 1, one group of Toggle Buttons is shown.
When self.reminder() = 2, two groups of Toggle Buttons are shown.
When self.reminder() = 3, three groups of Toggle Buttons are shown.
self.reminder() will not excess the value of 3.
So I have got my .py file
import kivy
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
import csv
from kivy.core.window import Window
class WindowManager(ScreenManager):
pass
#Backgroundcolour
Window.clearcolor = (0.67, 0.83, 0.88, 1)
class DiaryToday(Screen):
user_id = 3
# reads how many reminders (aka Toggle Buttons) the user wants from csv file
# used for textlabel, this textlabel will not show if reminder == 0 (is stated in kv file)
def reminder(self):
with open('users.csv') as file: #TO DO: needs to be adjusted to global ID
reader = csv.DictReader(file)
for row in reader:
if row['id'] == str(self.user_id): #TO DO: needs to be adjusted to global ID
if row['mood_rem'] == 'Zero':
return(0)
else:
return(row['mood_rem'][0])
# TO DO: STORES in CSV file which emoji you clicked
def mood_value(self, mood):
print (mood)
#Takes care of which group of ToggleButtons is shown in the Diary Screen
def add(self):
if root.reminder() == 0:
#should add or show no Toggle Buttons
if root.reminder() == 1:
#should add or show 1 set of Toggle Buttons
if root.reminder() == 2:
#should add or show 2 sets of Toggle Buttons
if root.reminder()== 3:
#should add or show 3 sets of Toggle Buttons
class LoopApp(App):
def build(self):
return DiaryToday()
if __name__ == '__main__':
LoopApp().run()
And my .kv file
<DiaryToday>:
name: "diarytoday"
answer: answer
diaryinput: diaryinput
id: test
FloatLayout:
Button:
background_color: 0.1, 0.5, 0.6, 1
pos_hint:{'center_y':0.05, 'center_x': 0.5}
font_size: 18
size_hint: 0.1, 0.05
text: "Save"
Button:
pos_hint:{'center_y':0.95, 'center_x': 0.175}
background_color: 0.1, 0.5, 0.6, 1
font_size: 18
size_hint: 0.15, 0.05
text: "Previous day"
Label:
pos_hint:{'center_y':0.95, 'center_x': 0.5}
size_hint: 0.1, 0.05
color: 0.1, 0.5, 0.6, 1
text: 'date'
font_size: 22
Label:
pos_hint:{'center_y':0.87, 'center_x': 0.5}
font_size: 18
size_hint: 0.1, 0.05
color: 0.1, 0.5, 0.6, 1
text: 'Question'
TextInput:
font_size: 14
size_hint: 0.8, 0.1
pos_hint:{'center_y':0.78, 'center_x': 0.5}
id: answer
Label:
pos_hint:{'center_y':0.67, 'center_x': 0.5}
size_hint: 0.1, 0.05
color: 0.1, 0.5, 0.6, 1
font_size: 18
text: 'My Diary'
TextInput:
font_size: 14
size_hint: 0.8, 0.22
pos_hint:{'center_y':0.51, 'center_x': 0.5}
id: diaryinput
Label:
pos_hint:{'center_y':0.36, 'center_x': 0.5}
size_hint: 0.1, 0.05
color: 0.1, 0.5, 0.6, 1
font_size: 18
text: ' ' if root.reminder() == 0 else 'How are you feeling?'
BoxLayout:
id: ToggleButtonGroup1
pos_hint: {'center_y':0.26, 'center_x': 0.5}
size_hint: 0.5, 0.1
ToggleButton:
background_normal: 'VerysadEmoji1.png'
background_down: 'VerysadEmoji2.png'
group: "emojis"
size_hint: 0.5, 1.3
on_press: root.mood_value(1)
ToggleButton:
background_normal: 'SadEmoji1.png'
background_down: 'SadEmoji2.png'
group: "emojis"
size_hint: 0.5, 1.3
on_press: root.mood_value(2)
ToggleButton:
background_normal: 'MediumEmoji1.png'
background_down: 'MediumEmoji2.png'
group: "emojis"
size_hint: 0.5, 1.3
on_press: root.mood_value(3)
ToggleButton:
background_normal: 'HappyEmoji1.png'
background_down: 'HappyEmoji2.png'
group: "emojis"
size_hint: 0.5, 1.3
on_press: root.mood_value(4)
ToggleButton:
background_normal: 'VeryHappyEmoji1.png'
background_down: 'VeryHappyEmoji2.png'
group: "emojis"
size_hint: 0.5, 1.3
on_press: root.mood_value(5)
Label:
pos_hint:{'center_y':0.19, 'center_x': 0.5}
size_hint: 0.1, 0.05
color: 0.1, 0.5, 0.6, 1
font_size: 18
text: "Here will come Toggle Button Group 2"
Label:
pos_hint:{'center_y':0.12, 'center_x': 0.5}
size_hint: 0.1, 0.05
color: 0.1, 0.5, 0.6, 1
font_size: 18
text: "Here will come Toggle Button Group 3"
Thanks!

You can define a class that is the Toggle Button Group that you want to add. Something like this:
class SomeToggles(BoxLayout):
group = StringProperty('') # this will be the group for the ToggleButtons
Then the add() method can be:
#Takes care of which group of ToggleButtons is shown in the Diary Screen
def add(self):
if self.reminder() == 0:
print('0')
#should add or show no Toggle Buttons
if self.reminder() == 1:
print('1')
self.ids.toggles.add_widget(SomeToggles(group=str(self.grp_count)))
self.grp_count += 1
#should add or show 1 set of Toggle Buttons
if self.reminder() == 2:
print('2')
#should add or show 2 sets of Toggle Buttons
if self.reminder()== 3:
print('3')
#should add or show 3 sets of Toggle Buttons
The above only handles the case where self.reminder() returns 1, but the others would be similar. Of course, the grp_count (which is just a construct of mine to define the group property) needs to be added:
class DiaryToday(Screen):
grp_count = 0
For this to work, a container with id of toggles must be defined. This will be another BoxLayout that contains the first set of Toggle Buttons as well as the added ones. So the modified kv file looks like:
<DiaryToday>:
name: "diarytoday"
answer: answer
diaryinput: diaryinput
id: test
FloatLayout:
Button:
background_color: 0.1, 0.5, 0.6, 1
pos_hint:{'center_y':0.05, 'center_x': 0.5}
font_size: 18
size_hint: 0.1, 0.05
text: "Save"
Button:
pos_hint:{'center_y':0.95, 'center_x': 0.175}
background_color: 0.1, 0.5, 0.6, 1
font_size: 18
size_hint: 0.15, 0.05
text: "Previous day"
Label:
pos_hint:{'center_y':0.95, 'center_x': 0.5}
size_hint: 0.1, 0.05
color: 0.1, 0.5, 0.6, 1
text: 'date'
font_size: 22
Label:
pos_hint:{'center_y':0.87, 'center_x': 0.5}
font_size: 18
size_hint: 0.1, 0.05
color: 0.1, 0.5, 0.6, 1
text: 'Question'
TextInput:
font_size: 14
size_hint: 0.8, 0.1
pos_hint:{'center_y':0.78, 'center_x': 0.5}
id: answer
Label:
pos_hint:{'center_y':0.67, 'center_x': 0.5}
size_hint: 0.1, 0.05
color: 0.1, 0.5, 0.6, 1
font_size: 18
text: 'My Diary'
TextInput:
font_size: 14
size_hint: 0.8, 0.22
pos_hint:{'center_y':0.51, 'center_x': 0.5}
id: diaryinput
Label:
pos_hint:{'center_y':0.36, 'center_x': 0.5}
size_hint: 0.1, 0.05
color: 0.1, 0.5, 0.6, 1
font_size: 18
text: ' ' if root.reminder() == 0 else 'How are you feeling?'
BoxLayout: # this contains all the Toggle Button groups
id: toggles
orientation: 'vertical'
pos_hint: {'center_y':0.26, 'center_x': 0.5}
size_hint_y: None
height: self.minimum_height
BoxLayout:
id: ToggleButtonGroup1
pos_hint: {'center_y':0.26, 'center_x': 0.5}
size_hint: 0.5, None
height: self.minimum_height
ToggleButton:
background_normal: 'VerysadEmoji1.png'
background_down: 'VerysadEmoji2.png'
group: "emojis"
size_hint: 0.5, None
height: 40
on_press: root.mood_value(1)
ToggleButton:
background_normal: 'SadEmoji1.png'
background_down: 'SadEmoji2.png'
group: "emojis"
size_hint: 0.5, None
height: 40
on_press: root.mood_value(2)
ToggleButton:
background_normal: 'MediumEmoji1.png'
background_down: 'MediumEmoji2.png'
group: "emojis"
size_hint: 0.5, None
height: 40
on_press: root.mood_value(3)
ToggleButton:
background_normal: 'HappyEmoji1.png'
background_down: 'HappyEmoji2.png'
group: "emojis"
size_hint: 0.5, None
height: 40
on_press: root.mood_value(4)
ToggleButton:
background_normal: 'VeryHappyEmoji1.png'
background_down: 'VeryHappyEmoji2.png'
group: "emojis"
size_hint: 0.5, None
height: 40
on_press: root.mood_value(5)
<SomeToggles>:
pos_hint: {'center_y':0.26, 'center_x': 0.5}
size_hint: 0.5, None
height: self.minimum_height
ToggleButton:
group: root.group
size_hint: 0.5, None
height: 40
ToggleButton:
group: root.group
size_hint: 0.5, None
height: 40
ToggleButton:
group: root.group
size_hint: 0.5, None
height: 40
The above kv also includes the <SomeToggles> rule that defines how the new Toggle Button group is built. You will also need to provide a mechanism for calling self.reminder(). I just added that call to the mood_value() method.

Related

AttributeError: 'MyMainApp' object has no attribute 'random_screen'

Hiii ^_^.
I am a beginner in python and kivy and I decided to learn by building an application with registration and login after which it will transfer me to the game. The game is based on images displayed through ScreenManager. All good so far. The code for the interface with menu, registration and logging is in another project and the one with the game in another, so I decided to combine them, I mostly succeeded but I got stuck at the step where it sends me to the first screen of the game and from there pressing a button to generate a Screen randomly I get this error
~~ AttributeError: 'MyMainApp' object has no attribute 'random_screen' ~~
I have tried all kinds of solutions to solve this problem, but I can't figure it out in any way.
Can someone tell me where I am wrong?
If I add the code lines with random_screen in the MyMainApp class, nothing happens..
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from database import DataBase
import random
class CreateAccountWindow(Screen):
namee = ObjectProperty(None)
email = ObjectProperty(None)
password = ObjectProperty(None)
def submit(self):
if self.namee.text != "" and self.email.text != "" and self.email.text.count("#") == 1 and self.email.text.count(".") > 0:
if self.password != "":
db.add_user(self.email.text, self.password.text, self.namee.text)
self.reset()
sm.current = "login"
else:
invalidForm()
else:
invalidForm()
def login(self):
self.reset()
sm.current = "login"
def reset(self):
self.email.text = ""
self.password.text = ""
self.namee.text = ""
class LoginWindow(Screen):
email = ObjectProperty(None)
password = ObjectProperty(None)
def loginBtn(self):
if db.validate(self.email.text, self.password.text):
MainWindow.current = self.email.text
self.reset()
sm.current = "main"
else:
invalidLogin()
def createBtn(self):
self.reset()
sm.current = "create"
def reset(self):
self.email.text = ""
self.password.text = ""
class MainWindow(Screen):
n = ObjectProperty(None)
created = ObjectProperty(None)
email = ObjectProperty(None)
current = ""
def logOut(self):
sm.current = "login"
class Q1(Screen):
pass
class Q2(Screen):
pass
class Q3(Screen):
pass
class Q4(Screen):
pass
class WrongAnswer(Screen):
pass
class TestApp:
def wrong_answer(self):
screen = ['WrongAnswer']
return random.choice(screen)
def random_screen(self):
screens = ['Q1', 'Q2', 'Q3', 'Q4']
return random.choice(screens)
def build(self):
sm = ScreenManager()
sm.add_widget(Q1(name='Q1'))
sm.add_widget(Q2(name='Q2'))
sm.add_widget(Q3(name='Q3'))
sm.add_widget(Q4(name='Q4'))
sm.add_widget(WrongAnswer(name='WrongAnswer'))
return sm
class WindowManager(ScreenManager):
pass
def invalidLogin():
pop = Popup(title='Invalid Login',
content=Label(text='Invalid username or password.'),
size_hint=(None, None), size=(400, 400))
pop.open()
def invalidForm():
pop = Popup(title='Invalid Form',
content=Label(text='Please fill in all inputs with valid information.'),
size_hint=(None, None), size=(400, 400))
pop.open()
kv = Builder.load_file("my.kv")
sm = WindowManager()
db = DataBase("users.txt")
screens = [LoginWindow(name="login"), CreateAccountWindow(name="create"),MainWindow(name="main"),Q1(name="start")]
for screen in screens:
sm.add_widget(screen)
sm.current = "login"
class MyMainApp(App):
def build(self):
return sm
if __name__ == "__main__":
MyMainApp().run()
<CreateAccountWindow>:
name: "create"
namee: namee
email: email
password: passw
FloatLayout:
cols:1
FloatLayout:
size: root.width, root.height/2
Label:
text: "Create an Account"
size_hint: 0.8, 0.2
pos_hint: {"x":0.16, "top":1}
font_size: (root.width**2 + root.height**2) / 14**4
Label:
size_hint: 0.5,0.12
pos_hint: {"x":0, "top":0.8}
text: "Name: "
font_size: (root.width**2 + root.height**2) / 14**4
TextInput:
pos_hint: {"x": 0.38, "top":0.77}
size_hint: 0.4, 0.075
id: namee
multiline: False
font_size: (root.width**2 + root.height**2) / 14**4
Label:
size_hint: 0.5,0.12
pos_hint: {"x":0, "top":0.8-0.13}
text: "E-Mail: "
font_size: (root.width**2 + root.height**2) / 14**4
TextInput:
pos_hint: {"x": 0.38, "top":0.65}
size_hint: 0.4, 0.075
id: email
multiline: False
font_size: (root.width**2 + root.height**2) / 14**4
Label:
size_hint: 0.5,0.12
pos_hint: {"x":0, "top":0.8-0.125*2}
text: "Password: "
font_size: (root.width**2 + root.height**2) / 14**4
TextInput:
pos_hint: {"x": 0.38, "top":0.53}
size_hint: 0.4, 0.075
id: passw
multiline: False
password: True
font_size: (root.width**2 + root.height**2) / 14**4
Button:
pos_hint:{"x":0.60,"y":0.35}
size_hint: 0.18, 0.075
font_size: (root.width**2.11 + root.height**2) / 17**4
text: "Back to Login"
on_release:
root.manager.transition.direction = "left"
root.login()
Button:
pos_hint:{"x":0.38,"y":0.35}
size_hint: 0.18, 0.075
text: "Register"
font_size: (root.width**1.95 + root.height**2) / 14**4
on_release:
root.manager.transition.direction = "left"
root.submit()
<LoginWindow>:
name: "login"
email: email
password: password
FloatLayout:
Label:
text:"E-Mail: "
font_size: (root.width**1.8 + root.height**2) / 13**4
pos_hint: {"x":0.1, "top":0.9}
size_hint: 0.40, 0.15
TextInput:
id: email
font_size: (root.width**1.91 + root.height**2) / 13**4
multiline: False
pos_hint: {"x": 0.38 , "top":0.86}
size_hint: 0.4, 0.075
Label:
text:"Password: "
font_size: (root.width**1.8 + root.height**2) / 13**4
pos_hint: {"x":0.106, "top":0.81}
size_hint: 0.35, 0.15
TextInput:
id: password
font_size: (root.width**1.91 + root.height**2) / 13**4
multiline: False
password: True
pos_hint: {"x": 0.38, "top":0.77}
size_hint: 0.4, 0.075
Button:
pos_hint:{"x":0.38,"y":0.605}
size_hint: 0.18, 0.075
font_size: (root.width**1.8 + root.height**2) / 13**4
text: "Login"
on_release:
root.manager.transition.direction = "up"
root.loginBtn()
Button:
pos_hint:{"x":0.60,"y":0.605}
size_hint: 0.18, 0.075
font_size: (root.width**2.09 + root.height**2) / 17**4
text: "Create Account"
on_release:
root.manager.transition.direction = "right"
root.createBtn()
<MainWindow>:
FloatLayout:
Button:
pos_hint:{"x": 0.6, "top":0.9}
size_hint:0.4, 0.1
text: "5 Players"
Button:
pos_hint:{"x": 0.6, "top":0.7}
size_hint:0.4, 0.1
text: "10 Players"
Button:
pos_hint:{"x": 0.6, "top":0.5}
size_hint:0.4, 0.1
text: "15 Players"
Button:
pos_hint:{"x": 0.6, "top":0.3}
size_hint:0.4, 0.1
text: "20 Players"
on_release:
app.root.current = "start"
root.manager.transition.direction = "down"
Button:
pos_hint:{"x":0.04, "y": 0.05}
size_hint:0.2,0.1
text: "Log Out"
on_release:
app.root.current = "login"
root.manager.transition.direction = "down"
<Q1>:
name: "start"
Image:
source: 'Q1.png'
FloatLayout:
size: root.width, root.height/2
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.09, "top":1.16}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.random_screen()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.5, "top":1.16}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.5, "top":0.7}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.09, "top":0.7}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
<Q2>:
Image:
source: 'Q2.png'
FloatLayout:
size: root.width, root.height/2
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.09, "top":1.16}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.5, "top":1.16}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.random_screen()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.5, "top":0.7}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.09, "top":0.7}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
<Q3>:
Image:
source: 'Q3.png'
FloatLayout:
size: root.width, root.height/2
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.09, "top":1.16}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.5, "top":1.16}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.5, "top":0.7}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.09, "top":0.7}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.random_screen()
<Q4>:
Image:
source: 'Q4.png'
FloatLayout:
size: root.width, root.height/2
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.09, "top":1.16}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.random_screen()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.5, "top":1.16}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.5, "top":0.7}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.09, "top":0.7}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
<WrongAnswer>:
Image:
source: 'L1.png'
You already knew what is the cause. in mymainapp class, you don't have the attirube: random_screen. random_screen is in class TestApp.
if you want that attribute exist in mymainapp class, you can use multiple inherit. like this:
class MyMainApp(App, TestApp):
def build(self):
return sm
Your random_screen function is in TestApp, which you don't use for anything. Instead, your app seems to be MyMainApp.
You can
move the contents of TestApp to MyMainApp (and get rid of TestApp),
or the other way around, make TestApp inherit from App and move the build method there, then use TestApp instead of MyMainApp.

Print which Radio-ToggleButton is in down state

I am new to both Python and Kivy. We are developping this application for an assignment and I am working on the preferences page. My labels, textinputs, togglebuttons and button are all in the right place and working, but I am struggling with how I can get the output of these buttons.
Basically, I would like to print the output like this, when someone presses the confirm button:
Name: Blabla
Mood reminders: 2 per day
Diary reminders: 1 per day
I figured on_press would not work since that would print a value everytime a button is pressed instead of only when confirm is pressed.
Right now my .py code looks like this
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import ObjectProperty
# Builder.load_file('preferences.kv')
class MyFloatLayout(FloatLayout):
name = ObjectProperty(None)
def mood_buttons(self):
pass
def diary_buttons(self):
pass
def print_specs(self):
print("Name: " + self.name.text
class PreferencesApp(App):
def build(self):
return MyFloatLayout()
if __name__ == '__main__':
PreferencesApp().run()
And my .kv language file looks like this
<Label>
font_size: 20
<TextInput>
font_size: 20
<Checkbox>
size_hint_x: .20
<MyFloatLayout>:
name: name
FloatLayout:
Label:
text: "Name: "
size_hint: 0.4, 0.08
pos_hint:{"x": 0.1, "center_y": 0.85}
TextInput:
id: name
multiline: False
size_hint: 0.4, 0.07
pos_hint:{"x":0.5,"center_y":0.85}
Label:
text: "How many mood reminders would you like?"
size_hint: 0.5, 0.1
pos_hint: {"center_x": 0.5, "top": 0.75}
BoxLayout:
pos_hint: {'center_x': 0.5, 'y': 0.55}
size_hint: 0.8, 0.1
ToggleButton:
text:"Zero"
id: m0
group: "mood_popups"
on_press: self.mood_buttons()
ToggleButton:
text:"1 per day"
id: m1
group: "mood_popups"
ToggleButton:
text:"2 per day"
id: m2
group: "mood_popups"
ToggleButton:
text:"3 per day"
id: m3
group: "mood_popups"
Label:
text: "How many diary reminders would you like?"
size_hint: 0.5, 0.1
pos_hint: {"center_x": 0.5, "top": 0.55}
BoxLayout:
pos_hint: {'center_x': 0.5, 'y': 0.35}
size_hint: 0.8, 0.1
ToggleButton:
text:"Zero"
id: d0
group: "diary_popups"
ToggleButton:
text:"1 per day"
id: d1
group: "diary_popups"
ToggleButton:
text:"1 per two days"
id: d2
group: "diary_popups"
ToggleButton:
text:"1 per week"
id: d3
group: "diary_popups"
Button:
text: 'Confirm'
size_hint: 0.5, 0.1
pos_hint: {"x": 0.25, "top": 0.2}
on_press: root.print_specs()
You can access all the Buttons in a group using the get_widgets() method. So your print_specs() method can be:
def print_specs(self):
print("Name: " + self.name.text)
# get mood reminder
mood_reminder = ''
for toggle in ToggleButton.get_widgets('mood_popups'):
if toggle.state == 'down':
mood_reminder = toggle.text
break
print('Mood reminders:', mood_reminder)
# get diary reminder
diary_reminder = ''
for toggle in ToggleButton.get_widgets('diary_popups'):
if toggle.state == 'down':
diary_reminder = toggle.text
break
print('Diary reminders:', diary_reminder)

Kivy anchor two widget at each side

I'm trying to do a video on top of a graph, with two buttons controlling the graph. I'd like one button to be at the left of the window, the other one at the right, both on the same row, and my problem is placing the - and + buttons.
I have the following kv file, the concerned buttons are the two Control class:
#:kivy 1.0.9
<Control>
canvas:
Rectangle:
size: 5, 5
pos: self.pos
<VideoWidget>:
video_player: video_handler
graph: graph_handler
data_plus: ctr_plus_handler
data_minus: ctr_minus_handler
BoxLayout:
orientation: 'vertical'
VideoHandler:
id: video_handler
state: 'play'
options: {'allow_stretch': True}
size_hint: 1, 0.45
on_touch_down: root.test()
on_position: root.move()
BoxLayout:
size_hint: 1, 0.1
orientation: 'horizontal'
Control:
id: ctr_minus_handler
size_hint: 0.1, 1
pos_hint: {'left': 0.1}
Control:
id: ctr_plus_handler
size_hint: 0.1, 1
pos_hint: {'right': 0.1}
GraphWidget:
id: graph_handler
size_hint: 1, 0.45
But both Control are taking half the width of the row, whatever I change... Any ideas ?
You can use an empty Widget to fill the blank space between the Controls like this:
BoxLayout:
size_hint: 1, 0.1
orientation: 'horizontal'
Control:
id: ctr_minus_handler
size_hint: 0.1, 1
Widget:
size_hint: 0.8, 1
Control:
id: ctr_plus_handler
size_hint: 0.1, 1
You have to use FloatLayout instead of BoxLayout with correct pos_hint values. Below is the snippet for the button widget part:
FloatLayout:
size_hint: 1, 0.1
orientation: 'horizontal'
Control:
id: ctr_minus_handler
size_hint: 0.1, 1
pos_hint: {'left': 1}
Control:
id: ctr_plus_handler
size_hint: 0.1, 1
pos_hint: {'right': 1}
Hope this would solve your issue.

How to save user entered text in kivy python?

I have this application where user enters his/her username. When the submit button is clicked, another page loads where the previous username entered should be displayed into an uneditable textbox. I have attached the full code below. How can I make the load_username textInput get the username textInput from the user page?
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
Builder.load_string("""
<User>:
username:username
user_label:user_label
but_1:but_1
# cols: 1
Label:
id: user_label
font_size: 30
color: 0.6, 0.6, 0.6, 1
text_size: self.width, None
halign: 'center'
text:'Enter username below'
TextInput:
id: username
font_size: 30
pos_hint:{"x":0.3,"y":0.25}
size_hint: 0.4, 0.07
color: 0.6, 0.6, 0.6, 1
text_size: self.width, None
halign: 'center'
Button:
id: but_1
font_size: 20
pos_hint:{"x":0.3,"y":0.15}
size_hint: 0.4, 0.07
text: 'Get username'
on_press:
root.save_username()
root.manager.current = 'get_user'
""")
Builder.load_string("""
<GetUser>:
load_username:load_username
user_label:user_label
but_1:but_1
# cols: 1
Label:
id: user_label
font_size: 30
color: 0.6, 0.6, 0.6, 1
text_size: self.width, None
halign: 'center'
text:'Received username from previous page'
TextInput:
id: load_username
font_size: 30
pos_hint:{"x":0.3,"y":0.25}
size_hint: 0.4, 0.07
color: 0.6, 0.6, 0.6, 1
text_size: self.width, None
halign: 'center'
disabled:True
Button:
id: but_1
font_size: 20
pos_hint:{"x":0.3,"y":0.15}
size_hint: 0.4, 0.07
text: 'Go back to username page'
on_press:
root.manager.current = 'user'
root.get_username()
""")
class User(Screen):
pass
def save_username(self):
print('saved: ', self.username.text)
class GetUser(Screen):
pass
def get_username(self):
self.load_username.text = "This should be previous username"
sm = ScreenManager()
sm.add_widget(User(name='user'))
sm.add_widget(GetUser(name='get_user'))
class UserName(App):
def build(self):
return sm
if __name__ == '__main__':
UserName().run()
You have to find a way to assign the text to the next screen when clicking the get username button.
Working code below:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
Builder.load_string("""
<User>:
username:username
user_label:user_label
but_1:but_1
# cols: 1
Label:
id: user_label
font_size: 30
color: 0.6, 0.6, 0.6, 1
text_size: self.width, None
halign: 'center'
text:'Enter username below'
TextInput:
id: username
font_size: 30
pos_hint:{"x":0.3,"y":0.25}
size_hint: 0.4, 0.07
color: 0.6, 0.6, 0.6, 1
text_size: self.width, None
halign: 'center'
Button:
id: but_1
font_size: 20
pos_hint:{"x":0.3,"y":0.15}
size_hint: 0.4, 0.07
text: 'Get username'
on_press:
root.save_username()
root.set_username()
root.manager.current = 'get_user'
<GetUser>:
load_username:load_username
user_label:user_label
but_1:but_1
# cols: 1
Label:
id: user_label
font_size: 30
color: 0.6, 0.6, 0.6, 1
text_size: self.width, None
halign: 'center'
text:'Received username from previous page'
TextInput:
id: load_username
font_size: 30
pos_hint:{"x":0.3,"y":0.25}
size_hint: 0.4, 0.07
color: 0.6, 0.6, 0.6, 1
text_size: self.width, None
halign: 'center'
disabled:True
Button:
id: but_1
font_size: 20
pos_hint:{"x":0.3,"y":0.15}
size_hint: 0.4, 0.07
text: 'Go back to username page'
on_press:
root.manager.current = 'user'
""")
class User(Screen):
def save_username(self):
print('saved: ', self.username.text)
def set_username(self): # <--- Asign the name here
screens = App.get_running_app().root.screens
other_screen = None
text = ""
for screen in screens:
if screen.name == "user":
text = screen.username.text
elif screen.name == "get_user":
other_screen = screen
other_screen.load_username.text = text
class GetUser(Screen):
pass
sm = ScreenManager()
sm.add_widget(User(name='user'))
sm.add_widget(GetUser(name='get_user'))
class UserName(App):
def build(self):
return sm
if __name__ == '__main__':
UserName().run()

Are Kivy Layouts Essentially Widgets?

I have a kivy app that I am (learning) to write. I am a bit confused about the layouts and when to use which ones.
I have a base class in a .kv file that then contains a number of layouts. Eventually these components will talk to each other and will be dynamically generated, but the first thing I wanted to do was just to get all the components on a screen to see if I could.
In a structure like this:
<MyApp>
<AnchorLayout>
<Widget1>
<Widget2>
<FloatLayout>
<Widget3>
<Widget4>
<Label>
text: "text here"
where is the proper place to use the size_hint and pos_hint tags. Should it be at the widget level, or the layout level? If anyone can be bothered, the reason I am asking this is that in the following code, it seems that for the Label at the end, I have to position it manually, the pos_hint does nothing (I want it more or less 25% up the page on the left hand side). What am I missing?
# File name: MagStripeApp.kv
#:kivy 1.9.0
<MagStripeReader>:
AnchorLayout:
anchor_x: 'left'
anchor_y: 'top'
HeaderBar:
id: _header_bar
size_hint: 1, 0.15
AnchorLayout:
anchor_x: 'center'
anchor_y: 'bottom'
SessionBar:
id: _session_bar
mag_stripe_reader: root
entry_box: _entry_box
size_hint: 1, 0.1
pos_hint: {'center_x':0.5, 'center_y': 0.5}
FloatLayout:
size_hint: 1, 0.2
EntryBox:
id: _entry_box
request_box: _request_box
person_counter: _person_counter
request_box: _request_box
size_hint: 0.333, 1
RequestBox:
id: _request_box
person_counter: _person_counter
card_reader: _card_reader
size_hint: 0.333, 1
CardReader:
id: _card_reader
person_counter: _person_counter
size_hint: 0.333, 1
PersonCounter:
id: _person_counter
<HeaderBar#Label>:
text: "Mag Stripe Reader Application"
font_size: root.height/2.5
size: self.texture_size
bold: True
color: 0, 0.70, 0.93, 1
#This is not quite right, but is ok for now. The resizing does not work
#quite perfectly.
<SessionButton#ToggleButton>:
group: 'session_options'
background_color: 0, 0.70, 0.93, 1
color: 0.11, 0.39, 0.33, 0.75, 0.02
bold: True
<SessionBar#GridLayout>:
cols: 2
#col_default_width: root.width/3
SessionButton:
text: "Start Session"
SessionButton:
text: "End Session"
<EntryButton#Button>:
group: 'entry_buttons'
background_color: 0, 0.70, 0.93, 1
color: 0.11, 0.39, 0.33, 0.75, 0.02
bold: True
<EntryBox#GridLayout>:
pos_hint: {'x':0, 'center_y':0.5}
cols: 1
rows: 2
Label:
text: "Does Entrant have an EBT card?"
font_size: root.height/8
size: self.texture_size
bold: True
color: 0, 0.70, 0.93, 1
GridLayout:
cols: 2
EntryButton:
text: 'YES'
EntryButton:
text: 'NO'
<RequestButton#Button>:
group: 'request_buttons'
background_color: 0, 0.70, 0.93, 1
color: 0.11, 0.39, 0.33, 0.75, 0.02
bold: True
<RequestBox#GridLayout>:
cols: 1
rows: 2
pos_hint: {'x': 0.333, 'center_y':0.5}
Label:
text: "Will Entrant scan EBT card?"
font_size: root.height/8
size: self.texture_size
bold: True
color: 0, 0.70, 0.93, 1
GridLayout:
cols: 2
EntryButton:
text: 'YES'
EntryButton:
text: 'NO'
<CardReader#GridLayout>
cols: 1
rows: 2
pos_hint: {'x': 0.666, 'center_y':0.5}
Label:
text: 'Please scan EBT card'
font_size: root.height/8
size: self.texture_size
bold: True
color: 0, 0.70, 0.93, 1
TextInput:
password: True
multiline: False
<PersonCounter#Label>:
id: _person_counter
text: '1'
pos_hint: {'x' : 0.1, 'y' : 0.25}
#pos: -500, 100
size: self.texture_size
halign: 'left'
font_size: 50
Are Kivy Layouts Essentially Widgets?
Layouts are widgets. The declaration of the Layout class is class Layout(Widget): etc.
where is the proper place to use the size_hint and pos_hint tags. Should it be at the widget level, or the layout level?
It should be one level below whatever widget you're trying to set their value for. e.g.
BoxLayout:
orientation: 'vertical' # this applies to the BoxLayout instance
FloatLayout:
size_hint_y: 0.75 # The FloatLayout will take 75% of the vertical space
Label:
pos_hint: {x: '0.5', y: '0.75'} # The Label is placed 50% across the x axis, and 75% up the y axis
size_hint: None, None
size: 50, 50 # ...and has a fixed size
text: '!'
Button:
size_hint_y: 0.25
I can't comment on your specific example with a Label, because it's not valid kv and doesn't try to do the thing you says fails. If this doesn't answer things for you, provide a full example that doesn't do what you expect.

Categories

Resources