Python : 使用回车键关闭弹出窗口

Python : Close popup using enter key

如何使用回车键关闭 popup.dismiss()。 当我 运行 test.py 单击 ok 按钮然后打开一个弹出窗口时。
有人能告诉我如何使用回车键关闭 popup 并在关闭弹出窗口后将 focus=True 设置为 name TextInput。

test.py

import kivy

kivy.require('1.9.0')  # replace with your current kivy version !
from kivy.uix.screenmanager import Screen
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.lang import Builder
from kivy.uix.widget import Widget
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout

Window.size = (500, 150)


class TestScreen(Screen):

    def insert_data(self):
        Alert(title='yeah!', text='inputs are invalid')

class Alert(Popup):

    def __init__(self, title, text):
        super(Alert, self).__init__()

        box = BoxLayout(orientation='vertical', padding=(5))
        box.add_widget(Label(text=text))
        btn1 = Button(text="Close")
        box.add_widget(btn1)

        popup = Popup(title=title, title_size=(30),
                      title_align='center', content=box,
                      size_hint=(None, None), size=(300, 200),
                      auto_dismiss=True)

        btn1.bind(on_press=popup.dismiss)
        popup.open()


class Test(App):
    def build(self):
        self.root = Builder.load_file('test.kv')
        return self.root



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

test.kv

TestScreen:

    GridLayout:
        cols: 2
        padding: 30, 30
        spacing: 10, 10
        row_default_height: '30dp'

        Label:
            text: 'Name'
            text_size: self.size
            valign: 'middle'
            #padding_x: 50

        TextInput:
            id: name

        Button:
            text: 'Ok'
            on_press: root.insert_data()

        Button:
            text: 'Cancel'
            on_press: app.stop()

在下面的示例中,完成了以下步骤:

  1. 使用 WindowBase.request_keyboard() 返回的键盘界面来检测按下的 ENTER 或 NUMPENTERPAD 键。
  2. 使用 ObjectProperty 连接到 TextInput
  3. auto_dismiss设置为False以便我们调用dismiss_callback 方法在弹出窗口关闭时将 focus 提供给 TextInput (id: name)。
  4. Class Alert 已经是一个 Popup 小部件,您不想创建另一个弹出窗口。

it is generally regarded as ‘best practice’ to use the ObjectProperty. This creates a direct reference, provides faster access and is more explicit.

示例

main.py

from kivy.uix.screenmanager import Screen
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty

Window.size = (500, 150)


class TestScreen(Screen):
    name = ObjectProperty(None)

    def insert_data(self):
        Alert(title='yeah!', text='inputs are invalid')


class Alert(Popup):

    def __init__(self, title, text):
        super(Alert, self).__init__()
        self._keyboard = Window.request_keyboard(
            self._keyboard_closed, self, 'text')
        if self._keyboard.widget:
            # If it exists, this widget is a VKeyboard object which you can use
            # to change the keyboard layout.
            pass
        self._keyboard.bind(on_key_down=self._on_keyboard_down)

        box = BoxLayout(orientation='vertical', padding=(5))
        box.add_widget(Label(text=text))
        btn1 = Button(text="Close")
        box.add_widget(btn1)

        self.title = title
        self.title_size = 30
        self.title_align = 'center'
        self.content = box
        self.size_hint = (None, None)
        self.size = (300, 200)
        self.auto_dismiss = False

        btn1.bind(on_press=self.dismiss_callback)
        self.open()

    def _keyboard_closed(self):
        self._keyboard.unbind(on_key_down=self._on_keyboard_down)
        self._keyboard = None

    def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
        if keycode[1] in ('enter', 'numpadenter'):
            print("keycode=", keycode)
            self.dismiss_callback()

        # Keycode is composed of an integer + a string
        # If we hit escape, release the keyboard
        if keycode[1] == 'escape':
            keyboard.release()

        # Return True to accept the key. Otherwise, it will be used by
        # the system.
        return True

    def dismiss_callback(self, instance=None):
        self.dismiss()
        App.get_running_app().root.name.focus = True


class Test(App):
    def build(self):
        self.root = Builder.load_file('test.kv')
        return self.root


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

输出