Reputation: 33
I'm fairly new to Kivy ( been learning it two days ago) I was working on a basic calculator but came across a hurdle I couldn't jump over.
I would like to create multiple screens because I intend to add more to my calculator as I'm further learning Kivy & I don't know how to adjust ScreenManager in my code.
This is my .py file
import kivy
kivy.require('1.11.0')
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.pagelayout import PageLayout
from kivy.core.window import Window
Window.clearcolor = .3,.3,.3,1
class RootWidget(GridLayout):
def calculate(self, calculation):
if calculation:
try:
self.display.text = str(eval(calculation))
except Exception:
self.display.text = "Error"
class kutuApp(App):
def build(self):
return RootWidget()
if __name__== '__main__':
kutuApp().run()
And this is my .kv file
<CustButton@Button>:
font_size: 35
background_color: 0,0,0,0
canvas.before:
Color:
rgba: (.4, .4, .4, 1) if self.state=='normal' else (0,.7,.7,1)
RoundedRectangle:
pos: self.pos
size: self.size
radius: [20, ]
<RawLayout@BoxLayout>:
spacing: 8
padding: 8
size_hint: [1, .2]
<RootWidget>:
id: calculator
rows: 10
display: entry
spacing: 1
BoxLayout:
size_hint: [1, .1]
Label:
text: 'Basic Calculator'
Label:
text: 'Made by Xrew'
BoxLayout:
padding: 10
TextInput:
id: entry
spacing: 1
padding: 5
font_size: 32
multiline: True
focus: False
# background_color: 0, 0, 0, 1
# foreground_color: [1, 0, 1, 1]
RawLayout:
CustButton:
text: '<'
on_press: entry.text += self.text
CustButton:
text: '>'
on_press: entry.text += self.text
CustButton:
text: '≈'
on_press: entry.text += '=='
RawLayout:
orientation: 'horizontal'
CustButton:
text: '('
on_press: entry.text += '('
CustButton:
text: ')'
on_press: entry.text += ')'
CustButton:
text: '√'
on_press: entry.text += '**(.5)'
CustButton:
text: '¹/x'
on_press: entry.text += '1/'
RawLayout:
orientation: 'horizontal'
CustButton:
text: 'Del'
on_press: entry.text = entry.text[:-1]
CustButton:
text: 'x²'
on_press: entry.text += '**2'
CustButton:
text: 'xⁿ'
on_press: entry.text += '**'
CustButton:
text: 'π'
on_press: entry.text += '3.14'
RawLayout:
orientation: 'horizontal'
cols: 4
CustButton:
text: 'Clr'
font_color: [255,0,0,1]
# background_normal: ' '
# background_color: 1, .3, .4, .85
on_press: entry.text = ""
CustButton:
text: '+'
on_press: entry.text += self.text
font_size: 32
CustButton:
text: '÷'
on_press: entry.text += '/'
CustButton:
text: '×'
on_press: entry.text += '*'
RawLayout:
rows: 1
orientation: 'horizontal'
CustButton:
text: '7'
on_press: entry.text += self.text
CustButton:
text: '8'
on_press: entry.text += self.text
CustButton:
text: '9'
on_press: entry.text += self.text
CustButton:
text: '-'
on_press: entry.text += self.text
RawLayout:
orientation: 'horizontal'
rows: 1
CustButton:
text: '4'
on_press: entry.text += self.text
CustButton:
text: '5'
on_press: entry.text += self.text
CustButton:
text: '6'
on_press: entry.text += self.text
CustButton:
text: '+'
on_press: entry.text += self.text
RawLayout:
orientation: 'horizontal'
cols: 3
CustButton:
text: '1'
size_hint: [.5, 1]
on_press: entry.text += self.text
CustButton:
text: '2'
size_hint: [.5, 1]
on_press: entry.text += self.text
CustButton:
text: '3'
size_hint: [.5, 1]
on_press: entry.text += self.text
CustButton:
text: ' '
size_hint: [.5, 1]
background_normal: ' '
background_color: 0, 0, 0, 0
RawLayout:
orientation: 'horizontal'
size_hint: [1, .2]
CustButton:
text: '0'
on_press: entry.text += self.text
size_hint: [.34, 1]
CustButton:
text: '.'
on_press: entry.text += self.text
size_hint: [.17, 1]
font_size: 32
CustButton:
text: '='
on_press: calculator.calculate(entry.text)
size_hint: [.17, 2.4]
# background_normal: ' '
# background_color: 0, .5, 95, 1
Upvotes: 3
Views: 5863
Reputation: 16041
The following steps illustrates how to expand a Kivy App with ScreenManager, Screen, and Button widgets, and one of Button
's events (on_release
, on_press
).
from kivy.uix.screenmanager import ScreenManager, Screen
class ScreenManagement(ScreenManager):
class MenuScreen(Screen):
and class CalculatorScreen(Screen):
pass
as body of the three new classes because we are going to use kv language to design their views / presentation.return RootWidget()
with return ScreenManagement()
because now the root of the App is a Kivy ScreenManagerclass RootWidget
to class Calculator
from kivy.uix.screenmanager import ScreenManager, Screen
...
class Calculator(GridLayout):
...
class MenuScreen(Screen):
pass
class CalculatorScreen(Screen):
pass
class ScreenManagement(ScreenManager):
pass
class kutuApp(App):
def build(self):
return ScreenManagement()
<MenuScreen>:
, <CalculatorScreen>:
<ScreenManagement>:
which corresponds to class MenuScreen(Screen):
, class CalculatorScreen(Screen):
, and class ScreenManagement(ScreenManager):
respectively in Python scriptRootWidget
to Calculator
Calculator:
as child of class rule, <CalculatorScreen>:
MenuScreen:
and CalculatorScreen:
as children of class rule, <ScreenManagement>:
MenuScreen:
and CalculatorScreen:
as name: 'menu'
and name: 'calculator'
respectively. This will enable us to reference them when switching screen.<ScreenManagement>:
MenuScreen:
name: 'menu'
CalculatorScreen:
name: 'calculator'
<MenuScreen>:
BoxLayout:
Button:
text: 'Goto Calculator'
on_press: root.manager.current = 'calculator'
Button:
text: 'Quit'
<CalculatorScreen>:
Calculator:
...
<Calculator>:
id: calculator
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.core.window import Window
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
Window.clearcolor = .3, .3, .3, 1
class Calculator(GridLayout):
def calculate(self, calculation):
if calculation:
try:
self.display.text = str(eval(calculation))
except Exception:
self.display.text = "Error"
class MenuScreen(Screen):
pass
class CalculatorScreen(Screen):
pass
class ScreenManagement(ScreenManager):
pass
Builder.load_file("main.kv")
class kutuApp(App):
def build(self):
return ScreenManagement()
if __name__ == '__main__':
kutuApp().run()
<ScreenManagement>:
MenuScreen:
name: 'menu'
CalculatorScreen:
name: 'calculator'
<MenuScreen>:
BoxLayout:
Button:
text: 'Goto Calculator'
on_press: root.manager.current = 'calculator'
Button:
text: 'Quit'
<CalculatorScreen>:
Calculator:
<CustButton@Button>:
font_size: 35
background_color: 0,0,0,0
canvas.before:
Color:
rgba: (.4, .4, .4, 1) if self.state=='normal' else (0,.7,.7,1)
RoundedRectangle:
pos: self.pos
size: self.size
radius: [20, ]
<RawLayout@BoxLayout>:
spacing: 8
padding: 8
size_hint: [1, .2]
<Calculator>:
id: calculator
rows: 10
display: entry
spacing: 1
BoxLayout:
size_hint: [1, .1]
Label:
text: 'Basic Calculator'
Label:
text: 'Made by Xrew'
BoxLayout:
padding: 10
TextInput:
id: entry
spacing: 1
padding: 5
font_size: 32
multiline: True
focus: False
# background_color: 0, 0, 0, 1
# foreground_color: [1, 0, 1, 1]
RawLayout:
CustButton:
text: '<'
on_press: entry.text += self.text
CustButton:
text: '>'
on_press: entry.text += self.text
CustButton:
text: '≈'
on_press: entry.text += '=='
RawLayout:
orientation: 'horizontal'
CustButton:
text: '('
on_press: entry.text += '('
CustButton:
text: ')'
on_press: entry.text += ')'
CustButton:
text: '√'
on_press: entry.text += '**(.5)'
CustButton:
text: '¹/x'
on_press: entry.text += '1/'
RawLayout:
orientation: 'horizontal'
CustButton:
text: 'Del'
on_press: entry.text = entry.text[:-1]
CustButton:
text: 'x²'
on_press: entry.text += '**2'
CustButton:
text: 'xⁿ'
on_press: entry.text += '**'
CustButton:
text: 'π'
on_press: entry.text += '3.14'
RawLayout:
orientation: 'horizontal'
cols: 4
CustButton:
text: 'Clr'
font_color: [255,0,0,1]
# background_normal: ' '
# background_color: 1, .3, .4, .85
on_press: entry.text = ""
CustButton:
text: '+'
on_press: entry.text += self.text
font_size: 32
CustButton:
text: '÷'
on_press: entry.text += '/'
CustButton:
text: '×'
on_press: entry.text += '*'
RawLayout:
rows: 1
orientation: 'horizontal'
CustButton:
text: '7'
on_press: entry.text += self.text
CustButton:
text: '8'
on_press: entry.text += self.text
CustButton:
text: '9'
on_press: entry.text += self.text
CustButton:
text: '-'
on_press: entry.text += self.text
RawLayout:
orientation: 'horizontal'
rows: 1
CustButton:
text: '4'
on_press: entry.text += self.text
CustButton:
text: '5'
on_press: entry.text += self.text
CustButton:
text: '6'
on_press: entry.text += self.text
CustButton:
text: '+'
on_press: entry.text += self.text
RawLayout:
orientation: 'horizontal'
cols: 3
CustButton:
text: '1'
size_hint: [.5, 1]
on_press: entry.text += self.text
CustButton:
text: '2'
size_hint: [.5, 1]
on_press: entry.text += self.text
CustButton:
text: '3'
size_hint: [.5, 1]
on_press: entry.text += self.text
CustButton:
text: ' '
size_hint: [.5, 1]
background_normal: ' '
background_color: 0, 0, 0, 0
RawLayout:
orientation: 'horizontal'
size_hint: [1, .2]
CustButton:
text: '0'
on_press: entry.text += self.text
size_hint: [.34, 1]
CustButton:
text: '.'
on_press: entry.text += self.text
size_hint: [.17, 1]
font_size: 32
CustButton:
text: '='
on_press: calculator.calculate(entry.text)
size_hint: [.17, 2.4]
# background_normal: ' '
# background_color: 0, .5, 95, 1
Upvotes: 9