实例教程-Python与Kivy联合开发Android程序及与硬件交互4

<<实例4:简单的触摸手势识别>>

在Ubuntu中创建一个文件夹,命名为pka04,在pka04文件夹中创建一个名称为main.py的Python文件,写入代码如下:

#-*-coding:utf-8-*-

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

Builder.load_file('gesture.kv')     

class myLayout(FloatLayout):
    pass

class pkaApp04(App):
    def build(self):
        return myLayout()

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

在pka04文件夹中创建一个名称为mygestures.py的Python文件,写入代码如下:

from kivy.gesture import GestureDatabase
gdb = GestureDatabase()
cross = gdb.str_to_gesture(
    'eNq1l9tu3DYQhu/1It6bLjicE+cFtrcF/ACBYwv2Iqkt7G7a5u1DDqlT0lZ7I2Mxsj5JP2f4k'
    'xR1OH85//X9+Npfb98uffd7Ow6hO7wM0D0+vD/92T90Q8z/5gN218eH6+3y8aW/5lPqDl8H7g'
    '7/KvLot3WDFCnNzw8f5/dbeSyVx+w/Hvuj3NUNUDMoKXzPj0DsTuGIGiRJGCOVbP4pV7E7/Ra'
    'ORJZMwhS1u35++v9WyFvh7rU2ENEMJI1RuLu+NnEEgyhpjEG2xb1y0H3Ek4vbKA6kEmyKEWdx'
    'WPaJsaVN8eidH2Ef8ejiOIqHdbeQLvolaLTFLxlty7ulsVlaNBKChCnmEpp+uRSSIozRBLbl3'
    'dSoe8m7rdF2kkc3FmGSB1FVphYT6qSejY2sOsXtyYRuLOIkHgEtGrZIKJP4Spk13ZG524qzrX'
    'FWLlHmfok/9UvcFndTUe8Rz8OVA7RIYXtAoluKdke3hJU42j0dQ24pwV7ybiptm1oGE+Rz4il'
    'u9w25q8R3qQtnZ2WKd+TutpLeox4pZmt1jHlh3VR3X8nuUceFdIm4qc5uKy9mapCY339jXKb+'
    '08tjewlmN5VxH3H3lBcLcASZfzGv4osFPiVk5SnmCb6p766y7qbvvvL0Zg2GKtHGCDjPJ2FKi'
    'cfI2wuNuKsCu2i7qYLzdiP3BXGLYIs1DEAo0hh1eyaJeyq8i7b7KdM26ddNXpPO7SCSTnHbSn'
    'ErxXaQVndSJyeJGQOMMe+RJm1aLrk5bku7kYp7SLuPOvlI6/FHs4+87hH2Fats/p8vff8+beV'
    'Vyl5etTucMA/a7kSE+XAbNHVPmcGK2ZKBsxSciTPUyqAwUmdRKouFCToDqgwLU3MWQmVUmDnD'
    '1O7jwsCfOuXFt0JxGKNDaS1rhVwhV5gqpBW0CnEJLaw0G4QKwwrGmlJaQaxw1bp5QRBsBb2iZ'
    'MvczQtSWjGvx09m5uXwmnk1tNKDEGYbZli94TX0aqg1nRrE5Z3WoFdDtWyFBr0aqR2URljLqa'
    '1bbNDrsToywth69QfqGIrcaDVoPSoBqkNtbDE1Wi3iqsAtV6gesSdL0vKCalLNdqa5rjpB3vr'
    'z69utfJTmz8qTFclM/z6/3N4cSteSyvT28bW/PL0/935Ffdsd1n9Q7muT+dNw+Xj59lzFU+6W'
    'Y5L8ug5qwTR/PFH5bDz+AM/6Dqo=')

