---
# System prepended metadata

title: Guide miniräknare i Kivy

---

# Guide miniräknare i Kivy

Vi ska bygga en miniräknar-app med hjälp av kivy och python. Appen ska bestå av två fält där man kan skriva in siffror, fyra knapper: en för varje räknesätt och en plats där resultatet skrivs ut. När man har skrivit in två siffror och trycker på en knapp ska rätt operation utföras och resultatet skrivas ut.

### Template kod

Vi utgår från template-koden för en kivy-app, och namn:
```python
from kivy.app import App
class Calculator(App):
    def build(self):
        #Här skapar vi alla widgets

Calculator().run()    
```

### Layout

Vi behöver följande kivy widgets för varje del av vår miniräknare:

* 2 st sifferfält --> TextInput
* 4 st knappar --> Button
* resultattext --> Label

Om vi använder oss av en BoxLayout för att lägga allt eftervarandra kan build-funktionen se ut så här:

```python
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.textinput import TextInput
from kivy.uix.label import Label
from kivy.uix.button import Button

class Calculator(App):
    def build(self):
        # Tre rutor i början: två inputs, en label
        layoutWidget = BoxLayout(orientation="vertical")
        
        textInputA = TextInput()
        textInputB = TextInput()

        layoutWidget.add_widget(textInputA)
        layoutWidget.add_widget(textInputB)

        addButton = Button(text="+")
        layoutWidget.add_widget(addButton)
        
        minusButton = Button(text="-")
        layoutWidget.add_widget(minusButton)
        
        multiplicationButton = Button(text="*")
        layoutWidget.add_widget(multiplicationButton)
        
        divisionButton = Button(text="/")
        layoutWidget.add_widget(divisionButton)
        
        resultLabel = Label()
        layoutWidget.add_widget(resultLabel)

        return layoutWidget
    

Calculator().run()
```


Vi kan snygga till det genom att lägga knapparna på samma *horisontella* rad.
För att göra det skapar vi en till BoxLayout för knapparna, och vi lägger den BoxLayouten i den vertikala BoxLayouten.

```python
...

#Skapa en ny layout för knapparna
buttonLayout = BoxLayout(orientation="horizontal")

addButton = Button(text="+")
buttonLayout.add_widget(addButton)

minusButton = Button(text="-")
buttonLayout.add_widget(minusButton)

multiplicationButton = Button(text="*")
buttonLayout.add_widget(multiplicationButton)

divisionButton = Button(text="/")
buttonLayout.add_widget(divisionButton)

#Lägg till knapp-layouten i den yttre layouten
layoutWidget.add(buttonLayout)
    
...

```

### Knapp-funktioner

För varje knapp vill vi nu lägga till funktioner som utför beräkningarna. Vi kan lägga till en funktion till en knapp med två steg.

1. Skapa funktionen inuti klassen
2. Anropa bind-funktionen på knappen

Till exempel, för plus-knappen kan vi skapa en funktion *add*. Obs! Den behöver ha två parameterar: `self` och `btn`

```python
# I Calculator-klassen
def add(self, btn):
    #Här skriver vi kod som körs när vi trycker på knappen
```

Vi lägger till funktionen genom att anropa `bind` med argumentet `on_press=self.add`

```
# I build funktionen:
...
    addButton = Button(text="+")
    layoutWidget.add_widget(addButton)
    addButton.bind(on_press=self.add)
...
```

Vi vill upprepa samma procedur för alla fyra knappar, med olika funktioner som heter relevanta saker.

### Skriva koden för räkneoperationer

Nu vill vi se till att `add`-funktionen samt de andra funktionerna inte är tomma.

För varje funktion vill vi: 

1. Läsa siffran i textInputA
2. Läsa siffran i textInputB
3. Uföra räknesättet med siffrorna
4. Ändra texten på resultat-label

För att göra detta måste vi ha tillgång till `textInputA`, `textInputB` och `resultLabel` som finns i build funktionen. Detta löser vi genom att lägga till `self.` framför variabelnamnen.

```python
self.textInputA = TextInput()
self.textInputB = TextInput()

layoutWidget.add_widget(self.textInputA)
layoutWidget.add_widget(self.textInputB)
...

self.resultLabel = Label()
layoutWidget.add_widget(self.resultLabel)
```

Då kan vi komma åt variabelerna i `add`. Vi kommer åt texten i en widget med `.text` och vi kan göra om det till en siffra med `int()`.

```python
def add(self, btn):
    numA = int(self.textInputA.text)
    numB = int(self.textInputB.text)
    
    resultValue = numA + numB
    self.resultLabel.text = str(resultValue)
```

Efter att vi har plockat ut värdena i TextInput A och B kan vi lägga ihop dem, och sätta resultLabelns text till resultatet. Här gör vi om värdet till en string igen med `str()`.

Nu behöver vi endast skapa de andra funktionerna på samma sätt, men med andra räknesätt!

