Kivy 1.10.1 Slider duplicating itself - python

I'm currently trying to create a simple Slider that will control the size of text in my application. The problem I'm running into though is that even though the slider functions as I intended, it seems to create another version of itself beneath the first slider that can't be moved. You can see how it looks in the provided image here [alt text: a screenshot of a rudimentary user interface showing a kivy slider. The slider has been moved forward behind it there is another copy in the default position] (as you can see the Label text inside the BoxLayout is also getting overlapped). I'm currently using Kivy 1.10.1 and Python 3.7.2.
Here is my Python script:
# -*- coding: utf-8 -*-
import kivy
kivy.require('1.10.1')
from kivy.app import App
from kivy.core.window import Window
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivy.uix.actionbar import ActionBar
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.graphics.vertex_instructions import (Rectangle, Ellipse, Line)
from kivy.graphics.context_instructions import Color
from kivy.uix.checkbox import CheckBox
from kivy.uix.slider import Slider
#Window.size = (360/1.2,740/1.2)
class HomeScreen(Screen):
pass
class OptionsScreen(Screen):
pass
class TutorialScreen(Screen):
pass
class ScreenController(ScreenManager):
pass
look = Builder.load_file('main.kv')
class MainApp(App):
def build(self):
return look
if __name__ == '__main__':
MainApp().run()
And here is the relevant piece of Kivy language meant to create the slider on my
<OptionsScreen>
name: 'option'
BoxLayout:
orientation:'vertical'
BoxLayout:
orientation:'horizontal'
size_hint_y: 1/3
Label:
text:'Text size'
font_size: textsize.value
size_hint_x:.5
Slider:
id:textsize
min: 5
max: 25
value:15
step: 1
size_hint_x:.5
Though if you want to read the entire Kivy language document I'm posting it here as well.
#: import FadeTransition kivy.uix.screenmanager.FadeTransition
# Reference main.py
#: import main main
#: import Slider kivy.uix.slider
#: import ActionBar kivy.uix.actionbar
#: import Window kivy.core.window
ScreenController:
transition: FadeTransition()
HomeScreen:
OptionsScreen:
TutorialScreen:
<HomeScreen>
name: 'home'
BoxLayout:
id:'hem'
orientation:'vertical'
BoxLayout:
size_hint_x: 1
orientation:'horizontal'
canvas:
Color:
rgba: 0,1,0,1
Rectangle
size: self.size
pos: self.pos
BoxLayout:
orientation:'horizontal'
BoxLayout:
size_hint_x: .5
orientation:'horizontal'
canvas:
Color:
rgba: 1,0,1,1
Rectangle
size: self.size
pos: self.pos
BoxLayout:
size_hint_x: .5
orientation:'horizontal'
canvas:
Color:
rgba: 1,1,0,1
Rectangle
size: self.size
pos: self.pos
ActionBar:
pos_hint: {'top':1}
ActionView:
use_separator: True
ActionPrevious:
title: 'Fredde & Kribbas kivy'
with_previous: False
ActionOverflow:
ActionGroup:
text: 'Group1'
ActionButton:
text: 'home'
on_touch_down: app.root.current = 'home'
ActionButton:
text: 'Options'
on_touch_down: app.root.current = 'option'
ActionButton:
text: 'Tutorial'
on_touch_down: app.root.current = 'tut'
<OptionsScreen>
name: 'option'
BoxLayout:
orientation:'vertical'
BoxLayout:
orientation:'horizontal'
size_hint_y: 1/3
Label:
text:'Text size'
font_size: textsize.value
size_hint_x:.5
Slider:
id:textsize
min: 5
max: 25
value:15
step: 1
size_hint_x:.5
BoxLayout:
#fontsize checkbox
orientation:'horizontal'
size_hint_y: 1/3
BoxLayout:
orientation:'vertical'
Label:
text: 'Nightmode'
CheckBox:
id:default
size_hint_y: None
active: True
height:'50dp'
group:'g1'
BoxLayout:
orientation:'vertical'
Label:
text: 'Daymode'
CheckBox:
id:stor
size_hint_y: None
height:'50dp'
group:'g1'
BoxLayout:
orientation:'horizontal'
size_hint_y: 1/3
canvas:
Color:
rgba: 0,0,1,1
Rectangle
size: self.size
pos: self.pos
ActionBar:
pos_hint: {'top':1}
ActionView:
use_separator: True
ActionPrevious:
title: 'Fredde & Kribbas kivy'
with_previous: False
ActionOverflow:
ActionGroup:
text: 'Group1'
ActionButton:
text: 'home'
on_touch_down: app.root.current = 'home'
ActionButton:
text: 'Options'
on_touch_down: app.root.current = 'option'
ActionButton:
text: 'Tutorial'
on_touch_down: app.root.current = 'tut'
<TutorialScreen>
name: 'tut'
ActionBar:
pos_hint: {'top':1}
ActionView:
use_separator: True
ActionPrevious:
title: 'Fredde & Kribbas kivy'
with_previous: False
ActionOverflow:
ActionGroup:
text: 'Group1'
ActionButton:
text: 'home'
on_touch_down: app.root.current = 'home'
ActionButton:
text: 'Options'
on_touch_down: app.root.current = 'option'
ActionButton:
text: 'Tutorial'
on_touch_down: app.root.current = 'tut'
Does anyone know why I might be having this issue? I'm fairly new to kivy but I've played around with the slider before and never had these issues until now.

