Kivy – Gesture

Kivy – Gesture ”; Previous Next The Kivy framework is capable of recording and identifying the gestures. Gesture is a sequence of touches generated by mouse pointer or fingers on a multitouch device. The kivy.gesture module defines Gesture class whose object is obtained by the (x,y) coordinated of the successive touch events captured on Kivy canvas. Gesture in Kicy is a python implementation of a gesture recognition algorithm by Oleg Dopertchouk. The same module also has GestureDatabase class. You can store one more Gesture objects in the gesture database, and find out if a certain gesture matches with any of the gestures already stored in the database. To create a Gesture object, you need a list of x,y coordinates. For example − from kivy.gesture import Gesture g = Gesture() g.add_stroke(point_list=[(1,1), (3,4), (2,1)]) g.normalize() The add_stroke() method constructs a gesture object from the pairs of coordinates. The normalize() method is needed to run the gesture normalization algorithm and calculates the dot product with self. Such Gesture objects are stored in GestureDatabase. from kivy.gesture import Gesture, GestureDatabase # Create a gesture gdb = GestureDatabase() gdb.add_gesture(g) Against the objects stored in this database, you can compare a certain other object and find if any of the gestures in the database match. g2 = Gesture() # … gdb.find(g2) The kivy.gesture module defines following methods in Gesture class − add_stroke() − constructs a stroke from a list of touch points to the gesture and returns the Stroke instance. normalize() − Runs the gesture normalization algorithm and calculates the dot product with self. get_score() − When a gesture is matched with another, this method returns the matching score. The GestureDatabase class has following important methods − add_gesture() − Add a new gesture to the database. find() − Find a matching gesture in the database. You can define the precision of find with min_score parameter. It should be between 0 to 1. gesture_to_str(gesture) − Convert a gesture into a unique string. str_to_gesture(data) − Convert a unique string to a gesture. Example We define the touch_down(), touch_move() and touch_up() handlers to capture the touch points and draw a pattern from them. All the points with their (touch.x and touch.y) coordinates are collected in a List. When the Add button is pressed, the points List is used to construct a Gesture. The gesture_to_string() method returns a binary string. if instance.text==”Add”: g = Gesture() g.add_stroke(point_list=Drawgesture.points) g.normalize() print (self.d.gdb.gesture_to_str(g)) self.d.gdb.add_gesture(g) print (str(g)) An example of the gesture string might look like this − b”eNprYJmayc4ABj082ZlllXrpqcUlpUWpU3rY3aGsyVM0G6fUTtHoYS3PTCnJmOLuYO9kuU766IwetozUzPSMEqCIC9NEhiUOGj38UO3xBUX5KaXJICmhWZ/F3Pse9LAXlxTlZ6cWT4mdksHQwws1PRgsiLCDrSA/M68EpEgDqIoHqioAJIhQxFgxxX3/LdkuHrnEhh7Gyinu9g9vmvlOTnlRmpQhCFGTIQJXkSHqbn9/U85stZMXcMrfxiZ/TfZI/b2QH8TIXydH/pLsv8/zPDJA8pfJkT9jU3RuT/kBYuTPp4ACaAGq/AmbtU412Qo45Q/YKmn+CRIAyR+nUP4wWD4BVX5DtZ7Sj8IHIPltJ4EeUHdAlY9n/VPH/4ABJL92MtAAvwaS5O3n8Z6ZJZ8Gkt9fDLK/hwGn/CJQ8G1E078eZP5TB5D8RlDyunEAp/xOkPxNNPO3N3WGd3CD/Lf/AND4TTlo5u9vEingUAHLnwDLo4aP/eED54+4yH3AKX/8wNSAFu0JIPkzYHnU8Lc/fSDqzhELUPzuvwBynpkBqvz5AwqZLC4LQPJXwPKo4W9/8f6nX4s0iJK/hk3+6v0dbY9MNUDyNyiUvwNzf2oPT3FyUWpqHqKccHdIcNSwvsgQ4+5QGrZn4XqNnLYpyGJOuwTWtWijiultr197/w2qGNum2DXTs8FiE3XfGfUrYRcrubfWerXfa7DYQ+MFU2RfAsW2rZBcxQZWl2hoGfR1zXocYn2Lvq/Y+wosFmmjo1YijCq20vFeB9NNoFja3KvLS7NQxYJmuyy7qAkWu+iyfccpW6CY3YzNy3Qgen+6T3g5cQFQTGua0tKOVSCxJE9fZ2+FdKCY2OSJS55kgsUKA2Sqn59ydyh+15e/ePZLVLFb3fcWfV8JFpsJcrIuUOxYp++i4ExUsU1toIAGix0MPXe3bCJQbF6L9kKuF2CxlxEr+Gy/AMXK6jnnH8oAiSULRjfas4ajilnGReWf2Q0US6qpmC+nDhZLTAQGqhxQzK/y+bzKF6hiVuVhc6+uAIt1pvBcjG4EiqmVHJ1rmA4W25j2jEnpKQ4xoSKTOb3qKGJF/4BB8OI5SCyFMWdG8sbVOMRe5QrNdlmOKnYtq3HWArAdKZr5hVMq+ZHEUkuTEns4S/JzUosS85JTgTXUzpkgMKs0SQ8Ayq8zuw==” You can add as many gestures as you want. Then, draw a pattern on the canvas and try to find out if any of the gestures matches with this one. The find() method does this work when the Find button is pressed. if instance.text==”Find”: g=Gesture() g.add_stroke(point_list=Drawgesture.points) g.normalize() g1=self.d.gdb.find(g, 0.65) print (g1) Here is the complete code for gesture recognition exercise − from kivy.app import App from kivy.graphics import * from kivy.uix.floatlayout import FloatLayout from kivy.gesture import Gesture, GestureDatabase from kivy.uix.button import Button from kivy.uix.widget import Widget from random import random from kivy.core.window import Window Window.size = (720, 400) class Drawgesture(Widget): points = [] def __init__(self, *args, **kwargs): super(Drawgesture, self).__init__() self.gdb = GestureDatabase() def on_touch_down(self, touch): with self.canvas: self.col = (random(), random(), random()) Color(self.col) touch.ud[“line”] = Line(points=(touch.x, touch.y), width=3) Drawgesture.points.append((touch.x, touch.y)) def on_touch_move(self, touch): with self.canvas: Color(self.col) touch.ud[“line”].points += (touch.x, touch.y) Drawgesture.points.append((touch.x, touch.y)) def on_touch_up(self, touch): print(”touch up”) class gestureApp(App): def pressed(self, instance): if instance.text == ”Add”: g = Gesture() g.add_stroke(point_list=Drawgesture.points) g.normalize() print(self.d.gdb.gesture_to_str(g)) self.d.gdb.add_gesture(g) print(str(g)) if instance.text == ”Find”: g = Gesture() g.add_stroke(point_list=Drawgesture.points) g.normalize() g1 = self.d.gdb.find(g, 0.65) print(g1) if instance.text == ”Clear”: self.d.canvas.clear() def build(self): f = FloatLayout() self.d = Drawgesture() f.add_widget(self.d) b1 = Button( text=”Add”, pos_hint={”x”: 0, ”y”: 0}, size_hint=(None, None) ) f.add_widget(b1) b2 = Button( text=”Find”, pos_hint={”x”: .2, ”y”: 0}, size_hint=(None, None) ) f.add_widget(b2) b3 = Button( text=”Clear”, pos_hint={”x”: .4, ”y”: 0}, size_hint=(None, None) ) f.add_widget(b3) b1.bind(on_press=self.pressed) b2.bind(on_press=self.pressed) b3.bind(on_press=self.pressed) return f gestureApp().run() Output If the match store is greater than or equal to the min_score parameter, you get the following result − (0.7093289348205829, <kivy.gesture.Gesture object at 0x000001B817C70490>) Print Page Previous Next Advertisements ”;

