Sometimes you need to be able to draw things that don’t use LVGL’s objects, buttons, sliders, etc. It is possible to do this, if you directly manipulate LVGL draw engine.
This post is intended to explain some of the more complex features of LVGL’s draw engine. You can find the fundamentals of the draw engine at How to Draw a Rectangle with Micropython LVGL.
Today, I will explain LVGL’s polygon. A polygon is essentially any shape that is not a circle and does not have parts of a circle in it. Some common polygons are squares, triangles, pentagons, etc.
There is one main limitation of LVGL’s polygon; LVGL can’t draw concave polygons (don’t worry if you don’t know what that is I will explain it latter.)
The Screen
To get the code below to work with your screen, you will need to add your screen setup code to the beginning of it. If you want more information, you can try How to get a LVGL Micropython screen to work.
Here is the code we will work through
import lvgl
def draw(data):
background = lvgl.draw_rect_dsc_t()
background.init()
background.bg_color = lvgl.color_hex(0x00ff00)
points = []
def add_point(x,y):
pt = lvgl.point_t()
pt.x = x
pt.y = y
points.append(pt)
add_point(160,120)
add_point(0,100)
add_point(100,200)
add_point(250,170)
draw_ctx = data.get_draw_ctx()
draw_ctx.polygon(background,points,len(points))
scr = lvgl.scr_act()
scr.add_event_cb(draw,lvgl.EVENT.DRAW_MAIN_END,None)
scr.invalidate()
Understanding This LVGL Code
Ok, now that you have seen all the code, let’s step through each section, so you can understand exactly what each part does. This will make it much easier to actually use polygons in your projects…
The Setup
We start by importing the LVGL library. Around here is a good place to put your screen setup code.
import lvgl
The Draw Function
We need to create a function to draw the polygon on the screen, so we start by defining it.
def draw(data):
Behind the scenes polygons use the same object as rectangles to apply styles to them, so we create a new one.
background = lvgl.draw_rect_dsc_t()
Next we have to initialize that variable.
background.init()
Just to show what this is for, we will set the polygons background color to green.
background.bg_color = lvgl.color_hex(0x00ff00)
To create a polygon you give LVGL a list of points and it will color in between those points. There are some restrictions on the points you give it, they are explained in the next section. For now we create an empty list.
points = []
To make this code smaller, we are going to create a function that helps us add points to that list. will start by defining it.
def add_point(x,y):
Inside this function, we start by creating a LVGL point.
pt = lvgl.point_t()
After that we will set the point’s x and y values.
pt.x = x
pt.y = y
Lastly, we append that point to the list of points.
points.append(pt)
Now we use the function we just created to add four points to our list.
add_point(160,120)
add_point(0,100)
add_point(100,200)
add_point(250,170)
To be able to draw on the screen, we need to get the draw_ctx class.
draw_ctx = data.get_draw_ctx()
Finally, we use draw_ctx to put our polygon on the screen. To make that work we have to give draw_ctx the background variable we created, the list of points, and how many points are in our list.
draw_ctx.polygon(background,points,len(points))
Restrictions
There are two types of polygons convex and concave. LVGL can not draw concave polygons.
What makes Concave polygons special is that one point dips inside of all the others. That part of the polygon looks like the > symbol.
If you do accidentally tell LVGL to draw one of these, all that will happen is that you board will freeze and you will have to restart it.
If you want to draw a concave polygon, you need to divide it into smaller pieces and draw those pieces separately.
Applying The Draw Function
We created a function to draw a polygon, but we need to add it to some object so its visible. For this example we will add it to the screen object. The first thing we need to do is collect the screen object.
scr = lvgl.scr_act()
Then we add our draw function to the screen.
scr.add_event_cb(draw,lvgl.EVENT.DRAW_MAIN_END,None)
And of course, we invalidate the screen so are polygon gets drawn.
scr.invalidate()
What Next?
Now that you have seen the code, try running it. You should see a green polygon that looks kind of like a rectangle that has been squished. If you modify the list of points you can create lots of new shapes. Don’t forget that you can also change the number of points you use.
The background variable we created is very similar to styles and has many of the same properties. You can use it to customize you polygons color,opacity, and several other properties.
The Polygon is probably the most important shape to know how to draw. The next shapes I would suggest learning is LVGL Arcs and Circles using polygons and arcs you can draw any shape.