You don't need to load your kv file inside your python code since you already named your kv file as main.kv.
You can try to remove this line:
look = Builder.load_file('main.kv')
and change this line:
return look
to:
pass

Related

Python Kivy Dyanmic Class not defined

I keep getting a Name Error reporting "name TripButton is not defined" although I have a button called TripButton defined in the same .kv file.
#:kivy 1.11.1
<TripButton#Button>:
size_hint: (0.15,0.15)
pos_hint: {'y':0.84}
text:"Test Text"
<MyPopup>:
size_hint: 0.5, 0.5
auto_dismiss: False
title: 'New Trip'
BoxLayout:
orientation: 'vertical'
TextInput:
id: trip_name
multiline: False
BoxLayout:
size_hint_y: None
height: 30
Button:
text: 'Submit'
on_release:
root.parent.parent.add_widget(TripButton(text=trip_name.text, size_hint=(1,0.1)))
root.dismiss()
Button:
text: 'Cancel'
on_release: root.dismiss()
<FirstScreen>:
name: 'first'
FloatLayout:
BoxLayout:
size_hint: (0.95, 0.95)
pos_hint: {'center_x':0.5, 'center_y':0.5}
orientation: "vertical"
canvas.before:
Color:
rgba: (1, 0, 0, 1) # Red color
Rectangle:
pos: self.pos
size: self.size
BoxLayout:
TripButton:
Button:
text: 'Add Trip'
font_size: 12
size_hint: (0.1, 0.1)
pos_hint: {'right':1, 'bottom':1}
on_release: app.open_popup()
pos_hint: {'right':1, 'bottom':1}
on_release: app.open_popup()
I tried declaring the TripButton class above and below the MyPopup class and that didn't work. I compared my code with the kivy documentation for dynamic classes and the from what I can tell I'm matching the syntax. I tried importing the Button class in both the python file and the .kv file and that hasn't worked.
To clarify all of this is in the same .kv file in the same directory as the python file. the app runs until I click the submit button in MyPopup then the program crashes and I get the NameError. This is what I have in my python file.
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.popup import Popup
class FirstScreen(Screen):
pass
class MyPopup(Popup):
pass
class MyApp(App):
def build(self):
sm = ScreenManager()
sm.add_widget(FirstScreen(name='first'))
sm.current = 'first'
return sm
def open_popup(self):
p = MyPopup()
p.open()
def add_button(self):
pass
if __name__ == '__main__':
MyApp().run()
What am I doing wrong? What else I can try? Thanks for your time.
To access classes defined within kv file use kivy.factory.Factory
Add id attribute to your button's BoxLayout, so replace following part of kv file:
BoxLayout:
TripButton:
with
BoxLayout:
id: trip_buttons
TripButton:
then replace:
root.parent.parent.add_widget(TripButton(text=trip_name.text, size_hint=(1,0.1)))
with:
app.root.current_screen.ids.trip_buttons.add_widget(kivy.factory.Factory.TripButton(text=trip_name.text, size_hint=(1,0.1)))
You also duplicated following lines within last button definition on first screen. Replace:
pos_hint: {'right':1, 'bottom':1}
on_release: app.open_popup()
pos_hint: {'right':1, 'bottom':1}
on_release: app.open_popup()
with
pos_hint: {'right':1, 'bottom':1}
on_release: app.open_popup()