Kivy – SVGs

Kivy – SVGs ”; Previous Next The Kivy framework supports displaying the SVG files, although it is still highly experimental at this stage. In computer graphics, SVG stands for Scalable Vector Graphics, a standard defined by W3 Consortium, for encoding the image data. The image formats such as PNG and JPG are based upon raster graphics, in which the image data is stored in the form of a bitmap, which is a grid of color and location of pixels. The downside of this format is that if the image is magnified, the image starts blurring after a certain point. On the other hand, a vector graphics image is stored mathematically as a series of XML instructions, with which the image is drawn on the screen. that tell a viewing program how to “draw” the image on your screen. The drawing can take place at any size because SVG files are resolution independent. They can be scaled up or down without any drop in quality or sharpness. Kivy library defines Svg class in the “kivy.graphics.svg” module. To draw a SVG image on the canvas of any widget we can use following syntax − from kivy.graphics.svg import Svg with widget.canvas: svg = Svg(“test.svg”) The Svg class has the following properties − anchor_x − Horizontal anchor position for scaling and rotations. Defaults to 0. Values 0,1, and 2 correspond to ”left”, ”center” and ”right”. anchor_y − Vertical anchor position for scaling and rotations. Defaults to 0. Values 0,1, and 2 correspond to ”left”, ”center” and ”right”. color − The default color used for SvgElements that specify “currentColor” height − ”double” source − SVG Filename / source to load. width − ”double” Example The following program uses a “kv” script to load a Scatter widget. An “svg” object is placed in a GridLayout. Give the name of the file as its source property. Here is the “kv” file − <SvgWidget>: do_rotation: True <FloatLayout>: canvas.before: Color: rgb: (1, 1, 1) Rectangle: pos: self.pos size: self.size Python code for Kivy App class − from kivy.uix.scatter import Scatter from kivy.app import App from kivy.graphics.svg import Svg from kivy.uix.gridlayout import GridLayout from kivy.lang import Builder from kivy.core.window import Window Window.size = (720,400) class SvgWidget(Scatter): def __init__(self, filename): super(SvgWidget, self).__init__() with self.canvas: svg = Svg(source=filename) self.size = Window.width, Window.height class SvgDemoApp(App): def build(self): self.root = GridLayout(cols=1) filename = “ship.svg” svg = SvgWidget(filename) self.root.add_widget(svg) svg.scale = 4 SvgDemoApp().run() Output When you run this program, it will produce the following output window − Print Page Previous Next Advertisements ”;

