Kivy - Multistroke



A MultiStroke Gesture in Kivy is a set of more than one Gesture objects. A Gesture constitutes a single stroke constructed out of a list of touch points between the "touch_down" and "touch_up" events. A MultiStrokeGesture is a collection of such strokes.

The "kivy.multistroke" module implements the Protractor gesture recognition algorithm. The two important classes defined in this module are MultistrokeGesture and Recognizer.

The MultiStrokeGesture class maintains a set of strokes and generates unistroke (i.e., UnistrokeTemplate) permutations that are used for evaluating candidates against this gesture later.

A MultriStroke object is obtained with the help of the following syntax −

from kivy.vector import Vector
from kivy.multistroke import MultistrokeGesture

gesture = MultistrokeGesture('my_gesture', strokes=[
   [Vector(x1, y1), Vector(x2, y2), ...... ], # stroke 1
   [Vector(), Vector(), Vector(), Vector() ] # stroke 2
   #, [stroke 3], [stroke 4], ...
])

Even though all the strokes are combined to a single list (unistroke), you should still specify the strokes individually, and set stroke_sensitive property to True.

Recognizer stores the list of MultistrokeGesture objects. It is the search/database API similar to GestureDatabase. It maintains a list of and allows you to search for a user-input gestures among them.

The Recognizer database is a a container for UnistrokeTemplate objects, and implements the heap permute algorithm to automatically generate all possible stroke orders.

An object of Candidate class represents a set of unistroke paths of user input. This object instantiated automatically by calling Recognizer.recognize().

from kivy.vector import Vector
from kivy.multistroke import Recognizer

gdb = Recognizer()
gdb.recognize([
   [Vector(x1, y1), Vector(x2, y2)],
   [Vector(x3, y3), Vector(x4, y4)]])

The Recognizer object is able to generate these events −

  • on_search_start − Fired when a new search is started using this Recognizer.

  • on_search_complete − Fired when a running search ends, for whatever reason.

These events can be mapped to callbacks to track the progress of search operation done by the Recognizer.recognize() method.

gdb.bind(on_search_start=search_start)
gdb.bind(on_search_complete=search_stop)

The examples of callback methods are as follows −

def search_start(gdb, pt):
   print("A search is starting with {} tasks".format(pt.tasks))
   
def search_stop(gdb, pt):
   best = pt.best
   print("Search ended {}. Best is {} (score {}, distance {})".format(
      pt.status, best['name'], best['score'], best['dist'] ))

Lastly, the "kivy.multistroke" module also provides a ProgressTracker class. It represents an ongoing (or completed) search operation.

The tracker object is instantiated automatically and returned by the Recognizer.recognize() method when it is called. The results attribute is a dictionary that is updated as the recognition operation progresses.

progress = gdb.recognize([
   [Vector(x1, y1), Vector(x2, y2)],
   [Vector(x3, y3), Vector(x4, y4)]])
   
progress.bind(on_progress=my_other_callback)
print(progress.progress)      # = 0
print(result.progress)        # = 1

You can save the multistroke gestures to a file with export_gesture() function.

  • export_gesture(filename=None) − It exports a list of MultistrokeGesture objects to a base64-encoded string that can be decoded to a Python list with the parse_gesture() function. It can also be imported directly to the database using Recognizer.import_gesture(). If filename is specified, the output is written to disk.

  • import_gesture(data=None,filename=None) − The import_gesture() function brings the gesture in a Recognizer database. Use this function to import a list of gestures as formatted by export_gesture(). Either data or filename parameter must be specified. This method accepts optional Recognizer.filter() arguments, if none are specified then all gestures in specified data are imported.

Advertisements