Kivy – Layouts in Layouts

Kivy – Layouts in Layouts ”; Previous Next A Layout in Kivy is a container widget. It provides an effective mechanism to construct a GUI having different widgets. Kivy library includes different Layout widgets such as GridLayout, BoxLayout, AnchorLayout, etc. A layout itself is a subclass of Widget class. Hence, we can strategically place one or more layouts inside a layout. In this way, a hierarchy of widget structure can be constructed to design an effective GUI for the app. Any Layout can be enclosed in any other layout. It all depends upon how the app design is envisaged by the developer. Let us plan our app interface layout as per the following schematic figure − Here, we need an uppermost one-column grid layout. Inside it, we want to put a TextInput and two more horizontal box layouts. The first box contains three buttons. The one below it has an Image control and an AnchorLayout widget that has a slider control in it. Example The following “kv” language script uses this planned structure − GridLayout: cols: 1 size: root.width, root.height TextInput: text: “Hello World!” font_size: 32 size_hint: (1, .2) BoxLayout: orientation:”horizontal” size_hint: (1, .2) Button: text:”Btn 1″ font_size:32 Button: text:”Btn 2″ font_size:32 Button: text:”Btn 3″ font_size:32 FloatLayout: Image: source: “kivy-logo.png.png” size_hint: .5, .75 pos_hint: {“center_x”: 0.25} AnchorLayout: anchor_x : ”center” anchor_y : ”top” size_hint: .5, .75 pos_hint: {“center_x”: 0.75} Slider: min:0 max:100 value:25 You can load this “kv” script in the following App class − from kivy.app import App from kivy.uix.widget import Widget from kivy.animation import Animation from kivy.core.window import Window Window.size = (720,400) class MyLayoutApp(App): def build(self): pass if __name__ == ”__main__”: MyLayoutApp().run() Output When you run this code, it will produce the following output window − The final appearance of the app window is similar to the initial plan, which uses “layouts in a layout”. Print Page Previous Next Advertisements ”;

Kivy – Bezier

Kivy – Bezier ”; Previous Next In this chapter, we shall create a Kivy app that will interactively draw a Bezier line along the list of points. If a closed line is drawn making use of the x and y coordinates computed with the help of following code segment, the resulting figure resembles a Pacman character − from math import cos, sin, radians x = y = 300 z = 200 self.points = [x, y] for i in range(45, 360, 45): i = radians(i) self.points.extend([x + cos(i) * z, y + sin(i) * z]) with self.layout.canvas: Color(1.0, 0.0, 1.0) self.line = Line( points=self.points + self.points[:2], dash_offset=10, dash_length=100 ) It generates a line pattern as the following − Then, we draw a Bezier line making use of the same list of points. Color(1.0, 0.0, 1.0) self.line = Line( points=self.points + self.points[:2], dash_offset=0, dash_length=100 ) The Line as well as the Beizer will appear as this − Now we want to construct these two curves dynamically. We use two slidersto change the dash length and offset values of both the line instruction and Bezier instruction as the value property of each slider changes with the following event handlers − def _set_bezier_dash_offset(self, instance, value): # effect to reduce length while increase offset self.bezier.dash_length = 100 – value self.bezier.dash_offset = value def _set_line_dash_offset(self, instance, value): # effect to reduce length while increase offset self.line.dash_length = 100 – value self.line.dash_offset = value As a result, change the slider values to see how the two curves are redrawn dynamically. Example The complete code is given below − from kivy.app import App from kivy.uix.floatlayout import FloatLayout from kivy.uix.label import Label from kivy.uix.slider import Slider from kivy.graphics import Color, Bezier, Line from kivy.core.window import Window Window.size = (720,400) class Main(App): title=”Bezier Example” def _set_bezier_dash_offset(self, instance, value): # effect to reduce length while increase offset self.bezier.dash_length = 100 – value self.bezier.dash_offset = value def _set_line_dash_offset(self, instance, value): # effect to reduce length while increase offset self.line.dash_length = 100 – value self.line.dash_offset = value def build(self): from math import cos, sin, radians x = y = 300 z = 200 # Pacman ! self.points = [x, y] for i in range(45, 360, 45): i = radians(i) self.points.extend([x + cos(i) * z, y + sin(i) * z]) print (self.points) self.layout = FloatLayout() with self.layout.canvas: Color(1.0, 0.0, 0.0) self.bezier = Bezier( points=self.points, segments=150, loop=True, dash_length=100, dash_offset=10 ) Color(1.0, 0.0, 1.0) self.line = Line( points=self.points + self.points[:2], dash_offset=10, dash_length=100) l1=Label( text=”Beizer offset”, pos_hint={”x”:.1}, size_hint=(.1, None), height=50 ) self.layout.add_widget(l1) s1 = Slider( y=0, pos_hint={”x”: .3}, size_hint=(.7, None), height=50 ) self.layout.add_widget(s1) s1.bind(value=self._set_bezier_dash_offset) l2=Label( text=”Line offset”, y=50, pos_hint={”x”:.1}, size_hint=(.1, None), height=50 ) self.layout.add_widget(l2) s2 = Slider( y=50, pos_hint={”x”: .3}, size_hint=(.7, None), height=50 ) self.layout.add_widget(s2) s2.bind(value=self._set_line_dash_offset) return self.layout if __name__ == ”__main__”: Main().run() Output The following screenshots show the curves at two different slider positions − Print Page Previous Next Advertisements ”;

Kivy – Miscellaneous

Kivy – Miscellaneous ”; Previous Next Kivy – Exception Handling In programming, Exception handling refers to the mechanism to prevent the program from crashing if it encounters run-time errors. Kivy provides a class called ExceptionHandler that can manage exceptions raised by Kivy or by your own code. The ExceptionManager class is defined in the “kivy.base” module. You need to import it from “kivy.base” and access the instance that handles Kivy exceptions. You can use this class to add custom handlers for different types of exceptions, or to override the default behavior of Kivy when an exception occurs. For example, you can use the handle_exception method to log the exception, show a message to the user, or exit the app gracefully. from kivy.base import ExceptionHandler, ExceptionManager from logging import Logger class handler(ExceptionHandler): def handle_exception(self, inst): Logger.exception(”Exception caught by ExceptionHandler”) return ExceptionManager.PASS ExceptionManager.add_handler(handler()) A handler function that takes the exception as an argument and returns one of the following values − ExceptionManager.PASS − The exception should be ignored as it was handled by the handler. ExceptionManager.RAISE − The exception should be re-raised. ExceptionManager.USER_HANDLED − The exception was handled by the user and should not be logged. You can also use the handle_exception method to manually handle an exception using the registered handlers. Kivy – Resources Management The “kivy.resources” module includes the functionality to for searching for specific resources across a list of paths particularly if you application deals with multiple paths and projects. When Kivy looks for any resource such as an image file, or a “kv” file, it searches through a predetermined set of folders. You can modify this folder list using the resource_add_path() and resource_remove_path() functions. If you want to use any alternative for the default style.kv or data/defaulttheme0.png you can add the path to your preferred alternatives via the resource_add_path() method. Following functions are defined in the “kivy.resources” module − resource_add_path(path) − Add a custom path to search in. resource_find(filename, use_cache=False) − Search for a resource in the list of paths. Find results are cached for 60 seconds. This can be disabled using use_cache=False. resource_remove_path(path) − Remove a search path. Kivy – Weak Proxy Python uses reference counting algorithm for garbage collection, by keeping count of how many objects are referencing a certain object. If the garbage collector finds that an object is referenced by another object, it can”t be garbage collected. If the counter reaches zero, the garbage collector will free that object. A weak reference is a reference that does not protect the object from getting garbage collected. To create weak references, Python has provided us with a module named weakref. Kivy defines WeakProxy class in kivy.weakproxy module. In order to allow garbage collection, the WeakProxy class provides weak references to objects. It effectively enhances the weakref.proxy by adding comparison support. Kivy – Context The Kivy objects Clock, Cache and Builder are global objects. To use them in the context of the present application you will have to register it. The kivy.context module defines a Context class, which inherits the properties of Python”s built-in dict class. In addition to the dict methods, we have the following functions defined in this module − get_current_context() − Return the current context. egister_context(name, cls, *args, **kwargs) − Register a new context. Print Page Previous Next Advertisements ”;

Kivy – File Syntax

Kivy – File Syntax ”; Previous Next Kivy framework provides a concise and declarative approach to define the widget structure and appearance, with the use of Kivy Language (also known as Kv language). It is a declarative language, used exclusively for building user interfaces in Kivy applications. Its main advantage is that you can separate the UI design from the application logic written in Python. The UI design is defined in a text file which must have a “.kv” extension. It contains the hierarchical sequence of widgets in the application window. The file adapts a tree-like structure, showing the parent-child-sibling relationship among the widgets. Below each widget, its properties, events and event handlers are specified. The kv design language stipulates the following conventions while creating a “.kv” file, so that Python and the Kivy framework can identify and load the appropriate widget structure − Name of the file must be in lowercase It must match with the main class in your application. This class is inherited from the App class. If the name of the class ends with “app” or “App” (for example, HelloApp), the “.kv” file must exclude “app” from its name. It means, for HelloApp class, the name of the “.kv” file must be “hello.kv”. The “.kv” file must be in the same folder in which the Python application file (.py) is present. While using the “.kv” file, the App class doesn”t override the build() method. Declaring a class simply with a pass statement is enough. When the run() method is invoked, Kivy automatically loads the UI from the respective “.kv” file. Let us first remove the build() method from the HelloApp class − Example from kivy.app import App class HelloApp(App): pass app = HelloApp() app.run() The User interface is defined in “hello.kv” file in the same folder. We have a top level BoxLayout with vertical orientation, under which two labels are placed. Save the following script as “hello.kv” file BoxLayout: orientation: ”vertical” Label: text: ”Python Kivy Tutorial” font_size: ”30pt” Label: text: ”From TutorialsPoint” font_size: ”50” color: (1,0,0,1) Now, if you run the “hello.py” program, it will produce the following output − Output In latter chapters, we shall learn how to add event handlers to the widgets in the “.kv” file. Print Page Previous Next Advertisements ”;

Kivy – Inputs

Kivy – Inputs ”; Previous Next The Kivy framework is equipped to receive and process different types of inputs from mouse, touchscreen, gyroscope, accelerometer, etc. Most of the times, Kivy automatically detects available hardware. However, if you want to support custom hardware, you will need to configure kivy accordingly. All the events generated by different input sources are represented by corresponding event classes. The MotionEvent is the base class used for events provided by pointing devices – both touch and non-touch events. Touch events − a motion event that contains at least an X and Y position. All the touch events are dispatched across the Widget tree. No-touch events − An example of non-touch event is the accelerometer as it is a continuous event, without position. It never starts or stops. These events are not dispatched across the Widget tree. Kivy applies post-processing to the input and analyzes it to make meaningful interpretations like − Is it a Double/triple-tap detection? (according to a distance and time threshold) Making events more accurate when the hardware is not accurate Reducing the amount of generated events if the native touch hardware is sending events with nearly the same position After processing, the motion event is dispatched to the Window. if it”s only a motion event, it will be dispatched to on_motion(). On the other hand, if it”s a touch event, the (x,y) position of the touch (0-1 range) will be scaled to the Window size (width/height), and dispatched to − on_touch_down() on_touch_move() on_touch_up() Example In the following example, we”ve defined a new class, called widget, which inherits from Widget. We need to import the Widget class with the following statement − from kivy.uix.widget import Widget There are three methods in the widget class − on_touch_down − It is the initial press. on_touch_move − It is the movement following and while there is a press. on_touch_up − It is the “release” of a press. class widget(Widget): def on_touch_down(self, touch): print(“Down:”,touch) def on_touch_move(self, touch): print(“Move:”,touch) def on_touch_up(self, touch): print(“UP!”,touch) Next, the build() method of App class, returns the widget() object. class MotionApp(App): def build(self): return widget() You can test the code by clicking and dragging on the screen. You should see the mouse”s location for all the movement and pressing you do. Here is the complete code. You can save and run it − from kivy.app import App from kivy.uix.widget import Widget from kivy.config import Config # Configuration Config.set(”graphics”, ”width”, ”720”) Config.set(”graphics”, ”height”, ”400”) Config.set(”graphics”, ”resizable”, ”1”) class widget(Widget): def on_touch_down(self, touch): print(“Down:”,touch) def on_touch_move(self, touch): print(“Move:”,touch) def on_touch_up(self, touch): print(“UP!”,touch) class MotionApp(App): def build(self): return widget() if __name__ == ”__main__”: MotionApp().run() Output The output is an empty application window without any UI widgets in it. Click with the mouse anywhere in the window. Both the “on_touch_down” and “on_touch_up” events will be captured, showing the location of the mouse touch as follows − Down: <MouseMotionEvent spos=(0.4228094575799722, 0.38596491228070173) pos=(304.0, 154.0)> UP! <MouseMotionEvent spos=(0.4228094575799722, 0.38596491228070173) pos=(304.0, 154.0)> Down: <MouseMotionEvent spos=(0.5730180806675939, 0.5137844611528822) pos=(412.0, 205.0)> UP! <MouseMotionEvent spos=(0.5730180806675939, 0.5137844611528822) pos=(412.0, 205.0)> Down: <MouseMotionEvent spos=(0.2517385257301808, 0.5588972431077694) pos=(181.0, 223.0)> UP! <MouseMotionEvent spos=(0.2517385257301808, 0.5588972431077694) pos=(181.0, 223.0)> The spos property of the MouseMotionEvent gives a relative location in the 0-1 coordinate system. The bottom-left corner of the application window corresponds to (0,0) and right-up corner corresponds to (1,1) The pos property shows the actual coordinates where the mouse was clicked. In the above example, it is 378.85 to right and 281.39 pixels upwards from the (0,0) position. Keep the mouse pressed and move it across the window, you will get the instantaneously changing values of the spos and pos properties. For example − Move: <MouseMotionEvent spos=(0.41863699582753827, 0.5338345864661654) pos=(376.3546592489569, 266.38345864661653)> Move: <MouseMotionEvent spos=(0.4172461752433936, 0.531328320802005) pos=(375.1043115438108, 265.1328320802005)> Move: <MouseMotionEvent spos=(0.41585535465924894, 0.5288220551378446) pos=(373.8539638386648, 263.88220551378447)> Event Profiles Based on the input provider and the type of the hardware being used, the event profile contains more information about the input event. The profile is a device specific property if the MotionEvent object. For example, a touch input has an (x,y) position, but might also have pressure information, blob size, an acceleration vector, etc. By adding the following statement in the touch_down event handler, we can find out the features supported by the current device. def on_touch_down(self, touch): print(touch.profile) The output will depend on the type of device. It could be − [”pos”, ”button”] Or, [”pos”, ”angle”] Profile Values The following are some of the profile values supported by default. Sr.No Profile value & Description 1 Angle 2D angle. Accessed via the “a” property. 2 Button Mouse button (”left”, ”right”, ”middle”, ”scrollup” or ”scrolldown”). Accessed via the button property. 3 Markerid Marker or Fiducial ID. Accessed via the fid property. 4 Pos 2D position. Accessed via the x, y or pos properties. 5 pos3d 3D position. Accessed via the x, y or z properties. 6 Pressure Pressure of the contact. Accessed via the pressure property. 7 Shape Contact shape. Accessed via the shape property. Touch Shape In Kivy, the area of interaction during touch event is represented by the term “touch shape”. It refers to the geometric shape used to represent a touch or touch event on the screen. If the touch has a shape, it will be reflected in the ”shape” property. Different touch shapes supported by Kivy are ellipse, rectangle, circle and square. Double / Triple Tap In the context of multi-touch devices, a double tap is the

Kivy – Round Buttons

Kivy – Round Buttons ”; Previous Next All the widgets in Kivy framework are rectangular in shape. A button object always has right-angled corners. Hence, creating buttons with rounded corners doesn”t have a straightforward solution, however we can achieve it by a couple of tricks. Using Image as a Button We can define a class which extends ButtonBehavior mixin and Image class. Using any photo editor, create an elliptical shape looking like a round button, and use it as source property of Image object. You can override the on_press() method of ButtonBehavior class that lets the image be used as a button. from kivy.uix.behaviors import ButtonBehavior from kivy.uix.image import Image class imgbtn(ButtonBehavior, Image): def __init__(self, **kwargs): super(imgbtn, self).__init__(**kwargs) self.source = ”hello.png” self.pos_hint= {”center_x”:.5, ”center_y”:.6} def on_press(self): print(“Button pressed”) We can now use imgbtn object in a Kivy App. KivyMD Buttons Using KivyMD extension, we can design more attractive interfaces. KivyMD is a collection of Material Design widgets, to be used in a Kivy app. The KivyMD library provides different button objects with rounded corners. MDRoundFlatButton MDRoundFlatIconButton MDFillRoundFlatButton MDFillRoundFlatIconButton First, install the KivyMD extension (ensure that Kivy framework is installed earlier) pip3 install KivyMD The App class must be a subclass of MDApp class instead of App class. In this example, we will use MDRoundFlatButton class. Most of its properties are the same as Kivy Button. from kivymd.app import MDApp from kivymd.uix.button import MDRoundFlatButton btn = MDRoundFlatButton( text= ”Hello Python”, font_size= 20, size_hint= (.3, .1), pos_hint= {”center_x”:.5, ”center_y”:.3}, line_width=3 ) Example In the following example, we have a MDApp class. The build() method puts an image button and a MDRoundButton object in the application window. from kivymd.app import MDApp from kivy.core.window import Window from kivy.uix.floatlayout import FloatLayout from kivy.uix.image import Image from kivy.uix.behaviors import ButtonBehavior from kivymd.uix.button import MDRoundFlatButton Window.size = (720, 300) class imgbtn(ButtonBehavior, Image): def __init__(self, **kwargs): super(imgbtn, self).__init__(**kwargs) self.source = ”btnnormal.png” self.pos_hint= {”center_x”:.5, ”center_y”:.6} def on_press(self): print(“Button pressed”) class ButtonApp(MDApp): def build(self): flo = FloatLayout() self.btn1 = imgbtn() self.btn2 = MDRoundFlatButton( text= ”Hello Python”, font_size= 20, size_hint= (.3, .1), pos_hint= {”center_x”:.5, ”center_y”:.3}, line_width=3 ) flo.add_widget(self.btn1) flo.add_widget(self.btn2) return flo if __name__ == ”__main__”: ButtonApp().run() Output Run the application. You should get the following output, having rounded buttons. Using Canvas In Kivy, canvas is the root object for drawing by a widget. To simulate a Label to work as a circular button, we define a class that extends ButtonBehavior and a Label. The “kv” file defines the structure of this object as − <RoundCorneredButton>: canvas: Color: rgb: (1, 0, 0, 1) if self.state == ”normal” else (0, 0, 0, 1) RoundedRectangle: size: (self.size) pos: (self.pos) radius: [200, ] on_release: print(“This is the button made up by the canvas”) The class definition is as follows − class RoundCorneredButton(ButtonBehavior, Label): pass Example We shall use the above class and the kv design in the following App code − from kivy.app import App from kivy.uix.label import Label from kivy.config import Config from kivy.uix.button import ButtonBehavior from kivy.graphics import Rectangle, Color # Configuration Config.set(”graphics”, ”width”, ”720”) Config.set(”graphics”, ”height”, ”300”) Config.set(”graphics”, ”resizable”, ”1”) from kivy.app import App class RoundCorneredButton(ButtonBehavior, Label): pass class HelloApp(App): def build(self): return RoundCorneredButton() HelloApp().run() Output Run the code now. You will get a button with a circular shape, as shown here − Print Page Previous Next Advertisements ”;

Kivy – Action Bar

Kivy – Action Bar ”; Previous Next Kivy framework provides ActionBar widget, which acts as an easy to access menu, usually towards top or bottom of the application window, somewhat similar to ActionBar in Android. The ActionBar class is defined in kivy.uix.actionbar module. The appearance of an action bar depends on the composition of ActionView inside it. The ActionView holds one or more ActionButtons, represented by appropriate text caption and/or icon. The ActionView contains ActionButtons, separators, or ActionGroup. ActionGroup is a collection of ActionButtons. When you click the ActionGroup caption, the buttons are shown in a dropdown. When the ActionBar area becomes too small to accommodate all the contents, widgets are moved into the ActionOverflow area. You may want to display some ActionItems always on the ActionBar, irrespective of the number of items present. If you set the Important property of the ActionButton to True, it will get a priority placement on the bar. Example The code given below puts a label and an ActionBar at the bottom of the app window. The ActionBar displays a couple of ActionButtons, the “on_press” event of each updates the label caption to its own text property. The App code consists of the myActionApp class, whose build method constructs the appearance of the window by loading the associated kv file script. The Python code is shown below − from kivy.app import App from kivy.uix.widget import Widget from kivy.core.window import Window Window.size = (720,400) class mywidget(Widget): def pressed(self, obj): self.ids.l1.text=obj.text class myActionApp(App): def build(self): return mywidget() myActionApp().run() Here, mywidget class subclasses Widget class. Following kv language script, to be saved as myAaction.kv, composes the ActionBar with two buttons. It also places a label to show the caption of the ActionButton pressed. <mywidget> Label: id:l1 text:”Hello” pos_hint:{”center_x”:.5, ”center_y”:1} pos:(root.width/2-150, root.height/2-50) font_size:48 size:(300,100) ActionBar: size:root.width, 50 pos_hint: {”top”:1} background_color: .6, 4, .2, .6 ActionView: use_separator: True ActionPrevious: title: ”Action Bar” with_previous: False ActionOverflow: ActionButton: icon: ”atlas://data/images/defaulttheme/audio-volume-high” ActionButton: important: True text: ”Important” on_press:root.pressed(self) ActionButton: text: ”Btn1” on_press:root.pressed(self) Output Print Page Previous Next Advertisements ”;

Kivy – Clock

Kivy – Clock ”; Previous Next The Clock object in Kivy framework is a global event dispatcher. It is used to schedule and trigger events at specific intervals. To schedule an event for repeated or one-time occurrence, it is bound to a callback function. You can get the time elapsed between the scheduling and the calling of the callback via the “dt” argument, which is the delta-time. The Clock object is defined in the “kivy.clock” module. It consists of methods such as “schedule_once()” and “schedule_interval()” to register functions or methods to be called after a certain delay or at regular intervals. This mechanism is useful for handling timed events, animation updates, and other recurring tasks in your app. Both the functions “schedule_interval()” and “schedule_once()” have two arguments; a callback and the time interval in seconds. from kivy.clock import Clock def clock_callback(dt): “Clock event occurred” # call clock_callback every 2 seconds Clock.schedule_interval(clock_callback, 2) # call clock_callback in 5 seconds Clock.schedule_once(clock_callback, 5) The default value of timeout dt argument is 0. Hence, to call the callback function as early as possible, set the second argument to schedule events to 0 or let the default value be used by not giving using the argument. Clock.schedule_once(my_callback) Using a timeout of “-1” causes the event to occur before the next frame, and setting it to 0 causes the event to occur after the next frame. Triggered Events The Clock object can trigger a clock event with the use of the following functions − schedule_interval(callback, timeout) − This function schedules an event to be called every specified seconds. The function returns a ClockEvent object. Call ClockEvent.cancel() on the returned event to unscheduled the event. schedule_once(callback, timeout=0) − This function schedules an event for one-time execution in specified seconds, and returns ClockEvent object. If timeout is unspecified or 0, the callback will be called after the next frame is rendered. To cancel the event, call ClockEvent.cancel() on the returned event. create_trigger(callback, timeout=0) − This function creates a Trigger event. Unlike the other two functions, the event is not scheduled automatically, you need to call it. Like the other two, cancel the event before it is executed, by calling ClockEvent.cancel(). To schedule it again, simply call the event (event()). The create_trigger() function has the following Parameters − callback − A callback to be executed. from kivy. It takes a timeout parameter to specify how long to wait before calling the callback. interval − a bool parameter indicates whether the callback should be called once (False) or repeatedly. from kivy.clock import Clock def clock_callback(dt): “Clock event occurred” triggerevent = Clock.create_trigger(clock_callback, 5) triggerevent() To unscheduled an event created by either of these ways, use event.cancel() or event.unschedule() methods. Example The code given below runs a countdown timer on the Kivy application window. The “kv” script puts a TextInput box, a label and a button in onecolumn gridlayout. <clockwidget>: GridLayout: cols:1 size:root.size TextInput : font_size : ”30pt” id:t1 halign:”center” valign:”center” Label: id: l1 text : ”Current Value: ” font_size : ”20pt” Button : id:b1 text : ”Start Countdown” font_size:20 The layout class clockwidget inherits GridLayout and binds the command button to a method that schedules a periodic event to occur after every one second. Each time the callback is invoked, the label shows decrementing number, starting from the value entered by the user in the text box. As it reaches 0, the event is unscheduled by its cancel() method. class clockwidget(GridLayout): def __init__(self, *args): super(*args).__init__() self.ids.b1.bind(on_press=self.showtime) def countdown(self, dt): if self.val==0: self.ids.l1.text=”Countdown Stopped” self.ids.l1.color=[1,0,0] self.ev.cancel() self.ids.b1.disabled=False else: self.ids.l1.text=”Current Value: {}”.format(self.val) self.ids.l1.color=[1,1,1] self.val=self.val-1 def showtime(self, *args): self.val=int(self.ids.t1.text) self.ev=Clock.schedule_interval(self.countdown, 1) self.ids.b1.disabled=True The complete code for this exercise is given below − from kivy.app import App from kivy.uix.gridlayout import GridLayout from kivy.clock import Clock from kivy.core.window import Window Window.size = (720, 400) class clockwidget(GridLayout): def __init__(self, *args): super(*args).__init__() self.ids.b1.bind(on_press=self.showtime) def countdown(self, dt): if self.val == 0: self.ids.l1.text = “Countdown Stopped” self.ids.l1.color = [1, 0, 0] self.ev.cancel() self.ids.b1.disabled = False else: self.ids.l1.text = “Current Value: {}”.format(self.val) self.ids.l1.color = [1, 1, 1] self.val = self.val – 1 def showtime(self, *args): self.val = int(self.ids.t1.text) self.ev = Clock.schedule_interval(self.countdown, 1) self.ids.b1.disabled = True class clockdemoapp(App): def build(self): w = clockwidget() w.cols = 1 return w clockdemoapp().run() Output When you run this program, it will show the following app window. Enter the value for the countdown timer and click the “start” button. The label starts updating, decrementing the number of countdown value. As it reaches “0”, the button is enabled again. Print Page Previous Next Advertisements ”;

Kivy – Scatter

Kivy – Scatter ”; Previous Next The Scatter widget in Kivy is especially useful for multitouch devices, wherein it is used to rotate and scale up/down the contents of the application window. The Scatter widget performs matrix transformation by changing the modelview matrix before the children are drawn and the previous matrix is restored when the drawing is finished, so that rotation, scaling and translation can be performed over the entire children tree without changing any widget properties. By default, the Scatter widget does not have a graphical representation: it is a container only. Other widgets are added to the scatter object. However, it should be noted that the Scatter widget is not a layout. You must manage the size of the children yourself. They are positioned relative to the scatter, similar to a RelativeLayout. That”s why dragging the scatter doesn”t change the position of the children, only the position of the scatter does. The scatter size has no impact on the size of its children. The Scatter class is defined in the “kivy.uix.scatter” module. The basic usage of Scatter widget is as follows − from kivy.uix.scatter import Scatter scatter=Scatter.add_widget(Image(source=”logo.jpg”)) The Scatter object is created with all interactions enabled by default. However, you may want to customize the interactions, for which the properties of Scatter object have to be defined accordingly. auto_bring_to_front − If True, the widget will be automatically pushed on the top of parent widget list for drawing. do_rotation − Allow rotation. By default, this property is True. do_scale − Allow scaling. Defaults to True. do_translation − Allow translation on the X or Y axis. scale − The Scale value of the scatter. scale is an AliasProperty and defaults to 1.0. scale_max − Maximum scaling factor allowed. Default value of maximum scaling allowed is upto 1e20. scale_min − Minimum scaling factor allowed with default value being 0.01 Example 1 Here is a simple example of how the Scatter widget works. We just have a label added to the Scatter widget in a Kivy app. The application starts with the label text appearing in the bottom-left corner of the application window. Use your mouse to drag it anywhere on the surface of the window. To simulate multitouch operations on a normal desktop, create two marks on the label area by right-clicking with the mouse and then you can magnify or rotate the label by dragging with the two marks. If you are working on a multitouch device, you can perform scaling and rotation by two finger touch. 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.core.window import Window Window.size = (720,350) class scatterdemoapp(App): def build(self): box=BoxLayout(orientation=”vertical”) scatr=Scatter() lbl=Label(text=”Hello”, font_size=60) scatr.add_widget(lbl) box.add_widget(scatr) return box scatterdemoapp().run() Output Let”s check how the output looks like − Example 2 Alternately, the “kv” language script may also be used to construct the same appearance. BoxLayout: orientation:”vertical” Scatter: Label: text:”Hello” font_size:60 Let us add some more interactivity to the above example. Here, we have added a text input box to the vertical boxlayout, above the Scatter widget. The “text” property is bound to the text property of the label. So, the label text gets updated as you add/remove letters from the text box. All the scatter operations like rotation and scaling can still be performed. 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.core.window import Window Window.size = (720,300) class scatterdemoapp(App): def build(self): box = BoxLayout(orientation=”vertical”) text1 = TextInput( text=”Hello World”, height=100, size_hint=(Window.width, None) ) box.add_widget(text1) scatr = Scatter() self.lbl = Label(text=”Hello”, font_size=60) text1.bind(text=self.lbl.setter(”text”)) scatr.add_widget(self.lbl) box.add_widget(scatr) return box scatterdemoapp().run() Output Now let”s check how the output window looks like − Print Page Previous Next Advertisements ”;

Kivy – Touch Ripple

Kivy – Touch Ripple ”; Previous Next In the Kivy framework, the “Touch Ripple” is not really a widget or any concrete class. Instead, the TouchRippleBehavior mixin adds a touch ripple visual effect to a layout or an individual widget. Normally, Kivy has a default press/release visualization. This class adds the ripple effect from Google Material Design. This mixin class is defined in the “kivy.uix.behaviors.touchripple” module. from kivy.uix.behaviors.touchripple import TouchRippleBehavior The Ripple behavior does not trigger automatically. A concrete class needs to implement this behavior mixin and explicitly call ripple_show() respective ripple_fade() methods manually. To customize the ripple effects, use the following properties − ripple_duration_in − Animation duration taken to show the overlay. It”s a NumericProperty and defaults to 0.5. ripple_duration_out − A NumericProperty defaulting to 0.2 sets the animation duration taken to fade the overlay. ripple_fade_from_alpha − Alpha channel for ripple color the animation starts with. Default value is 0.5. ripple_fade_to_alpha − Alpha channel for ripple color the animation targets to, defaults to 0.8. ripple_rad_default − Default radius the animation starts from. It is a NumericProperty and defaults to 10. ripple_scale − Max scale of the animation overlay calculated from max(width/height) of the decorated widget. The ripple_show() method begins ripple animation on current widget. You need to pass a touch event as argument. The ripple_fade() method is called to finish ripple animation on current widget. The ripple_func_in and ripple_funcion_out are animation callbacks for showing and hiding the overlay. Example In the following example, we have used kv script that puts a label inside a grid layout, and processes the touch_down and touch_up events. The on_touch_down() method calls the ripple_show() method to generate ripple effect with a duration of 3 seconds. The on_touch_up() methods finishes the ripple effect by calling the ripple_fade() method. from kivy.app import App from kivy.uix.gridlayout import GridLayout from kivy.uix.behaviors.touchripple import TouchRippleBehavior from kivy.core.window import Window Window.size = (720,300) class RippleLabel(TouchRippleBehavior, GridLayout): def __init__(self, **kwargs): super(RippleLabel, self).__init__(**kwargs) def on_touch_down(self, touch): collide_point = self.collide_point(touch.x, touch.y) if collide_point: touch.grab(self) self.ripple_duration_in=3 self.ripple_show(touch) return True return False def on_touch_up(self, touch): if touch.grab_current is self: touch.ungrab(self) self.ripple_duration_out=3 self.ripple_fade() return True return False class MyRippleApp(App): def build(self): return RippleLabel(cols=1) MyRippleApp().run() The “kv” script − <RippleLabel>: GridLayout: cols:1 Label: size:(root.width, root.height) pos_hint:{”center_x”:.5, ”center_y”:.5} text:”OK” font_size:100 color:(1,0,0,1) Output Run the program and click the “OK” label. It will produce ripple waves on the window surface. Increase the duration to see the effect. Print Page Previous Next Advertisements ”;