Kivy - Scatter



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 −

kivy scatter

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 −

Kivy Scatter Hello
Advertisements