2

I have a TextInput that is added to a kivy language <MyLayout>: rule and declared as a python class that inherits from a BoxLayout. The above rule is then added to a ModalView along with some buttons when another button is clicked. The main problem is that although I can get an instance of the text of the buttons within the <MyLayout>: rule and pass the text to the TextInput, I cannot seem to get the TextInput text output via a function called process_output().

The only reason I can guess is because the TextInput gets garbage collected. There is no error and the console prints carriage return as the output is empty but the screen moves up when I try to print() the TextInput text.

Python code:

class RootLay(FloatLayout):
    def get_keys(self):
        modal = ModalViewer()
        the_key = MyLayout()
        modal.add_widget(the_key)
        modal.open()
    def process_output(self):
        mod = ModalViewer()
        the_key = MyLayout()
        the_output = the_key.ids.show_input.text
        the_key.ids.show_input.text = ''
        print(the_output)
        mod.dismiss()
class MyLayout(BoxLayout):
    show_input = ObjectProperty()
    def __init__(self, **kwargs):
        super(MyLayout, self).__init__(**kwargs)
        btn = ['7', '8', '9', '4', '5', '6', '1', '2', '3', 'IN', '0', 'OUT']
        key_padbtns = []
        for b in btn:
            key_padbtns.append({'text': b, 'size_hint': [1, 1]})
        self.ids.view_keypad.data = key_padbtns

Kivy code:

<RootLay>:
    Button:
        text: 'Press for key'
        on_release: app.root.get_keys()
<MyLayout>:
    id: emp_keys
    orientation: 'vertical'
    size_hint: (0.94, 0.94)
    pos_hint: {'top': 0.94}
    TextInput:
        id: show_input
        hint_text: 'Type number'
        font_size: self.height / 1.7
        size_hint_y: 0.1
    RecycleView:
        id: view_keypad
        viewclass: 'KeyBut'
        size_hint: [1,1]
        RecycleGridLayout:
            cols: 3
            defualt_size: [100, 20]
            defualt_size_hint: [1,1]
<KeyBut>:
    on_press:
        if self.text == 'OUT' or self.text == 'IN': app.root.process_output()
        else: self.parent.parent.parent.ids.show_input.text = self.parent.parent.parent.ids.show_input.text + self.text

Can someone please give me idea of what is going wrong?

Hmerman6006
  • 1,622
  • 1
  • 20
  • 45
  • 1
    In your `process_output()` method you are creating a new instance of `MyLayout` on the line: `the_key = MyLayout()`. Can't be sure (you haven't posted enough code), but that is likely not the instance of `MyLayout` that appears in your GUI. I suspect that you actually want to get a reference to the already existing instance. – John Anderson Aug 27 '19 at 21:19
  • @John Anderson You are correct! Thank you very much. If you make your comment the answer I will mark it as such. The only thing that I did is to make the variable ```the_key``` an ```ObjectProperty()``` and reference ```self.the_key``` to create the instance and refer to the variable in ```process_output()```. I first of all check that the ```self.the_key != None``` before using it a second time. – Hmerman6006 Aug 28 '19 at 14:03
  • @John Anderson Do you maybe have an idea of how I can make the ```self.parent.parent.parent.ids.show_input.text``` reference in my code a bit more concise? – Hmerman6006 Aug 28 '19 at 14:10
  • 1
    Your `data` that is used for the `RecycleView` is a dictionary of properties to be set in your `ViewClass` instances (in your case `KeyBut`). Note that those properties that appear in the data dictionary do not have to be displayed properties. So you can add an `ObjectProperty` in your `KeyBut` that will hold a reference to some convenient widget (perhaps the `MyLayout` instance, or the `TextInput` instance). And add that property to your data dictionary. Then the `on_press` rule for the `KeyBut` can use that reference. – John Anderson Aug 28 '19 at 20:05
  • @John Anderson Wow! That is some powerful knowledge you just shared. Thank you! I did not know that properties can be references to other widgets within the ```data``` dictionary. I did as you said and declared a property ```'textbox': self.show_input``` in the ```KeyBut``` ```data``` dictionary. Now I just reference ```self.textbox.text``` instead of ```self.parent.parent.parent.ids.show_input.text```. – Hmerman6006 Aug 29 '19 at 18:19

0 Answers0