Search code examples
python-3.xkivykivy-language

Changing button text with popup text input kivy


So, I'm new to kivy and can't get this code to work. I'm trying to update a button text with a popup text input. The popup shows when the button is pressed, and when it's dismissed it should update the text on the button with whatever text was typed in it.

I've tried many variations of this code, but no one have worked. Either nothing happens or I get this error:

AttributeError: 'super' object has no attribute '__getattr__'

Here it is:

main.py

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.popup import Popup

class MainWidget(GridLayout):
    pass

class PopText(Popup):

    def textChange(self):
        MyButton().change()

    def getText(self):
        text = self.display
        return text

class MyButton(AnchorLayout):
    def change(self):
        self.ids.equip_bt.text = PopText().getText()
        print(self.ids.my_bt.text)

class MyApp(App):
    def build(self):
        return MainWidget()

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

my.kv

#:kivy 1.10.0
#:import F kivy.factory.Factory

<PopText>:
    size_hint: .7, .3
    title: "Input Text"
    on_dismiss: self.textChange()
    display: pop_text.text

    TextInput:
        id: pop_text
        focus: True
        multiline: False
        on_text_validate: root.dismiss()

<MyButton>:
    anchor_y: "top"
    anchor_x: "right"

    Button:
        id: my_bt
        text: "Input Text"
        on_release: F.PopText().open()

<MainWidget>:
    cols: 1
    rows: 2

    MyButton:
    MyButton:

Any ideas on how to solve this?


Solution

  • Here is a minimum example of what you are trying to achieve. The hard part is connection the button from the Popup to the Button which opened it. I am going through the app class to achieve that. I got to admit it is not a pretty solution.

    from kivy.app import App
    from kivy.uix.popup import Popup
    from kivy.uix.button import Button
    
    class PopupBttn(Button):
        def openPopup(self):
            Pop = TextPopup().open(self.text)
    
    class TextPopup(Popup):
        def open(self, text, **kwargs):
            super(TextPopup, self).open(**kwargs)
            self.ids.txtipt.text = text 
    
    class MyApp(App):
        pass
    
    if __name__ == "__main__":
        MyApp().run()
    

    kv file:

    BoxLayout:
        PopupBttn:
            id: bttn
            text: 'open Popup'
            on_press: self.openPopup()
    
    <TextPopup>:
        BoxLayout:
            orientation: "vertical"
            TextInput:
                id: txtipt
            Button:
                text: "OK"
                on_release: app.root.ids.bttn.text=root.ids.txtipt.text
                on_release: root.dismiss()
    

    Here is an updated version to use multiple buttons. Unfortunately, you will need to set ids and name to the string of id per Button.

    python file

    from kivy.app import App
    from kivy.uix.popup import Popup
    from kivy.uix.button import Button
    from kivy.properties import StringProperty
    
    class PopupBttn(Button):
        def openPopup(self):
            print(self.name)
            Pop = TextPopup().open(self.text, self.name)
    
    
    class TextPopup(Popup):
        bttnid = StringProperty()
        text = StringProperty()
        def open(self, text, id, **kwargs):
            super(TextPopup, self).open(**kwargs)
            self.ids.txtipt.text = text
            self.bttnid = id
    
        def setText(self):
            App.get_running_app().root.ids[self.bttnid].text = self.text
    
    class MyApp(App):
        pass
    
    if __name__ == "__main__":
        MyApp().run()
    

    kv file

    BoxLayout:
        orientation: 'vertical'
        PopupBttn:
            name: 'one'
            id: one
            text: 'I am the first Button'
        PopupBttn:
            name: 'two'
            id: two
        PopupBttn:
            name: 'three'
            id: three
        PopupBttn:
            name: 'four'
            id: four
            text: 'I am the fourth button'
    
    
    
    <PopupBttn>:
        text: 'open Popup'
        on_press: self.openPopup()
    
    <TextPopup>:
        text: txtipt.text
        BoxLayout:
            orientation: "vertical"
            TextInput:
                id: txtipt
            Button:
                text: "OK"
                on_release: root.setText()
                on_release: root.dismiss()