首页 > 解决方案 > Python Kivy 在 Popup 内的按钮之间切换

问题描述

我想在这里为 python kivy 桌面应用程序寻求帮助,我有一个小问题,但它很烦人。我遇到的问题是在带有键盘“Tab 键”的 kivy 弹出窗口中的两个按钮(是按钮和否按钮)之间切换不起作用,而且我希望能够为处理该功能的选定按钮按下“Enter 键”。

这是我的弹出窗口的样子:

弹出屏幕截图

弹出窗口的代码如下:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.popup import Popup
from kivy.uix.label import Label


class testWindow(BoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        def yes_btn(instance):
            print("this function is called.")

        contents = BoxLayout(orientation='vertical')
        content_text = Label(text="Lanjutkan Transaksi?")
        pop_btn = BoxLayout(spacing=10)
        btn_yes = Button(text='Ya', size_hint_y=None, height=40)
        btn_no = Button(text='Tidak', size_hint_y=None, height=40)
        pop_btn.add_widget(btn_yes)
        pop_btn.add_widget(btn_no)
        contents.add_widget(content_text)
        contents.add_widget(pop_btn)

        pop_insert = Popup(title="Confirmation Message", content=contents, size_hint=(None, None), size=(300, 300))

        btn_yes.bind(on_release=yes_btn)
        btn_no.bind(on_release=pop_insert.dismiss)

        pop_insert.open()


class testApp(App):
    def build(self):
        return testWindow()


if __name__ == '__main__':
    m = testApp()
    m.run()

当我使用鼠标单击按钮时,弹出窗口正常运行。如上面的弹出图片,我想让 Yes Button 聚焦,当我按下“Enter 键”弹出窗口关闭并运行我想要的功能。同时在按钮之间切换只需按“Tab 键”。

我一直在努力寻找解决问题的方法,但仍然没有结果,所以如果有人知道如何解决我的问题,请帮助我。

标签: pythonbuttonkeyboardpopupkivy

解决方案


这是对您的代码的修改,我认为它可以满足您的要求:

from kivy.app import App
from kivy.core.window import Window
from kivy.lang import Builder
from kivy.properties import BooleanProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from kivy.uix.behaviors import FocusBehavior

# This is a Button that also has focus behavior
class FocusButton(FocusBehavior, Button):
    first_focus = BooleanProperty(False)

    def on_parent(self, widget, parent):
        # if first_focus is set, this Button takes the focus first
        if self.first_focus:
            self.focus = True


class MyPopup(Popup):
    def keydown(self, window, scancode, what, text, modifiers):
        if scancode == 13:
            for w in self.walk():
                if isinstance(w, FocusButton) and w.focus:
                    w.dispatch('on_press')

    def keyup(self, key, scancode, codepoint):
        if scancode == 13:
            for w in self.walk():
                if isinstance(w, FocusButton) and w.focus:
                    w.dispatch('on_release')

    def on_dismiss(self):
        Window.unbind(on_key_down=self.keydown)
        Window.unbind(on_key_up=self.keyup)

Builder.load_string('''
# provide for a small border that indicates Focus
<FocusButton>:
    canvas.before:
        Color:
            rgba: 1,1,1,1
        Rectangle:
            pos: self.x-2, self.y-2
            size: (self.size[0]+4, self.size[1]+4) if self.focus else (0,0)
''')


class testWindow(BoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        def yes_btn(instance):
            print("this function is called.")

        contents = BoxLayout(orientation='vertical')
        content_text = Label(text="Lanjutkan Transaksi?")
        pop_btn = BoxLayout(spacing=10)

        # set first_focus to True for this Button
        self.btn_yes = FocusButton(text='Ya', size_hint_y=None, height=40, first_focus=True)
        self.btn_no = FocusButton(text='Tidak', size_hint_y=None, height=40)
        pop_btn.add_widget(self.btn_yes)
        pop_btn.add_widget(self.btn_no)
        contents.add_widget(content_text)
        contents.add_widget(pop_btn)

        pop_insert = MyPopup(title="Confirmation Message", content=contents, size_hint=(None, None), size=(300, 300))

        self.btn_yes.bind(on_release=yes_btn)
        self.btn_no.bind(on_release=pop_insert.dismiss)

        # bind to get key down and up events
        Window.bind(on_key_down=pop_insert.keydown)
        Window.bind(on_key_up=pop_insert.keyup)

        pop_insert.open()

class testApp(App):
    def build(self):
        return testWindow()


if __name__ == '__main__':
    m = testApp()
    m.run()

此代码添加FocusBehavior到 aButton以创建 a FocusButton,并将 key down 和 key up 处理添加到MyPopup类。


推荐阅读