Kivy – Clipboard

Kivy – Clipboard ”; Previous Next The Clipboard object in Kivy framework gives access to the clipboard of the operating system being used. With the help of Kivy”s Clipboard object, one can perform programmatically the cut, copy and paste operations. The clipboard is a temporary buffer in computer”s RAM that most operating systems provide for short-term storage and transfer within and between application programs. In the operating system, this clipboard is a global object. Most operating systems use conventional keyboard shortcuts for carrying out cut, copy and paste data between applications. Normally, the explicit use of the cut-copy-paste operations through the Clipboard is not necessary. However, in some cases it may be useful. The Clipboard object is defined in the “kivy.core.clipboard” module. The following methods are available for Clipboard object − copy() − Copy the value provided in argument data into current clipboard. If data is not of type string it will be converted to string. get() − Get the current data in clipboard, using the mimetype if possible. You not use this method directly. Use paste method instead. get_types() − Return a list of supported mimetypes. paste() − Get text from the system clipboard and return it a usable string. put() − Put data on the clipboard, and attach a mimetype. You should not use this method directly. Use copy method instead. Example In the following example, we have two multiline textboxes and two buttons arranged in a BoxLayout. The COPY button calls gettext() method which copies the selected text from the upper text box to the clipboard. def gettext(self, instance): Clipboard.copy(data=self.text1.selection_text) The PASTE button invokes a callback insert() which pastes the selected text at the cursor position. def insert(self, instance): txt = Clipboard.paste() print (txt) self.text2.insert_text(txt) These two functions are bound to two buttons − self.b1=Button(text=”COPY”) self.b1.bind(on_press=self.gettext) self.b2=Button(text=”PASTE”) self.b2.bind(on_press=self.insert) The build() method assembles the text boxes and buttons. Here is the complete code for this exercise − from kivy.app import App from kivy.uix.boxlayout import BoxLayout from kivy.uix.textinput import TextInput from kivy.uix.button import Button from kivy.core.clipboard import Clipboard from kivy.core.window import Window Window.size = (720, 400) class mydemoapp(App): def gettext(self, instance): Clipboard.copy(data=self.text1.selection_text) def insert(self, instance): txt = Clipboard.paste() print(txt) self.text2.insert_text(txt) def build(self): main = BoxLayout(orientation=”vertical”) self.text1 = TextInput(multiline=True, font_size=32) btns = BoxLayout(orientation=”horizontal”) self.b1 = Button(text=”COPY”) self.b1.bind(on_press=self.gettext) self.b2 = Button(text=”PASTE”) self.b2.bind(on_press=self.insert) self.text2 = TextInput( multiline=True, font_size=32, foreground_color=[0, 0, 1, 1] ) btns.add_widget(self.b1) btns.add_widget(self.b2) main.add_widget(self.text1) main.add_widget(btns) main.add_widget(self.text2) return main mydemoapp().run() Output When the program is run, you will observe two textboxes. Enter Simple is better than Complex in the upper box, and Complex is Complicated in the lower box. Then, select the substring better than, and click the COPY button to store it on the clipboard. Click besides the word Complicated in the lower box, and click the PASTE button. The text on the clipboard will be inserted. Print Page Previous Next Advertisements ”;

Kivy – Code Input

