退出时,Python kivymd Popup

时间:2018-08-06 22:14:07

标签: python popup kivy exit kivy-language

我正在尝试创建一个弹出窗口以退出该应用程序。但是我一直收到错误消息“对象。 init ()不带参数”。在我的项目文件夹中,我有一个名为“应用程序”的文件夹。在此文件夹中,我已将相关的kivymd * .py文件复制到名为kivymd的文件夹中。感谢您的帮助。单击“退出应用程序”选择后,我想要一个带有按钮的弹出窗口,以接受或取消该应用程序的退出。

在应用程序文件夹中,我有三个文件:main.py,main.kv和labels.py(用于将标签注入到main.py和main.kv中)。

main.py包含应用程序的所有逻辑。

# -*- coding: utf-8 -*-

import os

# Set virtual keyboard
from kivy.app import App
from kivy.config import Config
Config.set('kivy', 'keyboard_mode', 'systemandmulti')
from kivy.uix.popup import Popup
from kivy.uix.button import Button


from kivy.core.window import Window
Window.fullscreen = "auto"
from kivy.lang import Builder
from functools import partial


from kivymd.list import BaseListItem
from kivymd.material_resources import DEVICE_TYPE
from kivymd.navigationdrawer import MDNavigationDrawer, NavigationDrawerHeaderBase
from kivymd.theming import ThemeManager
from kivymd.button import MDIconButton


class HackedDemoNavDrawer(MDNavigationDrawer):
    # DO NOT USE
    def add_widget(self, widget, index=0):
        if issubclass(widget.__class__, BaseListItem):
            self._list.add_widget(widget, index)
            if len(self._list.children) == 1:
                widget._active = True
                self.active_item = widget
            # widget.bind(on_release=lambda x: self.panel.toggle_state())
            widget.bind(on_release=lambda x: x._set_active(True, list=self))
        elif issubclass(widget.__class__, NavigationDrawerHeaderBase):
            self._header_container.add_widget(widget)
        else:
            super(MDNavigationDrawer, self).add_widget(widget, index)


class MainApp(App):
    theme_cls = ThemeManager()
    title = "Application"

    def build(self):
        main_widget = Builder.load_file(
            os.path.join(os.path.dirname(__file__), "./main.kv")
        )
        self.theme_cls.theme_style = 'Dark'

        main_widget.ids.text_field_error.bind(
            on_text_validate=self.set_error_message,
            on_focus=self.set_error_message)
        self.bottom_navigation_remove_mobile(main_widget)
        return main_widget

    def stop(self, *largs):
        # Open the popup you want to open and declare callback if user pressed `Yes`
        popup = ExitPopup(title="Are you sure?",
                          content=Button(text='Close me!'),
                          size=(400, 400), size_hint=(None, None)
                          )
        popup.bind(on_confirm=partial(self.close_app, *largs))
        popup.open()

    def close_app(self, *largs):
        super(MainApp, self).stop(*largs)

    def bottom_navigation_remove_mobile(self, widget):
        # Removes some items from bottom-navigation demo when on mobile
        if DEVICE_TYPE == 'mobile':
            widget.ids.bottom_navigation_demo.remove_widget(widget.ids.bottom_navigation_desktop_2)
        if DEVICE_TYPE == 'mobile' or DEVICE_TYPE == 'tablet':
            widget.ids.bottom_navigation_demo.remove_widget(widget.ids.bottom_navigation_desktop_1)

    def set_error_message(self, *args):
        if len(self.root.ids.text_field_error.text) == 2:
            self.root.ids.text_field_error.error = True
        else:
            self.root.ids.text_field_error.error = False

    def on_pause(self):
        return True

    def on_stop(self):
        pass


class ExitPopup(Popup):

    def __init__(self, **kwargs):
        super(ExitPopup, self).__init__(**kwargs)
        self.register_event_type('on_confirm')

    def on_confirm(self):
        pass

    def on_button_yes(self):
        self.dispatch('on_confirm')


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

main.kv使用kv语言确定用户界面

# main.kv
#:kivy 1.10.1
#:import Toolbar kivymd.toolbar.Toolbar
#:import MDNavigationDrawer application.kivymd.navigationdrawer.MDNavigationDrawer
#:import NavigationLayout application.kivymd.navigationdrawer.NavigationLayout
#:import NavigationDrawerDivider application.kivymd.navigationdrawer.NavigationDrawerDivider
#:import NavigationDrawerToolbar application.kivymd.navigationdrawer.NavigationDrawerToolbar
#:import NavigationDrawerSubheader application.kivymd.navigationdrawer.NavigationDrawerSubheader
#:import MDTextField application.kivymd.textfields.MDTextField
#:import labels application.labels

