Kivy - Stencil View



The StencilView widget in Kivy library limits the canvas area of other children widgets added to it. Any instructions trying to draw outside the stencil view area will be clipped.

Stencil graphics instructions are used under the hood by the StencilView widget. It provides an efficient way to clip the drawing area of children.

The StencilView class is defined in the "kivy.uix.stencilview" module.

from kivy.uix.stencilview import StencilView

It may be noted that StencilView is not a layout. Hence, to add widgets to StencilView, you have to combine a StencilView and a Layout in order to achieve a layout's behavior. Further, you cannot add more than 128 stencil-aware widgets to the StencilView.

The general usage of StencilView is as follows −

st = StencilView(size=(x,y))
w = Widget()
st.add_widget(w)

To understand how exactly StencilView limits the drawable area of a widget, let us first execute certain graphics drawing instructions, and then impose StencilView to see the difference.

Example

In the following code, a mywidget class extends the Widget class, and draws 200 circles at random positions and with random RGB values. (This doesn't use StencilView yet)

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, 350)
class mywidget(Widget):
   def __init__(self, *args):
      super().__init__(*args)
      for i in range(200):
         colorR = random.randint(0, 255)
         colorG = random.randint(0, 255)
         colorB = random.randint(0, 255)
         posx = random.randint(0, Window.width)
         posy = random.randint(0, Window.height)
         self.canvas.add(Color(rgb=(colorR / 255.0, colorG / 255.0, colorB / 255.0)))
         d = 30
         self.canvas.add(Ellipse(pos=(posx, posy), size=(d, d)))

class circlesapp(App):
   def build(self):
      w = mywidget()
      return w

circlesapp().run()

Output

As you can see, the circles are drawn at random positions all over the app window area.

Kivy Stencial View

Now we chall apply the StencilView, and restrict the drawing area to 400×300 pixels in the center of the main window.

The StencilView object is created and we add a Widget object to it. The drawing loop remains the same.

class circlesapp(App):
   def build(self):
      st = StencilView(
         size_hint=(None, None), size=(400, 300),
         pos_hint={'center_x':.5, 'center_y':.5}
      )
      w=widget()
      st.add_widget(w)
      return st

If we now run the app, we should see the random circles appearing inside the stencil area, for all the positions outside it the drawing instructions are restricted.

Kivy Stencil Area
Advertisements