Kivy – Code Input ”; Previous Next The CodeInput widget in the Kivy framework is a specialized TextInput box, capable of displaying editable text that is highlighted as per the syntax of the language lexer chosen. The CodeInput widget requires the pygments package to be installed. The pygments package is a Python syntax highlighter. It is used in applications that need to prettify source code. Pygments supports almost all the languages, including programming, scripting languages and even capable of providing syntax highlighting as per the framework and library syntax. The support comes in the form of Lexer classes. For example, to pickup Python syntax for highlighting the language elements, we need to import Python3Lexer, for C++ code, the CppLexer class needs to be imported. Specifically the Kivy code is highlighted with KivyLexer. If your current working environment doesn”t have pygments installed, run the following command − pip3 install pygments The CodeInput class is defined in the “kivy.uix.codeinput” module. from kivy.uix.codeinput import CodeInput codewidget = CodeInput(**kwargs) The CodeInput class inherits the TextInput class, as well as CodeNavigationBehaviou mixin. Just as a TextInput object, the CodeInput widget is a multiline text box, which can be added to other layout classes. It can be instantiated by specifying following properties − lexer − This holds the selected Lexer used by pygments to highlight the code. It is an ObjectProperty and defaults to PythonLexer. style − The pygments style object to use for formatting. When style_name is set, this will be changed to the corresponding style object. style_name − Name of the pygments style to use for formatting. style_name is an OptionProperty and defaults to ”default”. There are a number of styles available in pygments. Some of the examples are emacs, xcode, vs, bw, colorful and many more. In addition to these, the properties are also inherited from TextInput class. The CodeNavigationBehavior mixin modifies navigation behavior in the TextInput, making it work like an IDE instead of a word processor. Example In the following code, the CodeInput widget uses PythonLexer to perform syntax highlighting of a Python source code. A “code.py” file is read using Python”s file object and the data is assigned to the text property of CodeInput object. from kivy.app import App from kivy.uix.gridlayout import GridLayout from kivy.uix.codeinput import CodeInput from pygments.lexers.python import Python3Lexer from kivy.uix.scrollview import ScrollView from kivy.uix.codeinput import CodeInput from kivy.core.window import Window Window.size = (720,400) class codeinputdemoapp(App): def build(self): scr = ScrollView(size=Window.size) codinp = CodeInput(style=”emacs”) codinp.height = max(codinp.minimum_height, scr.height) file=open(”code.py”) text=file.read() codinp.text=text scr.add_widget(codinp) return scrx codeinputdemoapp().run() To highlight the code which uses Kivy related keywords and functions, load the KivyLexer. You can also experiment with the “pigment” style, changing it to “colorful” or any of the available styles. from kivy.extras.highlight import KivyLexer Read the “kivycode.py” file and load it in the CodeInput box. file=open(”kivycode.py”) text=file.read() codinp.text=text You can also try and display a C++ code with CppLexer − from pygments.lexers.c_cpp import CppLexer This time, change the style to “friendly”. file=open(”test.cpp”) text=file.read() codinp.text=text Print Page Previous Next Advertisements ”;

Kivy – Camera Handling

Kivy – Camera Handling ”; Previous Next The Kivy framework supports Camera hardware through platform-specific providers. The “opncv-python” package enables camera support for Kivy on most operating systems. Hence it is recommended that the opencv-python package should be installed in Kivy”s working environment. In this chapter, we shall build a Camera app with Kivy library”s Camera class. A Camera widget along with a ToggleButton and a normal Button are placed in a vertical box layout to construct the app interface. The Camera instance starts with the initial play state as True, which means the app window will start the video stream from the camera as soon as it is loaded. The Toggle button stops the camera when it is down. It is bound to play() method. The Capture button will be in enabled state only when the camera is playing. def play(self, instance): if instance.state==”down”: self.mycam.play=False instance.text=”Play” self.cb.disabled=True else: self.mycam.play=True instance.text=”Stop” self.cb.disabled=False The Capture button saves the current frame to a PNG file by calling export_to_png() method of the Camera object. As the image is captured, Kivy pops up a message box with a title as Image Captured. def capture(self, instance): if self.tb.text == ”Stop”: self.mycam.export_to_png(“IMG.png”) layout = GridLayout(cols=1) popup = Popup( title=”Image Captured”, title_size=24, content=layout, auto_dismiss=True, size_hint=(None, None), size=(300, 100) ) popup.open() The rest of the code involves the composition of the app interface inside the build() method. Example The complete code is given below − from kivy.app import App from kivy.lang import Builder from kivy.uix.boxlayout import BoxLayout from kivy.uix.togglebutton import ToggleButton from kivy.uix.button import Button from kivy.uix.popup import Popup from kivy.uix.camera import Camera from kivy.core.window import Window Window.size = (720, 400) class TestCamera(App): def build(self): box = BoxLayout(orientation=”vertical”) self.mycam = Camera(play=True, resolution=(640, 480)) box.add_widget(self.mycam) self.tb = ToggleButton( text=”Stop”, size_hint_y=None, height=”48dp”, on_press=self.play ) box.add_widget(self.tb) self.cb = Button( text=”Capture”, size_hint_y=None, height=”48dp”, disabled=False, on_press=self.capture ) box.add_widget(self.cb) return box def play(self, instance): if instance.state == ”down”: self.mycam.play = False instance.text = ”Play” self.cb.disabled = True else: self.mycam.play = True instance.text = ”Stop” self.cb.disabled = False def capture(self, instance): if self.tb.text == ”Stop”: self.mycam.export_to_png(“IMG.png”) layout = GridLayout(cols=1) popup = Popup( title=”Image Captured”, title_size=24, content=layout, auto_dismiss=True, size_hint=(None, None), size=(300, 100) ) popup.open() TestCamera().run() Output The camera instance loads as the application starts. Note that depending on the system and the camera device, it may take a few seconds to start. The toggle button”s caption is stop and the capture button is enabled. If you press the Stop button down, the capture button gets disabled. When in enabled state, press the Capture button. The current frame will be saved as “img.png” with a popup box coming up. Print Page Previous Next Advertisements ”;

Kivy – Page Layout

