1

I am currently making a text based game using Python, and I have been wanting to use Kivy to make a Graphical Interface for it. I have been unable to get it to work so far though.

The reasoning is that I have changed from what was Print and Input to self.label1 = Label(text='Hello world') etc (There is multiple variables- label2, 3 and 4.) and then for the input, a text input box, which the input is used by a function when the button is pressed (Currently the textbox isn't involved, since I am first just testing whether the button works.). The problem is, I need a way to update the text displayed with the new value. For example I would like label1 to change to "These are the controls". But when a button is clicked, changes don't happen- I would like the GUI to be updated with the new text, through the changing of the values of the label variables. I believe that since those are being returned, the code above no longer loops through. The ideas I've been given, is to put the different sections into functions, or to use threading. Does anyone have any tips to push me in the right direction. I understand it may be too much be to ask, if so I'll continue to look for a solution myself. I can show some of the code if needed.

import kivy.uix.boxlayout
import kivy.uix.textinput
import kivy.uix.label
import kivy.uix.button
from kivy.app import App
from random import shuffle
import time
from kivy.uix.button import Button
from kivy.clock import Clock

alive = 1
buttonPressed = 0


class SimpleApp(App):
    def build(self):
        global alive
        global buttonPressed
        donext = 0
        alive = 1

        def callback(self):
            global buttonPressed
            buttonPressed = 1

        self.label1 = kivy.uix.label.Label(text="")
        self.label2 = kivy.uix.label.Label(text="")
        self.label3 = kivy.uix.label.Label(text="You have found yourself in a dungeon, somewhere is your escape path, will you make it out, and if so, what with?")
        self.label4 = kivy.uix.label.Label(text="")
        print(buttonPressed)
        if buttonPressed == 1:
            print("Has been pressed should work theoretically")
            self.label1 = kivy.uix.label.Label(text="These are the basic controls-")
            self.label2 = kivy.uix.label.Label(text="The controls-")
            self.label3 = kivy.uix.label.Label(text="A- approach enemy/ attack enemy")
            self.label4 = kivy.uix.label.Label(text="C- Go to chest")
        print("Press enter to continue.")

        self.boxLayout = kivy.uix.boxlayout.BoxLayout(orientation="vertical")
        self.boxLayout.add_widget(self.label1)
        self.boxLayout.add_widget(self.label2)
        self.boxLayout.add_widget(self.label3)
        self.boxLayout.add_widget(self.label4)
        self.btn1 = Button(text='Hello world 1', on_press=callback)
        self.boxLayout.add_widget(self.btn1)

        return self.boxLayout # Causes script not to continue
if __name__ == "__main__":
    simple = SimpleApp()
    simple.run()
  • provide a [mcve] – eyllanesc Oct 20 '18 at 21:25
  • Ok I shall do. Sorry about that. Thank you –  Oct 20 '18 at 21:26
  • I have now done that @eyllanesc . Thank you for letting me know –  Oct 20 '18 at 21:38
  • First, you talk about a problem but you do not clearly indicate what it is, then point out that you have been suggested to use other things, etc., but you do not explain what is your objective, what should appear at the beginning, before what action should something change the GUI, etc. On the other hand I see that you have defined self.label1, self.label2, self.label3, self.label4 but I do not see where you have defined self.label of which you speak. – eyllanesc Oct 20 '18 at 21:43
  • In conclusion we do not know what you want to do, that is, what makes your game. – eyllanesc Oct 20 '18 at 21:45
  • Ok thank you for the advice. Sorry about the mistakes I've made. Also I should have made it clearer, that I mean self.label1 to 4 rather than just self.label. The problem faced, is that upon press of the button, the GUI does not update with the new text. So the objective is to be able to update the GUI with the new text, upon click of the button. I shall do my best, so that later asked questions of mine are better. –  Oct 20 '18 at 21:49
  • @eyllanesc I have now made some changes, I hope that it should be clearer now, thank you for the tips on asking better questions on StackOverflow. –  Oct 20 '18 at 22:06
  • You say that update the label to a new text, I understand that the old text is "Hello World", what would be the new text ?, since you have 4 labels: what would be the new text for each one? – eyllanesc Oct 20 '18 at 22:13
  • Hi there. I'm sorry again for inconsistencies. I've updated it. –  Oct 20 '18 at 22:21
  • Before continuing to try blindly I recommend reading the kivy docs so that you understand the logic and concepts: https://kivy.org/doc/stable/ , On the other hand I have provided a solution, if it worked, do not forget to mark it as correct, if you do not know how to do it, review the [tour], that is the best way to thank. – eyllanesc Oct 20 '18 at 22:32
  • avoid using global variables: https://stackoverflow.com/questions/19158339/why-are-global-variables-evil – eyllanesc Oct 20 '18 at 22:33

1 Answers1

0

If you have been advised to use threads it seems that your advisor does not know about GUI, in the GUIs the tasks are done asynchronously through events, that is, the GUI will provide you with methods to indicate when something has happened in the GUI, for example the event on_press notifies you when the button is pressed, so they connect a signal to that event. On the other hand the GUIs have a high component of object-oriented programming, event-oriented programming, and in the .kv is a declarative language, so I recommend you read about those concepts and for it kivy offers a great documentation and examples, review them. If you want to update a Label at least it must be accessible in the whole class, so it must be an attribute of the class and use the text property, on the other hand if you want to show a text of several lines use \n to indicate that there is a jump of line.

Considering the above, the solution is as follows:

from kivy.app import App

from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.label import Label


class SimpleApp(App):
    def build(self):
        self.label = Label(text="You have found yourself in a dungeon,\nsomewhere is your escape path,\nwill you make it out, and if so, what with?")
        self.button = Button(text="Press Me", on_press=self.on_clicked, size_hint=(1.0, None))
        layout = BoxLayout(orientation="vertical")
        layout.add_widget(self.label)
        layout.add_widget(self.button)
        return layout

    def on_clicked(self, instance):
        self.label.text = "These are the basic controls-\nThe controls-\nA- approach enemy/ attack enemy\nC- Go to chest"


if __name__ == "__main__":
    SimpleApp().run()
eyllanesc
  • 235,170
  • 19
  • 170
  • 241