从自定义kivy小部件到标签输出触摸位置

时间:2013-10-14 20:47:32

标签: python-2.7 kivy

我正在尝试创建一个应用程序,在我单击鼠标的位置绘制一个小椭圆。然后,如果我再次单击,我希望它删除旧椭圆并在新的鼠标单击位置绘制一个新椭圆。我已经把这部分工作了。下一步是将鼠标单击位置打印到两个标签的文本。出于某种原因,我无法弄清楚如何正确引用标签文本来更新它。我的代码如下。 ColorLoopWidget主要基于Kivy教程中的A Simple Paint应用程序。

主要的.py

from kivy.config import Config
Config.set('graphics', 'width', '1000')
Config.set('graphics', 'height', '500')
Config.set('graphics', 'resizable', 0)
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
from kivy.properties import ObjectProperty
from kivy.graphics import Color, Ellipse, Line

Builder.load_file('hueLayout.kv')

class ColorLoopWidget(Widget):
    xlabel = ObjectProperty
    ylabel = ObjectProperty
    def on_touch_down(self, touch):
        with self.canvas:
            self.canvas.clear()
            d = 10
            Ellipse(pos=(touch.x - d/2, touch.y - d/2), size=(d,d))
            touch.ud['line'] = Line(points=(touch.x, touch.y))
##            self.xlabel.text = 'x: '+str(touch.x)
##            self.ylabel.text = 'y: '+str(touch.y)

##    def on_touch_move(self, touch):
##        touch.ud['line'].points += [touch.x, touch.y]



class HueLayout(Widget):
    colorloopwidget = ObjectProperty
    xlabel = ObjectProperty
    ylabel = ObjectProperty

##    def on_touch_down():
##        ColorLoopWidget.on_touch_down()
##
##    def on_touch_move():
##        ColorLoopWidget.on_touch_move()

    def clear_canvas(self):
        self.colorloopwidget.canvas.clear()


class HueApp(App):
    def build(self):
        return HueLayout()

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

HueLayout.kv

<HueLayout>:
    colorloopwidget: colorloopwidget
    xlabel: xlabel
    ylabel: ylabel

    BoxLayout:
        size: 1000, 500
        orientation: 'horizontal'

        ColorLoopWidget:
            id: colorloopwidget
            size: 500, 500

        BoxLayout:
            orientation: 'vertical'
            Button:
                text: 'Clear'
                on_release: root.clear_canvas()
            Label:
                id: xlabel
                text: 'x: '
                size_hint_y: 0.2
            Label:
                id: ylabel
                text: 'y: '
                size_hint_y: 0.2

1 个答案:

答案 0 :(得分:2)

两个问题:

1)你做xlabel = ObjectProperty,但这不是实例化ObjectProperty,而是将xlabel设置为ObjectProperty本身。你想做xlabel = ObjectProperty(),括号创建一个ObjectProperty实例。

2)你的on_touch_down方法在ColorLoopWidget中,并尝试(在你注释掉的代码中)引用self.xlabel和self.ylabel。这不起作用,因为从未设置过那些属性;如果你检查kv,你会看到HueLayout有xlabel: xlabelylabel: ylabel,但内部ColorLoopWidget没有。下面的代码添加了这些属性,以便ColorLoopWidget知道标签,并且它的on_touch_down方法能够引用它们。

以下代码修复了这两个问题,似乎对我有用。

main.py:

from kivy.config import Config
Config.set('graphics', 'width', '1000')
Config.set('graphics', 'height', '500')
Config.set('graphics', 'resizable', 0)
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
from kivy.properties import ObjectProperty
from kivy.graphics import Color, Ellipse, Line

Builder.load_file('hueLayout.kv')

class ColorLoopWidget(Widget):
    xlabel = ObjectProperty()
    ylabel = ObjectProperty()
    def on_touch_down(self, touch):
        with self.canvas:
            self.canvas.clear()
            d = 10
            Ellipse(pos=(touch.x - d/2, touch.y - d/2), size=(d,d))
            touch.ud['line'] = Line(points=(touch.x, touch.y))
            self.xlabel.text = 'x: '+str(touch.x)
            self.ylabel.text = 'y: '+str(touch.y)

##    def on_touch_move(self, touch):
##        touch.ud['line'].points += [touch.x, touch.y]



class HueLayout(Widget):
    colorloopwidget = ObjectProperty()
    xlabel = ObjectProperty()
    ylabel = ObjectProperty()

##    def on_touch_down():
##        ColorLoopWidget.on_touch_down()
##
##    def on_touch_move():
##        ColorLoopWidget.on_touch_move()

    def clear_canvas(self):
        self.colorloopwidget.canvas.clear()


class HueApp(App):
    def build(self):
        return HueLayout()

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

hueLayout.kv:

<HueLayout>:
    colorloopwidget: colorloopwidget
    xlabel: xlabel
    ylabel: ylabel

    BoxLayout:
        size: 1000, 500
        orientation: 'horizontal'

        ColorLoopWidget:
            xlabel: xlabel
            ylabel: ylabel
            id: colorloopwidget
            size: 500, 500

        BoxLayout:
            orientation: 'vertical'
            Button:
                text: 'Clear'
                on_release: root.clear_canvas()
            Label:
                id: xlabel
                text: 'x: '
                size_hint_y: 0.2
            Label:
                id: ylabel
                text: 'y: '
                size_hint_y: 0.2