High level GUI lib/framework
-
- Posts: 5
- Joined: Sat Jul 15, 2017 7:13 pm
High level GUI lib/framework
Hi fellow MicroPythonians,
I'm in the process of planning/building an app for a device that boasts a GUI (320x240 TFT) and has mostly button-driven inputs. It uses Micropython for its main application logic. I really like the full-featuredness of uP and especially the availability of the async functionality is great! This together with the support for my platform of choice (ESP32 + pSRAM) made going for uP a no-brainer.
I am pretty used to and confident writing embedded C code. If have not yet made a native (C) uP module, but I'm certainly not shying away from writing some supporting modules or device drivers in C (planning to do so when needed).
For the GUI part however, this is a bit more complex:
Performance really matters here (shoving a lot of data), so having a fast native module is essential IMO. I'd like to have a somewhat pleasant development experience, so the goal is to have a high(er) level GUI api available in uP. I'm not looking (only) for the lower level routines i.e. a raw framebuffer or some loose line/circle/fill methods.
I found two interesting libs/frameworks that probably would do the job (possibly with some modifications): uGIO from Achim Doebler (https://github.com/achimdoebler/UGUI) and GUISlice (https://github.com/ImpulseAdventure/GUIslice). The latter being the more comprehensive.
Both are written in pure C and it should be relatively easy to get going on the ESP32 (GUISlice even has "official" support for the ESP32 platform!)
As both modules model a GUI, they tend to use OO programming paradigms, with lots of C structs etc. And have a relatively large code base (compare to for instance a simple driver).
My question is:
How would you go about wrapping one of these libs up in a uP module whilst fitting the C object model as neatly as possible into uP?
e.g. having "Window", "button" and "Textbox" classes in uP, that more more less map directly map onto the objects in the C libs. Would this be possible without essentially (re)building the full GUI object model in uP (and as a result only having a low level graphics driver left over in native C code)?
I'm in the process of planning/building an app for a device that boasts a GUI (320x240 TFT) and has mostly button-driven inputs. It uses Micropython for its main application logic. I really like the full-featuredness of uP and especially the availability of the async functionality is great! This together with the support for my platform of choice (ESP32 + pSRAM) made going for uP a no-brainer.
I am pretty used to and confident writing embedded C code. If have not yet made a native (C) uP module, but I'm certainly not shying away from writing some supporting modules or device drivers in C (planning to do so when needed).
For the GUI part however, this is a bit more complex:
Performance really matters here (shoving a lot of data), so having a fast native module is essential IMO. I'd like to have a somewhat pleasant development experience, so the goal is to have a high(er) level GUI api available in uP. I'm not looking (only) for the lower level routines i.e. a raw framebuffer or some loose line/circle/fill methods.
I found two interesting libs/frameworks that probably would do the job (possibly with some modifications): uGIO from Achim Doebler (https://github.com/achimdoebler/UGUI) and GUISlice (https://github.com/ImpulseAdventure/GUIslice). The latter being the more comprehensive.
Both are written in pure C and it should be relatively easy to get going on the ESP32 (GUISlice even has "official" support for the ESP32 platform!)
As both modules model a GUI, they tend to use OO programming paradigms, with lots of C structs etc. And have a relatively large code base (compare to for instance a simple driver).
My question is:
How would you go about wrapping one of these libs up in a uP module whilst fitting the C object model as neatly as possible into uP?
e.g. having "Window", "button" and "Textbox" classes in uP, that more more less map directly map onto the objects in the C libs. Would this be possible without essentially (re)building the full GUI object model in uP (and as a result only having a low level graphics driver left over in native C code)?
Re: High level GUI lib/framework
I've also been looking at GUI framework options for MicroPython. There are a number of C UI libraries that could be leveraged but I'm hoping to write most of the code in MicroPython itself. The SPI comms to most display drivers is already fast in MicroPython and manipulating pixels in framebuffers should also be relatively efficient. Need to measure it obviously but I want to drop into C only if measurements dictate that it's necessary.
Worth noting that Adafruit are cooking up something; their upcoming version of CircuitPython adds a displayio module though it's not clear what they're intending to do with it yet...
Other libraries of interest: Peter Hinch's micropython-nano-gui. Loboris' display module (needs his LoBo MicroPython fork). As well as uGIO and GUISlice there's also cfGUI and littlevGL in the C-space.
I've already started building some basic menu widgets and a progress bar but this is all still quite experimental and built on top of Loboris' display module. When it becomes a little more mature I will share the code!
Worth noting that Adafruit are cooking up something; their upcoming version of CircuitPython adds a displayio module though it's not clear what they're intending to do with it yet...
Other libraries of interest: Peter Hinch's micropython-nano-gui. Loboris' display module (needs his LoBo MicroPython fork). As well as uGIO and GUISlice there's also cfGUI and littlevGL in the C-space.
I've already started building some basic menu widgets and a progress bar but this is all still quite experimental and built on top of Loboris' display module. When it becomes a little more mature I will share the code!
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: High level GUI lib/framework
In addition to nano GUI there is also this for SSD1963 displays and this for official LCD160cr.
The first is for OLED displays and is output only as these lack a touch overlay. The other two are touchscreen interfaces. As a general point it is possible to achieve decent responsiveness in Python, although the SSD1963 driver for large displays employs advanced techniques courtesy of @Robert_hh who contributed the low level driver code.
My point here is not to promote these drivers which may not match your intended use case but to suggest that using C may be unnecessary.
The first is for OLED displays and is output only as these lack a touch overlay. The other two are touchscreen interfaces. As a general point it is possible to achieve decent responsiveness in Python, although the SSD1963 driver for large displays employs advanced techniques courtesy of @Robert_hh who contributed the low level driver code.
My point here is not to promote these drivers which may not match your intended use case but to suggest that using C may be unnecessary.
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
-
- Posts: 5
- Joined: Sat Jul 15, 2017 7:13 pm
Re: High level GUI lib/framework
Thanks for the replies! Bit off topic but, I have to say it: one of the reasons for coming to uP is the vibrant community with some very nice and active people. It always thrills me seeing open source working in the wild!
Anyways, thanks for the handles regarding the UI.. now I have even more options to consider..
Does anyone happen to know if any of the given GUI-options work nicely together with an async/await-based application (i.e. implements the IO async, or push off to a thread where the heavy work is done in background)?
Part of my question was, although it probably deserves its own topic on the forum, how to integrate C modules/libs that use a lot of OO-style C coding. With OO-style I mean with a lot of structs pointing to other structs, to which one would like to have a nice representation mirrored in Python objects.
Maybe there are some good examples showing this already (probably in the GUI space?) of which the code can be studied (any suggestions)? IMO the whole C modules "advanced" uP topic is a bit underexposed in the documentation. For those of you who're reading along, I found this talk from Nick Moore in regards to how a C module is made highly enlightening, recommended!
Anyways, thanks for the handles regarding the UI.. now I have even more options to consider..
![Wink ;)](./images/smilies/icon_e_wink.gif)
Does anyone happen to know if any of the given GUI-options work nicely together with an async/await-based application (i.e. implements the IO async, or push off to a thread where the heavy work is done in background)?
Part of my question was, although it probably deserves its own topic on the forum, how to integrate C modules/libs that use a lot of OO-style C coding. With OO-style I mean with a lot of structs pointing to other structs, to which one would like to have a nice representation mirrored in Python objects.
Maybe there are some good examples showing this already (probably in the GUI space?) of which the code can be studied (any suggestions)? IMO the whole C modules "advanced" uP topic is a bit underexposed in the documentation. For those of you who're reading along, I found this talk from Nick Moore in regards to how a C module is made highly enlightening, recommended!
-
- Posts: 5
- Joined: Sat Jul 15, 2017 7:13 pm
Re: High level GUI lib/framework
@mattyt I would be interested in your library (on top of Loboris's), as it looks like the kind of UI I would be making (3-button type).
Btw. I'd would probably just (try to) extract the display driver from LoBo's port to include it in either mainline or the pfalcon uP port. as they support pSRAM now and seem more stable and are less a "one man show" than the LoBo port. I also have my doubts on development process and stability (I see a lot of issues like this: "Hey, in version x.y I suddenly get a coredump when starting xyz").
Hey, don't be shy it's never too early to share code on github!I've already started building some basic menu widgets and a progress bar but this is all still quite experimental and built on top of Loboris' display module. When it becomes a little more mature I will share the code!
![Very Happy :D](./images/smilies/icon_e_biggrin.gif)
Btw. I'd would probably just (try to) extract the display driver from LoBo's port to include it in either mainline or the pfalcon uP port. as they support pSRAM now and seem more stable and are less a "one man show" than the LoBo port. I also have my doubts on development process and stability (I see a lot of issues like this: "Hey, in version x.y I suddenly get a coredump when starting xyz").
-
- Posts: 847
- Joined: Mon Nov 20, 2017 10:18 am
Re: High level GUI lib/framework
Slightly off topic but related.
Lately I have been making UI using the this https://github.com/jczic/MicroWebSrv with websockets. I basically make a HTML page that is served up that has Javascript with the UI then any needed output from the UI is sent back to the ESP32 via a websocket. The Websocket has a callback on the ESP32. Sometimes I use this call back to run code but most of the time I mainly just use it to alter global variables that I use in my main program.
This way my GUI is on my tablet in my hand and it is wireless to the project.
Lately I have been making UI using the this https://github.com/jczic/MicroWebSrv with websockets. I basically make a HTML page that is served up that has Javascript with the UI then any needed output from the UI is sent back to the ESP32 via a websocket. The Websocket has a callback on the ESP32. Sometimes I use this call back to run code but most of the time I mainly just use it to alter global variables that I use in my main program.
This way my GUI is on my tablet in my hand and it is wireless to the project.
Re: High level GUI lib/framework
You might also want to check out a presentation Damien gave at our MicroPython Meetup back in June: Wrap a C module in MicroPython. I'm pressing him to do a follow-up that would explain more about how to neatly push data across the C/MicroPython boundary (it's not obvious how you'd allow keyword arguments to appear on the C side for example).
Best advice right now is to take a look at one of the APIs that's sort-of like what you need and copy it as a starting point. Documentation for C module development will come but perhaps not quickly!
I will release the code soon, but it's so immature and in flux at the moment I don't want to let it out in case someone starts using it! Give me a little while longer to figure out how I want to make it work...![Smile :)](./images/smilies/icon_e_smile.gif)
I did start with mainline and a driver (Jeff Mer's, though I looked at Deshipu's too) but the LoBo fork had more primitives that I wanted. Shouldn't be too hard to replace later.
And yeah, it's fantastic that Boris is ripping into implementing stuff quickly but mainline should be stable and it's ok to move a little slower.
Best advice right now is to take a look at one of the APIs that's sort-of like what you need and copy it as a starting point. Documentation for C module development will come but perhaps not quickly!
I will release the code soon, but it's so immature and in flux at the moment I don't want to let it out in case someone starts using it! Give me a little while longer to figure out how I want to make it work...
![Smile :)](./images/smilies/icon_e_smile.gif)
I did start with mainline and a driver (Jeff Mer's, though I looked at Deshipu's too) but the LoBo fork had more primitives that I wanted. Shouldn't be too hard to replace later.
And yeah, it's fantastic that Boris is ripping into implementing stuff quickly but mainline should be stable and it's ok to move a little slower.
- Mike Teachman
- Posts: 155
- Joined: Mon Jun 13, 2016 3:19 pm
- Location: Victoria, BC, Canada
Re: High level GUI lib/framework
Something related that might be useful to those writing modules in C.... As part of my learning how to write uPy modules in C I wrote a C file providing examples of the patterns used to map uPy calls to C, for both module functions and class methods.rogierlodewijks wrote: ↑Wed Nov 21, 2018 8:50 amIMO the whole C modules "advanced" uP topic is a bit underexposed in the documentation.
https://github.com/MikeTeachman/MicroPy ... examples.c
This file can be compiled into a build. I developed it on the ESP32/Lobo port, but I expect it will work for all uPy ports.
Each example shows:
- uPy interface to the function or method, with all positional and keyword argument variants
- C implementation with uPy<->C bindings
Code: Select all
// Method Example 3:
// variable number of positional arguments, specified by min and max,
// NOTE: for a method call, MIN_NUM_METHOD_ARGS must never be zero
//
// class Argex:
// m_min_max(self, [pos1]):
//
// from argex import Argex
// a = Argex(True, 7)
// a.m_min_max()
// a.m_min_max(False)
#define MIN_NUM_METHOD_ARGS (1) // self
#define MAX_NUM_METHOD_ARGS (2) // self + one Optional positional argument
STATIC mp_obj_t method_min_max_args(size_t n_args, const mp_obj_t *args) {
argex_obj_t *self = MP_OBJ_TO_PTR(args[0]);
// important notes:
// 'n_args' refers to the count of positional args, and +1 for the class instance self
printf("n_args = %u\n", n_args);
if (n_args == 1) {
// when n_args equals 1 it means that ONLY argument passed is the class instance self
return mp_obj_new_int(self->var1);
} else {
self->var1 = mp_obj_get_int(args[1]);
return mp_const_none;
}
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(method_min_max_args_obj, MIN_NUM_METHOD_ARGS, MAX_NUM_METHOD_ARGS, method_min_max_args);
Re: High level GUI lib/framework
This is a fantastic resource, thanks Mike! Just what I needed.Mike Teachman wrote: ↑Wed Nov 21, 2018 3:01 pmSomething related that might be useful to those writing modules in C.... As part of my learning how to write uPy modules in C I wrote a C file providing examples of the patterns used to map uPy calls to C, for both module functions and class methods.rogierlodewijks wrote: ↑Wed Nov 21, 2018 8:50 amIMO the whole C modules "advanced" uP topic is a bit underexposed in the documentation.
https://github.com/MikeTeachman/MicroPy ... examples.c
![Smile :)](./images/smilies/icon_e_smile.gif)
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: High level GUI lib/framework
The three GUI's I wrote and cited above are based on uasyncio.rogierlodewijks wrote: ↑Wed Nov 21, 2018 8:50 am...
Does anyone happen to know if any of the given GUI-options work nicely together with an async/await-based application (i.e. implements the IO async, or push off to a thread where the heavy work is done in background)?...
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.