Related
Python Code:
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.anchorlayout import AnchorLayout
from kivy.graphics import Color, Rectangle
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.image import AsyncImage
#logic
class FirstWindow(Screen):
pass
#Like Page
class SecondWindow(Screen):
pass
#Like Storage Page
class ThirdWindow(Screen):
pass
#More Information Page
class FourthWindow(Screen):
pass
class WindowManager(ScreenManager):
pass
# Designate Our .kv design file
kv = Builder.load_file('awesome.kv')
class AwesomeApp(App):
def build(self):
# return FirstWindow()
sm = WindowManager()
sm.current = "main"
return sm
# return kv
if __name__ == '__main__':
AwesomeApp().run()
kivy design file
#styling
WindowManager:
FirstWindow:
SecondWindow:
ThirdWindow:
FourthWindow:
<MyButton#Button>:
size_hint: [None, None]
size: [100, 100]
#navigation default
<NavigationBar>:
name: "navigationbar"
FloatLayout:
size_default: [None,None]
size_hint: [0.25,0.25]
pos_hint: [500,500]
GridLayout:
cols:1
Button:
text: "Home"
on_release:
app.root.current = "main"
cols:2
Button:
text: "Home"
TextInput:
id: minimum
cols:3
Button:
TextInput:
id: maximum
on_release:
app.root.current = "like"
#Entry Page
<FirstWindow>:
name: "main"
GridLayout:
padding: [200,200,200,200]
cols: 1
GridLayout:
cols:1
Label:
text: "ZipCode: "
cols: 2
TextInput:
id: zipcode
cols: 1
text: "Price Range: "
cols:2
TextInput:
id: min_price
cols:3
TextInput:
id: max_price
on_release:
app.root.current = "like"
FloatLayout:
size_hint: [.25,.25]
pos= [500,500]
GridLayout:
cols:1
Button:
text: "Home"
on_release:
app.root.current = "main"
cols:2
Button:
text: "Home"
TextInput:
id: minimum
cols:3
Button:
TextInput:
id: maximum
on_release:
app.root.current = "like"
#like page
<SecondWindow>:
name: "like"
AnchoredLayout:
anchor_x: "center"
anchor_y: "top"
# creating Canvas
canvas:
Color:
rgb: [.5, .324, .384]
Rectangle:
pos: self.pos
size: self.size
BoxLayout:
pos_hint:"horizontal"
Button:
text: "Home"
on_release:
app.root.current = "main"
root.manager.transition.direction = "right"
Button:
text: "Like Page"
on_release:
app.root.current = "storage"
root.manager.transition.direction = "left"
Button:
text: "More Information"
on_release:
app.root.current = "storage"
root.manager.transition.direction = "down"
Button:
text: "YES"
on_release:
app.root.current = "like"
root.manager.transition.direction = "right"
Button:
text: "NO"
on_release:
on_release:
app.root.current = "like"
root.manager.transition.direction = "left"
<ThirdWindow>:
name: "storage"
AnchoredLayout:
anchor_x: "center"
anchor_y: "top"
Button:
text: "Go Back"
on_release:
app.root.current = "like"
root.manager.transition.direction = "right"
<FourthWindow>:
name: "info"
Button:
text: "Go Back"
on_release:
app.root.current = "main"
root.manager.transition.direction = "right"
I am attempting to get a startup screen with a button to input zipcode, price min/max. I am getting nothing popping up, and an error output of ...
File "C:\Users\hanna\anaconda3\envs\spyder-cf\lib\site-packages\kivy\lang\parser.py", line 756, in parse_level
if current_property[:3] == 'on_':
TypeError: 'NoneType' object is not subscriptable
My code is not compiling, due to some errors (presumably with syntax or the default parameters of the code). Anyone who has worked with Kivy before, please hit me up!
from kivy.app import App
from kivy.graphics import Line
from kivy.metrics import dp
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.dropdown import DropDown
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.scrollview import ScrollView
from kivy.uix.stacklayout import StackLayout
from kivy.uix.widget import Widget
from kivy.lang import Builder
from kivymd.app import MDApp
class ScrollViewExample(ScrollView):
pass
class FirstWindow(Screen):
def set_text(self):
my_title_input = self.ids.note_title
my_details = self.ids.note_details
fo = open("notes.txt", "a")
fo.write('\n'+'\n'+my_title_input.text)
fo.write('\n'+my_details.text)
fo.close()
class SecondWindow(Screen):
pass
class ThirdWindow(Screen):
def on_toggle_button_state(self):
dark_mode = self.ids.dark_mode
dark_mode.text = 'Feature not available'
pass
class FourthWindow(Screen):
#This class displays notes from a file in buttons
#works but only the notes showup
def build(self):
root = FourthWindow()
root.add_widget(FourthWindow(name='StackLayout'))
class StackLayoutExample(StackLayout):
class ScrollView(ScrollView):
pass
def __init__(self, **kwargs):
super().__init__(**kwargs)
layout = StackLayout(orientation='lr-tb')
with open('notes.txt', 'r') as fp:
data = fp.read()
splat = data.split("\n\n")
notes = []
for i, note in enumerate(splat, 0):
notes.append(note)
for i in range(0, len(notes)):
b = Button(text=notes[i], size_hint=(.25, .4))
self.add_widget(b)
class WindowManager(ScreenManager):
pass
class RelativeLayoutExample(RelativeLayout):
pass
class ScreeManager(ScreenManager):
pass
class LineMaker(Widget):
pass
class Noteit(App):
pass
Noteit().run()
Noteit.kv <---The kv file begins here
WindowManager:
FirstWindow:
SecondWindow:
ThirdWindow:
FourthWindow:
<FirstWindow>:
id: first_window
name: "Notes"
RelativeLayout:
Label:
text: "Notes"
size_hint: None,None
pos_hint: {'top':1,'center_x':.5}
font_size: 35
Button:
text: 'Account'
size_hint: None,None
pos_hint: {'top':1,'right':1}
on_release:
app.root.current = "Account"
root.manager.transition.direction= "left"
Button:
text: 'Preferences'
size_hint: None,None
pos_hint: {'top':1,'left':1}
on_release:
app.root.current = "Preferences"
root.manager.transition.direction= "right"
Label:
text: "Title:"
size_hint: None,None
pos_hint: {'top':.85,'center_x':.5}
font_size: 20
TextInput:
id: note_title
size_hint: .45,.08
pos_hint: {'top':.75,'center_x':.5}
multiline: False
Label:
text: "Details:"
size_hint: None,None
pos_hint: {'top':.65,'center_x':.5}
font_size: 20
TextInput:
id: note_details
size_hint: .45,.3
pos_hint: {'top':.55,'center_x':.5}
multiline: True
Button:
text: "Submit"
size_hint: .25,.1
length: "100dp"
pos_hint: {'top':.25,'center_x':.5}
on_release:
root.set_text()
LineMaker:
canvas:
Color:
rgba: 1, 1, 1, 1
Line:
width: 2.
points: (self.width,self.height*.83,0,self.height*.83)
Button:
text: 'View All Notes'
size_hint:.25,.15
pos_hint: {'bottom':1,'center_x':.5}
on_release:
app.root.current = "View"
root.manager.transition.direction= "up"
<SecondWindow>:
name: "Account"
RelativeLayout:
Label:
text: "Account"
size_hint: None,None
pos_hint: {'top':1,'center_x':.5}
font_size: 35
Button:
text: 'Notes'
size_hint: None,None
pos_hint: {'top':1,'left':1}
on_release:
app.root.current = "Notes"
root.manager.transition.direction= "right"
Button:
text: 'Preferences'
size_hint: None,None
pos_hint: {'top':1,'right':1}
on_release:
app.root.current = "Preferences"
root.manager.transition.direction= "left"
Label:
text: "Username:"
size_hint: None,None
pos_hint: {'top':.85}
font_size: 20
TextInput:
size_hint: .5,.1
pos_hint: {'top':.55,'left':.3}
multiline: False
Label:
text: "Password:"
size_hint: None,None
pos_hint: {'top':.65}
font_size: 20
TextInput:
size_hint: .5,.1
pos_hint: {'top':.75,'left':.3}
multiline: False
Button:
text: "Log In"
size_hint: .25,.1
length: "100dp"
pos_hint: {'top':.45}
Button:
text: "Sign Up"
size_hint: .25,.1
length: "100dp"
pos_hint: {'top':.45,'center_x':.375}
LineMaker:
canvas:
Color:
rgba: 1, 1, 1, 1
Line:
width: 2.
points: (self.width,self.height*.83,0,self.height*.83)
<ThirdWindow>:
name: "Preferences"
RelativeLayout:
Label:
text: "Preferences"
size_hint: None,None
pos_hint: {'top':1,'center_x':.5}
font_size: 35
Button:
text: 'Notes'
size_hint: None,None
pos_hint: {'top':1,'right':1}
on_release:
app.root.current = "Notes"
root.manager.transition.direction= "left"
Button:
text: 'Account'
size_hint: None,None
pos_hint: {'top':1,'left':1}
on_release:
app.root.current = "Account"
root.manager.transition.direction= "right"
ToggleButton:
text: 'Dark Mode'
size_hint: .25,.1
pos_hint: {'top':.75,'center_x':.25}
on_state: root.on_toggle_button_state()
Label:
id: dark_mode
text: ''
LineMaker:
canvas:
Color:
rgba: 1, 1, 1, 1
Line:
width: 2.
points: (self.width,self.height*.83,0,self.height*.83)
<FourthWindow>:
name: "View"
RelativeLayout:
Button:
text: 'Note Submission'
size_hint:.25,.15
pos_hint: {'top':1,'center_x':.5}
on_release:
app.root.current = "Notes"
root.manager.transition.direction= "down"
Label:
text: 'All Notes'
size_hint: None,None
pos_hint: {'top':1,'right':.9}
font_size: 35
How do I make the stacklayout code showup with the kv file code? Or at least make the stacklayout part of the screen.
Right now the only option I have is either take the screen as output or the stack layout as output.
Replacing the def build(self) inside the class FourthWindow(Screen) will show the whole application. The code inside the def build(self) also works but they do not work together.
I am new to kivy and object oriented programming so I do not know much about this topic so I could be missing something really basic.
I'm a physicist, and as everyone knows, we like our cocktails. I am therefore trying to build an automatic bartender. Unfortunately, the only experience I have with programming in python is to do physics simulations, and I am not that savvy with coding anyways.
My problem is now this: there is a python list in the class BartenderApp that I want to use in the kivy file, specifically in the LoadNewIngredients in the kivy file, for the spinners to take their options from. I have looked quite a while for a solution and none have worked so far. I know I should be able to put the spinners and labels in the python file using a for loop, but I would much rather have it a bit more clean and keep them in the kivy file.
So if anyone could help me how to pass the list to the kivy file, it'd be much appreciated!
Here is the .py file:
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.core.window import Window
from kivy.uix.button import Button
from kivy.clock import mainthread
from functools import partial
#Import drink list
from drinks import drink_list, drink_options
class drink:
def __init__(self,name,ingredients,amount):
self.name = name
self.ingredients = ingredients
self.amount = amount
#Define the different screens
class MainMenu(Screen):
pass
class UseLastIngredients(Screen):
pass
class DrinkMenu(Screen):
#Mainthread will pause shortly to give script time, the rest adds the buttons
#mainthread
def on_enter(self):
self.buttons = []
self.ids.drinks.clear_widgets()
for btn in range(len(drink_list)):
self.buttons.append(Button(text=str(drink_list[btn]['name'])))
self.buttons[btn].bind(on_press = self.pour_drink)
self.ids.drinks.add_widget(self.buttons[btn])
def pour_drink(self, button):
print(button.text)
class LoadNewIngredients(Screen):
def spinner_clicked(self, ident, value):
if ident == 1:
pass
if ident == 2:
pass
if ident == 3:
pass
if ident == 4:
pass
if ident == 5:
pass
if ident == 6:
pass
if ident == 7:
pass
if ident == 8:
pass
#Define the ScreenManager
class MenuManager(ScreenManager):
pass
#Designate the .kv design file
kv = Builder.load_file('bartenderkv.kv')
class BartenderApp(App):
#I want to use the ingredients list in the kivy file
global ingredients
ingredients = []
for drink in range(len(drink_list)):
ings = list(drink_list[drink]['ingredients'].keys())
for ing in range(len(ings)):
elem = ings[ing]
if elem not in ingredients:
ingredients.append(elem)
def build(self):
return kv
if __name__ == '__main__':
BartenderApp().run()
and here is the .kv file:
#:import Factory kivy.factory.Factory
#:import ScrollView kivy.uix.scrollview
MenuManager:
MainMenu:
LoadNewIngredients:
DrinkMenu:
<MainMenu>:
name: "MainMenu"
GridLayout:
rows: 3
size: root.width, root.height
padding: 10
spacing: 10
Label:
text: "Main Menu"
font_size: 32
GridLayout:
cols: 2
size: root.width, root.height
spacing: 10
Button:
text: "Use Last Ingredients"
font_size: 32
on_release: app.root.current = "DrinkMenu"
Button:
text: "Load New Ingredients"
font_size: 32
on_release: app.root.current = "LoadNewIngredients"
Button:
text: "See Permissable Ingredients"
font_size: 32
#on_press: print("It Works")
on_release: Factory.PermissablePopup().open()
<LoadNewIngredients>:
name: "LoadNewIngredients"
GridLayout:
cols: 2
size: root.width, root.height
padding: 10
spacing: 10
GridLayout:
size: root.width, root.height
size_hint_x: 0.4
rows: 2
Button:
text: "Continue"
font_size: 24
on_release: app.root.current = "DrinkMenu"
Button:
text: "Main Menu"
font_size: 24
on_release: app.root.current = "MainMenu"
GridLayout:
#This is where I want the spinners to take in the ingredients list as options.
id: choices
rows: 4
orientation: 'tb-lr'
Label:
id: pump_1
text: "Pump 1"
font_size: 24
Label:
id: pump_2
text: "Pump 2"
font_size: 24
Label:
id: pump_3
text: "Pump 3"
font_size: 24
Label:
id: pump_4
text: "Pump 4"
font_size: 24
#Spinner is the easy drop down version in kivy, lets see how it looks.
Spinner:
id: spinner_id_1
text: "Pump_1"
values: ["1", "2", "3"]
on_text: root.spinner_clicked(1,spinner_id_1.text)
Spinner:
id: spinner_id_2
text: "Pump_2"
values: ["1", "2", "3"]
on_text: root.spinner_clicked(2,spinner_id_2.text)
Spinner:
id: spinner_id_3
text: "Pump_3"
values: ["1", "2", "3"]
on_text: root.spinner_clicked(3,spinner_id_3.text)
Spinner:
id: spinner_id_4
text: "Pump_4"
values: ["1", "2", "3"]
on_text: root.spinner_clicked(4,spinner_id_4.text)
Label:
id: pump_5
text: "Pump 5"
font_size: 24
Label:
id: pump_6
text: "Pump 6"
font_size: 24
Label:
id: pump_7
text: "Pump 7"
font_size: 24
Label:
id: pump_8
text: "Pump 8"
font_size: 24
#Spinner is the drop down version, lets see how it looks.
Spinner:
id: spinner_id_5
text: "Pump_5"
values: ["1", "2", "3"]
on_text: root.spinner_clicked(5,spinner_id_5.text)
Spinner:
id: spinner_id_6
text: "Pump_6"
values: ["1", "2", "3"]
on_text: root.spinner_clicked(6,spinner_id_6.text)
Spinner:
id: spinner_id_7
text: "Pump_7"
values: ["1", "2", "3"]
on_text: root.spinner_clicked(7,spinner_id_7.text)
Spinner:
id: spinner_id_8
text: "Pump_8"
values: ["1", "2", "3"]
on_text: root.spinner_clicked(8,spinner_id_8.text)
<DrinkMenu>:
name: "DrinkMenu"
GridLayout:
cols: 2
width: root.width
height: self.minimum_height
padding: 10
spacing: 10
GridLayout:
height: root.height
size_hint_x: 0.4
rows: 2
Button:
text: "Top Up"
font_size: 24
on_release:
Button:
text: "Main Menu"
font_size: 24
on_release: app.root.current = "MainMenu"
ScrollView:
size_hint_y: 0.73
pos_hint: {'x':0, 'y': 0.11}
do_scroll_x: False
do_scroll_y: True
GridLayout:
id: drinks
orientation: 'lr-tb'
size_hint_y: None
size_hint_x: 1.0
cols: 3
height: self.minimum_height
row_default_height: 180
row_force_default: True
#Create a rounded button, the #Button is what it inherits
<RoundedButton#Button>
background_color: (0,0,0,0)
background_normal: ''
canvas.before:
Color:
rgba:
(48/255,84/255,150/255,1)\
if self.state == 'normal' else (0.6,0.6,1,1) # Color is red if button is not pressed, otherwise color is green
RoundedRectangle:
size: self.size
pos: self.pos
radius: [58]
<PermissablePopup#Popup>
auto_dismiss: False
#size_hint: 0.6,0.2
#pos_hint: {"x":0.2, "top":0.9}
title: "Permissable Ingredients"
GridLayout:
rows: 2
size: root.width, root.height
spacing: 10
GridLayout:
cols: 2
Label:
text: "Sodas"
font_size: 32
#Add list of sodas
Label:
text: "Alcohol"
font_size: 32
#Add list of alcohols
Button:
text: "Done"
font_size: 24
on_release: root.dismiss()
Try adding a ListProperty (https://kivy.org/doc/stable/api-kivy.properties.html) to you App class. Like this:
class BartenderApp(App):
ingredients = ListProperty()
for drink in range(len(drink_list)):
ings = list(drink_list[drink]['ingredients'].keys())
for ing in range(len(ings)):
elem = ings[ing]
if elem not in self.ingredients:
self.ingredients.append(elem)
A list property is both accessible in the Python and KV file. What's more is that they can be bound to a callback so that you can create your own event!
In the KV file you can now refer to app.ingredients and any object that is defined by the list will be automatically updated when app.ingredients is changed. So for example if you had the following label in your KV file:
Label:
text: app.ingredients[0]
The text would automatically update when you change the list. Be careful though, you may get an index error if there isn't an object in the index you're referencing.
Let me know how you get on with this and whether it solves your problem.
I finally managed to solve it, maybe not the best solution, but it works.
In the class LoadNewIngredients I wrote a function that checked what ingredients are available and returns a list with the ingredients. This function is then referenced in the kivy app using root.function_name().
The .py file:
#Everything needed for kivy
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.core.window import Window
from kivy.uix.button import Button
from kivy.clock import mainthread
from functools import partial
#Import drink list
from drinks import drink_list, drink_options
class drink:
def __init__(self,name,ingredients,amount):
self.name = name
self.ingredients = ingredients
self.amount = amount
#Define the different screens
class MainMenu(Screen):
pass
class UseLastIngredients(Screen):
pass
class DrinkMenu(Screen):
#Mainthread will pause shortly to give script time, the rest adds the buttons
#mainthread
def on_enter(self):
self.buttons = []
self.ids.drinks.clear_widgets()
for btn in range(len(drink_list)):
self.buttons.append(Button(text=str(drink_list[btn]['name'])))
self.buttons[btn].bind(on_press = self.pour_drink)
self.ids.drinks.add_widget(self.buttons[btn])
def pour_drink(self, button):
print(button.text)
class LoadNewIngredients(Screen):
def spinner_clicked(self, ident, value):
if ident == 1:
pass
if ident == 2:
pass
if ident == 3:
pass
if ident == 4:
pass
if ident == 5:
pass
if ident == 6:
pass
if ident == 7:
pass
if ident == 8:
pass
#I want to use the ingredients list in the kivy file
def get_ingredients(self,*args,**kwargs):
global ingredients
ingredients = []
for drink in range(len(drink_list)):
ings = list(drink_list[drink]['ingredients'].keys())
for ing in range(len(ings)):
elem = ings[ing]
if elem not in ingredients:
ingredients.append(elem)
return ingredients
#Define the ScreenManager
class MenuManager(ScreenManager):
pass
#Designate the .kv design file
kv = Builder.load_file('bartenderkv.kv')
class BartenderApp(App):
def build(self):
return kv
if __name__ == '__main__':
BartenderApp().run()
and here is the .kv file:
#Need to define everything, the ScreenManager is the entity that keeps tabs
#on all the different menu windows
#This is for the popup, lets you instansiate a class from anywhere
#:import Factory kivy.factory.Factory
#:import ScrollView kivy.uix.scrollview
MenuManager:
MainMenu:
LoadNewIngredients:
DrinkMenu:
<MainMenu>:
name: "MainMenu"
GridLayout:
rows: 3
size: root.width, root.height
padding: 10
spacing: 10
Label:
text: "Main Menu"
font_size: 32
GridLayout:
cols: 2
size: root.width, root.height
spacing: 10
Button:
text: "Use Last Ingredients"
font_size: 32
on_release: app.root.current = "DrinkMenu"
Button:
text: "Load New Ingredients"
font_size: 32
on_release: app.root.current = "LoadNewIngredients"
Button:
text: "See Permissable Ingredients"
font_size: 32
on_release: Factory.PermissablePopup().open()
<LoadNewIngredients>:
name: "LoadNewIngredients"
GridLayout:
cols: 2
size: root.width, root.height
padding: 10
spacing: 10
#size hint sets relative sized, x-dir, y-dir
GridLayout:
size: root.width, root.height
size_hint_x: 0.4
rows: 2
Button:
text: "Continue"
font_size: 24
on_release: app.root.current = "DrinkMenu"
Button:
text: "Main Menu"
font_size: 24
on_release: app.root.current = "MainMenu"
GridLayout:
id: choices
rows: 4
orientation: 'tb-lr'
Label:
id: pump_1
text: "Pump 1"
font_size: 24
Label:
id: pump_2
text: "Pump 2"
font_size: 24
Label:
id: pump_3
text: "Pump 3"
font_size: 24
Label:
id: pump_4
text: "Pump 4"
font_size: 24
Spinner:
id: spinner_id_1
text: "Pump_1"
#This references the get_ingredients function in the main py file
values: root.get_ingredients()
on_text: root.spinner_clicked(1,spinner_id_1.text)
Spinner:
id: spinner_id_2
text: "Pump_2"
values: root.get_ingredients()
on_text: root.spinner_clicked(2,spinner_id_2.text)
Spinner:
id: spinner_id_3
text: "Pump_3"
values: root.get_ingredients()
on_text: root.spinner_clicked(3,spinner_id_3.text)
Spinner:
id: spinner_id_4
text: "Pump_4"
values: root.get_ingredients()
on_text: root.spinner_clicked(4,spinner_id_4.text)
Label:
id: pump_5
text: "Pump 5"
font_size: 24
Label:
id: pump_6
text: "Pump 6"
font_size: 24
Label:
id: pump_7
text: "Pump 7"
font_size: 24
Label:
id: pump_8
text: "Pump 8"
font_size: 24
Spinner:
id: spinner_id_5
text: "Pump_5"
values: root.get_ingredients()
on_text: root.spinner_clicked(5,spinner_id_5.text)
Spinner:
id: spinner_id_6
text: "Pump_6"
values: root.get_ingredients()
on_text: root.spinner_clicked(6,spinner_id_6.text)
Spinner:
id: spinner_id_7
text: "Pump_7"
values: root.get_ingredients()
on_text: root.spinner_clicked(7,spinner_id_7.text)
Spinner:
id: spinner_id_8
text: "Pump_8"
values: root.get_ingredients()
on_text: root.spinner_clicked(8,spinner_id_8.text)
<DrinkMenu>:
name: "DrinkMenu"
GridLayout:
cols: 2
width: root.width
height: self.minimum_height
padding: 10
spacing: 10
GridLayout:
height: root.height
size_hint_x: 0.4
rows: 2
Button:
text: "Top Up"
font_size: 24
on_release:
Button:
text: "Main Menu"
font_size: 24
on_release: app.root.current = "MainMenu"
ScrollView:
size_hint_y: 0.1
pos_hint: {'x':0, 'y': 0.11}
do_scroll_x: False
do_scroll_y: True
GridLayout:
id: drinks
orientation: 'lr-tb'
size_hint_y: None
size_hint_x: 1.0
cols: 3
height: self.minimum_height
row_default_height: 100
row_force_default: True
<RoundedButton#Button>
background_color: (0,0,0,0)
background_normal: ''
canvas.before:
Color:
rgba:
(48/255,84/255,150/255,1)\
if self.state == 'normal' else (0.6,0.6,1,1)
RoundedRectangle:
size: self.size
pos: self.pos
radius: [58]
<PermissablePopup#Popup>
auto_dismiss: False
#size_hint: 0.6,0.2
#pos_hint: {"x":0.2, "top":0.9}
title: "Permissable Ingredients"
GridLayout:
rows: 2
size: root.width, root.height
spacing: 10
GridLayout:
cols: 2
Label:
text: "Sodas"
font_size: 32
#Add list of sodas
Label:
text: "Alcohol"
font_size: 32
#Add list of alcohols
Button:
text: "Done"
font_size: 24
on_release: root.dismiss()
Hopefully this helps if someone else has the same problem.
But if anyone has any other solutions (or suggestions about the code in general), please let me know!
The screen has multiple layouts all child of a box layout. I am trying to add a button in the last sub layout (grid-layout) when a button in other layout is clicked. The code does not crash but nothing happens too. I want to add buttons to the layout with id drinkslayout when a button is clicked eg pepsi,sprite
Python:
class MainScreen(Screen):
pass
class AnotherScreen(Screen):
pass
class ScreenManagement(ScreenManager):
pass
class Stacks(StackLayout):
pass
present=Builder.load_file('hellokivy2.kv') #Specifying location of kv file
class MainApp(App):
def build(self):
return present
def drinksSelect(self,value): #creating a button by referring the id of the layout in which to create button
print(value)
yolo = AnotherScreen()
yolo2 = yolo.ids.newButtonLayout
button = Button(text="value",size_hint= (0.2,0.4))
yolo2.add_widget(button)
if __name__ == "__main__":
MainApp().run()
KV
#: import FadeTransition kivy.uix.screenmanager.FadeTransition
ScreenManagement:
transition: FadeTransition()
MainScreen:
AnotherScreen:
<MainScreen>:
name: "main"
canvas.before:
Color:
rgba: 1, 1, 1, 1
Rectangle:
pos: self.pos
size: self.size
BoxLayout:
orientation: 'vertical'
size:root.size
Button:
text: "Slideshow"
GridLayout:
cols: 2
Button:
text: "Burger"
Button:
text: "Drinks"
on_release: app.root.current = "other"
Button:
text: "Fries"
Button:
text: "Others"
Label:
text: "Your Cart"
font_size: 40
color:(0,0,0,1)
size_hint_y: None
canvas.before:
Color:
rgba:150,10,200,0.5
Rectangle:
pos: self.pos
size: self.size
<AnotherScreen>:
name: "other"
canvas.before:
Color:
rgba: 1, 1, 1, 1
Rectangle:
pos: self.pos
size: self.size
BoxLayout:
size:root.size
orientation: 'vertical'
GridLayout:
size_hint_y:0.1
orientation: 'vertical'
rows: 1
Button:
color: 1,1,1,1
font_size: 25
size_hint_y:0.1
text: "Back Home"
on_release: app.root.current = "main"
Label:
text: "Project BAM"
canvas.before:
Color:
rgba: 0,0,0,1
Rectangle:
pos: self.pos
size: self.size
Button:
color: 1,1,1,1
font_size: 25
size_hint_y:0.1
text: "Profile"
on_release: app.root.current = "main"
Button:
color: 1,1,1,1
font_size: 25
size_hint_y:0.9
text: "Whats New"
on_release: app.root.current = "main"
GridLayout:
rows: 2
Button:
text: "Pepsi"
on_release: app.drinksSelect(1)
Button:
text: "7up"
on_release: app.drinksSelect(2)
Button:
text: "Fanta"
on_release: app.drinksSelect(3)
Button:
text: "Mountain Dew"
on_release: app.drinksSelect(4)
Button:
text: "Diet Pepsi"
on_release: app.drinksSelect(5)
Button:
text: "Sprite"
on_release: app.drinksSelect(6)
GridLayout:
id: drinksLayout
size_hint_y: 0.3
orientation: 'horizontal'
rows: 1
Button:
id: label1
size_hint: 0.2,0.4
background_normal:'1.jpg'
text: 'B1'
Button:
id: label2
size_hint: 0.2,0.4
background_normal:'1.jpg'
text: 'B1'
Button:
id: label3
size_hint: 0.2,0.4
background_normal:'1.jpg'
text: 'B1'
Ok the problem was your drinksSelect method, also you need to keep the value of your screens
Try this:
py:
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang.builder import Builder
from kivy.uix.stacklayout import StackLayout
from kivy.uix.button import Button
from kivy.properties import ObjectProperty
class MainScreen(Screen):
pass
class AnotherScreen(Screen):
dl = ObjectProperty()
l = 0
limit = 3 # Fix your limit here 3 is an example
class ScreenManagement(ScreenManager):
m_s = ObjectProperty() # Here I will keep the value of the MainScreen
a_s = ObjectProperty() # Here the AnotherScreen so I can use them later
class Stacks(StackLayout):
pass
present = Builder.load_file('hellokivy2.kv') # Specifying location of kv file
class MainApp(App):
def build(self):
return present
def drinksSelect(self,value): # creating a button by referring the id of the layout in which to create button
print(value)
if self.root.a_s.l < self.root.a_s.limit: # You know what I mean
button = Button(text=str(value), size_hint= (0.2,0.4))
self.root.a_s.ids['place_remaining'].add_widget(button)
self.root.a_s.l += 1
if __name__ == "__main__":
MainApp().run()
kv:
#: import FadeTransition kivy.uix.screenmanager.FadeTransition
ScreenManagement:
m_s: m_s # so I can use it in the .py file
a_s:a_s # same here
transition: FadeTransition()
MainScreen:
id: m_s
AnotherScreen:
id: a_s
<MainScreen>:
name: "main"
canvas.before:
Color:
rgba: 1, 1, 1, 1
Rectangle:
pos: self.pos
size: self.size
BoxLayout:
orientation: 'vertical'
size:root.size
Button:
text: "Slideshow"
GridLayout:
cols: 2
Button:
text: "Burger"
Button:
text: "Drinks"
on_release: app.root.current = "other"
Button:
text: "Fries"
Button:
text: "Others"
Label:
text: "Your Cart"
font_size: 40
color:(0,0,0,1)
size_hint_y: None
canvas.before:
Color:
rgba:150,10,200,0.5
Rectangle:
pos: self.pos
size: self.size
<AnotherScreen>:
name: "other"
dl : drinksLayout
canvas.before:
Color:
rgba: 1, 1, 1, 1
Rectangle:
pos: self.pos
size: self.size
BoxLayout:
size:root.size
orientation: 'vertical'
GridLayout:
size_hint_y:0.1
orientation: 'vertical'
rows: 1
Button:
color: 1,1,1,1
font_size: 25
size_hint_y:0.1
text: "Back Home"
on_release: app.root.current = "main"
Label:
text: "Project BAM"
canvas.before:
Color:
rgba: 0,0,0,1
Rectangle:
pos: self.pos
size: self.size
Button:
color: 1,1,1,1
font_size: 25
size_hint_y:0.1
text: "Profile"
on_release: app.root.current = "main"
Button:
color: 1,1,1,1
font_size: 25
size_hint_y:0.9
text: "Whats New"
on_release: app.root.current = "main"
GridLayout:
rows: 2
Button:
text: "Pepsi"
on_release: app.drinksSelect(1)
Button:
text: "7up"
on_release: app.drinksSelect(2)
Button:
text: "Fanta"
on_release: app.drinksSelect(3)
Button:
text: "Mountain Dew"
on_release: app.drinksSelect(4)
Button:
text: "Diet Pepsi"
on_release: app.drinksSelect(5)
Button:
text: "Sprite"
on_release: app.drinksSelect(6)
GridLayout:
id: drinksLayout
size_hint_y: 0.3
orientation: 'horizontal'
rows: 1
GridLayout:
id: place_remaining
rows: 1
size_hint_x: 80
Button:
id: label1
width: 40 # Set the size_hint_x to None and then set the width if you want a fixed dimension
size_hint: None,0.4
background_normal:'1.jpg'
text: 'B1'
Button:
id: label2
width: 40
size_hint: None,0.4
background_normal:'1.jpg'
text: 'B1'
Button:
id: label3
width: 40
size_hint: None,0.4
background_normal:'1.jpg'
text: 'B1'
Outputs:
I hope that the code is a bit clear now
I'm quite new to Kivy (started yesterday) and am trying to create a simple enough app that has input boxes for several values of height and area to calculate volumes. I cant find any working methods of doing this. So far all I have got is this:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
Builder.load_string("""
<MenuScreen>:
FloatLayout:
Label:
text: 'Please Select an Area to Work With:'
pos: 230, 490
size_hint: .15, .05
font_size: 23
Button:
text: "A"
pos: 230, 100
size_hint: .4,.1
font_size: 23
on_press: root.manager.current = 'settings'
Button:
text: "B"
pos: 230, 210
size_hint: .4,.1
font_size: 23
on_press: root.manager.current = 'settings'
Button:
text: "C"
pos: 230, 320
size_hint: .4,.1
font_size: 23
on_press: root.manager.current = 'settings'
Button:
text: "D"
pos: 230, 420
size_hint: .4,.1
font_size: 23
on_press: root.manager.current = 'settings'
<SettingsScreen>:
GridLayout:
Label:
text: 'Room 1'
pos: 6, 460
size_hint: .15, .05
font_size: 23
Label:
text: 'Room 2'
pos: 6, 420
size_hint: .15, .05
font_size: 23
Label:
text: 'Room 3'
pos: 6, 380
size_hint: .15, .05
font_size: 23
Label:
text: 'Room 4'
pos: 6, 340
size_hint: .15, .05
font_size: 23
Label:
text: 'Room 5'
pos: 6, 300
size_hint: .15, .05
font_size: 23
Label:
text: 'Room 6'
pos: 6, 260
size_hint: .15, .05
font_size: 23
TextInput:
text1: "0"
multiline: False
pos: 200,420
font_size: 23
on_text: viewer.text = self.text1
size_hint: .001, .001
TextInput:
text2: "0"
multiline: False
pos: 200, 420
font_size: 23
on_text: viewer.text = self.text2
size_hint: .001, .001
TextInput:
text3: "0"
multiline: False
pos: 200,380
font_size: 23
on_text: viewer.text = self.text3
size_hint: .001, .001
TextInput:
text4: "0"
multiline: False
pos: 200,340
font_size: 23
on_text: viewer.text = self.text4
size_hint: .001, .001
TextInput:
text5: "0"
multiline: False
pos: 200,300
font_size: 23
on_text: viewer.text = self.text5
size_hint: .001, .001
TextInput:
text6: "0"
multiline: False
pos: 200,240
font_size: 23
on_text: viewer.text = self.text6
size_hint: .001, .001
""")
# Declare both screen
class MenuScreen(Screen):
pass
class SettingsScreen(Screen):
pass
# Create the screen manager
sm = ScreenManager()
sm.add_widget(MenuScreen(name='menu'))
sm.add_widget(SettingsScreen(name='settings'))
class TestApp(App):
def build(self):
return sm
if __name__ == '__main__':
TestApp().run()
Im planning to have the second page unique for each button pressed, but want Any help would be appreciated.
I hope I got to understand your question. You are asking for methods to do this. The plain answer is that you have the whole Python to do all the operations you want. Kivy is a library that provides a lot of components to design GUI. It also provides you with a language that is parsed by the Builder.load_string(). Here is an example that might be more or less what you are looking for. It is sort of a calculator on the first screen. The second screen is empty and you can move between them with the bottom buttons.
The calculator on the first screen has two InputTexts and two buttons (Sum and Product). The Sum Button has the implementation of a sum directly on the kivy language. The Product Button calls a method in the root (an instance of Calc). The method doesn't exist by itself. I created in the python code below the kivy section. There is some comments on the code for what I am saying.
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
Builder.load_string("""
<Calc>:
# This are attributes of the class Calc now
a: _a
b: _b
result: _result
AnchorLayout:
anchor_x: 'center'
anchor_y: 'top'
ScreenManager:
size_hint: 1, .9
id: _screen_manager
Screen:
name: 'screen1'
GridLayout:
cols:1
TextInput:
id: _a
text: '3'
TextInput:
id: _b
text: '5'
Label:
id: _result
Button:
text: 'sum'
# You can do the opertion directly
on_press: _result.text = str(int(_a.text) + int(_b.text))
Button:
text: 'product'
# Or you can call a method from the root class (instance of calc)
on_press: root.product(*args)
Screen:
name: 'screen2'
Label:
text: 'The second screen'
AnchorLayout:
anchor_x: 'center'
anchor_y: 'bottom'
BoxLayout:
orientation: 'horizontal'
size_hint: 1, .1
Button:
text: 'Go to Screen 1'
on_press: _screen_manager.current = 'screen1'
Button:
text: 'Go to Screen 2'
on_press: _screen_manager.current = 'screen2'""")
class Calc(FloatLayout):
# define the multiplication of a function
def product(self, instance):
# self.result, self.a and self.b where defined explicitely in the kv
self.result.text = str(int(self.a.text) * int(self.b.text))
class TestApp(App):
def build(self):
return Calc()
if __name__ == '__main__':
TestApp().run()