π
<-

Zero Mise à jour Zero 2.23 avec bibliothèque graphique Python !

New postby critor » 20 Apr 2025, 09:54

22120Fan de la TI-83 Premium CE (ou hors de France de la TI-84 Plus CE), aujourd'hui nous te reparlons de la Zero ZGC4, le clone non officiel qui serait censé sortir pour la rentrée 2025.

Nous avons reçu une nouvelle mise à jour 2.23 pour la ZGC4, également compatible avec le prototype précédent ZGC3.

Plus précisément, nous passons donc de la version 2.22.0 du 11 décembre 2024 à la version 2.23.0 du 25 mars 2025.
Dans la dernière version, nous regrettions que la programmation Python qui devenait enfin fonctionnelle, n'offrait pas encore de bibliothèque graphique.

22130Et bien portons toute notre attention sur la programmation Python, car cela a visiblement bougé une nouvelle fois avec cette dernière mise à jour 2.23.

En effet l'interpréteur Micropython utilisé a été lui aussi mis à jour, passant de la version 1.22.0 sortie le 27 décembre 2023 à la version 1.23.0 sortie le 31 mai 2024.

2213121769Nous n'avons pas besoin de chercher bien loin, un simple appel help("modules") nous indique que le Python de la Zero dispose désormais d'une bibliothèque standard supplémentaire par rapport à la version précédente, lvgl, qui est justement une bibliothèque graphique !

Rappelons que niveau graphismes en Python, les calculatrices concurrents répartissent habituellement les fonctionnalités sur 3 bibliothèques :
  • une bibliothèque de tracé par pixels (habituellement propriétaire, c'est-à-dire spécifique à chaque marque ou pire modèle sans compatibilité du code entre les marques ou modèles)
  • une bibliothèque de tracé dans un repère (matplotlib, standard)
  • une bibliothèque de tracé à la tortue (turtle, standard)

Avec lvgl, la Zero nous offre déjà le gros avantage d'une bibliothèque de tracé par pixels standard !

À partir de l'objet écran lvgl.scr_act(), les méthodes .get_width() et .get_height() nous permettent de déterminer que nous contrôlons une zone graphique de 320×218 pixels, la barre de titre permanente occupant donc 22 pixels de hauteur.

Exemple 1 :
22122
Code: Select all
import lvgl as lv

scr = lv.scr_act()

# Height of persistent header on screen
header_height = lv.get_header_height()

print("Screen width: ", scr.get_width())
print("Screen height: ", scr.get_height())
print("Header height: ", header_height)

def draw_cb(obj, mask, mode):
    if mode == lv.DESIGN.DRAW_MAIN:
        objArea = lv.area_t()
        obj.get_coords(objArea)

        # Fill bg
        bgColor = lv.color_make(0xFF, 0xFF, 0xFF)
        lv.draw_fill(objArea, mask, bgColor, lv.OPA._100)

        styleLine = lv.style_t()
        styleLine.copy(lv.style_plain)
        styleLine.line.color = lv.color_make(0xFF, 0x00, 0x00)
        styleLine.line.width = 3
        styleLine.line.rounded = 1

        # Draw hor line (in coordinates of display (320x240))
        horLinePoint1 = { "x": objArea.x1, "y": objArea.y1 + int(objArea.get_height() / 2) }
        horLinePoint2 = { "x": objArea.x2, "y": objArea.y1 + int(objArea.get_height() / 2) }
        lv.draw_line(horLinePoint1, horLinePoint2, mask, styleLine, lv.OPA._100)

        # Draw ver line (in coordinates of display (320x240))
        verLinePoint1 = { "x": objArea.x1 + int(objArea.get_width() / 2), "y": objArea.y1 }
        verLinePoint2 = { "x": objArea.x1 + int(objArea.get_width() / 2), "y": objArea.y2 }
        lv.draw_line(verLinePoint1, verLinePoint2, mask, styleLine, lv.OPA._100)

        # Draw four pixels
        pxColor = lv.color_make(0x00, 0x00, 0x00)
        lv.draw_px(objArea.x1 + 50, objArea.y1 + 50, mask, pxColor, lv.OPA._100)
        lv.draw_px(objArea.x1 + 50, objArea.y2 - 50, mask, pxColor, lv.OPA._100)
        lv.draw_px(objArea.x2 - 50, objArea.y1 + 50, mask, pxColor, lv.OPA._100)
        lv.draw_px(objArea.x2 - 50, objArea.y2 - 50, mask, pxColor, lv.OPA._100)

        # Draw rectangle
        styleRect = lv.style_t()
        styleRect.copy(lv.style_plain)
        styleRect.body.main_color = lv.color_make(0x00, 0xFF, 0x00)
        styleRect.body.grad_color = lv.color_make(0x00, 0xFF, 0x00)
        styleRect.body.radius = 5

        rectArea = lv.area_t()
        rectArea.set(objArea.x1 + 60, objArea.y1 + 60, objArea.x1 + 100, objArea.y1 + 100)
        lv.draw_rect(rectArea, mask, styleRect, lv.OPA._100)

        # Draw label
        labelStyle = lv.style_t()
        labelStyle.copy(lv.style_plain)
        labelStyle.text.color = lv.color_make(0x00, 0xFF, 0xFF)

        labelOffset = {"x": 0, "y": 0}

        labelArea = lv.area_t()
        labelArea.set(objArea.x1 + 180, objArea.y1 + 60, objArea.x2, objArea.y1 + 80)
        lv.draw_label(labelArea, mask, labelStyle, lv.OPA._100, "Label", 0, labelOffset, None, None, lv.BIDI_DIR.LTR)

        # Draw triangle
        styleRect.body.main_color = lv.color_make(0xFF, 0x00, 0x00)
        trigPoints = [ {"x":200, "y":150},
                        {"x":240, "y":150},
                        {"x":240, "y":200}]
        lv.draw_triangle(trigPoints, mask, styleRect, lv.OPA._100)

        # Draw polygon
        styleRect.body.main_color = lv.color_make(0x00, 0x00, 0xFF)
        polyPoints = [ {"x":100, "y":150},
                        {"x":140, "y":150},
                        {"x":140, "y":200},
                        {"x":100, "y":220}]
        lv.draw_polygon(polyPoints, len(polyPoints), mask, styleRect, lv.OPA._100)

        return True
    else:
        return False

scr.set_design_cb(draw_cb)

print("Main draw finished")

lv.show()


Exemple 2:
22138
Code: Select all
import lvgl as lv

# Create an array for the points of the line
line_points = [ {"x":5, "y":5},
                {"x":70, "y":70},
                {"x":120, "y":10},
                {"x":180, "y":60},
                {"x":240, "y":10}]

# Create new style (thick dark blue)
style_line = lv.style_t()
style_line.copy(lv.style_plain)
style_line.line.color = lv.color_make(0x00, 0x3b, 0x75)
style_line.line.width = 3
style_line.line.rounded = 1

# Copy the previous line and apply the new style
line1 = lv.line(lv.scr_act(), None)
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.CENTER, 0, 0)

