Kivy - 让按钮改变 TextInput 的文本?
Kivy - Make buttons change the text of TextInput?
我正在尝试制作一个带有 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)
它不起作用的原因是因为 root
指的是当前规则的根(在本例中为 <Buttons>
)。规则的根还包含该规则中包含的 ID,因此函数在 Buttons
上调用,但由于它没有 ID,因此 self.ids
为空。
在您的第二个示例中,root
引用 <Main2Widget>
,它在其规则中确实包含一个 ID 为 textbox
的小部件。
一般来说,小部件规则 (<Buttons>
) 无法访问其自身规则之外的小部件。这是因为它可以插入任何地方,可能有也可能没有任何东西可以访问。
App
对象除外。您可以在 kv 中的任何地方访问您的应用程序对象。
我可以想到 3 种解决方法来解决您的问题。最简单的方法是将函数调用放在 <Main2Widget>
规则(您试过)中。如果你真的想要一个单独的按钮规则,那么第二个选项是将 callback
函数放在你的 App
class 中,然后调用 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 上):
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。
我正在尝试制作一个带有 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)
它不起作用的原因是因为 root
指的是当前规则的根(在本例中为 <Buttons>
)。规则的根还包含该规则中包含的 ID,因此函数在 Buttons
上调用,但由于它没有 ID,因此 self.ids
为空。
在您的第二个示例中,root
引用 <Main2Widget>
,它在其规则中确实包含一个 ID 为 textbox
的小部件。
一般来说,小部件规则 (<Buttons>
) 无法访问其自身规则之外的小部件。这是因为它可以插入任何地方,可能有也可能没有任何东西可以访问。
App
对象除外。您可以在 kv 中的任何地方访问您的应用程序对象。
我可以想到 3 种解决方法来解决您的问题。最简单的方法是将函数调用放在 <Main2Widget>
规则(您试过)中。如果你真的想要一个单独的按钮规则,那么第二个选项是将 callback
函数放在你的 App
class 中,然后调用 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 上):
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。