Call methods/functions from a kivy button (on_release)

Question:

I am just starting to write this program but have already ran into problems (I don’t really know what I did, just coppied it from somewhere and tweaked it a little bit). So basically I want that if a button is pressed, the on_release: function in the my.kv file sould call sth. like root.button_input(text) and pass the button’s text. (bc I will have many buttons, so its easier if they pass their texts than their ids)

So the main.py file:

import kivy
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.layout import Layout
from kivy.properties import ObjectProperty
from kivy.lang import Builder
from kivy.core.text import LabelBase
from kivy.uix.screenmanager import ScreenManager, Screen

from kivy.config import Config
Config.set('graphics', 'width', '180')
Config.set('graphics', 'height', '380')
# Config.set('graphics', 'fullscreen', 0)
Config.write()

LabelBase.register(name='JBR', fn_regular='fonts/JetBrainsMono-Regular.ttf')

button_input_text = ""

class MainWindow(Screen):

    def button_input(self, inp):
        print(inp)


class WindowManager(ScreenManager):
    pass


Builder.load_file('my.kv')
sm = WindowManager()
screens = [MainWindow(name="main")]
for screen in screens:
    sm.add_widget(screen)


class MyMainApp(App):
    def build(self):
        return sm


if __name__ == "__main__":
    MyMainApp().run()

and the my.kv file:

<GreyButton@FloatLayout>:
    id: float_root
    size_hint: (None, None)
    text: ""
    bg_color: (0.2, 0.2, 0.2, 1)
    btn_size: (40,40)
    size: (40,40)
    pos_hint: {"x": 0.5, "y": 0.5}
    on_release:
        MyMainApp.button_input(self.text)
    Button:
        text: float_root.text
        font_name: "JBR"
        font_size: 19
        size_hint: (None, None)
        size: float_root.btn_size
        pos_hint: {"x": 0.25, "y": 0.25}
        background_normal: ""
        background_color: (0,0,0,0)
        canvas.before:
            Color:
                rgba: float_root.bg_color
            Ellipse:
                size: self.size
                pos: self.pos
        on_press:
            float_root.bg_color = (0.25, 0.25, 0.25, 1)
        on_release:
            float_root.bg_color = (0.2, 0.2, 0.2, 1)


WindowManager:
    MainWindow:

<MainWindow>:
    name: "main"

    FloatLayout:
        size: root.width, root.height

        GreyButton:
            text: "="
            pos_hint: {"right":0.9, "y":0}

So my question is: HOW do I do this, and most importantly, WHERE in the code? Thanks in advance.

Asked By: cozycoder

||

Answers:

After researching for some days I have found what I think is the best solution to my problem.

So. First I got rid of the screenmanager, just do troubleshoot better, but I realized, I wouldn’t need it anyway.

Next I discovered that i do not really neet the @Floatlayout in the .kv file, when I create a class in the .py file like so:

class GreenButton(Floatlayout):
    def pressed(self):
        MainWindow.input()

I called the pressed() in the on_release event, where I also change the color.
Next, I linked the green and grey button, so when they are pressed, they both call the same function input() in the Mainwindow(Floatlayout).

I found that with self., I always refer to the one button pressed, and could not change the text of a Label in the FloatLayout.

This now works:

App.get_running_app().root.ids.calc_label.text = self.text

And I gave all my individual buttons ids. These are: "1", "2", "3" etc.
Now I can change every button with a premade dict containing a list of the now-state and the next-state (index 0 and 1):

for i in range(28):
    App.get_running_app().root.ids[str(i + 1)].text = change_dict[str(i + 1)][1]

This solved all my problems.

Answered By: cozycoder
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.