Closed uraich closed 3 years ago
Thank you very much! It will be extremely helpful.
@embeddedt What is the current state/idea of integration into the docs?
I should be able to generate links to the simulator for each of these as long as the names and paths are consistent with the C examples (looks like they are).
The names are compatible except for:
It would be nice to have a button to show or hide the code the same way it is done for the C code.
That should be doable.
We can however rename them to e.g. lv_ex_gauge_2.py for the file that runs on the simulator and lv_ex_gauge_2_png.py for the one that does not.
That would probably be best. We can thus avoid needing to make a symlink for all the working examples.
Great! Let me know if it's ready to merge or need assistance from my side.
The examples using images may not run yet on the simulator.
@uraich Why? Did you try the raw images instead of PNG? Let me if you need any advice.
@amirgon: Maybe I expressed myself wrongly. I have 2 versions of the programs: One using raw images, which work on the simulator and the corresponding ones using png images, which work only on the unix/SDL version or on the hardware. No problem there.
I wrote another little micropython example for the canvas. This is an analogue watch, showing time and date. The app updates every sec. If you want to have a look at the code, you will find it here: https://github.com/uraich/lv_mpy_examples/blob/main/widgets/canvas/aclock.py
@uraich It's not necessary to keep the C and Mpy examples in sync. So if you wish, you can add a clock example to this PR.
I wrote another little micropython example for the canvas. This is an analogue watch, showing time and date. The app updates every sec. If you want to have a look at the code, you will find it here:
Very nice!
A few questions/comments:
time
is not available on all Micropython ports. So this example can't run everywhere. It can't run on the online simulator.Hi Amir, Thanks for your comments. I will try to improve. In fact I am about to write a few programs to be run on the LilyGo t-watch 2020 which uses an ESP32 and time exists there. Which method should I use to get the current time in a portable fashion? and how do I make the hands a widget? I have seen no docs on how to make custom widgets. The t-watch programs I have so far are:
utime
is available on the simulator and STM32 last time I checked. I assume it's also available on Unix and ESP32.
I modified the analogue clock according to the recommendations by embeddedt and amir. (I still don't know, how to create a widget for the hands) When trying to run it on the simulator however, I get an error when I try to create the update task. The code works ok on the SDL unix port.
Which method should I use to get the current time in a portable fashion?
Apparently, Micropython's JS port contains an incomplete utime
module, and real-time clock functionality is completely missing.
Other ports (unix, esp32, etc.) seem to have a more complete utime
implementation.
It seems to be a problem specific to the JS port utime implementation, I've opened an issue on Micropython: https://github.com/micropython/micropython/issues/6670
how do I make the hands a widget?
I didn't do it a lot, but here is an example of a pure python custom widget.
It's only a simple line, but it demonstrate how to write the design
and signal
callbacks required for implementing a new widget.
When trying to run it on the simulator however, I get an error when I try to create the update task. The code works ok on the SDL unix port.
The only problem is the missing functions in utime
module.
When removing them, it works fine (although cannot point to the correct time)
Perhaps the example can detect the presence of the functions in utime
and just use a fake time if they aren't present?
Perhaps the example can detect the presence of the functions in
utime
and just use a fake time if they aren't present?
Good idea!
You may want to check this one as well: You find it here: https://github.com/uraich/lv_mpy_examples/blob/main/t-watch_examples/calculator.py
It works well in the online simulator, though I had to remove the while True: pass
loop, as the simulator does not need it, and crashes if it is present.
Well, I uploaded the program as I run it in the lvgl unix port, where the loop is needed. I expected that you had to remove the loop for the simulator.
Well, I uploaded the program as I run it in the lvgl unix port, where the loop is needed.
@uraich That loop is not necessarily needed for the unix simulator.
I usually run the unix simulator with -i
option, which opens the REPL after loading the script and would not close it until you exit.
When running with the -i
option you should not put this endless loop, otherwise you would not reach the REPL.
Hi Amir, I tried your custom widget, which works fine on the simulator but gives me trouble when running it on the lvgl unix port (v7.8). I see the line coming up. When pressing it it changes direction as expected. However, when releasing the mouse pointer it does not switch back. I see the release event but design is not called. I am interested in it because I would like to create 2 custom widgets:
a meter widget, similar to a slider but with scale
another type of a gauge widget:
I see the line coming up. When pressing it it changes direction as expected. However, when releasing the mouse pointer it does not switch back. I see the release event but design is not called.
@uraich you are right, there is a small bug in this script - I forgot to call invalidate
.
Here is a fixed script which calls invalidate
whenever the pressed
state changes.
It should work correctly now.
Thanks Amir, Now it works as expected.
Sorry, I have another problem: I try to follow this tutorial and write the examples in Python: https://blog.lvgl.io/2018-12-13/extend-lvgl-objects I guess that instead of adding fields to the extended data structure I should use class variables in Python? When trying to follow the temperature button example I can get the original design_cb with self.get_design_cb, however I get a blob that is not callable. How do I have to do this correctly?
I guess that instead of adding fields to the extended data structure I should use class variables in Python?
Correct. You can't access the extended data structure from Python, but you can extend the Python object which is really a cleaner approach than using C structs.
I can get the original design_cb with self.get_design_cb, however I get a blob that is not callable. How do I have to do this correctly?
Today the Micropython binding does not provide a way to call a C function pointer.
I've added an enhancement issue for that: https://github.com/lvgl/lv_binding_micropython/issues/110
In the meanwhile there might be a workaround.
Have a look at how signal_cb
is called on the example script:
saved_signal = self.get_signal_cb()
self.set_signal_cb(self.ancestor_signal)
res = lv.signal_send(self, sign, param)
self.set_signal_cb(saved_signal)
In case of design
there is no lv.design_send
function, but it's very easy to add one in the C code for that purpose.
Are there still problems with this pull request?
lv_colors.py is already in lib. Do we need it here as well?
No, wd need it only onceSent from my Samsung Galaxy smartphone. -------- Original message --------From: Amir Gonnen notifications@github.com Date: 12/11/20 21:22 (GMT+01:00) To: lvgl/lv_examples lv_examples@noreply.github.com Cc: Uli Raich uli.raich@gmail.com, Mention mention@noreply.github.com Subject: Re: [lvgl/lv_examples] Mpy examples (#85) lv_colors.py is already in lib. Do we need it here as well?
—You are receiving this because you were mentioned.Reply to this email directly, view it on GitHub, or unsubscribe. [ { "@context": "http://schema.org", "@type": "EmailMessage", "potentialAction": { "@type": "ViewAction", "target": "https://github.com/lvgl/lv_examples/pull/85#issuecomment-743407831", "url": "https://github.com/lvgl/lv_examples/pull/85#issuecomment-743407831", "name": "View Pull Request" }, "description": "View this Pull Request on GitHub", "publisher": { "@type": "Organization", "name": "GitHub", "url": "https://github.com" } } ]
I saw that reading the binary images did not work for the ili9341. The reason is the different colour format as compared to the SDL driver. I created the rgb565 binary image files and added them. The programs using binary images where adapted to this change.
The reason is the different colour format as compared to the SDL driver.
That's right, and imagetools.py contains special conversion functions for that purpose ("convert_rgba8888_to_XXXX").
It automatically detects the required color mode and performs a conversion if needed.
These functions are currently used only for PNG decoding, but they can also be used with binary images saved in rgba8888 format.
Thanks for the hint. I now have 2 versions of binary image files: xxx.argb (for the rgb8888 format) and xxx.rgb565 (for the 16 bit format with swap) I created the files from the C image code. I also converted blue_flower_argb.bin to blue_flower_rgb565.bin. All image examples in
If you agree I merge this PR. Even if they are minor issues I'm sure it will be extremely useful for the users.
Small fixes (if needed can be) added in a new PR.
So, if you say go, I hit the merge button. :slightly_smiling_face:
I guess there will be a few issues but it will be easier for me to fix those once the PR is merged (e.g. once the image files are available on their default github locations)
Okay, great! Merged.
Thank you very much for the amazing and exhaustive work, @uraich.
Can someone add the necessary "try yourself" links into the documentation? I will then check each example one be one on the simulator.
@embeddedt is the wizard who can cast these magics :slightly_smiling_face:
@uraich Can you open a new issue for it?
Starting to work on it now.
When trying to follow the temperature button example I can get the original design_cb with self.get_design_cb, however I get a blob that is not callable. How do I have to do this correctly?
@uraich I've added support for function pointers (https://github.com/lvgl/lv_binding_micropython/issues/110), so you can now call the returned function from get_design_cb
.
Please let me know if you see any problems.
Sorry, Where did you make the changes? I pulled lv_bindings and lvgl but your example program from https://github.com/lvgl/lv_binding_micropython/issues/110 still gives me "Blob' object isn't callable" (and so does mine) It would be very nice to have a call: lv_version() returning the current version of lvgl such that I can be sure I have the latest and the greatest
Sorry, I made a super stupid mistake! Your examples works fine. Will still have to check a few things on mine. The error "Blob' object isn't callable" has gone.
It would be very nice to have a call: lv_version() returning the current version of lvgl such that I can be sure I have the latest and the greatest
There are macros for LVGL version but macros are not accessible from Micropython. We can add an inline function that returns the version according the macros, which can be called from Micropython.
But take into account that there are multiple components, LVGL is only one them.
There's LVGL core, Micropython core, the binding scripts, drivers etc. each with its own version. Unfortunately we don't have today a consistent way to identify each version of each component, other than git commit hash.
The recent change for example didn't modify LVGL version, only updated the binding script.
It seems to me that most users would care mainly about the LVGL version. I have yet to see any problems with MicroPython breaking old scripts (though that could also happen down the road).
The documentation links are almost ready. I have run into a bit of a logic issue with the simulator and I've forgotten what the approach we discussed was.
Currently, the simulator's default program has a startup script which looks like this:
# Initialize
import imp, sys
sys.path.append('https://raw.githubusercontent.com/littlevgl/lv_binding_micropython/master/lib')
import display_driver
This hack is used to load display_driver.py straight from the repository instead of having to bake an old version into the simulator.
The header.py file @uraich is using does not contain the lines which manipulate the import functionality, which means that the simulator is unable to find display_driver.py.
I see two possible solutions:
import imp, sys
and sys.path.append
lines regardless of what script the user provides.Which would be preferable?
I don't think you need header.py to run the demos on the simulator. When I tried this last time it worked without. However: https://raw.githubusercontent.com/littlevgl/lv_binding_micropython/master/lib does not exists any longer. It should be replaced by https://raw.githubusercontent.comlvgl/lv_binding_micropython/master/lib but maybe I missed something?
- Have the simulator always run the
import imp, sys
andsys.path.append
lines regardless of what script the user provides.
This is a bit too hard-coded. What if we want to import display_driver from someplace else for some reason? What if we want to import a specific version of the display driver (v7, v8 etc.)?
Another example - what if we want to run with uasyncio? When using uasyncio LVGL event loop (which calls task_handler) is initialized differently and today the display initializes the even loop.
My opinion is that paths into github should not be hard-coded in the simulator.
I don't think you need header.py to run the demos on the simulator. When I tried this last time it worked without.
https://github.com/lvgl/lv_examples/blob/master/src/lv_ex_widgets/lv_ex_arc/lv_ex_arc_1.py
This example isn't importing the display driver, etc. at the top. I assume the other widget examples work similarly.
https://raw.githubusercontent.com/littlevgl/lv_binding_micropython/master/lib does not exists any longer.
I believe GitHub redirects to the new name automatically.
My opinion is that paths into github should not be hard-coded in the simulator.
In that case, I will modify header.py to check whether it is running on JS or not.
https://github.com/lvgl/lv_examples/blob/master/src/lv_ex_widgets/lv_ex_arc/lv_ex_arc_1.py
This example isn't importing the display driver, etc. at the top. I assume the other widget examples work similarly.
I think you can add to the URL two scripts, one is the header (fixed for all examples) and the other is the example with no imports. (script
and script_startup
)
Hi Amir, Concerning the function pointers: I still had a problem with my program (did not return lv.RES.OK after my new design callback) but once I found that, the program worked flawlessly. Thanks very much.
These are my micropython examples. I tried to do a "word by word" translation from the C originals. The examples using images may not run yet on the simulator. However, I prepared examples with the extension ...sim.py for which a conversion to a program running on the simulator should be easy. Only the filename of the binary file must be changed to the URL of the binary image. Please check