Kivy TextInput 字段抛出缺少背景颜色错误
Kivy TextInput field throwing missing background color error
我正在尝试熟悉一些基本的 Kivy GUI 构建,并正在尝试创建一个 TextField,用户输入一些文本并在他们按下 Return 时更改标签。
我的代码:
from kivy.app import App
from kivy.uix.textinput import TextInput
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.label import Label
class textInput(FloatLayout):
def __init__(self, **kwargs):
super(textInput, self).__init__(**kwargs)
self.label = Label(text = 'No text')
self.textSpace = TextInput(pos = (300,300), text = 'Type here', multiline = False, on_enter = changeText())
self.orientation = 'horizontal'
self.size = (450,300)
self.add_widget(label)
self.add_widget(textSpace)
def changeText(value):
self.textSpace.text = value
class myApp(App):
def build(self):
return textInput()
if __name__ == '__main__':
myApp().run()
尝试从终端执行代码,我收到以下错误:
Traceback (most recent call last):
File "/usr/local/lib/python3.5/site-packages/kivy/lang.py", line 1649, in create_handler
return eval(value, idmap)
File "/usr/local/lib/python3.5/site-packages/kivy/data/style.kv", line 167, in <module>
rgba: self.background_color
File "kivy/weakproxy.pyx", line 19, in kivy.weakproxy.WeakProxy.__getattr__ (/var/folders/yx/bvym8vps2sd_0q19bxy2ddfw0000gn/T/pip-xjpmjrk9-build/kivy/weakproxy.c:1101)
AttributeError: 'textInput' object has no attribute 'background_color'
我试图找到一些关于 TextInput 的教程,其中 none 有关于在小部件上设置背景颜色的内容。
我试图给它一个背景颜色,但没有成功。我尝试了不同的布局类型(网格布局),结果相同。
我认为您遇到了名称冲突问题 - 我不确定为什么,但您的 textInput 正在尝试应用 TextInput kv 规则。也许某处有一个 .lower()
。您可以重命名 class,无论如何,使用相同的名称(大小写)并不是好的风格。
你也有几个问题,例如self.add_widget(label)
当没有变量 label
因为你的意思是 self.label
.
出于某种原因,class 名称 textInput
会导致问题。 Class名字无论如何都要大写,我建议在你选择的名字前面加上'my',那么MyTextWidget
怎么样?
第二个主要问题是:TextInput
小部件没有 on_enter
事件。很明显,您阅读了有关 TextInput 的文档,因为文档为 TextInput 的 on_text_validate
事件分配了一个函数(当您按下 Enter 时触发),并且文档用于其事件处理函数的名称是...on_enter.充其量令人困惑,但事件名称是 on_text_validate
,因此您需要将函数分配给该事件。文档应该将他们的事件处理函数命名为 my_func
而不是 on_enter
.
此外,当你为一个事件分配一个函数时,你不是调用该函数的人,而是 kivy 会在未来的某个时间调用该函数,所以你不想这样做:
def do_stuff():
return 'hello'
on_text_validate = do_stuff() #Calls function now!
原因是:代码中的所有函数调用都被函数的 return 值替换(如果没有 [=67=默认情况下还有一个函数 returns None =]语句),所以上面相当于写:
on_text_validate = "hello"
稍后,kivy 将调用分配给 on_text_validate
的任何内容,就好像它是一个函数一样:
on_text_validate(..)
这将产生错误:
TypeError: 'str' object is not callable
你要做的是:将 function name
分配给 on_text_validate
:
def do_stuff():
print 'hello'
on_text_validate = do_stuff #Function does not execute without the trailing: ()
#Time passes...
on_text_validate(...) #kivy will do this after the user hits Enter in the TextInput
--output:--
hello
这很正常python,这意味着执行以下操作是正常的:
def do_stuff():
print 'hello'
f = do_stuff
f() #=> hello
而且更有用:
+-----+ +-----+
func=greet | | x="hello" | |
V | V |
def do_stuff(func): | def show(x): |
func() | print x |
print 'world' | |
| |
def greet(): | |
print 'hello' | |
| +-----+
+--------+ |
| |
do_stuff(greet) show('hello')
--output:- --output:--
hello hello
world
正如@inclement 所指出的,您的代码还有其他问题。请参阅下面的评论:
from kivy.app import App
from kivy.uix.textinput import TextInput
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.label import Label
class MyTextWidget(FloatLayout): #Capitalization here
def __init__(self, **kwargs):
super(MyTextWidget, self).__init__(**kwargs) #Capitalization here
self.label = Label(text = 'No text')
self.textSpace = TextInput(
pos = (20, 20), #The top of the TextInput is off the screen
text = 'Type here',
multiline = False,
on_text_validate = self.changeText #You assign the function name here
)
self.orientation = 'horizontal'
self.size = (450,300)
self.add_widget(self.label) #Nowhere in your code is there a variable
#named label
self.add_widget(self.textSpace) #Nowhere in your code is there
#a variable named textSpace
def changeText(self, textInput):
self.textSpace.text = textInput.text + ": is what you entered"
class myApp(App):
def build(self):
return MyTextWidget()
if __name__ == '__main__':
myApp().run()
请注意,因为您不调用分配给事件的函数,所以您无法指定参数。如果指定参数,例如
on_validate_text = do_stuff('hello', 10)
然后函数立即执行,函数的return值赋给on_validate_text。这就提出了一个问题:你应该如何定义你的函数?它应该接受一个论点吗?两个参数? kivy 将这样调用你的函数:
on_validate_text(arg1, arg2..., argn)
所以你必须阅读文档才能知道 kivy 在调用你的事件处理函数时会指定多少个参数。或者,如果文档不充分,您可以这样做:
def do_stuff(*args):
for arg in args:
print arg
...
...
on_text_validate = do_stuff
然后检查输出。
我正在尝试熟悉一些基本的 Kivy GUI 构建,并正在尝试创建一个 TextField,用户输入一些文本并在他们按下 Return 时更改标签。
我的代码:
from kivy.app import App
from kivy.uix.textinput import TextInput
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.label import Label
class textInput(FloatLayout):
def __init__(self, **kwargs):
super(textInput, self).__init__(**kwargs)
self.label = Label(text = 'No text')
self.textSpace = TextInput(pos = (300,300), text = 'Type here', multiline = False, on_enter = changeText())
self.orientation = 'horizontal'
self.size = (450,300)
self.add_widget(label)
self.add_widget(textSpace)
def changeText(value):
self.textSpace.text = value
class myApp(App):
def build(self):
return textInput()
if __name__ == '__main__':
myApp().run()
尝试从终端执行代码,我收到以下错误:
Traceback (most recent call last):
File "/usr/local/lib/python3.5/site-packages/kivy/lang.py", line 1649, in create_handler
return eval(value, idmap)
File "/usr/local/lib/python3.5/site-packages/kivy/data/style.kv", line 167, in <module>
rgba: self.background_color
File "kivy/weakproxy.pyx", line 19, in kivy.weakproxy.WeakProxy.__getattr__ (/var/folders/yx/bvym8vps2sd_0q19bxy2ddfw0000gn/T/pip-xjpmjrk9-build/kivy/weakproxy.c:1101)
AttributeError: 'textInput' object has no attribute 'background_color'
我试图找到一些关于 TextInput 的教程,其中 none 有关于在小部件上设置背景颜色的内容。
我试图给它一个背景颜色,但没有成功。我尝试了不同的布局类型(网格布局),结果相同。
我认为您遇到了名称冲突问题 - 我不确定为什么,但您的 textInput 正在尝试应用 TextInput kv 规则。也许某处有一个 .lower()
。您可以重命名 class,无论如何,使用相同的名称(大小写)并不是好的风格。
你也有几个问题,例如self.add_widget(label)
当没有变量 label
因为你的意思是 self.label
.
出于某种原因,class 名称 textInput
会导致问题。 Class名字无论如何都要大写,我建议在你选择的名字前面加上'my',那么MyTextWidget
怎么样?
第二个主要问题是:TextInput
小部件没有 on_enter
事件。很明显,您阅读了有关 TextInput 的文档,因为文档为 TextInput 的 on_text_validate
事件分配了一个函数(当您按下 Enter 时触发),并且文档用于其事件处理函数的名称是...on_enter.充其量令人困惑,但事件名称是 on_text_validate
,因此您需要将函数分配给该事件。文档应该将他们的事件处理函数命名为 my_func
而不是 on_enter
.
此外,当你为一个事件分配一个函数时,你不是调用该函数的人,而是 kivy 会在未来的某个时间调用该函数,所以你不想这样做:
def do_stuff():
return 'hello'
on_text_validate = do_stuff() #Calls function now!
原因是:代码中的所有函数调用都被函数的 return 值替换(如果没有 [=67=默认情况下还有一个函数 returns None =]语句),所以上面相当于写:
on_text_validate = "hello"
稍后,kivy 将调用分配给 on_text_validate
的任何内容,就好像它是一个函数一样:
on_text_validate(..)
这将产生错误:
TypeError: 'str' object is not callable
你要做的是:将 function name
分配给 on_text_validate
:
def do_stuff():
print 'hello'
on_text_validate = do_stuff #Function does not execute without the trailing: ()
#Time passes...
on_text_validate(...) #kivy will do this after the user hits Enter in the TextInput
--output:--
hello
这很正常python,这意味着执行以下操作是正常的:
def do_stuff():
print 'hello'
f = do_stuff
f() #=> hello
而且更有用:
+-----+ +-----+
func=greet | | x="hello" | |
V | V |
def do_stuff(func): | def show(x): |
func() | print x |
print 'world' | |
| |
def greet(): | |
print 'hello' | |
| +-----+
+--------+ |
| |
do_stuff(greet) show('hello')
--output:- --output:--
hello hello
world
正如@inclement 所指出的,您的代码还有其他问题。请参阅下面的评论:
from kivy.app import App
from kivy.uix.textinput import TextInput
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.label import Label
class MyTextWidget(FloatLayout): #Capitalization here
def __init__(self, **kwargs):
super(MyTextWidget, self).__init__(**kwargs) #Capitalization here
self.label = Label(text = 'No text')
self.textSpace = TextInput(
pos = (20, 20), #The top of the TextInput is off the screen
text = 'Type here',
multiline = False,
on_text_validate = self.changeText #You assign the function name here
)
self.orientation = 'horizontal'
self.size = (450,300)
self.add_widget(self.label) #Nowhere in your code is there a variable
#named label
self.add_widget(self.textSpace) #Nowhere in your code is there
#a variable named textSpace
def changeText(self, textInput):
self.textSpace.text = textInput.text + ": is what you entered"
class myApp(App):
def build(self):
return MyTextWidget()
if __name__ == '__main__':
myApp().run()
请注意,因为您不调用分配给事件的函数,所以您无法指定参数。如果指定参数,例如
on_validate_text = do_stuff('hello', 10)
然后函数立即执行,函数的return值赋给on_validate_text。这就提出了一个问题:你应该如何定义你的函数?它应该接受一个论点吗?两个参数? kivy 将这样调用你的函数:
on_validate_text(arg1, arg2..., argn)
所以你必须阅读文档才能知道 kivy 在调用你的事件处理函数时会指定多少个参数。或者,如果文档不充分,您可以这样做:
def do_stuff(*args):
for arg in args:
print arg
...
...
on_text_validate = do_stuff
然后检查输出。