Kivy – Page Layout ”; Previous Next The PageLayout class in Kivy is a little different from the other container widgets in Kivy. With PageLayout, you can create a simple multi-page layout so that it allows easy flipping from one page to another using borders. Transitions from one page to the next are made by swiping in from the border areas on the right or left hand side. As PageLayout does not support the size_hint, size_hint_min, size_hint_max, or pos_hint properties, only one widget per page can be displayed. However, you can put multiple widgets in a page by putting a compound layout object such as box layout, grid layout or float layout in a single page. The PageLayout class is defined in the “kivy.uix.pagelayout” module. from kivy.uix.pagelayout import PageLayout pg = PageLayout(**kwargs) You can define following properties as keyword arguments for the PageLayout constructor − anim_kwargs − The animation kwargs used to construct the animation. It is a DictProperty and defaults to {”d”: .5, ”t”: ”in_quad”}. border − The width of the border around the current page used to display the previous/next page swipe areas when needed. It is a NumericProperty and defaults to 50dp. page − The currently displayed page, which is a NumericProperty and defaults to 0. swipe_threshold − The threshold used to trigger swipes as ratio of the widget size. swipe_threshold is a NumericProperty and defaults to 0.5. PageLayout recognizes the touch events and you can override the following event handlers − on_touch_down(touch) − Receive a touch down event with touch parameter as MotionEvent class. It returns a bool. If True, the dispatching of the touch event will stop. If False, the event will continue to be dispatched to the rest of the widget tree. on_touch_move(touch) − Receive a touch move event. The touch is in parent coordinates. n_touch_up(touch) − Receive a touch up event. The touch is in parent coordinates. Here is a simple PageLayout example. We place three buttons, each as a separate page. class PageApp(App): def build(self): pg = PageLayout() btn1 = Button(text =”Page 1”) btn2 = Button(text =”Page 2”) btn3 = Button(text =”Page 3”) pg.add_widget(btn1) pg.add_widget(btn2) pg.add_widget(btn3) return pg When run, the Button with page 1 caption displays. Swipe from right to left with the mouse pressed, to display the second and third pages. Swiping from left to right brings the previous pages in focus. Example In the following example, we add two float layouts in the PageLayout. The “kv” file is used to design the UI. First, the Python code to run the PageLayout app − from kivy.app import App from kivy.uix.label import Label from kivy.uix.button import Button from kivy.uix.textinput import TextInput from kivy.uix.floatlayout import FloatLayout from kivy.uix.pagelayout import PageLayout from kivy.config import Config Config.set(”graphics”, ”width”, ”720”) Config.set(”graphics”, ”height”, ”400”) Config.set(”graphics”, ”resizable”, ”1”) class PageDemoApp(App): def build(self): pass if __name__ == ”__main__”: PageDemoApp().run() Given below is the “PageDemo.kv” file script. The PageLayout embeds to FloatLayout objects. Upper float layout is the design of a registration page, and the bottom float layout is the second page consisting of login screen. PageLayout: FloatLayout: orientation:”vertical” Label: text:”Register” font_size:”20pt” pos_hint:{”center_x”: .5, ”center_y”: .9} Label: text:”Name” size_hint:(.2, .1) pos_hint:{”x”:.2, ”y”:.75} TextInput: size_hint:(.4, .1) pos_hint:{”x”:.3, ”y”:.65} Label: text:”email” size_hint:(.2, .1) pos_hint:{”x”:.2, ”y”:.55} TextInput: size_hint:(.4, .1) pos_hint:{”x”:.3, ”y”:.45} Label: text:”Password” size_hint:(.2, .1) pos_hint:{”x”:.2, ”y”:.35} TextInput: password:True size_hint:(.4, .1) pos:(400, 150) pos_hint:{”x”:.3, ”y”:.25} Button: text:”Submit” size_hint : (.2, .1) pos_hint : {”center_x”:.5, ”center_y”:.09} FloatLayout: orientation:”vertical” size:(720,400) canvas.before: Color: rgba: 0,0,0, 1 Rectangle: pos: self.pos size: self.size Label: text:”Login” font_size: ”30pt” pos_hint:{”center_x”: .5, ”center_y”: .75} Label: text:”email” size_hint:(.2, .1) pos_hint:{”x”:.2, ”y”:.55} TextInput: size_hint:(.4, .1) pos_hint:{”x”:.3, ”y”:.45} Label: text:”Password” size_hint:(.2, .1) pos_hint:{”x”:.2, ”y”:.35} TextInput: password:True size_hint:(.4, .1) pos:(400, 150) pos_hint:{”x”:.3, ”y”:.25} Button: text:”Submit” size_hint : (.2, .1) pos_hint : {”center_x”:.5, ”center_y”:.09} Output Save both the “PageDemoApp.py” and “PageDemo.kv” files, and run the Python script. You should first get the registration page. Now, swipe the screen from right to left to make the login page appear in the application window − Print Page Previous Next Advertisements ”;

Kivy – Input Recorder