NavigationLayout:
    id: nav_layout
    MDNavigationDrawer:
        id: nav_drawer
        NavigationDrawerToolbar:
            title: labels.NAVIGATION
        NavigationDrawerIconButton:
            icon: 'checkbox-blank-circle'
            text: labels.SYSTEM_PARAMETERS
            on_release: app.root.ids.scr_mngr.current = 'system_parameters'
        NavigationDrawerIconButton:
            icon: "checkbox-blank-circle"
            text: labels.CLOSE_APPLICATION
            on_release: app.stop()
    BoxLayout:
        orientation: 'vertical'
        halign: "center"
        Toolbar:
            id: toolbar
            title: labels.APPLICATION_NAME
            md_bg_color: app.theme_cls.primary_color
            background_palette: 'Primary'
            background_hue: '500'
            left_action_items: [['menu', lambda x: app.root.toggle_nav_drawer()]]
            #right_action_items: [['dots-vertical', lambda x: app.root.toggle_nav_drawer()]]
        ScreenManager:
            id: scr_mngr
            Screen:
                name: 'system_parameters'
                BoxLayout:
                    orientation: "horizontal"
                    BoxLayout:
                        orientation: 'vertical'
                        size_hint_y: None
                        height: self.minimum_height
                        padding: dp(48)
                        spacing: 10
                        MDTextField:
                            hint_text: "Helper text on focus"
                            helper_text: "This will disappear when you click off"
                            helper_text_mode: "on_focus"
                            input_filter: "int"
                    BoxLayout:
                        orientation: 'vertical'
                        size_hint_y: None
                        height: self.minimum_height
                        padding: dp(48)
                        spacing: 10
                        MDTextField:
                            hint_text: "Helper text on focus"
                            helper_text: "This will disappear when you click off"
                            helper_text_mode: "on_focus"
                            input_filter: "float"

            Screen:
                name: 'textfields'
                ScrollView:
                    BoxLayout:
                        orientation: 'vertical'
                        MDTextField:
                            id: text_field_error
                            hint_text: "Helper text on error (Hit Enter with two characters here)"
                            helper_text: "Two is my least favorite number"
                            helper_text_mode: "on_error"

            Screen:
                name: 'nav_drawer'
                HackedDemoNavDrawer:
                    # NavigationDrawerToolbar:
                    #     title: "Navigation Drawer Widgets"
                    NavigationDrawerIconButton:
                        icon: 'checkbox-blank-circle'
                        text: "Badge text ---->"
                        badge_text: "99+"
                    NavigationDrawerIconButton:
                        active_color_type: 'accent'
                        text: "Accent active color"
                    NavigationDrawerIconButton:
                        active_color_type: 'custom'
                        text: "Custom active color"
                        active_color: [1, 0, 1, 1]
                    NavigationDrawerIconButton:
                        use_active: False
                        text: "Use active = False"
                    NavigationDrawerIconButton:
                        text: "Different icon"
                        icon: 'alarm'
                    NavigationDrawerDivider:
                    NavigationDrawerSubheader:
                        text: "NavigationDrawerSubheader"
                    NavigationDrawerIconButton:
                        text: "NavigationDrawerDivider \/"
                    NavigationDrawerDivider:

labels.py很短

# labels.py
APPLICATION_NAME = "Application"
CLOSE_APPLICATION = "Close Application"
NAVIGATION = "Navigation"
SYSTEM_PARAMETERS = "System Parameters"

1 个答案:

答案 0 :(得分:1)

解决方案-使用KivyMD MDDialog

在下面的示例中,它使用KivyMD MDDialog作为弹出窗口。

摘要

from kivymd.dialog import MDDialog
from kivymd.label import MDLabel
from kivy.metrics import dp