How to add an action bar in kivy using screenmanager widget?

I am trying to add an action bar on top in the first screen of my project. I tried using screenmanager widget and sending the action bar as it's children like how to manage/get both of the screens. At first I tried just adding the action bar code in root.widget in the first screen, but they are showing the class for this as an invalid class.
How to add both of them? Also I can't show the buttons from top to bottom even though I added orientation : 'vertical'
import kivy
kivy.require('1.10.1')
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
from kivy.uix.gridlayout import GridLayout
from kivy.uix.screenmanager import ScreenManager,Screen,FadeTransition
class SomeLayout_GridLayout(Screen):
pass
class FirstScreen(Screen):
pass
class SecondScreen(Screen):
pass
class ScreenManager(ScreenManager):
pass
root_widget = Builder.load_string('''
ScreenManager:
FirstScreen:
SecondScreen:
SomeLayout_GridLayout:
<FirstScreen>:
name: 'first'
<SomeLayout_GridLayout>:
cols: 1
rows: 2
row_force_default: True
rows_minimum: {0: ActionBar.height, 1: self.height - ActionBar.height}
SomeMenu_ActionBar:
id: ActionBar
<SomeMenu_ActionBar#ActionBar>:
ActionView:
id: ActionView
ActionGroup:
id: App_ActionGroup
mode: 'spinner'
text: 'App'
ActionButton:
text: 'Settings'
on_press: app.open_settings()
ActionButton:
text: 'Quit'
on_press: app.get_running_app().stop()
ActionGroup:
id: File_ActionGroup
mode: 'spinner'
text: 'File'
ActionButton:
text: 'Open'
ActionButton:
text: 'Save'
<HiddenIcon_ActionPrevious#ActionPrevious>:
title: app.title if app.title is not None else 'Action Previous'
with_previous: False
app_icon: ''
app_icon_width: 0
app_icon_height: 0
size_hint_x: None
width: len(self.title) * 10
<HiddenText_ActionPrevious#ActionPrevious>: #
with_previous: False
on_press: print(self)
title: ''
<Hidden_ActionPrevious#ActionPrevious>:
with_previous: False
on_press: print(self)
title: ''
size_hint: None, None
size: 0, 0
BoxLayout:
orientation: 'horizontal'
BoxLayout:
Button:
text: 'Crime Prediction'
font_size: 30
on_release: app.root.current = 'second'
Button:
text: 'Forum'
font_size: 30
on_release: app.root.current = 'second'
Button:
text: 'Probable Suspect'
font_size: 30
on_release: app.root.current = 'second'
<SecondScreen>:
name: 'second'
BoxLayout:
orientation: 'vertical'
Label:
text: 'Predict Crime Nigga!'
font_size: 50
BoxLayout:`enter code here`
Button:
text: 'Back to Main Menu'
font_size: 30
on_release: app.root.current = 'first'
Button:
text: 'get random colour screen'
font_size: 30
on_release: app.root.current = 'first'
''')
class ScreenManagerApp(App):
def build(self):
return root_widget
ScreenManagerApp().run()
Kivy App with ActionBar & ScreenManager
Declare a root widget with inheritance of BoxLayout
Add ActionBar as child of root widget
Add ScreenManager as child of root widget, and with id: sm
Snippets
BoxLayout:
orientation: 'vertical'
ActionBar:
...
ScreenManager:
id: sm
FirstScreen:
SecondScreen:
Example
main.py
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
class WelcomeScreen(Screen):
pass
class FirstScreen(Screen):
pass
class SecondScreen(Screen):
pass
class ScreenManager(ScreenManager):
pass
class CrimePrevention(BoxLayout):
pass
Builder.load_file("main.kv")
class TestApp(App):
title = 'Kivy ScreenManager & ActionBar Demo'
def build(self):
return CrimePrevention()
if __name__ == '__main__':
TestApp().run()
main.kv
#:kivy 1.11.0
#:import sp kivy.metrics.sp
#:import dp kivy.metrics.dp
<CrimePrevention>:
orientation: 'vertical'
canvas.before:
Color:
rgb: .6, .6, .6
Rectangle:
pos: self.pos
size: self.size
# source: 'data/background.png'
SomeMenu_ActionBar:
id: ActionBar
ScreenManager:
id: sm
WelcomeScreen:
FirstScreen:
SecondScreen:
<SomeMenu_ActionBar#ActionBar>:
ActionView:
id: ActionView
HiddenIcon_ActionPrevious:
ActionGroup:
id: App_ActionGroup
mode: 'spinner'
text: 'Jump to Screen'
ActionButton:
text: 'Crime Prediction'
on_release: app.root.ids.sm.current = 'second'
ActionButton:
text: 'Forum'
on_release: app.root.ids.sm.current = 'second'
ActionButton:
text: 'Probable Suspect'
on_release: app.root.ids.sm.current = 'second'
ActionGroup:
id: App_ActionGroup
mode: 'spinner'
text: 'App'
ActionButton:
text: 'Settings'
on_press: app.open_settings()
ActionButton:
text: 'Quit'
on_press: app.get_running_app().stop()
ActionGroup:
id: File_ActionGroup
mode: 'spinner'
text: 'File'
ActionButton:
text: 'Open'
ActionButton:
text: 'Save'
<HiddenIcon_ActionPrevious#ActionPrevious>:
title: '' # app.title if app.title is not None else 'Action Previous'
with_previous: False
app_icon: ''
app_icon_width: 0
app_icon_height: 0
size_hint_x: None
width: len(self.title) * 10
<WelcomeScreen>:
name: 'welcome'
Label:
text: 'Welcome Screen'
font_size: sp(50)
<FirstScreen>:
name: 'first'
Label:
text: 'First Screen'
<SecondScreen>:
name: 'second'
BoxLayout:
orientation: 'vertical'
Label:
text: 'Predict Crime'
font_size: 50
BoxLayout:
Button:
text: 'Back to Main Menu'
font_size: 30
on_release: app.root.ids.sm.current = 'first'
Button:
text: 'get random colour screen'
font_size: 30
on_release: app.root.ids.sm.current = 'first'
Output

No Screen with name

All my program works up-to a point and I'm road blocked by it.
My program loads some starter screens in the main app.
Based on user input the program loads a completely different sub app.
Problem occurs when trying to change screens in the loaded sub app
Here is the code where the problem exists:
The .py file:
import kivy
kivy.require('1.10.0')
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager, FadeTransition
from kivy.uix.button import Button
from kivy.uix.label import Label
chClass = ""
class ScreenManage(ScreenManager):
pass
class Home(ScreenManager):
pass
class TitleScreen(Screen):
pass
class GameScreen(Screen):
pass
class ClassScreen(Screen):
pass
class Warrior1(Screen):
def GetChClass(self, ch):
return ch
def build(self):
ExecuteW().run()
class Acrobat1(Screen):
def GetChClass(self, ch):
return ch
class Spell1(Screen):
def GetChClass(self, ch):
return ch
class HomeScreen(Screen):
pass
class WarriorStats(Screen):
pass
class AcrobatStats(Screen):
pass
class SpellCasterStats(Screen):
pass
class ExecuteW(App):
def build(self):
return Home()
class RevengeApp(App):
def build(self):
return ScreenManage()
if __name__ == '__main__':
print chClass
RevengeApp().run()
revenge.kv:
#: import sm kivy.uix.screenmanager
#: import Factory kivy.factory.Factory
#: import builder kivy.lang.Builder
<ScreenManage>
transition: sm.FadeTransition()
TitleScreen:
ClassScreen:
GameScreen:
Warrior1:
Acrobat1:
Spell1:
WarriorStats:
<TitleScreen>
on_touch_down: app.root.current = 'Game'
canvas:
Rectangle:
size: self.size
pos: self.pos
source: 'KnightArmor.jpg'
BoxLayout:
orientation: 'vertical'
Label:
font_size: '30sp'
color: 1,0,0,1
text: "Warrior's Revenge"
Label:
color: 1,0,0,1
text: "Click to Continue:"
<GameScreen>
name: 'Game'
canvas:
Rectangle:
size: self.size
pos: self.pos
source: 'KnightArmor.jpg'
BoxLayout:
Button:
size_hint: .5,.1
text: "New Game"
on_release: app.root.current = 'Class'
Button:
size_hint: .5,.1
text: "Load Game"
<ClassScreen>
name: 'Class'
BoxLayout:
orientation: 'vertical'
Label:
text: "Choose Your Path"
Button:
text: "Warrior"
on_release: app.root.current = "Warrior1"
Button:
text: "Acrobat"
on_release: app.root.current = "Acrobat1"
Button:
text: "Spell Caster"
on_release: app.root.current = "Spell1"
<Warrior1>
name: "Warrior1"
canvas:
Rectangle:
size: self.size
pos: self.pos
source: "Warrior.jpg"
BoxLayout:
orientation: 'vertical'
Label:
font_size: "20sp"
text: "Warrior's are physically strong"
color: 0,.5,1,1
Label:
font_size: "20sp"
text: "experts in hand to hand combat,"
color: 0,.5,1,1
Label:
font_size: "20sp"
text: "and knowledgeable in the ways of"
color: 0,.5,1,1
Label:
font_size: "20sp"
text: "arms and armor"
color: 0,.5,1,1
BoxLayout:
orientation: 'horizontal'
Button:
text: "Cancel"
on_release: app.root.current = "Class"
Button:
name: "warrior_confirm"
text: "Confirm"
on_release: chClass = root.GetChClass('Warrior')
on_release: root.build()
executew.kv:
#: import sm kivy.uix.screenmanager
<Home>:
transition: sm.FadeTransition()
HomeScreen:
WarriorStats:
<HomeScreen>
name: 'Home'
AnchorLayout:
Button:
text: "Stats"
on_release: app.root.current = 'WStats'
<WarriorStats>
name: 'WStats'
canvas:
Rectangle:
size: self.size
pos: self.pos
source: "Warrior.jpg"
The problem:
When clicking the stats button on the home screen in executew the WarriorStats screen named 'WStats' should be loaded, but I get the error "no screen with name 'WStats'"
Answer that I figured out on my own
class HomeScreen(Screen):
def switch(self):
self.manager.current = "WStats"
And in executew:
<HomeScreen>
Button:
text: "Stats"
on_release: root.switch()

Python - Kivy - Screen Manager - Changing a Button Text with Text Input issue

I'm currently working with Kivy for GUI Design I was looking for a way to change a button text with a TextInput from another screen.
My Screen 1 has a button that will work as a "label", there I have another button to go to screen 2.
Screen 2 is a Keypad with a Textinput on it, there I put the numbers that I want to set in the button "label" from screen 1.
With a button called "ENTER" I want to go back to the screen 1 and update the new text in the button "label". But I can't figure out how to do it properly.
Here is a little piece of the project code main.py :
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.graphics import Line
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
class Main_Screen(Screen):
pass
class Input_Number_Inch_Screen(Screen):
pass
class Input_Screen(Screen):
pass
class Screen_Management(ScreenManager):
pass
presentation = Builder.load_file("screen3.kv")
class Screen3App(App):
def build(self):
return presentation
Screen3App().run()
the screen3.kv file:
Screen_Management:
id: screen_management
transition: FadeTransition()
Main_Screen:
id: main_screen
name: "main_screen_name"
manager: screen_management
Input_Screen:
id: tire_setup_screen_id
name: "tire_setup_screen_name"
manager: screen_management
Input_Number_Inch_Screen:
name: "inch_screen"
manager: screen_management
<Main_Screen>:
canvas:
Color:
rgb: [.30, .30, .30]
Rectangle:
pos: self.pos
size: self.size
Button:
background_color: .52, .52, .52, 1
bold: 1
color: .0078,.67,.69,1
size_hint: .2, 1
pos_hint: {"x": 0, "center_y": .5}
on_release: app.root.current = "tire_setup_screen_name"
text: " INPUTS "
font_size: 30
# Screen 1: Input Screen
<Input_Screen>:
canvas:
Color:
rgb: [.30, .30, .30]
Rectangle:
pos: self.pos
size: self.size
GridLayout:
cols: 2
pos: (160,150)
size_hint: (.8, .8)
Button:
background_color: .52, .52, .52, 1
bold: 1
color: .0078,.67,.69,1
font_size: 30
text: "INPUT\n(Inch)"
size_hint_x: None
width: 150
on_release: app.root.current = "inch_screen"
# This button will go to the screen2
Button:
id: inch_input
background_color: .52, .52, .52, 1
bold: 1
color: .0078,.67,.69,1
font_size: 100
text: "THIS IS THE TEXT THAT I WANT TO UPDATE"
# Screen 2: Input Inch Screen Data
<Input_Number_Inch_Screen>:
canvas:
Color:
rgb: [.30, .30, .30]
Rectangle:
pos: self.pos
size: self.size
GridLayout:
orientation: 'vertical'
display: entry
rows: 6
padding: 10
spacing: 10
# This is the TextInput
BoxLayout:
TextInput:
id: entry
font_size: 75
multiline: False
# This will be the button that would go back to the screen and update
# the button text with the new text entered in the TextInput
BoxLayout:
spacing: 10
Button:
background_color: .52, .52, .52, 1
bold: 1
color: .0078,.67,.69,1
font_size: 40
text:"ENTER"
on_release: app.root.current = "tire_setup_screen_name"
on_press: app.root.inch_input.text = entry.text
Any comment to help it would be great, thanks for your time.
Please replace the following in screen3.kv:
on_press: app.root.inch_input.text = entry.text
with:
on_press: root.manager.ids.tire_setup_screen_id.ids.inch_input.text = entry.text
Example
main.py
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.graphics import Line
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
class Main_Screen(Screen):
pass
class Input_Number_Inch_Screen(Screen):
pass
class Input_Screen(Screen):
pass
class Screen_Management(ScreenManager):
pass
presentation = Builder.load_file("screen3.kv")
class Screen3App(App):
def build(self):
return presentation
if __name__ == "__main__":
Screen3App().run()
screen3.kv
#:kivy 1.10.0
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
Screen_Management:
id: screen_management
transition: FadeTransition()
Main_Screen:
id: main_screen
name: "main_screen_name"
manager: screen_management
Input_Screen:
id: tire_setup_screen_id
name: "tire_setup_screen_name"
manager: screen_management
Input_Number_Inch_Screen:
name: "inch_screen"
manager: screen_management
<Main_Screen>:
canvas:
Color:
rgb: [.30, .30, .30]
Rectangle:
pos: self.pos
size: self.size
Button:
background_color: .52, .52, .52, 1
bold: 1
color: .0078,.67,.69,1
size_hint: .2, 1
pos_hint: {"x": 0, "center_y": .5}
on_release: root.manager.current = "tire_setup_screen_name"
text: " INPUTS "
font_size: 30
# Screen 1: Input Screen
<Input_Screen>:
canvas:
Color:
rgb: [.30, .30, .30]
Rectangle:
pos: self.pos
size: self.size
GridLayout:
cols: 2
pos: (160,150)
size_hint: (.8, .8)
Button:
background_color: .52, .52, .52, 1
bold: 1
color: .0078,.67,.69,1
font_size: 30
text: "INPUT\n(Inch)"
size_hint_x: None
width: 150
on_release: root.manager.current = "inch_screen"
# This button will go to the screen2
Button:
id: inch_input
background_color: .52, .52, .52, 1
bold: 1
color: .0078,.67,.69,1
font_size: 100
text: "THIS IS THE TEXT THAT I WANT TO UPDATE"
# Screen 2: Input Inch Screen Data
<Input_Number_Inch_Screen>:
canvas:
Color:
rgb: [.30, .30, .30]
Rectangle:
pos: self.pos
size: self.size
GridLayout:
orientation: 'vertical'
display: entry
rows: 6
padding: 10
spacing: 10
# This is the TextInput
BoxLayout:
TextInput:
id: entry
font_size: 75
multiline: False
# This will be the button that would go back to the screen and update
# the button text with the new text entered in the TextInput
BoxLayout:
spacing: 10
Button:
background_color: .52, .52, .52, 1
bold: 1
color: .0078,.67,.69,1
font_size: 40
text:"ENTER"
on_release: root.manager.current = "tire_setup_screen_name"
on_press: root.manager.ids.tire_setup_screen_id.ids.inch_input.text = entry.text
Outpu