Kivy – Input Recorder ”; Previous Next The functionality of Recorder class in Kivy framework is still under development, and is still at experimental stage. The Recorder object records the input events such as touch events, key events and click events. They are recorded in a file with a “.kvi” extension. Kivy uses this file and replays the events by generating equivalent fake events and dispatches them to the event loop. The Recorder class is defined in the “kivy.input.recorder” module − from kivy.input.recorder import Recorder rec = Recorder(**kwargs) To start recording, press F8 after the Recorder object is instantiated. The event data is recorded in the “recorder.kvi” file in the current folder. You can specify any other filename to the file attribute. rec = Recorder(filename=”myrecorder.kvi”) Press F7 to replay the events. To control the recording and replay manually, use the record and play properties of the Recorder object. To start recording − rec = Recorder(filename=”myrecorder.kvi”) rec.record = True rec.start() To stop recording − rec.record = False rec.stop() Similarly, to start replay − rec.play = True rec.start() and, to stop playback − rec.play = False rec.stop() You can make the replay go on in a loop − def playloop(instance, value): if value is False: instance.play = True rec = Recorder(filename=”myrecorder.kvi”) rec.bind(play=playloop) rec.play = True Example In the code given below, a Label is added to a Scatter widget, so that you can perform rotation, zooming and transformation. Further, the text property of the label updates as the user changes the contents of the TextInput box. The recording and replay of events is defined on the on_press event of two buttons. Here”s the complete code − from kivy.app import App from kivy.uix.label import Label from kivy.uix.scatter import Scatter from kivy.uix.boxlayout import BoxLayout from kivy.uix.textinput import TextInput from kivy.uix.togglebutton import ToggleButton from kivy.input.recorder import Recorder from kivy.core.window import Window Window.size = (720,400) class scatterdemoapp(App): def build(self): self.rec = Recorder(filename=”myrecorder.kvi”) box=BoxLayout(orientation=”vertical”) box1=BoxLayout(orientation=”horizontal”) text1=TextInput(text=”Hi”, pos_hint={”top”:1},height=100, size_hint=(.5, None)) b1=ToggleButton(text=”record”,pos_hint={”top”:1}, height=100, size_hint=(.25, None)) b1.bind(on_press=self.on_recording) b2=ToggleButton(text=”play”, pos_hint={”top”:1},height=100, size_hint=(.25, None)) b2.bind(on_press=self.on_playing) box1.add_widget(text1) box1.add_widget(b1) box1.add_widget(b2) box.add_widget(box1) scatr=Scatter() self.lbl=Label(text=”Hi”, font_size=60, pos=(Window.width/2-100,200 )) text1.bind(text=self.lbl.setter(”text”)) scatr.add_widget(self.lbl) box.add_widget(scatr) return box def on_recording(self, obj): if obj.state==”down”: self.rec.record=True self.rec.start() else: self.rec.record=False self.rec.stop() def on_playing(self, obj): if obj.state==”down”: self.rec.play=True self.rec.start() else: self.rec.play=False self.rec.stop() scatterdemoapp().run() Output The App window appears as shown here − Hit the record button and all the screen activities including the key_down events are recorded in the “.kvi” file. The console window shows that inputs have been recorded. [INFO ] [Recorder ] Recording inputs to ”myrecorder.kvi” [INFO ] [Recorder ] Recorded 901 events in ”myrecorder.kvi” On pressing the play button to replay the recorded events. Accordingly the console echoes the corresponding log. [INFO ] [Recorder ] Start playing 901 events from ”myrecorder.kvi” Print Page Previous Next Advertisements ”;

Kivy – Canvas Stress

Kivy – Canvas Stress ”; Previous Next In this chapter, we shall find out how efficient is the graphics engine. This can be done by adding a large number of graphics instructions to the canvas of a Kivy object. The program given below measures the time required by the graphics engine to draw ten thousand rectangles at random positions and with randomly chosen color value. Thus it will give an evaluation of how much stress the canvas can sustain. Syntax A rectangle instruction is drawn on the canvas of any Kivy widget with the following syntax − with self.root.canvas: Color(r,g,b,a) Rectangle(pos, size) We shall generate random values for RGB as well as x and y coordinates for the rectangle and display 10, 000 rectangles. The time taken for it is calculated by the perf_counter() function. t1=perf_counter() with self.root.canvas: for i in range(10000): Color(r,g,b,a) Rectangle(pos, size) t2=perf_counter() The time required to draw will be “t2 – t1”. It will be displayed on the title bar of the Kivy app window. Example The complete program is as follows − from kivy.app import App from kivy.graphics import * from kivy.uix.floatlayout import FloatLayout from kivy.uix.gridlayout import GridLayout from kivy.uix.button import Button from random import random as r from time import perf_counter from kivy.core.window import Window Window.size = (720, 400) class StresstestApp(App): def add_rects(self, *args): self.t1 = perf_counter() with self.root.canvas: for i in range(10000): Color(r(), 1, 1, mode=”hsv”) Rectangle( pos=(r() * self.root.width + self.root.x, r() * self.root.height + self.root.y), size=(20, 20) ) self.t2 = perf_counter() self.title = str(self.t2 – self.t1) + “Sec. to draw 10000 rectangles” def build(self): main = GridLayout(cols=1) self.root = FloatLayout(size=(Window.width, 100)) self.btn1 = Button( text=”start”, size_hint=(1, None), pos_hint={”center_x”: .5, ”center_y”: .1} ) self.btn1.bind(on_press=self.add_rects) self.root.add_widget(self.btn1) main.add_widget(self.root) return main StresstestApp().run() Output Run the program and click the “start” button. You will get the time taken displayed on the title bar as shown in the following figure − Print Page Previous Next Advertisements ”;

