Search code examples
pythonkivy

How to change variables value depending on the function in Kivy


I am coding a quiz program. I want to make that every time the user clicks on the button called "GO", the picture that is the question - changes. At the same time, the answer options should be changed accordingly. I mean that the text of the buttons should change every time user clicks on the "GO" button. In the future, I plan to use a random selection from the list, but at the moment I just need to understand how to modify the text of the buttons and the image based on pressing the "GO" button. I coded a program but it doesn't work. I am using Kivy/Python. The code is provided below. I removed all unnecessary parts of the code to make it minimal reproducable. You can also look at the comments inside the code, where I pointed out important components and key problems. Most likely I'm doing something wrong, since my function does not modify the data that needs to be changed in any way. I have detailed everything in the comments below. Please help me solve this issue.

from kivy.uix.label import Label
from kivy.uix.image import Image
from kivy.uix.button import Button
from kivy.core.window import Window
from kivy.uix.screenmanager import Screen
from kivy.core.audio import SoundLoader
from kivy.config import Config

Config.set('input', 'mouse', 'mouse,multitouch_on_demand')


class Quiz(Screen):
    def __init__(self, **kwargs):
        super(Quiz, self).__init__(**kwargs)
        Window.size = (900, 600)
        self.cols = 1

        self.im = Image(source="picture1.png") # Here I am adding the first picture only as an example, but after the clicking "GO" button the picture should changed depending on function which is described in the bottom of the code. 
        self.im.size_hint = (0.50, 0.50)
        self.im.pos_hint = {"center_x": 0.5, "center_y": 0.80}
        self.add_widget(self.im)

        self.app_text = Label(font_size='16',
                      text="Find correct answer!",
                      color='white',
                      halign='center')
        self.app_text.pos_hint = {"center_x": 0.5, "center_y": 0.65}

        self.add_widget(self.app_text)

        # I have 4 buttons and as you can see these 4 buttons only have empty string value at the start, but after the clicking to button named "GO" (indicated below) the function (indicated at the bottom of code) should work and changed the string value of these buttons. 
        self.button1 = Button(text='', background_color='#F62C3F')
        self.button2 = Button(text='', background_color='#F62C3F')
        self.button3 = Button(text='', background_color='#F62C3F')
        self.button4 = Button(text='', background_color='#F62C3F')

        self.button_go = Button(text='GO', background_color='#04D0F9')

        self.button1.size_hint = (0.15, 0.05)
        self.button2.size_hint = (0.15, 0.05)
        self.button3.size_hint = (0.15, 0.05)
        self.button4.size_hint = (0.15, 0.05)

        self.button_go.size_hint = (0.15, 0.05)

        self.button1.pos_hint = {"center_x": 0.4, "center_y": 0.54}
        self.button2.pos_hint = {"center_x": 0.4, "center_y": 0.48}
        self.button3.pos_hint = {"center_x": 0.6, "center_y": 0.54}
        self.button4.pos_hint = {"center_x": 0.6, "center_y": 0.48}

        self.button_go.pos_hint = {"center_x": 0.5, "center_y": 0.36}

        self.button_go.bind(on_press=self.next_question) # This button should call the function described below and then the buttons and picture should be changed based on function body. 

        self.add_widget(self.button1)
        self.add_widget(self.button2)
        self.add_widget(self.button3)
        self.add_widget(self.button4)

        self.add_widget(self.button_go)

    # Actually this function is the main problem of mine. Function is not working and doesn't modify the text of buttons as I expected. 
    def next_question(self, instance):
        self.im = Image(source="picture_2.png")
        self.button1 = Button(text='A', background_color='#F62C3F')
        self.button2 = Button(text='B', background_color='#F62C3F')
        self.button3 = Button(text='C', background_color='#F62C3F')
        self.button4 = Button(text='D', background_color='#F62C3F')

Solution

  • Based on partial error message I assume that you use the same name next_question as function's name and to keep some string - and now it makes problem.

    You expect that self.next_question gives function but code sees string assigned to this variable.

    You have to use different names.

    But without FULL error message I can't confirm that problem makes next_question.
    Maybe problem makes other variable.


    EDIT:

    Meanwhile I made minimal working code which shows how to change text on button - so I put it - but your real problem doesn't need this example.

    But if you uncomment self.change_text = "some text" then you should also get AssertionError: 'some text' is not callable

    #import kivy
    from kivy.app import App
    from kivy.uix.button import Button
    
    class MyApp(App):
    
        def build(self):
            self.button = Button(text='Hello World')
            #self.change_text = "some text"
            self.button.bind(on_press=self.change_text)
            return self.button
        
        def change_text(self, event):
            self.button.text = 'Good Bye'
    
    if __name__ == '__main__':
        MyApp().run()