lvgl / lv_demos

Examples, tutorials and applications for the LVGL embedded GUI library
https://lvgl.io
492 stars 366 forks source link

MicroPython examples #40

Closed stepansnigirev closed 4 years ago

stepansnigirev commented 4 years ago

Micropython examples for most of the object types. Related discussion: https://forum.littlevgl.com/t/examples-for-lvgl-in-micropython/1190

Not implemented examples:

Method get_selected_str() in ddlist and roller works but pretty ugly - it requires to pass a string as an argument and changes part of it in place. Therefore in the examples I use the following callback:

def event_handler(obj, event):
    if event == lv.EVENT.VALUE_CHANGED:
        idx = obj.get_selected()
        option = obj.get_options().split("\n")[idx]
        print("Option: %s" % option)

Also I don't know how to get data from lv.event_get_data() (ta example)

embeddedt commented 4 years ago

@amirgon Can you review this?

amirgon commented 4 years ago

@stepansnigirev Nice work!

Since the simulator is currently based on older code, I suggest testing these scripts on the unix (linux) simulator on dev-6.1 branch of lv_micropython.
dev-6.1 will be merge very soon with master so it makes sense working on it and building the simulator from it.

@stepansnigirev were you able to build and run it on your side?

  • arc - 2nd example - uses lv.task_t, I was not able to make it work :(
  • label - 3rd example - similar to arc - also uses lv.task_t

On the latest version, Tasks work. I've implemented arc - 2nd example here: https://gist.github.com/amirgon/ececcec778fb089a6ddc7dbf728d2ec2 Please have a look, it work well on dev-6.1. (You can take it as is if you want)

It shows:

  • calendar - highlighted_dates method doesn't accept a list

As discussed, we would need to change highlighted_dates prototype on lvgl sources, and perhaps other functions that receive a pointer instead of an array.
I will create a PR for this.

  • img - not sure how to provide image data yet, probably makes sense to use png loader or a hardcoded bytearray
  • mgbtn - same as above

You can load files from the network the same way you can import from the network.
Just need to provide the full URL as the filename and make sure the web server support CORS (if you stick to githubusercontent you'll be fine, it supports CORS)

This example shows how to load image from the web (it also shows how to display raw image and PNG image).
It takes some time to load on the web browser, be patient.

The relevant line is

with open('https://raw.githubusercontent.com/littlevgl/lv_binding_micropython/master/examples/png_decoder_test.png','rb') as f:
  png_data = f.read()
  • tileview - requires passing an array of lv_point_t, list doesn't work. Very similar to calendar problem.

Same issue as highlighted_dates - C prototype needs to be changed to array. I'll add this to the PR. I also noticed lv_mbox_add_btns, I think your modal message box demo doesn't work because of this.
Did you find more examples?

Method get_selected_str() in ddlist and roller works but pretty ugly - it requires to pass a string as an argument and changes part of it in place.

In principle strings are supposed to be immutable.
But in this case it's so much easier to initialize a string and pass it. This is how C expects it to work, and it works here as well.
My opinion is that it's better to pass a string than create workarounds like you suggested here.
We can consider passing a bytearray and convert it to string, if this is important.

Also I don't know how to get data from lv.event_get_data() (ta example)

In the case of ta example, you need to cast a pointer to string. It's a bit tricky in Micropython, but here is an example of how this can be done:

import display_driver
import lvgl as lv

def cb(ta, event):
    if event == lv.EVENT.INSERT:
        ptr = lv.C_Pointer()
        ptr.ptr_val = lv.event_get_data()
        print(ptr.str_val)

ta = lv.ta(lv.scr_act())
ta.set_event_cb(cb)

The C_Pointer struct (union actually) is used to cast a pointer to other types, such as string.

stepansnigirev commented 4 years ago

I checked all existing examples on dev-6.1 branch and added a few missing examples. Calendar, Tileview and Tasks work - that's awesome! I also added a png example in lv_ex_img, but because of header parsing and decoding, this example becomes not so minimal...

For lv_arc I took an example from @amirgon , I also refactored the mbox modal example with a class.

One more issue I found: calendar.get_pressed_date() doesn't return None if the header is clicked (on C side it returns NULL but it is not converted to None)

I also noticed lv_mbox_add_btns, I think your modal message box demo doesn't work because of this. Did you find more examples?

Actually mbox demo works fine: demo

kisvegabor commented 4 years ago

@stepansnigirev You made awesome progress. Congratulations, and thank you! :slightly_smiling_face:

I'll merge it if @amirgon approves it.

amirgon commented 4 years ago

calendar.get_pressed_date() doesn't return None if the header is clicked (on C side it returns NULL but it is not converted to None)

It should be quite simple to fix. I've opened a new issue: littlevgl/lv_binding_micropython#50

Fixed.

kisvegabor commented 4 years ago

Anyway, I've submitted a PR for fixing this on lvgl: littlevgl/lvgl#1279

Merged!

amirgon commented 4 years ago

The micropython examples themselves look good, I think they can be merged. Thanks @stepansnigirev!

Open issues are related to the online simulator:

kisvegabor commented 4 years ago

I think they can be merged.

I merged it so it will be part of the documentation of v6.0 (released today).

@stepansnigirev Thank you very much for adding these examples! :clap: :clap: :clap: