Version

Quick search

EffectWidget

New in version 1.9.0.

The EffectWidget is able to apply a variety of fancy graphical effects to its children. It works by rendering to a series of Fbo instances with custom opengl fragment shaders. As such, effects can freely do almost anything, from inverting the colors of the widget, to anti-aliasing, to emulating the appearance of a crt monitor!

Warning

This code is still experimental, and its API is subject to change in a future version.

The basic usage is as follows:

w = EffectWidget()
w.add_widget(Button(text='Hello!')
w.effects = [InvertEffect(), HorizontalBlurEffect(size=2.0)]

The equivalent in kv would be:

#: import ew kivy.uix.effectwidget
EffectWidget:
    effects: ew.InvertEffect(), ew.HorizontalBlurEffect(size=2.0)
    Button:
        text: 'Hello!'

The effects can be a list of effects of any length, and they will be applied sequentially.

The module comes with a range of prebuilt effects, but the interface is designed to make it easy to create your own. Instead of writing a full glsl shader, you provide a single function that takes some inputs based on the screen (current pixel color, current widget texture etc.). See the sections below for more information.

Usage Guidelines

It is not efficient to resize an EffectWidget, as the Fbo is recreated on each resize event. If you need to resize frequently, consider doing things a different way.

Although some effects have adjustable parameters, it is not efficient to animate these, as the entire shader is reconstructed every time. You should use glsl uniform variables instead. The AdvancedEffectBase may make this easier.

Note

The EffectWidget cannot draw outside its own widget area (pos -> pos + size). Any child widgets overlapping the boundary will be cut off at this point.

Provided Effects

The module comes with several pre-written effects. Some have adjustable properties (e.g. blur radius). Please see the individual effect documentation for more details.

Creating Effects

Effects are designed to make it easy to create and use your own transformations. You do this by creating and using an instance of EffectBase with your own custom EffectBase.glsl property.

The glsl property is a string representing part of a glsl fragment shader. You can include as many functions as you like (the string is simply spliced into the whole shader), but it must implement a function effect as below:

vec4 effect(vec4 color, sampler2D texture, vec2 tex_coords, vec2 coords)
{
    // ... your code here
    return something;  // must be a vec4 representing the new color
}

The full shader will calculate the normal pixel color at each point, then call your effect function to transform it. The parameters are:

  • color: The normal color of the current pixel (i.e. texture sampled at tex_coords).

  • texture: The texture containing the widget’s normal background.

  • tex_coords: The normal texture_coords used to access texture.

  • coords: The pixel indices of the current pixel.

The shader code also has access to two useful uniform variables, time containing the time (in seconds) since the program start, and resolution containing the shape (x pixels, y pixels) of the widget.

For instance, the following simple string (taken from the InvertEffect) would invert the input color but set alpha to 1.0:

vec4 effect(vec4 color, sampler2D texture, vec2 tex_coords, vec2 coords)
{
    return vec4(1.0 - color.xyz, 1.0);
}

You can also set the glsl by automatically loading the string from a file, simply set the EffectBase.source property of an effect.

class kivy.uix.effectwidget.AdvancedEffectBase(*args, **kwargs)[source]

Bases: kivy.uix.effectwidget.EffectBase

An EffectBase with additional behavior to easily set and update uniform variables in your shader.

This class is provided for convenience when implementing your own effects: it is not used by any of those provided with Kivy.

In addition to your base glsl string that must be provided as normal, the AdvancedEffectBase has an extra property uniforms, a dictionary of name-value pairs. Whenever a value is changed, the new value for the uniform variable is uploaded to the shader.

You must still manually declare your uniform variables at the top of your glsl string.

set_fbo_shader(*args)[source]

Sets the Fbo’s shader by splicing the glsl string into a full fragment shader.

The full shader is made up of shader_header + shader_uniforms + self.glsl + shader_footer_effect.

uniforms

A dictionary of uniform variable names and their values. These are automatically uploaded to the fbo shader if appropriate.

uniforms is a DictProperty and defaults to {}.

class kivy.uix.effectwidget.ChannelMixEffect(*args, **kwargs)[source]

Bases: kivy.uix.effectwidget.EffectBase

Mixes the color channels of the input according to the order property. Channels may be arbitrarily rearranged or repeated.

order

The new sorted order of the rgb channels.

order is a ListProperty and defaults to [1, 2, 0], corresponding to (g, b, r).

class kivy.uix.effectwidget.EffectBase(*args, **kwargs)[source]

Bases: kivy.event.EventDispatcher

The base class for GLSL effects. It simply returns its input.

See the module documentation for more details.

fbo

The fbo currently using this effect. The EffectBase automatically handles this.

fbo is an ObjectProperty and defaults to None.

glsl

The glsl string defining your effect function. See the module documentation for more details.

glsl is a StringProperty and defaults to a trivial effect that returns its input.

set_fbo_shader(*args)[source]

Sets the Fbo’s shader by splicing the glsl string into a full fragment shader.

The full shader is made up of shader_header + shader_uniforms + self.glsl + shader_footer_effect.

source

The (optional) filename from which to load the glsl string.

source is a StringProperty and defaults to ‘’.

class kivy.uix.effectwidget.EffectWidget(**kwargs)[source]

Bases: kivy.uix.relativelayout.RelativeLayout

Widget with the ability to apply a series of graphical effects to its children. See the module documentation for more information on setting effects and creating your own.

add_widget(*args, **kwargs)[source]

Add a new widget as a child of this widget.

Parameters:
widget: Widget

Widget to add to our list of children.

index: int, defaults to 0

Index to insert the widget in the list. Notice that the default of 0 means the widget is inserted at the beginning of the list and will thus be drawn on top of other sibling widgets. For a full discussion of the index and widget hierarchy, please see the Widgets Programming Guide.

New in version 1.0.5.

canvas: str, defaults to None

Canvas to add widget’s canvas to. Can be ‘before’, ‘after’ or None for the default canvas.

New in version 1.9.0.

>>> from kivy.uix.button import Button
>>> from kivy.uix.slider import Slider
>>> root = Widget()
>>> root.add_widget(Button())
>>> slider = Slider()
>>> root.add_widget(slider)
background_color

This defines the background color to be used for the fbo in the EffectWidget.

background_color is a ListProperty defaults to (0, 0, 0, 0)

clear_widgets(*args, **kwargs)[source]

Remove all (or the specified) children of this widget. If the ‘children’ argument is specified, it should be a list (or filtered list) of children of the current widget.

Changed in version 1.8.0: The children argument can be used to specify the children you want to remove.

Changed in version 2.1.0: Specifying an empty children list leaves the widgets unchanged. Previously it was treated like None and all children were removed.

effects

List of all the effects to be applied. These should all be instances or subclasses of EffectBase.

effects is a ListProperty and defaults to [].

fbo_list

(internal) List of all the fbos that are being used to apply the effects.

fbo_list is a ListProperty and defaults to [].

refresh_fbo_setup(*args)[source]

(internal) Creates and assigns one Fbo per effect, and makes sure all sizes etc. are correct and consistent.

remove_widget(*args, **kwargs)[source]

Remove a widget from the children of this widget.

Parameters:
widget: Widget

Widget to remove from our children list.

>>> from kivy.uix.button import Button
>>> root = Widget()
>>> button = Button()
>>> root.add_widget(button)
>>> root.remove_widget(button)
texture

The output texture of the final Fbo after all effects have been applied.

texture is an ObjectProperty and defaults to None.

class kivy.uix.effectwidget.FXAAEffect(*args, **kwargs)[source]

Bases: kivy.uix.effectwidget.EffectBase

Applies very simple anti-aliasing via fxaa.

class kivy.uix.effectwidget.HorizontalBlurEffect(*args, **kwargs)[source]

Bases: kivy.uix.effectwidget.EffectBase

Blurs the input horizontally, with the width given by size.

size

The blur width in pixels.

size is a NumericProperty and defaults to 4.0.

class kivy.uix.effectwidget.InvertEffect(*args, **kwargs)[source]

Bases: kivy.uix.effectwidget.EffectBase

Inverts the colors in the input.

class kivy.uix.effectwidget.MonochromeEffect(*args, **kwargs)[source]

Bases: kivy.uix.effectwidget.EffectBase

Returns its input colors in monochrome.

class kivy.uix.effectwidget.PixelateEffect(*args, **kwargs)[source]

Bases: kivy.uix.effectwidget.EffectBase

Pixelates the input according to its pixel_size

pixel_size

Sets the size of a new ‘pixel’ in the effect, in terms of number of ‘real’ pixels.

pixel_size is a NumericProperty and defaults to 10.

class kivy.uix.effectwidget.ScanlinesEffect(*args, **kwargs)[source]

Bases: kivy.uix.effectwidget.EffectBase

Adds scanlines to the input.

class kivy.uix.effectwidget.VerticalBlurEffect(*args, **kwargs)[source]

Bases: kivy.uix.effectwidget.EffectBase

Blurs the input vertically, with the width given by size.

size

The blur width in pixels.

size is a NumericProperty and defaults to 4.0.