lv.show()
lvgl se révèle être une bibliothèque de tracé par pixels hautement poussée, encore mieux que le double buffering des Casio et TI-Nspire CX II, nous manipulons hors écran autant de calques que nous voulons, comme sur HP Prime !

Exemple :
22121
Code: Select all
import lvgl as lv

CANVAS_WIDTH  = 200
CANVAS_HEIGHT = 150

style = lv.style_t()
style.copy(lv.style_plain)
style.body.main_color = lv.color_make(0xFF,0,0)
style.body.grad_color = lv.color_make(0x80,0,0)
style.body.radius = 4
style.body.border.width = 2
style.body.border.color = lv.color_make(0xFF,0xFF,0xFF)
style.body.shadow.color = lv.color_make(0xFF,0xFF,0xFF)
style.body.shadow.width = 4
style.line.width = 2
style.line.color = lv.color_make(0,0,0)
style.text.color = lv.color_make(0,0,0xFF)

# CF.TRUE_COLOR requires 4 bytes per pixel
cbuf = bytearray(CANVAS_WIDTH * CANVAS_HEIGHT * 4)

canvas = lv.canvas(lv.scr_act(), None)
canvas.set_buffer(cbuf, CANVAS_WIDTH, CANVAS_HEIGHT, lv.img.CF.TRUE_COLOR)
canvas.align(None, lv.ALIGN.CENTER, 0, 0)
canvas.fill_bg(lv.color_make(0xC0, 0xC0, 0xC0))

canvas.draw_rect(70, 60, 100, 70, style)

canvas.draw_text(40, 20, 100, style, "Some text on text canvas", lv.label.ALIGN.LEFT)

# Test the rotation. It requires an other buffer where the original image is stored.
# So copy the current image to buffer and rotate it to the canvas
img = lv.img_dsc_t()
img.data = cbuf[:]
img.header.cf = lv.img.CF.TRUE_COLOR
img.header.w = CANVAS_WIDTH
img.header.h = CANVAS_HEIGHT