circle = gdb.str_to_gesture(
    'eNq1WNtyGzcMfd8fiV+iIS4EyB9QXzuTD+g4icbxpLU1ttI2f18QoHa5jpy12qlGAyUw9hA4B'
    'yQh3dx/vf/z++7u8Hz69nSYfumfxzTdfD7C9OHdw+0fh3fTEe2f9kHT84d3z6enx6+HZ/svTz'
    'e/H/N0cxHkg4dNR2lQas8fH+8fTu2x0h6rrzz2a4uajhAZtBS+2yOA0z7tCDMkqjk1y0W1pfN'
    '3+zNN+/dpl0pGqmdLJcv0/PH25+uwr5Onu74EMxErVLeGMT3fNXQDT4C1kopbLVBhG92LB91G'
    'h6RJinRb5A2ZF8euM/aP5JyxhVVShbBiJW9ho7OPcMZG1YTzWzTP2LgAm8XyBmx0bJqxsfSkm'
    '8UqMzaRluVduW5ju5o4qwkKmFWruM28cGLNcW3eriXOWi5kv8zbNK7GcwmbabtP0LXEWcuB7M'
    'Y3pSVxVuRMiGFJaBOcXEzqYrZtwglLEsluBdOSen7R5LiN7nISzehAwsQZwC3yfwJ3PSnP4FZ'
    '31fnNrZX/PS8uKOkCvpBiFkfSF2Sz3PpoC9wVpTqDExXKmkvYmoc274S8nRZ2RXlR1B5u5xGG'
    '1bKcK7a5rtz77ILyIihVSVzL2bb8zuB4LefsgnJ+AzjQtTuUXVBeBCVRTKSMbq1HA/u9b7DMo'
    'hpWSLbPFnZFuf4/6NklzYOki57N1rzAQ8YV/HY3Ztc0L5piXR0BMqAj1GItLmELb/OeXdQ87F'
    'KB8QhIOKDXOXGzOb2BGVc1D9sUaNxJNiPM6LQkbpbS9lbKrmpeVAXluRtTTloXdDs2B95z3UY'
    'XV1UWVe2aPydutqAO6HIt7+KqCm0f7A2+Fk1JkNyiTQ+b8C6rzJdpyrkoQUlhUx6IZ61XEi8u'
    'qyzXKSODTSphAcsAjnBlz4irKvN9CjVxsXEwu2UZ9iopXcmLuqgKWwOMb2JJNoh2y284B9Q11'
    'WU6En2NFuRrFVVXVJdhN71QdDhjBIe3a/3xtg3/n54Oh4d5lFdps7zNmjd7Rt2laY9ad3V88X'
    'Q6apluW0TxiAL2Yc7qTkqjs6RwSjgxnOBOhpUTw6krJ7kz06up2D3iETUiNB7L7pT+WLZhf3h'
    'Ji5CIiLyU4zENZ5SlPYWoVSNZTeGMWv25vWnqzhq1amBKYNaotcTjuUdGrSXy8+rMGbWW7E6u'
    '66SpRUStJRbgvGZDW0QUXqICjgqqjE6q4dSVM19Yrawi4MJqwUIJyTBqg5TGOpC6F1be9ON6t'
    'tdGVkB+XNA2ZYREjwFfCgmSNJKC8/JBjMbyAN0bzLjS5k3dG9RoLJJK95axY9K52KBAohGShB'
    'eCAgncdIFcABj79nJI8JHzT0L6/kg/CQk+mFd5Q/BBtKoRZNzXZz4g+MC0YhSCD+hqXWhGgCA'
    'n1dcFxWAqdV0uND1gMJWCTIyeBnRy7CtZeLl7KbxRLPaykMObXu1k+1rpIb2VL20Hm9siJFKl'
    'TiTqylu7t4SXx31o35ZW3p4zpZVXLyxNsAq5xBIFH/1syH1FCj76Hs69PSn4KHU8k2w+D5aCZ'
    '+lbhKLqGvVJF5+i6hp0yRk3WiLFWSedfepdQOMBCtyFl/GsBe5a9xO4r8axESCNh7UNo+GFVw'
    '95YB57VHuaHL0Pebwy7DYPb79IevLcex/W3n7/0dobhWI+X1buzVEoytprhcYN/OVwf/fl1H7'
    '0sql+ry83CbbfxP66/3z64iF2m9sJZxjmPT3+fni6ffh08L9w/IixfkGL68PDb8enx8/fPsVS'
    'edrnnc05diDYoIA2CpbUvu7t/gFuoPx3')

