Hello, I was wandering how can I draw a rectangle in lvgl 7 with a cyberpi,
have a great day
LVGL how to draw a rectangle
Considering lvgl 7 does not have a dedicated polygon function, my best bet would be a connected line:
try:
# Create an array for the points of the line
line_points = [ {"x":10, "y":10},
{"x":100, "y":10},
{"x":100, "y":50},
{"x":10, "y":50},
{"x":10, "y":10}]
# Create new style (thick dark blue)
style_line = lv.style_t()
lv.style_copy(style_line, lv.style_plain)
style_line.line.color = lv.color_make(0x00, 0x3b, 0x75)
style_line.line.width = 5
style_line.line.rounded = 0
# Copy the previous line and apply the new style
scr = lv.obj()
line1 = lv.line(scr)
line1.set_points(line_points, len(line_points)) # Set the points
line1.set_style(lv.line.STYLE.MAIN, style_line)
line1.align(None, lv.ALIGN.IN_TOP_MID, 0, 0)
lv.scr_load(scr)
except Exception as err:
pass
cyberpi.console.print(err)
Otherwise, the button object is a rectangle with lots of adjustments.
The canvas object allows you to draw anything, but canvas requires buffer management:
https://docs.lvgl.io/6.1/object-types/canvas.html#example
BTW, I found that the 6.1 documentation is half-decent to work with the LGVL 7 in the MicroPython environment.
In the cyberpi, it does have the polygone and the draw_triangle func, i know it because i search using cyberpi commands
also sry I didn’t specify it but I’m looking for full filled custom rectangles (like I can chose 4 random points to make a rectangle (for 3D))
draw_ functions are not exposed in our version of micropython and are not meant to be accessed directly. They are accessible through the canvas object as I wrote above, but canvas in our version does not accept a rectangle descriptor (no polygons either).
Another approach would be to draw rectangles using lvgl base object, which is a rectangle by itself.
# Create a new style
r_style = lv.style_t(lv.style_plain)
r_style.body.main_color = lv.color_make(255, 0, 0) # Red
r_style.body.grad_color = lv.color_make(155, 0, 0) # Gradient other color is red too
r_style.body.radius = 2
# Create a screen and load it
scr = lv.obj()
lv.scr_load(scr)
# Create a rectangle (lv.obj is rectangular by default)
rect = lv.obj(scr)
rect.set_size(100, 50)
rect.align(scr, lv.ALIGN.CENTER, 0, 0)
# Apply style using legacy API
rect.set_style(r_style)
or by-pixel rendering.
here’s an e.g with pentagon shape:
import lvgl as lv
import gc
import math
gc.collect()
# Canvas setup
WIDTH = 127
HEIGHT = 127
buf = bytearray(WIDTH * HEIGHT * 4)
screen = lv.obj()
lv.scr_load(screen)
canvas = lv.canvas(screen)
canvas.set_buffer(buf, WIDTH, HEIGHT, lv.img.CF.TRUE_COLOR)
canvas.fill_bg(lv.color_make(255, 255, 255)) # White background
# Helper: set pixel safely
def set_pixel_safe(x, y, color):
if 0 <= x < WIDTH and 0 <= y < HEIGHT:
canvas.set_px(x, y, color)
# Helper: draw filled triangle using scanline fill
def draw_filled_triangle(p1, p2, p3, color):
points = sorted([p1, p2, p3], key=lambda p: p[1]) # Sort by Y
x1, y1 = points[0]
x2, y2 = points[1]
x3, y3 = points[2]
def interpolate(y, x0, y0, x1, y1):
if y1 == y0:
return x0
return int(x0 + (x1 - x0) * (y - y0) / (y1 - y0))
y_start = max(y1, 0)
y_end = min(y3, HEIGHT - 1)
for y in range(y_start, y_end + 1):
if y < y2:
xa = interpolate(y, x1, y1, x2, y2)
xb = interpolate(y, x1, y1, x3, y3)
else:
xa = interpolate(y, x2, y2, x3, y3)
xb = interpolate(y, x1, y1, x3, y3)
if xa > xb:
xa, xb = xb, xa
for x in range(max(xa, 0), min(xb + 1, WIDTH)):
set_pixel_safe(x, y, color)
# Draw filled pentagon at center
def draw_filled_pentagon(cx, cy, r, rotation_deg, color):
points = []
for i in range(5):
angle_deg = rotation_deg + i * 72 # 360 / 5
angle_rad = math.radians(angle_deg)
x = int(cx + r * math.cos(angle_rad))
y = int(cy + r * math.sin(angle_rad))
points.append((x, y))
# Triangle fan: center to edges
for i in range(5):
p1 = (cx, cy)
p2 = points[i]
p3 = points[(i + 1) % 5]
draw_filled_triangle(p1, p2, p3, color)
# Parameters: center x, y, radius, rotation, color
draw_filled_pentagon(
cx=64,
cy=64,
r=40,
rotation_deg=-70,
color=lv.color_make(0, 255, 0)
)