Kivy – Widget Animation

Kivy – Widget Animation ”; Previous Next Any widget in Kivy toolkit can be animated. All you need to do is define an object of Animation class, choose at least one property of the target widget to animate and specify its final value to be reached after the animation effect is complete. Call the start() method of the Animation object, passing the target widget to it. anim = Animation(property1=value1, property2=value2, ..) anim.start(widget) In the following example, we have placed four Kivy Buttons. Two buttons are placed along the X-axis, keeping the “y” coordinate to 0 and randomizing the “x” coordinate so that one button is placed in first half and the other in second half. Similarly, two more buttons are placed along the Y-axis, their “x” coordinate as 0 and y coordinate value assigned randomly. Buttons placed along X-axis are animated to move up and down. The “y” coordinate value starts from its initial value all the way upto the maximum height of the window, and back to original position. The up and down movement is looping as the repeat property is set to True. Both horizontally placed buttons are bound to the method below − def animate1(self, instance): animation = Animation(pos=(instance.pos[0], Window.height)) animation += Animation(pos=(instance.pos[0], 0)) animation.repeat=True animation.start(instance) Similarly, the vertically arranged buttons b3 and b4 are bound to the following method. Their “x” coordinate value changes from their current value to maximum width and back. def animate2(self, instance): animation = Animation(pos=(Window.width, instance.pos[1])) animation += Animation(pos=(0, instance.pos[1])) animation.repeat=True animation.start(instance) While animation of each button can begin by pressing each button, we can make all the four buttons start animating simultaneously on a touch down event. The above callbacks are triggered by the trigger_action() method. def on_touch_down(self, *args): self.b1.trigger_action(5) self.b2.trigger_action(10) self.b3.trigger_action(15) self.b4.trigger_action(20) Rest of the code is just setting up the UI of four buttons in the build() method of the App class. Example Here”s the complete code − import kivy kivy.require(”1.0.7”) import random from kivy.animation import Animation from kivy.app import App from kivy.uix.button import Button from kivy.uix.floatlayout import FloatLayout from kivy.core.window import Window Window.size = (720,400) class TestApp(App): def animate1(self, instance): animation = Animation(pos=(instance.pos[0], Window.height)) animation += Animation(pos=(instance.pos[0], 0)) animation.repeat=True animation.start(instance) def animate2(self, instance): animation = Animation(pos=(Window.width, instance.pos[1])) animation += Animation(pos=(0, instance.pos[1])) animation.repeat=True animation.start(instance) def on_touch_down(self, *args): self.b1.trigger_action(5) self.b2.trigger_action(10) self.b3.trigger_action(15) self.b4.trigger_action(20) def build(self): box=FloatLayout() # create a button and attach animate() method # as a on_press handler self.b1 = Button( size_hint=(.15, .08), text=”BTN1”, pos=(random.randint(Window.width/2, Window.width), 0), on_press=self.animate1 ) self.b2 = Button( size_hint=(.15, .08), text=”BTN2”, pos=(random.randint(0, Window.width/2), 0), on_press=self.animate1 ) self.b3 = Button( size_hint=(.15, .08), text=”BTN3”, pos=(0, random.randint(0, Window.height/2)), on_press=self.animate2 ) self.b4 = Button( size_hint=(.15, .08), text=”BTN4”, pos=(0, random.randint(Window.height/2, Window.height)), on_press=self.animate2 ) box.add_widget(self.b1) box.add_widget(self.b2) box.add_widget(self.b3) box.add_widget(self.b4) box.bind(on_touch_down=self.on_touch_down) return box if __name__ == ”__main__”: TestApp().run() Output The program starts with the button position randomized. Click anywhere on the application window. Buttons b1 and b2 will start moving up and down. Buttons b3 and b4 will start moving back and forth. This is the initial position − The following figure is a screenshot of button positions while they are moving − Print Page Previous Next Advertisements ”;

Kivy – Canvas

