Search code examples
pythonkivykivy-language

Kivy: Using Popup.open()


I have code with Popup, which containts TextInput. Form code in example is working, but with using TextInputPopup constructor is falling down after using Popup.open() (version with costructor is in the note).

  • What must I repair for using constructor?
  • Parameter from TextInputPopup is used in function TextInputPopup.next_step(). Can I use this parametr in function SaveAs.on_call_popup(), which call TextInputPopup? How do I it?

Example:

   Builder.load_string('''
    <SaveAs>:
        teinp: teinp
        Button:
            text:'Hi users'
            on_release: root.on_call_popup()
        TextInput:
            id: teinp
            text:'text input'

    <TextInputPopup>:
        answer: answer

        title: root.title
        size_hint: None, None
        size: app.root.width/2, app.root.height/2
        auto_dismis: False

        BoxLayout:
            orientation: 'vertical'
            Label:
                text: root.label
            TextInput:
                id: answer
                text: ''
            BoxLayout:
                Button:
                    text: 'Cancel'
                    on_press: root.dismiss()
                Button:
                    text: 'OK'
                    on_press: root.dismiss()
    ''')

    class TextInputPopup(Popup):
        title = StringProperty()
        label = StringProperty()
        answer = ObjectProperty()
        '''
        def __init__ (self,title, label):
            self.set_description(title, label)
            return
        '''
        def set_description(self,title, label):
            self.title = title
            self.label = label
            return

        def get_answer(self):
            return self.answer.text

    class SaveAs(BoxLayout):
        teinp = ObjectProperty()

        def on_call_popup(self):
            self.poti = TextInputPopup()
    #        self.poti = TextInputPopup('File Manager', 'Name')
            self.poti.open()   
            self.poti.set_description('File Manager', 'Name') 
            self.poti.bind(on_dismiss = self.next_step)
            return

        def next_step(self, obj):
            a = self.poti.get_answer()
            self.teinp.text = self.poti.get_answer()
            return

    class ExplorerApp(App):

        def build(self):
            return SaveAs()

    if __name__ == '__main__':
        ExplorerApp().run()

Solution

  • You must call the initializer of the parent class (__init__), for that use super:

    from kivy.app import App
    from kivy.uix.boxlayout import BoxLayout
    from kivy.uix.popup import Popup
    from kivy.properties import StringProperty, ObjectProperty
    from kivy.lang.builder import Builder
    
    
    Builder.load_string('''
    <SaveAs>:
        teinp: teinp
        Button:
            text:'Hi users'
            on_release: root.on_call_popup()
        TextInput:
            id: teinp
            text:'text input'
    
    <TextInputPopup>:
        answer: answer
        title: root.title
        size_hint: None, None
        size: app.root.width/2, app.root.height/2
        auto_dismis: False
    
        BoxLayout:
            orientation: 'vertical'
            Label:
                text: root.label
            TextInput:
                id: answer
                text: ''
            BoxLayout:
                Button:
                    text: 'Cancel'
                    on_press: root.dismiss()
                Button:
                    text: 'OK'
                    on_press: root.dismiss()
     ''')
    
    
    class TextInputPopup(Popup):
        title = StringProperty()
        label = StringProperty()
        answer = ObjectProperty()
    
        def __init__(self, title, label, **kwargs):
            super(TextInputPopup, self).__init__(**kwargs)
            self.set_description(title, label)
    
        def set_description(self, title, label):
            self.title = title
            self.label = label
    
        def get_answer(self):
            return self.answer.text
    
    
    class SaveAs(BoxLayout):
        teinp = ObjectProperty()
    
        def on_call_popup(self):
            poti = TextInputPopup('File Manager', 'Name')
            poti.open()
            poti.bind(on_dismiss=self.next_step)
    
        def next_step(self, popup):
            self.teinp.text = popup.get_answer()
    
    
    class ExplorerApp(App):
    
        def build(self):
            return SaveAs()
    
    
    if __name__ == '__main__':
        ExplorerApp().run()
    

    If you use __init__ in your class derived, you are re-defining parent constructor, which would normally run the initialization of the base class. super is used to run the parent __init__ without an explicit call to the parent class and allow you to pass parameters to it.

    In principle, whenever you overwrite __init__ in a daughter class you should call the __init__ of your parent class with the necessary arguments to be properly initialized.