canvas.fill_bg(lv.color_make(0xC0, 0xC0, 0xC0))
canvas.rotate(img, 30, 0, 0, CANVAS_WIDTH // 2, CANVAS_HEIGHT // 2)

lv.show()
Mais ce n'est pas tout… Nul besoin de changer de bibliothèque ici, deux en un, lvgl permet également les tracés dans un repère comme matplotlib !

Exemple :
22124
Code: Select all
import lvgl as lv

# Create a chart
chart = lv.chart(lv.scr_act(), None)
chart.set_size(200, 150)
chart.align(None, lv.ALIGN.CENTER, 0, 0)
chart.set_type(lv.chart.TYPE.POINT | lv.chart.TYPE.LINE)   # Show lines and points too
chart.set_series_opa(lv.OPA._70)                           # Opacity of the data series
chart.set_series_width(4)                                  # Line width and point radious

chart.set_range(0, 100)

# Add two data series
ser1 = chart.add_series(lv.color_make(0xFF, 0x00, 0x00))
ser2 = chart.add_series(lv.color_make(0x00, 0x80, 0x00))

# Set points on 'dl1'
chart.set_points(ser1, [10, 10, 10, 10, 10, 10, 10, 30, 70, 90])

# Set points on 'dl2'
chart.set_points(ser2, [90, 70, 65, 65, 65, 65, 65, 65, 65, 65])

lv.show()
print("LVGL drawing finished")
Mais lvgl c'est encore bien plus que cela, car il s'agit en fait d'une bibliothèque graphique orientée objet. Tu peux en quelques lignes créer nombre d'objets graphiques différents ! 👍

Exemple : boutons poussoir
22136
Code: Select all
import lvgl as lv

def event_handler(obj, event):
    if event == lv.EVENT.CLICKED:
        print("Button clicked")
   
btn1 = lv.btn(lv.scr_act(), None)
btn1.align(None, lv.ALIGN.CENTER, 0, -40)
btn1.set_event_cb(event_handler)
label = lv.label(btn1, None)
label.set_text("Button")

btn2 = lv.btn(lv.scr_act(), None)
# callback can be lambda:
btn2.set_event_cb(lambda obj, event: print("Toggled") if event == lv.EVENT.VALUE_CHANGED else None)
btn2.align(None, lv.ALIGN.CENTER, 0, 40)
btn2.set_toggle(True)
btn2.toggle()
btn2.set_fit2(lv.FIT.NONE, lv.FIT.TIGHT)

label = lv.label(btn2, None)
label.set_text("Toggled")

# Keyboard register
keyboardDriver = lv.indev_drv_t()
keyboardDriver.init()
keyboardDriver.type = lv.INDEV_TYPE.KEYPAD
keyboardDriver.read_cb = lv.keypad_read
keyboard = keyboardDriver.register()

# Create groupe for buttons
group = lv.group_create()
group.add_obj(btn1)
group.add_obj(btn2)
keyboard.set_group(group)

lv.show()
print("LVGL drawing finished")


Exemple : boîtes à cocher
2213522134
Code: Select all
import lvgl as lv

# Keyboard register
keyboardDriver = lv.indev_drv_t()
keyboardDriver.init()
keyboardDriver.type = lv.INDEV_TYPE.KEYPAD
keyboardDriver.read_cb = lv.keypad_read
keyboard = keyboardDriver.register()

# Create groupe for keyboard handled objects
group = lv.group_create()
keyboard.set_group(group)

def event_handler(obj, event):
    if event == lv.EVENT.VALUE_CHANGED:
        print("State: %s" % ("Checked" if obj.is_checked() else "Unchecked"))

cb = lv.cb(lv.scr_act(), None)
cb.set_text("I agree to terms")
cb.align(None, lv.ALIGN.CENTER, 0, 0)
cb.set_event_cb(event_handler)

group.add_obj(cb)

lv.show()
print("LVGL drawing finished")


Exemple : interrupteurs à bascule
2214022139
Code: Select all
import lvgl as lv

# Keyboard register
keyboardDriver = lv.indev_drv_t()
keyboardDriver.init()
keyboardDriver.type = lv.INDEV_TYPE.KEYPAD
keyboardDriver.read_cb = lv.keypad_read
keyboard = keyboardDriver.register()

# Create groupe for keyboard handled objects
group = lv.group_create()
keyboard.set_group(group)

def event_handler(obj, event):
    if event == lv.EVENT.VALUE_CHANGED:
        print("State: %s" % ("On" if obj.get_state() else "Off"))

# Create styles for the switch
bg_style = lv.style_t()
indic_style = lv.style_t()
knob_on_style = lv.style_t()
knob_off_style = lv.style_t()

bg_style.copy(lv.style_pretty)
bg_style.body.radius = 800
bg_style.body.padding.top = 6
bg_style.body.padding.bottom = 6

indic_style.copy(lv.style_pretty_color)
indic_style.body.radius = 800
indic_style.body.main_color = lv.color_hex(0x9fc8ef)
indic_style.body.grad_color = lv.color_hex(0x9fc8ef)
indic_style.body.padding.left = 0
indic_style.body.padding.right = 0
indic_style.body.padding.top = 0
indic_style.body.padding.bottom = 0

knob_off_style.copy(lv.style_pretty)
knob_off_style.body.radius = 800
knob_off_style.body.shadow.width = 4
knob_off_style.body.shadow.type = lv.SHADOW.BOTTOM

knob_on_style.copy(lv.style_pretty_color)
knob_on_style.body.radius = 800
knob_on_style.body.shadow.width = 4
knob_on_style.body.shadow.type = lv.SHADOW.BOTTOM

# Create a switch and apply the styles
sw1 = lv.sw(lv.scr_act(), None)
sw1.set_style(lv.sw.STYLE.BG, bg_style)
sw1.set_style(lv.sw.STYLE.INDIC, indic_style)
sw1.set_style(lv.sw.STYLE.KNOB_ON, knob_on_style)
sw1.set_style(lv.sw.STYLE.KNOB_OFF, knob_off_style)
sw1.align(None, lv.ALIGN.CENTER, 0, -50)
sw1.set_event_cb(event_handler)

# Copy the first switch and turn it ON
sw2 = lv.sw(lv.scr_act(), None)
sw2.set_style(lv.sw.STYLE.BG, bg_style)
sw2.set_style(lv.sw.STYLE.INDIC, indic_style)
sw2.set_style(lv.sw.STYLE.KNOB_ON, knob_on_style)
sw2.set_style(lv.sw.STYLE.KNOB_OFF, knob_off_style)
sw2.on(lv.ANIM.ON)
sw2.align(None, lv.ALIGN.CENTER, 0, 50)
sw2.set_event_cb(lambda o,e: None)

group.add_obj(sw1)
group.add_obj(sw2)

lv.show()


Exemple : barre de progression horizontale
22133
Code: Select all
import lvgl as lv

bar1 = lv.bar(lv.scr_act(), None)
bar1.set_size(200, 30)
bar1.align(None, lv.ALIGN.CENTER, 0, 0)
bar1.set_anim_time(2500)
bar1.set_value(100, lv.ANIM.ON)

lv.show()
print("LVGL drawing finished")


Exemple : barre de progression ou d'attente chargement circulaire
22132
Code: Select all
import lvgl as lv

# Create style for the Arcs
style = lv.style_t()
style.copy(lv.style_plain)
style.line.color = lv.color_make(0x00, 0xFF, 0xFF) # Arc color
style.line.width = 8                      # Arc width

# Create an Arc
arc = lv.arc(lv.scr_act(), None)
arc.set_style(lv.arc.STYLE.MAIN, style)   # Use the new style
arc.set_angles(90, 60)
arc.set_size(150, 150)
arc.align(None, lv.ALIGN.CENTER, 0, 0)

lv.show()
print("LVGL drawing finished")


Exemple : champ de saisie numérique
22128
Code: Select all
import lvgl as lv

# Keyboard register
keyboardDriver = lv.indev_drv_t()
keyboardDriver.init()
keyboardDriver.type = lv.INDEV_TYPE.KEYPAD
keyboardDriver.read_cb = lv.keypad_read
keyboard = keyboardDriver.register()

# Create groupe for keyboard handled objects
group = lv.group_create()
keyboard.set_group(group)

def event_handler(obj, event):
    if event == lv.EVENT.VALUE_CHANGED:
        print("Value: %d" % obj.get_value())
    elif event == lv.EVENT.CLICKED:
        # For simple test: Click the spinbox to increment its value
        obj.increment()

spinbox = lv.spinbox(lv.scr_act(), None)
spinbox.set_digit_format(5, 3)
spinbox.step_prev()
spinbox.set_width(100)
spinbox.align(None, lv.ALIGN.CENTER, 0, 0)
spinbox.set_event_cb(event_handler)

group.add_obj(spinbox)

lv.show()


Exemple : jauge 1
22141
Code: Select all
import lvgl as lv

# Create a style
style = lv.style_t()
style.copy(lv.style_pretty_color)
style.body.main_color = lv.color_hex3(0x666)     # Line color at the beginning
style.body.grad_color =  lv.color_hex3(0x666)    # Line color at the end
style.body.padding.left = 10                     # Scale line length
style.body.padding.inner = 8                     # Scale label padding
style.body.border.color = lv.color_hex3(0x333)   # Needle middle circle color
style.line.width = 3
style.text.color = lv.color_hex3(0xFFFFFF)
style.line.color = lv.color_hex3(0xF00)          # Line color after the critical value

# Describe the color for the needles
needle_colors = [
    lv.color_make(0x00, 0x00, 0xFF),
    lv.color_make(0xFF, 0xA5, 0x00),
    lv.color_make(0x80, 0x00, 0x80)
]

# Create a gauge
gauge1 = lv.gauge(lv.scr_act(), None)
gauge1.set_style(lv.gauge.STYLE.MAIN, style)
gauge1.set_needle_count(len(needle_colors), needle_colors)
gauge1.set_size(150, 150)
gauge1.align(None, lv.ALIGN.CENTER, 0, 20)

# Set the values
gauge1.set_value(0, 10)
gauge1.set_value(1, 20)
gauge1.set_value(2, 30)

lv.show()
print("LVGL drawing finished")


Exemple : jauge 2
22142
Code: Select all
import lvgl as lv

# Create a style for the line meter
style_lmeter = lv.style_t()
style_lmeter.copy(lv.style_pretty_color)
style_lmeter.line.width = 2
style_lmeter.line.color = lv.color_hex(0xc0c0c0)              # Silver
style_lmeter.body.main_color = lv.color_hex(0x91bfed)         # Light blue
style_lmeter.body.grad_color = lv.color_hex(0x04386c)         # Dark blue
style_lmeter.body.padding.left = 16                           # Line length

# Create a line meter
lmeter = lv.lmeter(lv.scr_act(), None)
lmeter.set_range(0, 100)                    # Set the range
lmeter.set_value(80)                        # Set the current value
lmeter.set_scale(240, 31)                   # Set the angle and number of lines
lmeter.set_style(lv.lmeter.STYLE.MAIN, style_lmeter)          # Apply the new style
lmeter.set_size(150, 150)

lv.show()


Exemple : curseur
22143
Code: Select all
import lvgl as lv

# Keyboard register
keyboardDriver = lv.indev_drv_t()
keyboardDriver.init()
keyboardDriver.type = lv.INDEV_TYPE.KEYPAD
keyboardDriver.read_cb = lv.keypad_read
keyboard = keyboardDriver.register()

# Create groupe for keyboard handled objects
group = lv.group_create()
keyboard.set_group(group)

# Create a label below the slider
slider_label = lv.label(lv.scr_act(), None)
slider_label.set_text("0")
slider_label.set_auto_realign(True)

def slider_event_cb(obj, event):
    if event == lv.EVENT.VALUE_CHANGED:
        slider_label.set_text("%u" % obj.get_value())

# Create a slider in the center of the display
slider = lv.slider(lv.scr_act(), None)
slider.set_width(200)
slider.align(None, lv.ALIGN.CENTER, 0, 0)
slider.set_event_cb(slider_event_cb)
slider.set_range(0, 100)

slider_label.align(slider, lv.ALIGN.OUT_BOTTOM_MID, 0, 10)

# Create an informative label
info = lv.label(lv.scr_act(), None)
info.set_text("""Welcome to the slider+label demo!
Move the slider and see that the label
updates to match it.""")
info.align(None, lv.ALIGN.IN_TOP_LEFT, 10, 10)

group.add_obj(slider)

lv.show()


Exemple : liste de choix
22127
Code: Select all
import lvgl as lv

# Keyboard register
keyboardDriver = lv.indev_drv_t()
keyboardDriver.init()
keyboardDriver.type = lv.INDEV_TYPE.KEYPAD
keyboardDriver.read_cb = lv.keypad_read
keyboard = keyboardDriver.register()

# Create groupe for keyboard handled objects
group = lv.group_create()
keyboard.set_group(group)

def event_handler(obj, event):
    if event == lv.EVENT.VALUE_CHANGED:
        option = " "*10
        obj.get_selected_str(option, len(option))
        print("Selected month: %s" % option.strip())

roller1 = lv.roller(lv.scr_act(), None)
roller1.set_options("\n".join([
                    "January",
                    "February",
                    "March",
                    "April",
                    "May",
                    "June",
                    "July",
                    "August",
                    "September",
                    "October",
                    "November",
                    "December"]), lv.roller.MODE.INIFINITE)

roller1.set_visible_row_count(4)
roller1.align(None, lv.ALIGN.CENTER, 0, 0)
roller1.set_event_cb(event_handler)

group.add_obj(roller1)

lv.show()
Et bien évidemment, lvgl permet d'organiser nombre de ces objets graphiques de façon complexe et d'en gérer les différents événements ! 👍

Exemple : boîte de dialogue de confirmation ou annulation
22137
Code: Select all
import lvgl as lv

# Keyboard register
keyboardDriver = lv.indev_drv_t()
keyboardDriver.init()
keyboardDriver.type = lv.INDEV_TYPE.KEYPAD
keyboardDriver.read_cb = lv.keypad_read
keyboard = keyboardDriver.register()

# Create groupe for keyboard handled objects
group = lv.group_create()
keyboard.set_group(group)

def event_handler(obj, event):
    if event == lv.EVENT.VALUE_CHANGED:
        print("Button: %s" % lv.mbox.get_active_btn_text(obj))

mbox1 = lv.mbox(lv.scr_act(), None)
mbox1.set_text("A message box with two buttons.")
mbox1.add_btns(["Apply", "Close", ""])
mbox1.set_width(200)
mbox1.set_event_cb(event_handler)
mbox1.align(None, lv.ALIGN.CENTER, 0, 0)  # Align to the corner

group.add_obj(mbox1)

lv.show()


Exemple : Grille de boutons poussoir
22125
Code: Select all
import lvgl as lv

# Keyboard register
keyboardDriver = lv.indev_drv_t()
keyboardDriver.init()
keyboardDriver.type = lv.INDEV_TYPE.KEYPAD
keyboardDriver.read_cb = lv.keypad_read
keyboard = keyboardDriver.register()

# Create groupe for keyboard handled objects
group = lv.group_create()
keyboard.set_group(group)

def event_handler(obj, event):
    if event == lv.EVENT.VALUE_CHANGED:
        txt = obj.get_active_btn_text()
        print("%s was pressed" % txt)

btnm1 = lv.btnm(lv.scr_act(), None)
btnm1.set_map( ["1", "2", "3", "4", "5", "\n",
            "6", "7", "8", "9", "0", "\n",
            "Action1", "Action2", ""])
btnm1.set_btn_width(10, 2)        # Make "Action1" twice as wide as "Action2"
btnm1.align(None, lv.ALIGN.CENTER, 0, 0)
btnm1.set_event_cb(event_handler)

group.add_obj(btnm1)

lv.show()
print("LVGL drawing finished")


Exemple : Vues par onglets
22126
Code: Select all
import lvgl as lv

# Keyboard register
keyboardDriver = lv.indev_drv_t()
keyboardDriver.init()
keyboardDriver.type = lv.INDEV_TYPE.KEYPAD
keyboardDriver.read_cb = lv.keypad_read
keyboard = keyboardDriver.register()

# Create groupe for keyboard handled objects
group = lv.group_create()
keyboard.set_group(group)

# Create a Tab view object
tabview = lv.tabview(lv.scr_act(), None)

# Add 3 tabs (the tabs are page (lv_page) and can be scrolled
tab1 = tabview.add_tab("Tab 1")
tab2 = tabview.add_tab("Tab 2")
tab3 = tabview.add_tab("Tab 3")

# Add content to the tabs
label = lv.label(tab1, None)
label.set_text("""This the first tab

If the content
of a tab
become too long
the it
automatically
become
scrollable.""")

label = lv.label(tab2, None)
label.set_text("Second tab")

label = lv.label(tab3, None)
label.set_text("Third tab")

group.add_obj(tabview)

lv.show()


Exemple : zone à défiler
22144
Code: Select all
import lvgl as lv

# Keyboard register
keyboardDriver = lv.indev_drv_t()
keyboardDriver.init()
keyboardDriver.type = lv.INDEV_TYPE.KEYPAD
keyboardDriver.read_cb = lv.keypad_read
keyboard = keyboardDriver.register()

# Create groupe for keyboard handled objects
group = lv.group_create()
keyboard.set_group(group)

valid_pos = [{"x":0, "y": 0}, {"x": 0, "y": 1}, {"x": 1,"y": 1}]

# resolution of the screen
HOR_RES = lv.scr_act().get_width()
VER_RES = lv.scr_act().get_height()

tileview = lv.tileview(lv.scr_act(), None)
tileview.set_valid_positions(valid_pos, len(valid_pos))
tileview.set_edge_flash(True)

# Tile1: just a label
tile1 = lv.obj(tileview, None)
tile1.set_size(HOR_RES, VER_RES)
tile1.set_style(lv.style_pretty)
tileview.add_element(tile1)

label = lv.label(tile1, None)
label.set_text("Tile 1")
label.align(None, lv.ALIGN.CENTER, 0, 0)

# Tile2: a list
lst = lv.list(tileview, None)
lst.set_size(HOR_RES, VER_RES)
lst.set_pos(0, VER_RES)
lst.set_scroll_propagation(True)
lst.set_sb_mode(lv.SB_MODE.OFF)
tileview.add_element(lst)

list_btn = lst.add_btn(None, "One")
tileview.add_element(list_btn)

list_btn = lst.add_btn(None, "Two")
tileview.add_element(list_btn)

list_btn = lst.add_btn(None, "Three")
tileview.add_element(list_btn)

list_btn = lst.add_btn(None, "Four")
tileview.add_element(list_btn)

list_btn = lst.add_btn(None, "Five")
tileview.add_element(list_btn)

list_btn = lst.add_btn(None, "Six")
tileview.add_element(list_btn)

list_btn = lst.add_btn(None, "Seven")
tileview.add_element(list_btn)

list_btn = lst.add_btn(None, "Eight")
tileview.add_element(list_btn)

# Tile3: a button
tile3 = lv.obj(tileview, None)
tile3.set_size(HOR_RES, VER_RES)
tile3.set_pos(HOR_RES, VER_RES)
tileview.add_element(tile3)

btn = lv.btn(tile3, None)
btn.align(None, lv.ALIGN.CENTER, 0, 0)

label = lv.label(btn, None)
label.set_text("Button")

group.add_obj(tileview)

lv.show()
Clairement niveau graphismes Python, dire que la Zero rattrape aujourd'hui les TI-83/84 serait un euphémisme. Bien au-delà, elle les dépasse et les laisse loin derrière ainsi que l'ensemble de la concurrence ! 🥳

HP Bêta-test public mise à jour HP Prime 2.4.15342

New postby critor » 19 Apr 2025, 18:08

En février 2025 nous avions eu droit à une mise à jour HP Prime 2.3.1.

Nous n'y avions noté aucune nouveauté intéressante, et surtout un très grave bug rendant la calculatrice totalement inutilisable dans le cas d'utilisation de fichiers de configuration du mode examen (à notre connaissance, concerne entre autres les Pays-Bas et le Baccalauréat International).

Il était donc urgent de sortir une mise à jour avant la session d'examens 2025.
2211622115Aujourd'hui Moravia t'invite à venir bêta-tester la mise à jour HP Prime 2.4.

Plus précisément nous passons de la version 2.3.1.15270 compilée le 31 janvier 2025 à la version 2.4.15342 compilée le 11 avril 2025.

Le bug majeur en cas de personnalisation du mode examen a été corrigé, mais ce n'est pas tout.

En effet il y a un autre changement majeur qui motive cette phase de bêta test public.

La HP Prime dispose de 2 moteurs de calcul distincts :
  • un moteur de calcul numérique BCD (Binary Coded Decimal) ne s'occupant que de calcul décimal
  • un moteur de calcul littéral et formel accessible via la touche
    CAS
    et également appelable depuis partout ailleurs via des appels CAS.EVAL("...")

C'est-à-dire que par défaut, sans manipulations spécifiques pour se placer dans un contexte CAS, la HP Prime se comportait moins bien que nombre de modèles concurrents d'entrée ou de milieu de gamme actuel, avoir au moins un moteur de calcul exact QPiRac étant désormais la norme.
2211922118Alors nous sommes encore très loin d'atteindre le niveau de la concurrence d'entrée de gamme, mais la mise à jour 2.4 fait un premier pas vers un rééquilibrage des deux moteurs de calcul de la HP Prime.

Amélioration majeure, il nous semble enfin la toute première depuis que Moravia a racheté la branche HP calculatrices pour la rentrée 2021, le moteur de calcul numérique est désormais capable de travailler en interne sur des nombres rationnels. Nous ne sommes donc pas au niveau d'un moteur QPiRac, mais nous pourrions déjà le qualifier de Q.

Précisons que pour le moment, ces nouvelles capacités ne sont exploitées qu'en interne, la calculatrice continuant à afficher des résultats en écriture décimale. Ces derniers sont toutefois meilleurs dans certains cas.




Téléchargements :

Casio Commémoration 60 ans calculatrice électronique Casio 001

New postby critor » 19 Apr 2025, 10:16

22105Septembre 1965, nous n'étions pas encore là pour t'en parler, mais Casio lançait sa toute première calculatrice de bureau entièrement électronique (mais pas encore scientifique), la Casio 001. Elle se distinguait de ses prédécesseures par l'abandon de la technologie électromécanique des relais.

Voici une modeste frise des innovations majeures de Casio dans le domaine des calculatrices :
  • 1965 : 001, première calculatrice électronique de bureau au monde !
  • 1967 : 101P, première calculatrice imprimante au monde !
  • 1971 : fx-1, première calculatrice scientifique
  • 1972 : Mini, première calculatrice miniaturisée au monde !
  • 1983 : SL-800, première calculatrice ultra fine au monde (épaisseur d'une carte de paiement)
  • 1985 : fx-7000G, première calculatrice à écran graphique matriciel au monde !
  • 1986 : fx-8000G, première calculatrice graphique connectable (imprimante ou lecteur-enregistreur de programmes sur cassette via interface FA-80 sur port parallèle Centronics)
  • 1992 : fx-7700/8700GB, premières calculatrices graphiques à connectivité série (mini-Jack 2.5mm)
  • 1995 : cfx-9800G, première calculatrice graphique à écran couleur au monde (4 couleurs), connue en France sous le nom de cfx-9900GC, prédécesseures des Graph 60/65
  • 1997 : cfx-9970G, première calculatrice graphique formelle, connue en France sous le nom de cfx-9990GT, prédécesseurs des Graph 80/100
  • 1999 : Algebra FX 2.0 et FX 1.0, premières calculatrices graphiques à mémoire Flash permettant l'installation d'applications, connues en France sous le nom de Graph 100
  • 2001 : Algebra FX 2.0+ et FX 1.0+, premières calculatrices graphiques à mémoire Flash permettant le stockage persistant de données sans aucune alimentation électrique, connues en France sous le nom de Graph 100+
  • 2003 : Classpad 300, première calculatrice graphique à écran tactile et également première calculatrice à mémoire Flash permettant les mises à jour du système d'exploitation et donc la correction de bugs sans avoir à racheter de calculatrice !
  • 2005 : fx-9860G SD, première calculatrice graphique avec lecteur de carte mémoire (SD) pour stockage nomade de données, connue en France sous le nom de Graph 85 SD
  • 2005 : Classpad 300+ et fx-9860G, premières calculatrice à connectivité USB
  • 2011 : fx-CG10/20, premières calculatrices graphiques à écran couleur 16 bits au monde (65536 couleurs), prédécesseures des Graph 90+E et Graph Math+

Cette année, nous fêtons donc les 60 ans de la Casio 001. Le constructeur nous a préparé un site dédié.

Casio nous sort pour l'occasion une série commémorative, les MS-20UC-J, consistant en des éditions spéciales de sa calculatrice MS-20UC arborant des motifs japonais traditionnels :
  • la MS-20UC-JRD avec motif asanoha rouge, un motif consistant en une réprésentation géométrique de feuilles de chanvre, plante résistante, symbole de croissance, vigueur et résistance
  • la MS-20UC-JBU avec motif seigaiha bleu, un motif représentant des vagues, symbole de calme et force tranquille
  • la MS-20UC-JWE avec motif takekago blanc, un motif représentant un tressage en bambou (panier ou sac), symbole de connexions entre les individus
221062210722108
221092211022111


221132211222114Mais ce n'est pas tout, Casio nous sort également un tout nouveau modèle, la Comfy JT-200T, disponible en blanc cassé ou gris foncé. Ce modèle solaire se veut non seulement commémoratif mais aussi comme son nom l'indique confortable, avec :
  • Un placement original des cellules solaires, non pas sur le dessus comme habituellement ni sur le dessous comme sur les modèles rétroprojetables, mais en incliné sur la tranche supérieure. En conséquence un confort exceptionnelle pour une utilisation dans un environnement domestique, notamment face à l'unique fenêtre d'une pièce !
  • La reprise pour les inscriptions clavier de la même police de caractères très lisible que la Casio Mini de 1972 !
  • Un pied rétractable permettant une inclinaison jusqu'à 8 degrés.
  • L'utilisation de plastique recyclé pour préserver l'environnement.




Source : https://www.casio.com/intl/news/2025/0415-ms20uc/

Divers Rentrée 2025: jusqu'à 5€ de remise immédiate sur TI-82/83 !

New postby critor » 16 Apr 2025, 11:51

Bientôt la rentrée 2024 et donc la problématique de l'équipement en calculatrice graphique pour les lycéens et lycéennes entrant en Seconde, ainsi que ceux et celles plus avancés dans leur scolarité mais non encore équipés.

Et bien bonne nouvelle, Texas Instruments reconduit une nouvelle fois cette année sa remarquable promotion initiée il y a deux ans :
  • -3€ sur la TI-82 Advanced monochrome
  • -4€ sur la TI-82 Advanced Edition Python couleur
  • -5€ sur la TI-83 Premium CE Edition Python couleur
Image

Il s'agit ici d'une remise immédiate, et tu n'as aucune démarche supplémentaire à effectuer pour en bénéficier ! 👍

Une fois de plus une initiative fort appréciable de la part de Texas Instruments allant dans l'intérêt de l'équipement de tous les élèves, merci ! ❤️

Par contre, la remise est effectuée par les distributeurs participants, dont la liste n'est pas rendue publique par le site de Texas Instruments.

Bien que cela contribue fort heureusement à une baisse de la moyenne des prix pratiqués, il te reste encore à identifier les boutiques les moins chères qui sont peut-être justement celles participant à l'offre.

Et nul besoin d'effectuer des kilomètres ou recherches pour cela, nous t'invitons tout simplement à passer par notre comparateur de prix dédié qui te donnera directement le moins cher au moment de ta consulation !

Divers Offre d'équipement enseignants TI rentrée 2025

New postby critor » 16 Apr 2025, 11:20

Enseignant en lycée en France ou dans le réseau AEFE européen ? Texas Instruments t'offre chaque année la possibilité de t'équiper à tarif préférentiel.

L'I-Store dédié vient de rouvrir afin de te permettre de t'équiper au moins cher pour la rentrée 2025.
Pour la rentrée 2025, y sont donc disponibles à prix formidablement bas :
  • calculatrice scientifique TI-Collège Plus à 12€
  • calculatrice graphique TI-82 Advanced Edition Python à 39€ seulement !
  • calculatrice graphique TI-83 Premium CE Edition Python à 59€ seulement !
  • calculatrice graphique TI-Nspire CX II-T CAS à 79€ seulement !
  • chargeur USB secteur (compatible avec tous les modèles graphiques précédents) à 5,90€
  • interface TI-Innovator Hub à 62€
  • robot TI-Innovator Rover à 119€
De formidables réductions par rapport aux prix pratiqués dans le commerce que tu peux d'ailleurs vérifier pour comparaison dans notre comparateur dédié, allant jusque dans les -50% pour le haut de gamme ! 👍

Pas de frais cachés, les prix sont toutes taxes incluses et même port inclus.
Par contre bien évidemment, cette offre d'équipement est limitée en quantité. Il s'agit ici de t'équiper personnellement et non d'équiper une classe ; tu n'as droit au maximum qu'à 1 exemplaire de chaque référence par an.

Lien : https://epsstore.ti.com/OA_HTML/ibeCZzp ... 1&cntry=FR

-
Search
-
Social TI-Planet
-
Featured topics
Comparaisons des meilleurs prix pour acheter sa calculatrice !
"1 calculatrice pour tous", le programme solidaire de Texas Instruments. Reçois gratuitement et sans aucune obligation d'achat, 5 calculatrices couleur programmables en Python à donner aux élèves les plus nécessiteux de ton lycée. Tu peux recevoir au choix 5 TI-82 Advanced Edition Python ou bien 5 TI-83 Premium CE Edition Python.
Enseignant(e), reçois gratuitement 1 exemplaire de test de la TI-82 Advanced Edition Python. À demander d'ici le 31 décembre 2024.
Aidez la communauté à documenter les révisions matérielles en listant vos calculatrices graphiques !
1234
-
Donations / Premium
For more contests, prizes, reviews, helping us pay the server and domains...
Donate
Discover the the advantages of a donor account !
JoinRejoignez the donors and/or premium!les donateurs et/ou premium !


Partner and ad
Notre partenaire Jarrety Calculatrices à acheter chez Calcuso
-
Stats.
1444 utilisateurs:
>1398 invités
>40 membres
>6 robots
Record simultané (sur 6 mois):
6892 utilisateurs (le 07/06/2017)
-
Other interesting websites
Texas Instruments Education
Global | France
 (English / Français)
Banque de programmes TI
ticalc.org
 (English)
La communauté TI-82
tout82.free.fr
 (Français)