在Kivy app中阅读.kv文件

时间:2014-04-11 06:16:27

标签: kivy

我的文件main.py包含以下代码:

from kivy.app import App
from kivy.config import Config
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.graphics import Color, Ellipse, Line
from kivy.lang import Builder 

from enum import IntEnum
from enum import Enum

from random import random

class Vertice(Widget):
    def __init__(self, pos=None):

        self.pos = pos
        #print self.pos
        print self.size

class Type(IntEnum):
    RIGHT_TOP = 1
    RIGHT_BOTTOM = 2
    LEFT_BOTTOM = 3
    LEFT_TOP = 4
    UNDEFINED = 5

class Direction(Enum):
    CLOCKWISE = 1
    COUNTER_CLOCKWISE = 2
    UNDEFINED = 3

class MindMapWidget(Widget):
    circleShape = [Type.RIGHT_TOP, Type.RIGHT_BOTTOM, Type.LEFT_BOTTOM, Type.LEFT_TOP]
    editing = False
    bounds = []
    vertices = []

    def getType(self, dx, dy, direction):
        result = Type.UNDEFINED

        if direction != Direction.UNDEFINED:
            if dx > 0 and dy > 0:
                if (self.isClockwise(direction)):
                    result = Type.RIGHT_TOP
                else:
                    result = Type.LEFT_BOTTOM
            else:
                if dx < 0 and dy > 0:
                    if (self.isClockwise(direction)):
                        result = Type.RIGHT_BOTTOM
                    else:
                        result = Type.LEFT_TOP
                else:
                    if dx < 0 and dy < 0:
                        if (self.isClockwise(direction)):
                            result = Type.LEFT_BOTTOM
                        else:
                            result = Type.RIGHT_TOP
                    else:
                        if dx > 0 and dy < 0:
                            if (self.isClockwise(direction)):
                                result = Type.LEFT_TOP
                            else:
                                result = Type.RIGHT_BOTTOM

        print result

        return result

    def getPointsXAndY(self, points, index):
        startIndex = index * 2

        return [points[startIndex], points[startIndex + 1]]

    def isClockwise(self, direction):
        return direction == Direction.CLOCKWISE

    def isCircle(self, points, direction): 
        result = False
        shape = self.circleShape
        STEP = 5
        index = 0
        startIndex = 0

        detected = [None] * 4

        currentPoint = self.getPointsXAndY(points, 0)
        currentType = None

        if direction != Direction.UNDEFINED:
            for x in range(STEP, len(points), STEP):
                try:
                    nextPoint = self.getPointsXAndY(points, x)
                except:
                    break

                dx = nextPoint[0] - currentPoint[0]
                dy = -(nextPoint[1] - currentPoint[1])

                if dx == 0 or dy == 0:
                    continue

                newType = self.getType(dx, dy, direction)

                # get the first item, or if the direction has changed
                if currentType is None or currentType != newType:
                    # if we have at least the first direction, check if the next direction is the next step in the circle drawing process
                    if currentType is not None:
                        if newType != shape[index]:
                                break

                    # a circle is a distionct set of drawing directions, so we need to follow them in order, from where the user started drawing
                    else:
                        index = shape.index(newType)
                        startIndex = index

                    self.bounds.insert(index, currentPoint)

                    # don't double up on actions, because we need to compare lists
                    if detected.count(newType) == 0:
                        print index
                        #detected.insert(index, newType)
                        detected[index] = newType

                    # because we may start anywhere in the shape, we may need to do circular traversal of the shape array
                    if direction == Direction.CLOCKWISE:
                        index = (index + 1) % len(shape)
                    else:
                        index = (index - 1) % len(shape)

                currentType = newType
                currentPoint = nextPoint

                if shape == detected:
                    result = True
                    break

        return result


    """def reverseDirection(self, direction):
        result = None

        if direction == Direction.UNDEFINED:
            result = direction
        else:
            if direction == Direction.CLOCKWISE:
                result = Direction.COUNTER_CLOCKWISE
            else:
                result = Direction.CLOCKWISE

        return result"""

    def determineDirection(self, points):
        result = Direction.UNDEFINED
        total = 0
        currentPoint = None
        previousPoint = None

        for i in range(0, len(points)/2, 1):
            currentPoint = self.getPointsXAndY(points, i)

            if previousPoint is not None:
                total += (currentPoint[0] - previousPoint[0]) * (currentPoint[1] + previousPoint[1])

            previousPoint = currentPoint

        if total > 0:
            result = Direction.CLOCKWISE
        else:
            if total < 0:
                result = Direction.COUNTER_CLOCKWISE

        return result

    def on_touch_down(self, touch):
        editing = True
        color = (random(), 1., 1.)

        with self.canvas:
            Color(*color, mode='hsv')
            touch.ud['line'] = Line(points=(touch.x, touch.y))

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

    def on_touch_up(self, touch):
        editing = False
        direction = None

        if len(touch.ud['line'].points) > 0:
            points = touch.ud['line'].points

            if self.isCircle(points, self.determineDirection(points)):
                print "circle"

                with self.canvas:
                    #Ellipse(pos=(self.bounds[0]), size=(50, 50))
                    Vertice(pos=self.bounds[0])
            else:
                print "unknown"


class MindMapApp(App):

    def build(self):
        parent = Widget()
        painter = MindMapWidget()
        clearbtn = Button(text='Clear')
        parent.add_widget(painter)
        parent.add_widget(clearbtn)

        def clear_canvas(obj):
            painter.canvas.clear()

        clearbtn.bind(on_release=clear_canvas)

        Config.set('input','multitouchscreen1','tuio,192.168.0.4:3333')
        return parent


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

我有一个mindmap.kv文件:

#:kivy 1.8

<Vertice>:
    size: 50, 50
    canvas:
        Ellipse:
            pos: self.pos
            size: self.size

声明的输出:

 print self.size

是:

[100,100]

这是默认的小部件大小。当应用程序加载时,它会抛出此调试:

[DEBUG             ] [App         ] Loading kv <./mindmap.kv>

这告诉我.kv文件正在加载而没有被正确解释。我错过了一个链接吗?我不确定如何解决这个问题。

1 个答案:

答案 0 :(得分:3)

MindMap.kv应该是mindmap.kv,即它应该是小写字母。请试试。

另外,为了运行此功能,您需要在代码末尾添加以下行

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

加载.kv文件的另一种方法是使用构建器     Builder.load_file( '路径/到/ file.kv')

了解更多信息,请查看http://kivy.org/docs/guide/lang.html

将您的Vertice类更改为以下内容:

class Vertice(Widget):
    def __init__(self, pos=None):
        super(Vertice, self).__init__()

        self.pos = pos
        #print self.pos
        print self.size