Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how does `with canvas:` (Python `with something() as x:`) works implicitly in Kivy?

Tags:

python

kivy

I just realized there is something mysterious (at least for me) in the way you can add vertex instructions in Kivy with the with Python statement. For example, the way with is used goes something like this:

... some code
class MyWidget(Widget)
    ... some code 

    def some_method (self):
        with self.canvas:
           Rectangle(pos=self.pos, size=self.size)

At the beginning I thought that it was just the with Python statement that I have used occasionally. But suddenly I realize it is not. Usually it looks more like this (example taken from here):

with open('output.txt', 'w') as f:
   f.write('Hi there!')

There is usually an as after the instance and something like and alias to the object. In the Kivy example we don't define and alias which is still ok. But the part that puzzles me is that instruction Rectangle is still associated to the self.canvas. After reading about the with statement, I am quite convinced that the Kivy code should be written like:

class MyWidget(Widget)
    ... some code 

    def some_method (self):
        with self.canvas as c:
           c.add (Rectangle(pos=self.pos, size=self.size))

I am assuming that internally the method add is the one being called. The assumption is based that we can simply add the rectangles with self.add (Rectangle(pos=self.pos, size=self.size))

Am I missing something about the with Python statement? or is this somehow something Kivy implements?

like image 980
toto_tico Avatar asked Jun 23 '13 03:06

toto_tico


People also ask

What is a canvas in KIVY?

The Canvas is the root object used for drawing by a Widget. A kivy canvas is not the place where you paint. Each Widget in Kivy already has a Canvas by default. When you create a widget, you can create all the instructions needed for drawing.

What is root widget in KIVY?

Widgets in Kivy are organized in trees. Your application has a root widget , which usually has children that can have children of their own. Children of a widget are represented as the children attribute, a Kivy ListProperty .

What is Self in KIVY?

self refers to current widget instance Rectangle. Rectangle is not a widget, it is a canvas instruction. self does refer to the current widget, which in your example is the PongGame .


1 Answers

I don't know Kivy, but I think I can guess how this specific construction work.

Instead of keeping a handle to the object you are interacting with (the canvas?), the with statement is programmed to store it in some global variable, hidden to you. Then, the statements you use inside with use that global variable to retrieve the object. At the end of the block, the global variable is cleared as part of cleanup.

The result is a trade-off: code is less explicit (which is usually a desired feature in Python). However, the code is shorter, which might lead to easier understanding (with the assumption that the reader knows how Kivy works). This is actually one of the techniques of making embedded DSLs in Python.

There are some technicalities involved. For example, if you want to be able to nest such constructions (put one with inside another), instead of a simple global variable you would want to use a global variable that keeps a stack of such objects. Also, if you need to deal with threading, you would use a thread-local variable instead of a global one. But the generic mechanism is still the same—Kivy uses some state which is kept in a place outside your direct control.

like image 74
liori Avatar answered Oct 27 '22 01:10

liori