line = gdb.str_to_gesture(
    'eNq1l8tSKzcQhvfzIrCJS62+v4CzTRUPkCLgAtc5AZfxSXLePq0eIJ7UYGljbwZ6fn0j9a9L6'
    '3b/bf/Xz83T7u3047ibfn1/Hsp0+3iA6e7m5f7P3c10qPFnPHB6u7t5Ox1fv+3e4l+abr8feL'
    'pdhdylbDpIQ2m0P7zuX06tmbVm/kWz35pqOsDcg9aFn9EE6rT9pWxKYfDiXB2KEDBmh/5pAkw'
    'BO2G8KFbFiCRe/3F/+TuU3+Hp6cInnj7oZGhaXFQJHLlPz8GDjtEBvRCiRZgL9eGWcB+CkzpV'
    'YHXGakBFuviaDlQYwxfSYpESY5L4RJ9ek45Xoqerla9ET1frmKtIWlFFgUwMdcDXmr7WMV+rc'
    '8ybCDGzlWjao2PainAletqKY7ZWtEK1ioOpm0KfnrYiX4metuKYrcBgkRitglKlUn89YdqKfi'
    'U8pa8E18KnsTRmLABIic1SWSP3ULSPT2dpzNmiCrVqNWeDEptaH5/W0pi1BQGIFTTOD2uD6C9'
    'ZSm9pwNv2CrHtAwAcZxSAQ7//nOYyXI2f7jIO8VENXN1VlbGI99PD6S6/u9vohVlAkavEWYQk'
    '+omP76kxghaw6MFA39Nb1uvA01j2IXgcI8C11KLSDvH+QSJpq8AQ3bQSl9jIokLgkSUraargE'
    'D12SHSk0ERpE8u2T09P5cxTwYLV3aV6VBryyY6lSkquNaYixq7cny+SlooOsKNQkjhi1YPLMf'
    'X77HRUfIDtMbkxNkh3jjfWz7imnwp9NkKUYxZgiLMpTtk+Os1UHECzC5vFcY2KZaDe0HRSB5x'
    'EM3RiqFFK1iiZGrpdCB6Ou93LZ3mv0up71el2GxNqU6ZtLRyP0yGm1X0L4iLoc9DOg1YyyLQI'
    'QgZlwbSaQV0wDTNoyyBl0OsiyC1IBTZ+/qMzhaQCdNFMM1iX/cvhES7753NwMTzP4RFRW5T//'
    'eRMkWONKb1olmMleR+BLFtjU+Cs8BXwmjxTQipfA+f8qH2tmPNj5UOxSKQ2xZysDzfWFHPmjF'
    'ZcWJPPOTX9EghlzrDZGDHKiNQ7rSZuRT9b4X6hC+kFr06tVT3Neh7VpzUMMNplmfV4ocs6S+i'
    'CJKyal/3zbv/0fGp37+LT9n+j1Lj6hubv/ePpuUniPr+Niiq4ET29ft8d718edvkG8gBq8ff9'
    '6ffD8fXxx0Oi25ZUN3HtNlaOLa1obZvl5l8HGD4O')