Kivy Using a ScreenManager from kv file

I'm writing a kivy program/game. I've made one before, but was only 1 screen in total. I've started developing a new program with ideas of implementing a Screen Manager. I managed to build the Screen Manager inside of the python file, but it wasn't suitable for my long term usage, and I wanted to try my hand at a Screen Manager from the .kv file.
Any guidance will be greatly appreciated, not sure what I missed. I looked at this questionv(Kivy - Screen Manager - Accessing attribute in other class), and pieced together what I thought was right, but still can't get a screen to load - I feel this is a simple answer and I'm being blind...
main.py;
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
class MenuScreen(Screen):
pass
class NewGameScreen(Screen):
pass
class LoadGameScreen(Screen):
pass
class ASCIILifeApp(App):
pass
if __name__ == "__main__":
ASCIILifeApp().run()
ASCIILife.kv;
#: kivy 1.9
#: import ScreenManager kivy.uix.screenmanager.ScreenManager
#: import Screen kivy.uix.screenmanager.ScreenManager
#: import NewGameScreen screen
#: import LoadGameScreen screen
ScreenManager:
id: screen_manager
#transition: FadeTransition()
MenuScreen:
id: menu_screen
name: 'MenuScreen'
manager: 'screen_manager'
NewGameScreen:
id: newgame_screen
name: 'NewGameScreen'
manager: 'screen_manager'
LoadGameScreen:
id: loadgame_screen
name: 'LoadGameScreen'
manager: 'screen_manager'
<MenuScreen>:
BoxLayout:
orientation: 'vertical'
Label:
text: 'ASCII Life'
font_size: 50
Button:
text: 'New Game'
font_size: 30
on_release: app.root.current = 'newgame'
Button:
text: 'Load Game'
font_size: 30
on_release: app.root.current = 'loadgame'
Button:
text: 'Settings'
font_size: 30
on_release: app.root.current = 'something'
<NewGameScreen>:
BoxLayout:
orientation: 'vertical'
BoxLayout:
orientation: 'vertical'
Label:
text: 'Game Length in Days'
font_size: 30
BoxLayout:
orientation: 'horizontal'
ToggleButton:
text: '100'
state: 'down'
group: 'newgame_days'
font_size: 30
ToggleButton:
text: '200'
group: 'newgame_days'
font_size: 30
BoxLayout:
orientation: 'horizontal'
ToggleButton:
text: '365'
group: 'newgame_days'
font_size: 30
ToggleButton:
text: '3650'
group: 'newgame_days'
font_size: 30
ToggleButton:
text: 'Unlimited'
group: 'newgame_days'
font_size: 30
BoxLayout:
orientation: 'vertical'
size_hint: (1, .5)
Label:
text: 'Difficulty (Score Multiplier)'
font_size: 30
BoxLayout:
orientation: 'horizontal'
ToggleButton:
text: 'Easy (x1)'
state: 'down'
group: 'newgame_difficulty'
font_size: 30
ToggleButton:
text: 'Medium (x2.5)'
group: 'newgame_difficulty'
font_size: 30
ToggleButton:
text: 'Hard (x5)'
group: 'newgame_difficulty'
font_size: 30
<LoadGameScreen>:
BoxLayout:
orientation: 'vertical'
Label:
text: 'load a game'
font_size: 30
Widget:
canvas:
Ellipse:
pos: self.pos
size: self.size
BoxLayout:
Button:
text: 'Menu'
font_size: 30
on_release: app.root.current = 'menu'
Button:
text: 'text'
font_size: 30
Edit: Truncated kv file
The answer was using a builder to build the kv file. Knew it was something simple. File below;
main.py
#!/usr/bin/kivy
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.properties import ObjectProperty
class MenuScreen(Screen):
pass
class NewGameScreen(Screen):
pass
class LoadGameScreen(Screen):
pass
class ScreenManager(ScreenManager):
pass
buildKV = Builder.load_file("ASCIILife.kv")
class ASCIILifeApp(App):
def build(self):
return buildKV
if __name__ == "__main__":
ASCIILifeApp().run()
To elaborate on Chazara's findings:
Either rename the kv code file according to the naming convension:
Kivy looks for a Kv file with the same name as your App class in
lowercase, minus “App” if it ends with ‘App’.
From the documentation:how to load kv language
Or just make it explicit with the builder function:
Builder.load_file('path/to/file.kv')
To elaborate on Chazara's findings even more:
i tested the code from Chazara with kivy 1.10.1dev0 and Python 3.6; i got an error saying:
kivy.uix.screenmanager.ScreenManagerException: No Screen with name "something".
to fix it, i changed in the .kv file
[...]
Button:
text: 'New Game'
font_size: 30
on_release: app.root.current = 'newgame'
[...]
to:
[...]
Button:
text: 'New Game'
font_size: 30
on_release: app.root.current = 'NewGameScreen'
[...]
it references the name of NewGameScreen given in the ScreenManager
ScreenManager:
[...]
NewGameScreen:
id: newgame_screen
*name: 'NewGameScreen'*
manager: 'screen_manager'

Categories