Arthur Pereira
Arthur Pereira

Reputation: 1559

In Kivy, how do I close a Popup using a close button from another class?

I need to close a Popup in kivy using some close button.

I've found some solutions here but it's not compatible with the ScreenManager i'm currently using. To show my popup like i want i use a FloatLayout and pass it as content for a popup. When i use the function close it calls inside de FloatLayout class and doesn't work. So how can I close the popup in the MainWindow?

Here is my code:

    from kivy.app import App
    from kivy.uix.screenmanager import ScreenManager, Screen
    from kivy.lang import Builder
    from kivy.uix.popup import Popup
    from kivy.uix.floatlayout import FloatLayout

    class MainWindow(Screen):
        def open(self):
            pop = Pop()
            popup = Popup(title="",
                          content=pop,
                          size_hint=(.8, .8))
            popup.open()

    class Pop(FloatLayout):
        def close(self):
            self.dismiss()

    class Setting(Screen):
        pass

    class WindowManager(ScreenManager):
        pass

    kv = Builder.load_file("teste.kv")

    class TesteApp(App):
        def build(self):
            return kv

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

And for my kv file:

    #:import NoTransition kivy.uix.screenmanager.NoTransition
    #:import SlideTransition kivy.uix.screenmanager.SlideTransition

    WindowManager:
        MainWindow:
        Setting:


    <MainWindow>:
        name: "main"

        FloatLayout:
            Label:
                pos_hint:{'center_x': .5, 'center_y': .8}
                size_hint:0.5, 0.5
                text: "TITLE"
                font_size: (root.width/30 + root.height/30)

            Button:
                pos_hint:{'center_x': .5, 'center_y': .4}
                size_hint:0.6, 0.1
                text: "Set"
                on_release:
                    app.root.transition = SlideTransition(direction='left')
                    app.root.current = "setting"

            Button:
                pos_hint:{'center_x': .5, 'center_y': .25}
                size_hint:0.6,0.1
                text: "Pop"
                on_release:
                    root.open()


    <Setting>:
        name: "setting"

        FloatLayout:
            Label:
                text: 'Set Time'
                pos_hint:{'center_x': .5, 'center_y': .75}
                size_hint: 0.1, 0.1
                font_size: (root.width/30 + root.height/30)

            Button:
                pos_hint:{'center_x': .1, 'center_y': .1}
                size_hint:0.05,0.05
                on_release:
                    app.root.transition = SlideTransition(direction='right')
                    app.root.current = 'main'

    <Pop>:
        Label:
            text: 'Popup text'
            size_hint: .4, .15
            pos_hint:{'center_x': .5, 'center_y': .7}
            halign: "center"
            valign: "center"

        Button:
            text: "Close"
            size_hint: .4, .15
            pos_hint:{'center_x': .5, 'center_y': .15}
            on_release: root.close()

Upvotes: 0

Views: 1240

Answers (1)

John Anderson
John Anderson

Reputation: 38857

You can do this by saving a reference to the Popup in your open() method and placing the close() method in the same class. In your modified code below, the Close button now calls the close() method of the MainWindow:

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
from kivy.uix.popup import Popup
from kivy.uix.floatlayout import FloatLayout


class MainWindow(Screen):
    def open(self):
        pop = Pop()
        self.popup = Popup(title="",
                      content=pop,
                      size_hint=(.8, .8))
        self.popup.open()

    def close(self):
        self.popup.dismiss()


class Pop(FloatLayout):
    pass


class Setting(Screen):
    pass


class WindowManager(ScreenManager):
    pass


kv = Builder.load_string('''
#:import NoTransition kivy.uix.screenmanager.NoTransition
#:import SlideTransition kivy.uix.screenmanager.SlideTransition

WindowManager:
    MainWindow:
    Setting:


<MainWindow>:
    name: "main"

    FloatLayout:
        Label:
            pos_hint:{'center_x': .5, 'center_y': .8}
            size_hint:0.5, 0.5
            text: "TITLE"
            font_size: (root.width/30 + root.height/30)

        Button:
            pos_hint:{'center_x': .5, 'center_y': .4}
            size_hint:0.6, 0.1
            text: "Set"
            on_release:
                app.root.transition = SlideTransition(direction='left')
                app.root.current = "setting"

        Button:
            pos_hint:{'center_x': .5, 'center_y': .25}
            size_hint:0.6,0.1
            text: "Pop"
            on_release:
                root.open()


<Setting>:
    name: "setting"

    FloatLayout:
        Label:
            text: 'Set Time'
            pos_hint:{'center_x': .5, 'center_y': .75}
            size_hint: 0.1, 0.1
            font_size: (root.width/30 + root.height/30)

        Button:
            pos_hint:{'center_x': .1, 'center_y': .1}
            size_hint:0.05,0.05
            on_release:
                app.root.transition = SlideTransition(direction='right')
                app.root.current = 'main'

<Pop>:
    Label:
        text: 'Popup text'
        size_hint: .4, .15
        pos_hint:{'center_x': .5, 'center_y': .7}
        halign: "center"
        valign: "center"

    Button:
        text: "Close"
        size_hint: .4, .15
        pos_hint:{'center_x': .5, 'center_y': .15}
        on_release: app.root.get_screen('main').close()
        # if you are sure the current screen will still be "main":
        # on_release: app.root.current_screen.close()
''')


class TesteApp(App):
    def build(self):
        return kv


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

Upvotes: 1

Related Questions