Kivy – Canvas ”; Previous Next Unlike some of the other GUI toolkits (such as TKinter for example), Kivy doesn”t have an independent Canvas widget. Instead, you need to use the canvas that each Widget in Kivy already has by default. When you create a widget, you can create all the instructions needed for drawing on its canvas. We need to note that all the widgets have a different canvas but all the canvas draw in exactly the same drawing space, i.e. the coordinate space. Moreover, the drawing space is not limited to the position and size of the widget. The (0,0) of the drawing space is always the bottom-left corner. The “canvas.before” property particularly useful when you need to manipulate the Color of an instance. On the other hand, canvas.after is used to execute any instructions after the children were added. It is called after traverse all the children. Canvas in Kivy is a set of drawing instructions. To draw, you will need a Canvas object and Instruction objects. For example, to draw a rectangle on a label”s canvas − from kivy.graphics import * with label.canvas: Color(1., 0, 0) # Add a red color # Add a rectangle Rectangle(pos=(10, 10), size=(500, 500)) If you have to do the same by not using Python”s context manager − label.canvas.add(Color(1., 0, 0)) label.canvas.add(Rectangle(size=(500, 500))) You can draw shapes such as rectangle, ellipse, line and Beizer on any widget”s canvas, including the Widget object itself. (Widget class is the base for all the other visual widgets in Kivy) To draw a rectangle on the canvas, we need to specify the pos and size attributes − from kivy.graphics import Rectangle Rectangle(**kwargs) Parameters pos − List of X and Y coordinate values specifying Position of the rectangle, in the format (x, y). size − List specifying the width and height of the rectangle, in the format (width, height). The following code draws a rectangle on the canvas of a Widget object − widget=Widget() with widget.canvas: Color(0,0,1,1) Rectangle(pos=(50,300), size_hint=(None, None), size=(300,200)) The instructions Color and Rectangle are automatically added to the canvas object and will be used when the window is drawn. Syntax You may want to use the “kv” language syntax − Widget: canvas: color: rgb: 0,0,1 Rectangle: pos: self.pos size: self.size A Label object in Kivy doesn”t have a backgound color property. To get around this, you can draw a rectangle fille with the desired color on its canvas to lend background. lbl = Label(text=”Hello World”, font_size=24) with lbl.canvas.before: Color(1,1,0) Rectangle(pos=lbl.pos, size=lbl.size) Or, using the “kv” script − Label: text:”Hello World” font_size:24 canvas.before: Color: rgb: (1,1,0) Rectangle: pos:self.pos size=:self.size Syntax You can draw an ellipse on the canvas using the following syntax − from kivy.graphics import Ellipse Ellipse(*args, **kwargs) Parameters segments − Defines how many segments are needed for drawing the ellipse. More the segments, drawing will be smoother if you have many segments. angle_start − float, defaults to 0.0 and Specifies the starting angle, in degrees, of the disk portion. angle_end − float, defaults to 360.0, specifies the ending angle, in degrees, of the disk portion. angle_end − End angle of the ellipse in degrees, defaults to 360. angle_start − Start angle of the ellipse in degrees, defaults to 0. pos − the position on the canvas coordinate system size − the X and Y radii of the ellipse. If both are equal, it becomes a circle. You can also draw an image directly on the canvas, by assigning the image file as the source property of rectangle or ellipse. Example 1 The following code implements all the drawing instructions explained above to display a rectangle, an ellipse and an image on a widget canvas. It also places a label with a rectangle having background color drawn on its canvas. from kivy.app import App from kivy.uix.image import Image from kivy.uix.widget import Widget from kivy.uix.label import Label from kivy.uix.button import Button from kivy.graphics import * from kivy.core.window import Window Window.size = (720,400) class canvasdemoapp(App): def build(self): widget=Widget() # rectangle on canvas with widget.canvas: Color(0,0,1,1) Rectangle( pos=(50,300), size_hint=(None, None), size=(300,200) ) Color(0.5, .2, 0.4, 1) d = 100 # ellipse Ellipse(pos=(600,100), size=(d+75, d)) Color(.5,.5,.5) # image Rectangle(source=”kivy-logo.png”, pos=(50,100)) Color(1,1,1) Rectangle(source=”TPlogo.png”, pos=(300, 100)) # label with background lbl = Label( text=”Hello World”, font_size=24, pos=(Window.width/2, 300), size =(200,200), color=(0,0,1,1) ) with lbl.canvas.before: Color(1,1,0) Rectangle(pos=lbl.pos, size=lbl.size) widget.add_widget(lbl) btn=Button( text=”Button”, font_size=24, background_color= (.8, .4, .3, 1), pos=(500,10) ) widget.add_widget(btn) return widget canvasdemoapp().run() Output When you run this code, it will produce the following output − Example 2 The Widget object responds to all the touch events (such as on_touch_down and on_touch_move, etc.). In the example below, a callback on the on_touch_down event on a Widget object obtains the coordinates where the touch event occurred and draws a circle (ellipse of equal X and Y radii) with random values of RGB colours. from kivy.app import App from kivy.uix.widget import Widget from kivy.graphics import * import random from kivy.core.window import Window Window.size = (720,300) class widget(Widget): def on_touch_down(self, touch): colorR = random.randint(0, 255) colorG = random.randint(0, 255) colorB = random.randint(0, 255) self.canvas.add(Color( rgb=(colorR / 255.0, colorG / 255.0, colorB / 255.0) )) d = 30 self.canvas.add(Ellipse( pos=(touch.x – d / 2, touch.y – d / 2), size=(d, d) )) class circlesapp(App): def build(self): return widget() circlesapp().run() Output Run the program and generate touch_down event at different places. Circles will be painted at locations. Print Page Previous Next Advertisements ”;