Kivy - 使用Python

时间:2017-07-20 14:36:25

标签: python-2.7 kivy kivy-language

我希望使用KV语言控制在Kivy中创建的简单Ellipse小部件。几天来,我一直在努力阅读并完成了Kivy:Python中的交互式应用程序练习,Roberto Ulloa和Ben Rousch在https://bradfortner.wordpress.com/2017/07/19/good-kivy-tutorial/的在线研讨会。

虽然这些教程中提供的示例似乎可以在预定义的Kivy小部件(即按钮和标签)上正常工作,但我无法控制我定义的小部件,例如下面的代码中所示的圆形椭圆

在代码(下面)中,我在第10行和第45行创建了圆形椭圆类Widget(名为Ball)。我将Ball Widget放在我的布局上(第29行),然后将Widget命名为my_circle(第30行)。最后,我提供了将窗口小部件链接到Python的代码(第26行),因此Python代码可以控制窗口小部件。

然而,当我按下"收缩圈"按钮和shrink_circle()函数被调用对小部件没有影响。知道代码出错的地方吗?我很想知道,因为它对我来说变得相当神秘,我找不到任何简单的解释我需要做些什么来纠正这个问题。

以下完整代码。

提前感谢。

.... ....布拉德

# Modified from https://github.com/brousch/pyohio-kivy-tutorial/blob/master/tutorial/step11_tts/saythis.kv

import kivy
from kivy.lang import Builder
from kivy.app import App
from kivy.properties import ObjectProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.widget import Widget
kivy.require("1.9.1")

Builder.load_string('''
<Ball>:
    size: 1, 1
    canvas:
        Color:
            rgba: 1, 1, 1, 1
        Ellipse:
            pos: 350,290
            size: 70,70
<ShrinkThis>:
    button_font_size: '30sp'
    canvas:
        Color:
            rgba: 0, 0, 0, 1
        Rectangle:        
            pos: self.pos
            size: self.size
    my_circle: my_circle
    BoxLayout:
        orientation: 'horizontal'
        Ball:
            id: my_circle
        Button:
            text: 'Shrink Circle'
            font_size: root.button_font_size
            size_hint: 1, None
            on_press: root.shrink_circle()            
''')

class ShrinkThis(BoxLayout):

    my_circle = ObjectProperty(None)

    def shrink_circle(self):
        self.my_circle.size = (10,10)

class Ball(Widget):
    pass

class ShrinkThisApp(App):
    def build(self):
        return ShrinkThis()

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

2 个答案:

答案 0 :(得分:1)

请记住,kivy canvas不是一个小部件,它不是您绘制的空间,它只是一个指令集来绘制。 Ball应该是一个小部件。

另一方面,如果未禁用size属性,则忽略size_hint属性

简化示例:

import kivy
kivy.require("1.9.1")

from kivy.app import App
from kivy.lang import Builder
from kivy.properties import ObjectProperty
from kivy.uix.floatlayout import FloatLayout


Builder.load_string('''
<Ball@Widget>
    size: 70, 70
    pos: 350,290
    size_hint: None, None

    canvas:
        Color:
            rgba: 1, 1, 1, 1
        Ellipse:
            pos: self.pos
            size: self.size

<ShrinkThis>:
    button_font_size: '30sp'
    my_circle: my_circle

    Ball:
        id: my_circle
    Button:
        text: 'Shrink Circle'
        font_size: root.button_font_size
        size_hint: 1, None
        on_press: root.shrink_circle()            
''')

<强>输出:

enter code here

答案 1 :(得分:0)

现在神秘已经解决,为了完成这个问题,我已经发布了下面的完整工作代码。我还在这个更新的代码中添加了位置更改,以便将来看到这一点的人也知道如何编码位置更改。

对Roberto Ulloa来说也是公平的,他将Kivy:Python中的交互式应用程序写入Ben Rousch的在线研讨会;

  • Ulloa的书确实解决了FJSevella在上面的代码中纠正的小部件寻址问题。虽然他的书很好但是Ulloa可能在一章中使用了多个让我困惑的.kv文件。我认为寻址()被用来引用不同的.kv文件。
  • Rousch的在线研讨会没有解决Kivy的画布问题,即使我已经读过你应该了解的关于Kivy的10件事情,我仍然试图包裹我的大脑。帆布好几次。 (http://robertour.com/2013/07/19/10-things-you-should-know-about-the-kivy-canvas/)。

以下是完整的工作代码;

# Modified from https://github.com/brousch/pyohio-kivy-tutorial/blob/master/tutorial/step11_tts/saythis.kv
# And https://stackoverflow.com/questions/45217816/kivy-addressing-an-ellipse-widget-created-in-kv-language-using-python

import kivy
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import ObjectProperty
from kivy.uix.widget import Widget
kivy.require("1.9.1")

Builder.load_string('''
<Ball@Widget>
    size: 70, 70
    pos: 350,290
    size_hint: None, None
    canvas:
        Color:
            rgba: 1, 1, 1, 1
        Ellipse:
            pos: self.pos
            size: self.size
<ShrinkThis>:
    button_font_size: '30sp'
    my_circle: my_circle
    Ball:
        id: my_circle
    Button:
        text: 'Shrink & Reposition Circle'
        font_size: root.button_font_size
        size_hint: 1, None
        on_press: root.shrink_reposition_circle()            
''')

class ShrinkThis(FloatLayout):

    my_circle = ObjectProperty(None)

    def shrink_reposition_circle(self):
        self.my_circle.size = (10,10)
        self.my_circle.pos = (300, 500)

class Ball(Widget):
    pass

class ShrinkThisApp(App):
    def build(self):
        return ShrinkThis()

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