kv根变量在python中是不可访问的

时间:2018-06-01 20:05:35

标签: python-3.x kivy kivy-language

这是我的kv文件,我用kv本身创建了一个自定义小部件和两个根变量名和日期。

<Entry@Widget>:
    name: ''
    date: ''
    size_hint: (None, None)
    canvas.before:
        Color:
            rgba: 1, 1, 1, .4
        Rectangle:
            pos: self.pos
            size: self.size
        Color:
            rgba: 0, 0, 0, 1
    Label:
        text: root.name[0:1]
        color: 41/255, 128/255, 185/255, 1
        pos: root.pos
        font_size: sp(50)
    Label:
        text: root.name[1:]
        color: 41/255, 128/255, 185/255, 1
        pos: root.x+sp(80), root.y+sp(8)
        font_size: sp(30)
    Label:
        text: root.date
        color: 17/255, 80/255, 122/255, 1
        pos: root.x+sp(50), root.y-sp(10)
        font_size: 10

还有一件事。我在下面的python代码中输入了关于Entry小部件的on_touch_down事件:

class Entry(RelativeLayout):

    def on_touch_down(self, touch):
        super(Entry, self).on_touch_down(touch)
        popup = Mypopup()
        popup.open()
        return True

现在在我的主屏幕中我动态添加小部件,所以我在python中输入代码,如下所示: -

class MainScreen(FloatLayout):

    def __init__(self, **kargs):
        super(MainScreen, self).__init__(**kargs)
        layout = GridLayout(cols=1, spacing=10, size_hint_y=None)
        layout.bind(minimum_height=layout.setter('height'))
        for i in range(100):
            entry = Entry(name='Facebook', date='30/21/2', size=(Window.width, sp(100)))
            layout.add_widget(entry)    
        scroll = ScrollView(size_hint=(1, None), height=Window.height)
        scroll.add_widget(layout)
        self.add_widget(scroll)

但它给我一个错误说: -

File "C:\Users\Himanshu Pharawal\AppData\Local\Programs\Python\Python36\lib\site-packages\kivy\app.py", line 802, in run
     root = self.build()    File "main.py", line 47, in build
     return MainScreen()    File "main.py", line 38, in __init__
     entry = Entry(name='Facebook', date='30/21/2', size=(Window.width, sp(100)))    File "main.py", line 21, in __init__
     super(Entry, self).__init__(*args, **kargs)    File "C:\Users\Himanshu Pharawal\AppData\Local\Programs\Python\Python36\lib\site-packages\kivy\uix\relativelayout.py", line 265, in __init__
     super(RelativeLayout, self).__init__(**kw)    File "C:\Users\Himanshu Pharawal\AppData\Local\Programs\Python\Python36\lib\site-packages\kivy\uix\floatlayout.py", line 65, in __init__
     super(FloatLayout, self).__init__(**kwargs)    File "C:\Users\Himanshu Pharawal\AppData\Local\Programs\Python\Python36\lib\site-packages\kivy\uix\layout.py", line 76, in __init__
     super(Layout, self).__init__(**kwargs)    File "C:\Users\Himanshu Pharawal\AppData\Local\Programs\Python\Python36\lib\site-packages\kivy\uix\widget.py", line 337, in __init__
     super(Widget, self).__init__(**kwargs)    File "kivy\_event.pyx", line 254, in kivy._event.EventDispatcher.__init__ (kivy\_event.c:5332) TypeError: object.__init__() takes no parameters

2 个答案:

答案 0 :(得分:0)

您无法表明您有一个名为Entry的类继承自.py中的FloatLayout,另一个Entry继承自.kv中的Widget ,首先它不会消除.kv中创建的条目,你必须做的只是表明你将继续通过<Entry>继续实现该类,而没有.kv中的任何其他内容。

另一方面,名称和日期属性不会自动识别,您必须做的是将它们分开,如下所示:

<强> main.py

from kivy.app import App

from kivy.core.window import Window

from kivy.metrics import sp

from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.popup import Popup

class Mypopup(Popup):
    pass

class Entry(FloatLayout):
    def __init__(self, name="", date="", **kwargs):
        super(Entry, self).__init__(**kwargs)
        self.name = name
        self.date = date

    def on_touch_down(self, touch):
        super(Entry, self).on_touch_down(touch)
        popup = Mypopup()
        popup.open()
        return True

class MainScreen(FloatLayout):
    def __init__(self, **kargs):
        super(MainScreen, self).__init__(**kargs)
        layout = GridLayout(cols=1, spacing=10, size_hint_y=None)
        layout.bind(minimum_height=layout.setter('height'))
        for i in range(100):
            entry = Entry(name='Facebook', date='30/21/2', size=(Window.width, sp(100)))
            layout.add_widget(entry)    
        scroll = ScrollView(size_hint=(1, None), height=Window.height)
        scroll.add_widget(layout)
        self.add_widget(scroll)