square = gdb.str_to_gesture(
    'eNq1mEluIzcYRvd1EXsT4Z+HC6i3AXyAwG0LttEdW7DUSfr2YZHVEgk4KQGCtZH8RD4OH4eSb'
    '1++vfz1c/O0Oxx/vO+mL8v7Hqbbxz1Odzev93/ubqY9lY/ljafD3c3h+P72bXcof8p0+32v0+'
    '2HkrtabNrbrPJSf//28nqcq8VcLf+j2u9zqWmPrQdzF36WKkjTFjasKZKMaJwqGTp355/5a56'
    '2v8FGREAVLIINymebDl/v/78Zqc3o9LS04EgogK6ECeSlhadFTomIHElsKqoS6/I6dPQL5JiW'
    'aSTKYMZEuS6PKs8L5DD03DB11U51+gnX7EVuGOQUgqDIxHGBnKqc1+XkJXLMyAyXUFkPlGqgp'
    'J/irnmSr7s5kThBIhAB5RJ3jZPOcYpbiIG6elkc81Je3DL222TVzTVMPoVJggFESoEGBIJndy'
    'irWWpYRonyAnfNkk9ZQkQYghuLSlnI7tfIa5i8hDmvZFBSUwdH5ixDgKv6XvNkP+mxbDxgo1S'
    '2JIhr3DVPzpOb0IGQ3DTVhTPP8nEH+bpcaqCCJzkHOjlqpISFAp/lZMqMZqIBLnCBvCYqfJKL'
    'EqNyCgkFFNlZjt0qJaD1rS81UTknKuEGqYgRGUZdnsxlnapilrkiKafjurzmKec8Sy12KTPvT'
    'mWn5lle9mS/B2z9MJcaqOSqvC7TflRlkZZ7bM2vNVPFT/PXWJUv8ZO5hkiAQVkz5Wpat9dcVT'
    '/JXoNVv8Quoz3Wl43WZDU/x241V1vfq+UrRTFhLicyAxpecG1YTdXOqVLXP4XSRmcHCg/NIPG'
    'AcnOs22uqdk4Vx777dfaaqp2uU+jPWGdkvcpeU7X8HLvXVP10pWJKOdSFksIMSgNXyWuofrpT'
    'yyUKaewgxuCJeJW8ZuqnB6TxIATspkXGJ16r8vkHwMP7bvd6epx3m5/ny0V/uy1X4wamLaWVt'
    '+PeY7qfoQ8wG8wGvcKACjMGiDMsj/EDpApRB8gV0lhdKpSxulaoI7QKDQfoDfIAY4Cyyf4lc4'
    'lsJaSV4FotYYDzCd69bC6BfYloU5XUQ88GeYBLA9JD+6BfqX0J1VZtGThVKD72i+cS3k+NUKv'
    'WZkFbhMwfVMu+BOXYHy8lENqcaMuM2vyWp+WB2kJpoLrQNhOqI21Toa3HJAttw5c2fOKFtvGz'
    'jrSNmWikbdAAI11WMw8U23L2HCkOdBkxUk8/msyyCVsj0IeAKAP9aI5R+yJ1+mZqPXVYqPc0f'
    'jUSA82FZk9zmWNqo45hG5WfSB1lWOaCqDMwLDkTD/SXoQy0nTzPu5en52P9f4BO25jbLfTvl8'
    'fjc4VWoDZ4fPu+e79/fdjVL7we0jC+cC63nJJ/7N/fHn88NHdM29xw+VUXOp+Mzm7FcPi6+Re'
    'GcFi7')

在以上的mygestures.py文件中我们预定义了四个常用的手势:cross、circle、line、square,分别对应叉子手势、圆圈手势、直线手势和方形手势。

在pka04文件夹中创建一个名称gesture.kv的Kv文件,写入代码如下:

#-*-coding:utf-8-*-
#:import gesture_board gesture_board
<mylayout>:
    orientation:'vertical'
    BoxLayout:
        orientation:'horizontal'
        size_hint_y:.1
        Button:    
            size_hint_x:.3
            font_name:'simhei.ttf'
            text:'叉子图形相似度:'
        Button:    
            id:text1
            text:'cross'
    BoxLayout:
        orientation:'horizontal'
        size_hint_y:.1
        Button:    
            size_hint_x:.3
            font_name:'simhei.ttf'
            text:'横线图形相似度:'
        Button:    
            id:text2
            text:'line'
    BoxLayout:
        orientation:'horizontal'
        size_hint_y:.1
        Button:    
            size_hint_x:.3
            font_name:'simhei.ttf'
            text:'圆圈图形相似度:'
        Button:    
            id:text3
            text:'circle'
    BoxLayout:
        orientation:'horizontal'
        size_hint_y:.1
        Button:    
            size_hint_x:.3
            font_name:'simhei.ttf'
            text:'方形图形相似度:'
        Button:    
            id:text4
            text:'square'
    BoxLayout:
        orientation:'horizontal'
        size_hint_y:.1
        Button:    
            size_hint_x:.3
            font_name:'simhei.ttf'
            text:'大于0.7的手势:'
        Button:    
            id:text5
            text:'gesture'
    BoxLayout:
        orientation:'horizontal'
        size_hint_y:.1
        Button:    
            font_name:'simhei.ttf'
            text:'手势图形为:'
        Button:    
            id:text6
            font_name:'simhei.ttf'
            text:'gesture'
    GestureBoard:
        id:gestureboard1
        atext1:text1   
        atext2:text2
        atext3:text3
        atext4:text4
        atext5:text5
        atext6:text6