class ExitPopup(MDDialog):

    def __init__(self, **kwargs):
        super(ExitPopup, self).__init__(**kwargs)
        content = MDLabel(font_style='Body1',
                          theme_text_color='Secondary',
                          text="Are you sure?",
                          size_hint_y=None,
                          valign='top')
        content.bind(texture_size=content.setter('size'))
        self.dialog = MDDialog(title="Close Application",
                               content=content,
                               size_hint=(.3, None),
                               height=dp(200))

        self.dialog.add_action_button("Close me!",
                                      action=lambda *x: self.dismiss_callback())
        self.dialog.open()

    def dismiss_callback(self):
        self.dialog.dismiss()
        App.get_running_app().close_app()

...

    def stop(self, *largs):
        # Open the popup you want to open and declare callback if user pressed `Yes`
        ExitPopup()

输出-KivyMD MDDialog

Img01 - KivyMD MDDialog Img02 - Clikced button, "Close me!"

解决方案-使用Kivy Popup

有关详细信息,请参阅分步指南,片段和示例。

  1. 添加导入语句from kivy.uix.button import Button
  2. MDIconButton替换为Button

摘要

def stop(self, *largs):
    # Open the popup you want to open and declare callback if user pressed `Yes`
    popup = ExitPopup(title="Are you sure?",
                      content=Button(text='Close me!'),
                      size=(400, 400), size_hint=(None, None)
                      )

示例-Kivy Popup

main.py

# -*- coding: utf-8 -*-

import os

# Set virtual keyboard
from kivy.app import App
from kivy.config import Config
from kivy.uix.popup import Popup
from kivy.uix.button import Button

Config.set('kivy', 'keyboard_mode', 'systemandmulti')
from kivy.core.window import Window
# Window.fullscreen = "auto"
from kivy.lang import Builder
from functools import partial


from kivymd.list import BaseListItem
from kivymd.material_resources import DEVICE_TYPE
from kivymd.navigationdrawer import MDNavigationDrawer, NavigationDrawerHeaderBase
from kivymd.theming import ThemeManager


class HackedDemoNavDrawer(MDNavigationDrawer):
    # DO NOT USE
    def add_widget(self, widget, index=0):
        if issubclass(widget.__class__, BaseListItem):
            self._list.add_widget(widget, index)
            if len(self._list.children) == 1:
                widget._active = True
                self.active_item = widget
            # widget.bind(on_release=lambda x: self.panel.toggle_state())
            widget.bind(on_release=lambda x: x._set_active(True, list=self))
        elif issubclass(widget.__class__, NavigationDrawerHeaderBase):
            self._header_container.add_widget(widget)
        else:
            super(MDNavigationDrawer, self).add_widget(widget, index)


class MainApp(App):
    theme_cls = ThemeManager()
    title = "Application"

    def build(self):
        main_widget = Builder.load_file(
            os.path.join(os.path.dirname(__file__), "./main.kv")
        )
        self.theme_cls.theme_style = 'Dark'

        main_widget.ids.text_field_error.bind(
            on_text_validate=self.set_error_message,
            on_focus=self.set_error_message)
        self.bottom_navigation_remove_mobile(main_widget)
        return main_widget

    def stop(self, *largs):
        # Open the popup you want to open and declare callback if user pressed `Yes`
        popup = ExitPopup(title="Are you sure?",
                          content=Button(text='Close me!'),
                          size=(400, 400), size_hint=(None, None)
                          )
        popup.bind(on_confirm=partial(self.close_app, *largs))
        popup.open()

    def close_app(self, *largs):
        super(MainApp, self).stop(*largs)

    def bottom_navigation_remove_mobile(self, widget):
        # Removes some items from bottom-navigation demo when on mobile
        if DEVICE_TYPE == 'mobile':
            widget.ids.bottom_navigation_demo.remove_widget(widget.ids.bottom_navigation_desktop_2)
        if DEVICE_TYPE == 'mobile' or DEVICE_TYPE == 'tablet':
            widget.ids.bottom_navigation_demo.remove_widget(widget.ids.bottom_navigation_desktop_1)

    def set_error_message(self, *args):
        if len(self.root.ids.text_field_error.text) == 2:
            self.root.ids.text_field_error.error = True
        else:
            self.root.ids.text_field_error.error = False

    def on_pause(self):
        return True

    def on_stop(self):
        pass


class ExitPopup(Popup):

    def __init__(self, **kwargs):
        super(ExitPopup, self).__init__(**kwargs)
        self.register_event_type('on_confirm')

    def on_confirm(self):
        pass

    def on_button_yes(self):
        self.dispatch('on_confirm')


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

输出-Kivy Popup

Img01 - Popup