Kivy - 使按钮更改TextInput的文本?

时间:2015-09-28 16:16:36

标签: python kivy

我试图制作一个带有3个按钮和一个显示器的应用程序(我使用的是TextInput)。

按下按钮时,我希望按钮的文本显示在显示中。例如,如果按1 1 2,我希望112显示在显示屏上。

有没有办法在不手动将每个按钮添加on_press的情况下执行此操作?这里的代码不起作用。我认为它不起作用,因为" self.ids.textbox.text"指的是错误的东西。我不确定如何解决这个问题。

不工作main2.py:

import kivy
kivy.require("1.9.0")

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.core.window import Window

class Buttons(Button):

    def callback(self, text):
        self.ids.textbox.text = "Hi"


class Main2Widget(BoxLayout):

    pass

class Main2App(App):
    '''docstring for Main2App'''
    def build(self):
        Window.size = (300, 200)
        return Main2Widget()


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

不工作main2.kv:

#:kivy 1.9.0

<Buttons>:
    on_press: root.callback(self.text)

<Main2Widget>:
    id: mainapp

    orientation: 'vertical'

    TextInput:
        id: textbox
        multiline: False
        readonly: True

        hint_text: "I'm an input box!"
        font_size: 20

    GridLayout:
        cols: 3

        Buttons:
            id: btn1
            text: "1"

        Buttons:
            id: btn2
            text: "2"

        Buttons:
            id: btn3
            text: "3"

如果我这样做,它会起作用:

使用main2.py:

import kivy
kivy.require("1.9.0")

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.core.window import Window


class Main2Widget(BoxLayout):

    def callback(self, text):
        self.ids.textbox.text += text

    pass

class Main2App(App):
    '''docstring for Main2App'''
    def build(self):
        Window.size = (300, 200)
        return Main2Widget()


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

工作main2.kv:

#:kivy 1.9.0

<Main2Widget>:
    orientation: 'vertical'

    TextInput:
        id: textbox
        multiline: False
        readonly: True

        hint_text: "I'm an input box!"
        font_size: 20

    GridLayout:
        cols: 3

        Button:
            id: btn1
            text: "1"
            on_press: root.callback(self.text)

        Button:
            id: btn2
            text: "2"
            on_press: root.callback(self.text)

        Button:
            id: btn3
            text: "3"
            on_press: root.callback(self.text)

1 个答案:

答案 0 :(得分:1)

它不起作用的原因是因为root引用了当前规则的根(在本例中为<Buttons>)。规则的根目录还包含该规则中包含的ID,因此该函数在Buttons上调用,但由于它没有ID,self.ids为空。

在第二个示例中,root引用了<Main2Widget>,其中包含一个ID为textbox的小部件。

通常,窗口小部件规则(<Buttons>)无法访问其自己的规则之外的窗口小部件。这是因为它可以插入任何地方,可能有也可能没有任何东西可以访问。

例外是App对象。您可以在kv。

中的任何位置访问您的应用程序对象

我可以为您的问题考虑3种解决方法。最简单的方法是将函数调用放在<Main2Widget>规则中(您尝试过)。如果您确实需要单独的按钮规则,则第二个选项是将callback功能放在App课程中,然后拨打app.callback。然后你可以保持对根小部件的引用:

class Main2App(App):
    '''docstring for Main2App'''    
    def build(self):
        Window.size = (300, 200)
        self.root =  Main2Widget()
        return self.root

    def callback(self, text):
        self.root.ids.textbox.text = "Hi"

最后一个,我可能会使用的是使用StringProperty(也在App类上):

class Main2App(App):
    '''docstring for Main2App'''
    the_text = StringProperty()
    def build(self):
        Window.size = (300, 200)
        return Main2Widget()

然后,您可以使用text: app.the_text将textinput绑定到属性,并使用on_press: app.the_text = self.text将其设置在按钮中。在我看来这更干净,因为你不需要使用回调或访问python端的id。