以上Kv文件描述窗口的布局,如下图:
实例教程-Python与Kivy联合开发Android程序及与硬件交互4_第1张图片
接下来在pka04文件夹中创建一个名称gesture_board.py的Python文件,写入代码如下:

#-*-coding:utf-8-*-

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.graphics import Color, Ellipse, Line
from kivy.gesture import Gesture, GestureDatabase
from mygestures import cross, circle,line, square

def simplegesture(name, point_list):
    """
    将点集合转换为手势
    """
    g = Gesture()
    g.add_stroke(point_list)
    g.normalize()
    g.name = name
    return g
class GestureBoard(BoxLayout):
    def __init__(self, *args, **kwargs):
        super(GestureBoard, self).__init__()
        self.gdb = GestureDatabase()
        #将已定义的手势添加到手势库
        self.gdb.add_gesture(cross)
        self.gdb.add_gesture(line)
        self.gdb.add_gesture(circle)
        self.gdb.add_gesture(square)

    def on_touch_down(self, touch):
        # 开始收集点到touch.ud
        # 创建线显示这些点
        userdata = touch.ud
        with self.canvas:
            Color(1, 1, 0)
            d = 10.
            Ellipse(pos=(touch.x - d / 2, touch.y - d / 2), size=(d, d))
            userdata['line'] = Line(points=(touch.x, touch.y))
        return True

    def on_touch_move(self, touch):
        # 存储触摸移动的点
        try:
            touch.ud['line'].points += [touch.x, touch.y]
            return True
        except (KeyError) as e:
            pass

    def on_touch_up(self, touch):
        # 触摸结束,显示信息,检测是否有匹配,确认手势

        g = simplegesture('', list(zip(touch.ud['line'].points[::2],
                                       touch.ud['line'].points[1::2])))
        #命令行输出手势字符串
        print("gesture representation:", self.gdb.gesture_to_str(g))

        #输出与所有已知手势的匹配得分        
        self.atext1.text=str(g.get_score(cross))
        self.atext2.text=str(g.get_score(line))
        self.atext3.text=str(g.get_score(circle))
        self.atext4.text=str(g.get_score(square))

        # 在数据库中查找最匹配的手势
        g2 = self.gdb.find(g, minscore=0.70)
        print str(g2)
    
        #输出手势数据v
        self.atext5.text=str(g2)
        if g2:    #如果g2不为空
            if g2[1] == circle:
                self.atext6.text="圆圈"
            if g2[1] == square:
                self.atext6.text="方形"
            if g2[1] == line:
                self.atext6.text="直线"
            if g2[1] == cross:
                self.atext6.text="叉子"
        else:
            self.atext6.text="无"

接下来就可以通过 python main.py 来测试及判断手势了,结果如下图:
实例教程-Python与Kivy联合开发Android程序及与硬件交互4_第2张图片
实例教程-Python与Kivy联合开发Android程序及与硬件交互4_第3张图片
实例教程-Python与Kivy联合开发Android程序及与硬件交互4_第4张图片
实例教程-Python与Kivy联合开发Android程序及与硬件交互4_第5张图片

你可能感兴趣的:(实例教程-Python与Kivy联合开发Android程序及与硬件交互4)