用箭头改变焦点并访问 kivy 中的子项

发布于 2025-01-12 09:02:33 字数 1813 浏览 0 评论 0原文

根据 kivy 在组件之间移动的情况,我有两个问题。

.py

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.textinput import TextInput
from kivy.uix.widget import Widget
from kivy.properties import StringProperty

Builder.load_file("keyboardreader.kv")

class MyTextInput(TextInput):
    focused=StringProperty('id1')
    def keyboard_on_key_down(self, window, keycode, text, modifiers):
        print(keycode, text, modifiers)
        if keycode[1] == "backspace":
            print("print backspace down", keycode)
        TextInput.keyboard_on_key_down(self, window, keycode, text, modifiers)
       
        if keycode[1]=="right":
            if int(self.focused[2])<5:
                focusedid=int(self.focused[2])+1
                self.focused="id"+str(focusedid)       
        if keycode[1]=="left":
            if int(self.focused[2])>1:
                focusedid=int(self.focused[2])-1
                self.focused="id"+str(focusedid)
        print(self.focused)
            
        

class MainScreen(Widget):
    pass
    
                 
class TestingappApp(App):
    def build(self):
        return MainScreen()
    
TestingappApp().run()

.kv

<MainScreen>:
    BoxLayout:
        id: layout
        size: root.width,root.height
        MyTextInput:
            id: id1
        MyTextInput:
            id: id2
        MyTextInput:
            id: id3
        MyTextInput:
            id: id4
        MyTextInput:
            id: id5
        

根据这段代码我几乎没有问题。

  1. 如何从 .kv 文件中访问具有特定 id 的元素? 我一直使用相同的表格,以前可以用,但现在不行了。例如,如果我想关注 id1 的元素,我正在考虑使用“
self.ids["id1"].focus=True 
  1. 如何访问元素的所有子元素?”例如,我想要 id:layout 的 BoxLayout 的子级列表,其中有 id1,id2,...,id5 元素。

I have two questions according to kivy moving between components.

.py

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.textinput import TextInput
from kivy.uix.widget import Widget
from kivy.properties import StringProperty

Builder.load_file("keyboardreader.kv")

class MyTextInput(TextInput):
    focused=StringProperty('id1')
    def keyboard_on_key_down(self, window, keycode, text, modifiers):
        print(keycode, text, modifiers)
        if keycode[1] == "backspace":
            print("print backspace down", keycode)
        TextInput.keyboard_on_key_down(self, window, keycode, text, modifiers)
       
        if keycode[1]=="right":
            if int(self.focused[2])<5:
                focusedid=int(self.focused[2])+1
                self.focused="id"+str(focusedid)       
        if keycode[1]=="left":
            if int(self.focused[2])>1:
                focusedid=int(self.focused[2])-1
                self.focused="id"+str(focusedid)
        print(self.focused)
            
        

class MainScreen(Widget):
    pass
    
                 
class TestingappApp(App):
    def build(self):
        return MainScreen()
    
TestingappApp().run()

.kv

<MainScreen>:
    BoxLayout:
        id: layout
        size: root.width,root.height
        MyTextInput:
            id: id1
        MyTextInput:
            id: id2
        MyTextInput:
            id: id3
        MyTextInput:
            id: id4
        MyTextInput:
            id: id5
        

I have few problems according to this code.

  1. How can I access the element with certain id from the .kv file?
    I was always using the same form and it used to work, now it doesn't. For example, if I wanted to make a focus on element with id1, I was thinking about using
self.ids["id1"].focus=True 
  1. How can I access all children elements of an element? For example, I want the list of children of BoxLayout with id:layout, that there are id1,id2,...,id5 elements.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

生寂 2025-01-19 09:02:33

通常为了访问某个小部件的子部件,您可以使用 prop.该小部件的子级。但从以下...

我想要 id:layout 的 BoxLayout 的子级列表,其中有 id1,id2,...,id5 元素。

看来您想将所有子项打包到某个东西中(这里,在'BoxLayout with id:layout'中)。为此,我将 kvlang 中的代码修改为这样,

<MainScreen>:
    CustomBox:
        id: layout
        size: root.size


<CustomBox@BoxLayout>:
    MyTextInput:
        id: id1
        focused: "id1"
    MyTextInput:
        id: id2
        focused: "id2"
    # etc.

这将使您能够通过 ids 访问其子项(即 TextInput 对象)。另请注意,您必须使用不同的 focused 属性初始化每个 MyTextInput 实例(以便稍后访问它们)。

现在保持方法 keyboard_on_key_down 不变,我将 focused 属性绑定到回调函数,例如 change_focus (您可以使用 on_prop 方法或采取任何其他方法),

class MyTextInput(TextInput):
    focused=StringProperty('id1')
    
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.bind(focused = self.change_focus) # Will call this function each time 'focused' changes.
    
    def change_focus(self, *args):
        id_val = self.focused
        app = App.get_running_app()
        if app.root is not None:
            # Now access the container.
            layout = app.root.ids["layout"]
            # Access the required widget and set its focus.
            layout.ids[id_val].focus = True

    def keyboard_on_key_down(self, window, keycode, text, modifiers):
        print(keycode, text, modifiers)
        ...

注意:

这应该使方法 keyboard_on_key_down 按预期发生,但您再次需要更改其中的一些逻辑才能获得完美的结果。

Usually in order to access the children of a certain widget you can use the prop. children of that widget. But from the following...

I want the list of children of BoxLayout with id:layout, that there are id1,id2,...,id5 elements.

it seems you want to pack all the children into something (here, in 'BoxLayout with id:layout'). For this I modified your code in kvlang into this,

<MainScreen>:
    CustomBox:
        id: layout
        size: root.size


<CustomBox@BoxLayout>:
    MyTextInput:
        id: id1
        focused: "id1"
    MyTextInput:
        id: id2
        focused: "id2"
    # etc.

This will enable you to access its children (i.e. TextInput objects) by ids. Also note that you have to initialize each MyTextInput instance with different focused property (in order to access them later).

Now keeping the method keyboard_on_key_down as it is, I bind the focused property to a callback function, say, change_focus (you can use on_prop method or take any other approaches) as,

class MyTextInput(TextInput):
    focused=StringProperty('id1')
    
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.bind(focused = self.change_focus) # Will call this function each time 'focused' changes.
    
    def change_focus(self, *args):
        id_val = self.focused
        app = App.get_running_app()
        if app.root is not None:
            # Now access the container.
            layout = app.root.ids["layout"]
            # Access the required widget and set its focus.
            layout.ids[id_val].focus = True

    def keyboard_on_key_down(self, window, keycode, text, modifiers):
        print(keycode, text, modifiers)
        ...

Note:

This should make the method keyboard_on_key_down happen as expected but again you need to change some logic in it to get perfect result.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文