class TestApp(App):
    def build(self):
        return MainScreen()

if __name__ == '__main__':
    TestApp().run()

test.kv:

<Entry>:
    name: ''
    date: ''
    size_hint: (None, None)
    canvas.before:
        Color:
            rgba: 1, 1, 1, .4
        Rectangle:
            pos: self.pos
            size: self.size
        Color:
            rgba: 0, 0, 0, 1
    Label:
        text: root.name[0:1]
        color: 41/255, 128/255, 185/255, 1
        pos: root.pos
        font_size: sp(50)
    Label:
        text: root.name[1:]
        color: 41/255, 128/255, 185/255, 1
        pos: root.x+sp(80), root.y+sp(8)
        font_size: sp(30)
    Label:
        text: root.date
        color: 17/255, 80/255, 122/255, 1
        pos: root.x+sp(50), root.y-sp(10)
        font_size: 10

答案 1 :(得分:0)

错误解决方案

解决该错误的解决方案是在类 Entry 中定义两个 StringProperty 变量, name date 在main.py。

覆盖on_touch_down方法

默认情况下,会将触摸事件分派给所有当前显示的窗口小部件。因此,在实例化和打开Entry之前,我们需要检查触摸是否属于Mypopup窗口小部件。

片段

class Entry(RelativeLayout):
    name = StringProperty()
    date = StringProperty()

    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            popup = Mypopup()
            popup.open()
            return True
        return super(Entry, self).on_touch_down(touch)

如果触摸属于我们的窗口小部件,我们将实例化并打开Mypopup,并返回True,表示我们已经消耗了触摸并且不希望它进一步传播。

最后,如果触摸不在我们的小部件之外,我们使用super(…)调用原始事件并返回结果。这使得触摸事件传播能够像通常一样继续传播。

Programming Guide » Input management » Touch event basics

  

默认情况下,会将触摸事件分派给当前显示的所有内容   小部件。这意味着小部件接收触摸事件是否发生   在他们的物理区域内或不。 ... ...为了提供   最大的灵活性,Kivy将事件分派给所有小部件和   让他们决定如何对他们做出反应。如果你只想回应   触摸小部件内的事件,您只需检查:

def on_touch_down(self, touch):
    if self.collide_point(*touch.pos):
        # The touch has occurred inside the widgets area. Do stuff!
        pass

实施例

main.py

from kivy.app import App
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.popup import Popup
from kivy.core.window import Window
from kivy.metrics import sp
from kivy.properties import StringProperty


class Mypopup(Popup):
    pass


class Entry(RelativeLayout):
    name = StringProperty()
    date = StringProperty()

    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            popup = Mypopup()
            popup.open()
            return True
        return super(Entry, self).on_touch_down(touch)


class MainScreen(FloatLayout):

    def __init__(self, **kargs):
        super(MainScreen, self).__init__(**kargs)
        layout = GridLayout(cols=1, spacing=10, size_hint_y=None)
        layout.bind(minimum_height=layout.setter('height'))
        for i in range(100):
            entry = Entry(name='Facebook', date='30/21/2', size=(Window.width, sp(100)))
            layout.add_widget(entry)
        scroll = ScrollView(size_hint=(1, None), height=Window.height)
        scroll.add_widget(layout)
        self.add_widget(scroll)


class TestApp(App):

    def build(self):
        return MainScreen()


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

test.kv

#:kivy 1.10.0

<Mypopup>:
    title: 'Test popup'
    size_hint: (None, None)
    size: (400, 400)
    BoxLayout:
        Label:
            text: 'Hello world'

<Entry@Widget>:
    name: ''
    date: ''
    size_hint: (None, None)
    canvas.before:
        Color:
            rgba: 1, 1, 1, .4
        Rectangle:
            pos: self.pos
            size: self.size
        Color:
            rgba: 0, 0, 0, 1
    Label:
        text: root.name[0:1]
        color: 41/255, 128/255, 185/255, 1
        pos: root.pos
        font_size: sp(50)
    Label:
        text: root.name[1:]
        color: 41/255, 128/255, 185/255, 1
        pos: root.x+sp(80), root.y+sp(8)
        font_size: sp(30)
    Label:
        text: root.date
        color: 17/255, 80/255, 122/255, 1
        pos: root.x+sp(50), root.y-sp(10)
        font_size: 10

输出

Img01 - App Startup Img02 - Mypopup open