Kivy TextInput字段丢失背景颜色错误

时间:2015-12-10 17:11:11

标签: python-3.x kivy

我正在尝试熟悉一些基本的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上找到一些教程,但没有任何教程在窗口小部件上设置背景颜色。

我试图给它背景颜色但没有成功。我尝试了不同的布局类型(网格布局),结果相同。

2 个答案:

答案 0 :(得分:1)

我认为你有一个名字冲突问题 - 我不确定原因,但你的textInput正在尝试应用TextInput kv规则。也许那里有一个.lower()。你可以重命名这个类,但是不管怎么说都不是一个好的风格(最好是大小写)。

您还可能遇到以下问题:如果没有变量self.add_widget(label),则label因为您的意思是self.label

答案 1 :(得分:1)

由于某种原因,类名textInput会导致问题。无论如何,班级名称应该大写,我建议把我的&#39;在你选择的名字前面,那么MyTextWidget怎么样?

第二个主要问题是:on_enter小部件没有TextInput个事件。很明显,您阅读了有关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语句,函数默认返回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)

然后函数立即执行,函数的返回值分配给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

然后检查输出。