{"id":13802155,"url":"https://github.com/lvgl/lv_binding_micropython","last_synced_at":"2025-05-15T18:08:10.204Z","repository":{"id":37894971,"uuid":"167166039","full_name":"lvgl/lv_binding_micropython","owner":"lvgl","description":"LVGL binding for MicroPython","archived":false,"fork":false,"pushed_at":"2025-03-18T20:35:23.000Z","size":3841,"stargazers_count":286,"open_issues_count":49,"forks_count":178,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-04-01T00:32:34.554Z","etag":null,"topics":["gui","lvgl","micropython","tft"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lvgl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-01-23T10:42:58.000Z","updated_at":"2025-03-30T00:45:21.000Z","dependencies_parsed_at":"2023-09-26T12:33:55.279Z","dependency_job_id":"decc0e5e-1194-4e17-b0ce-e0185354bd0f","html_url":"https://github.com/lvgl/lv_binding_micropython","commit_stats":{"total_commits":657,"total_committers":35,"mean_commits":"18.771428571428572","dds":"0.19939117199391176","last_synced_commit":"96d6d3538fec4de99c200c1bb388b02b95cbbdaf"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lvgl%2Flv_binding_micropython","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lvgl%2Flv_binding_micropython/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lvgl%2Flv_binding_micropython/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lvgl%2Flv_binding_micropython/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lvgl","download_url":"https://codeload.github.com/lvgl/lv_binding_micropython/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247760822,"owners_count":20991531,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gui","lvgl","micropython","tft"],"created_at":"2024-08-04T00:01:37.613Z","updated_at":"2025-04-08T01:34:24.881Z","avatar_url":"https://github.com/lvgl.png","language":"C","readme":"![Build lv_micropython unix port](https://github.com/lvgl/lv_binding_micropython/workflows/Build%20lv_micropython%20unix%20port/badge.svg)\n\n# Bindings for LVGL\n\n---\n\nThis repo is a submodule of [lv_micropython](https://github.com/lvgl/lv_micropython).\nPlease fork [lv_micropython](https://github.com/lvgl/lv_micropython) for a quick start with LVGL MicroPython Bindings.\n\n---\n\nSee also [Micropython + LittlevGL](https://blog.lvgl.io/2019-02-20/micropython-bindings) blog post. (LittlevGL is the previous name of LVGL.)\nFor advanced features, see [Pure MicroPython Display Driver](https://blog.lvgl.io/2019-08-05/micropython-pure-display-driver) blog post.\nFor questions and discussions - please use the forum: https://forum.lvgl.io/c/micropython\n\n## MicroPython\n\nMicroPython Binding for LVGL provides an automatically generated MicroPython module with classes and functions that allow the user access much of the LVGL library.\nThe module is generated automatically by the script [`gen_mpy.py`](https://github.com/lvgl/lv_binding_micropython/blob/master/gen/gen_mpy.py).\nThis script reads, preprocesses and parses LVGL header files, and generates a C file `lv_mpy.c` which defines the MicroPython module (API) for accessing LVGL from MicroPython.\nMicopython's build script (Makefile or CMake) should run `gen_mpy.py` automatically to generate and compile `lv_mpy.c`.\n\n- If you would like to see an example of how a generated `lv_mpy.c` looks like, have a look at [`lv_mpy_example.c`](https://raw.githubusercontent.com/lvgl/lv_binding_micropython/master/gen/lv_mpy_example.c). Note that its only exported (non static) symbol is `mp_module_lvgl` which should be registered in MicroPython as a module.\n- lv_binding_micropython is usually used as a git submodule of [lv_micropython](https://github.com/lvgl/lv_micropython) which builds MicroPython + LVGL + lvgl-bindings, but can also be used on other forks of MicroPython.\n\nIt's worth noting that the Micropython Bindings module (`lv_mpy.c`) is dependent on LVGL configuration.\nLVGL is configured by `lv_conf.h` where different objects and features could be enabled or disabled. LVGL bindings are generated only for the enabled objects and features. Changing `lv_conf.h` requires re running `gen_mpy.py`, therefore it's useful to run it automatically in the build script, as done by lv_micropython.\n\n### Memory Management\n\nWhen LVGL is built as a MicroPython library, it is configured to allocate memory using MicroPython memory allocation functions and take advantage of MicroPython *Garbage Collection* (\"gc\").\nThis means that structs allocated for LVGL use don't need to be deallocated explicitly, gc takes care of that.\nFor this to work correctly, LVGL is configured to use gc and to use MicroPython's memory allocation functions, and also register all LVGL \"root\" global variables to MicroPython's gc.\n\nFrom the user's perspective, structs can be created and will be collected by gc when they are no longer referenced.\nHowever, LVGL screen objects (`lv.obj` with no parent) are automatically assigned to default display, therefore not collected by gc even when no longer explicitly referenced.\nWhen you want to free a screen and all its descendants so gc could collect their memory, make sure you call `screen.delete()` when you no longer need it.\n\nMake sure you keep a reference to your display driver and input driver to prevent them from being collected.\n\n### Concurrency\n\nThis implementation of MicroPython Bindings to LVGL assumes that MicroPython and LVGL are running **on a single thread** and **on the same thread** (or alternatively, running without multithreading at all).\nNo synchronization means (locks, mutexes) are taken.\nHowever, asynchronous calls to LVGL still take place periodically for screen refresh and other LVGL tasks such as animation.\n\nThis is achieved by using the internal MicroPython scheduler (that must be enabled), by calling `mp_sched_schedule`.\n`mp_sched_schedule` is called when screen needs to be refreshed. LVGL expects the function `lv_task_handler` to be called periodically (see [lvgl/README.md#porting](https://github.com/lvgl/lvgl/blob/6718decbb7b561b68e450203b83dff60ce3d802c/README.md#porting)). This is usually handled in the display device driver.\nHere is [an example](https://github.com/lvgl/lv_binding_micropython/blob/77b0c9f2678b6fbd0950fbf27380052246841082/driver/SDL/modSDL.c#L23) of calling `lv_task_handler` with `mp_sched_schedule` for refreshing LVGL. [`mp_lv_task_handler`](https://github.com/lvgl/lv_binding_micropython/blob/77b0c9f2678b6fbd0950fbf27380052246841082/driver/SDL/modSDL.c#L7) is scheduled to run on the same thread MicroPython is running, and it calls both `lv_task_handler` for LVGL task handling and `monitor_sdl_refr_core` for refreshing the display and handling mouse events.\n\nWith REPL (interactive console), when waiting for the user input, asynchronous events can also happen. In [this example](https://github.com/lvgl/lv_mpy/blob/bc635700e4186f39763e5edee73660fbe1a27cd4/ports/unix/unix_mphal.c#L176) we just call `mp_handle_pending` periodically when waiting for a keypress. `mp_handle_pending` takes care of dispatching asynchronous events registered with `mp_sched_schedule`.\n\n### Structs Classes and globals\n\nThe LVGL binding script parses LVGL headers and provides API to access LVGL **classes** (such as `btn`) and **structs** (such as `color_t`). All structs and classes are available under lvgl micropython module.\n\nlvgl Class contains:\n- functions (such as `set_x`)\n- enums related to that class (such as `STATE` of a `btn`)\n\nlvgl struct contains only attributes that can be read or written. For example:\n```python\nc = lvgl.color_t()\nc.ch.red = 0xff\n```\nstructs can also be initialized from dict. For example, the example above can be written like this:\n```python\nc = lvgl.color_t({'ch': {'red' : 0xff}})\n```\n\nAll lvgl globals (functions, enums, types) are available under lvgl module. For example, `lvgl.SYMBOL` is an \"enum\" of symbol strings, `lvgl.anim_create` will create animation etc.\n\n### Callbacks\n\nIn C a callback is a function pointer.\nIn MicroPython we would also need to register a *MicroPython callable object* for each callback.\nTherefore in the MicroPython binding we need to register both a function pointer and a MicroPython object for every callback.\n\nTherefore we defined a **callback convention** that expects lvgl headers to be defined in a certain way. Callbacks that are declared according to the convention would allow the binding to register a MicroPython object next to the function pointer when registering a callback, and access that object when the callback is called.\nThe MicroPython callable object is automatically saved in a `user_data` variable which is provided when registering or calling the callback.\n\nThe callback convention assumes the following:\n- There's a struct that contains a field called `void * user_data`.\n- A pointer to that struct is provided as the first argument of a callback registration function.\n- A pointer to that struct is provided as the first argument of the callback itself.\n\nAnother option is that the callback function pointer is just a field of a struct, in that case we expect the same struct to contain `user_data` field as well.\n\nAnother option is:\n- A parameter called `void * user_data` is provided to the registration function as the last argument.\n- The callback itself receives `void *` as the last argument\n\nIn this case, the user should provide either `None` or a dict as the `user_data` argument of the registration function.\nThe callback will receive a Blob which can be casted to the dict in the last argument.\n(See `async_call` example below)\n\nAs long as the convention above is followed, the lvgl MicroPython binding script would automatically set and use `user_data` when callbacks are set and used.\n\nFrom the user perspective, any python callable object (such as python regular function, class function, lambda etc.) can be user as an lvgl callbacks. For example:\n```python\nlvgl.anim_set_custom_exec_cb(anim, lambda anim, val, obj=obj: obj.set_y(val))\n```\nIn this example an exec callback is registered for an animation `anim`, which would animate the y coordinate of `obj`.\nAn lvgl API function can also be used as a callback directly, so the example above could also be written like this:\n```python\nlv.anim_set_exec_cb(anim, obj, obj.set_y)\n```\n\nlvgl callbacks that do not follow the Callback Convention cannot be used with micropython callable objects. A discussion related to adjusting lvgl callbacks to the convention: https://github.com/lvgl/lvgl/issues/1036\n\nThe `user_data` field **must not be used directly by the user**, since it is used internally to hold pointers to MicroPython objects.\n\n### Display and Input Drivers\n\nLVGL can be configured to use different displays and different input devices. More information is available on [LVGL documentation](https://docs.lvgl.io/master/porting/display.html).\nRegistering a driver is essentially calling a registration function (for example `disp_drv_register`) and passing a function pointer as a parameter (actually a struct that contains function pointers). The function pointer is used to access the actual display / input device.\n\nWhen implementing a display or input LVGL driver with MicroPython, there are 3 option:\n- Implement a Pure Python driver. It the easiest way to implement a driver, but may perform poorly\n- Implement a Pure C driver.\n- Implemnent a Hybrid driver where the critical parts (such as the `flush` function) are in C, and the non-critical part (such as initializing the display) are implemented in Python.\n\nAn example of Pure/Hybrid driver is the [ili9XXX.py](https://github.com/lvgl/lv_binding_micropython/blob/master/driver/esp32/ili9XXX.py).\n\nThe driver registration should eventually be performed in the MicroPython script, either in the driver code itself in case of the pure/hybrid driver or in user code in case of C driver (for example, in the case of the SDL driver). Registering the driver on Python and not in C is important to make it easy for the user to select and replace drivers without building the project and changing C files.\n\nWhen creating a display or input LVGL driver, make sure you let the user **configure all parameters on runtime**, such as SPI pins, frequency, etc.\nEventually the user would want to build the firmware once and use the same driver in different configuration without re-building the C project.\nThis is different from standard LVGL C drivers where you usually use macros to configure parameters and require the user to re-build when any configurations changes.\n\nExample:\n\n```python\n\n# Initialize ILI9341 display\n\nfrom ili9XXX import ili9341\nself.disp = ili9341(dc=32, cs=33, power=-1, backlight=-1)\n\n# Register xpt2046 touch driver\n\nfrom xpt2046 import xpt2046\nself.touch = xpt2046()\n```\n\nExample:\n\n```python\n# init\n\nimport lvgl as lv\nlv.init()\n\nfrom lv_utils import event_loop\n\nWIDTH = 480\nHEIGHT = 320\n\nevent_loop = event_loop()\ndisp_drv = lv.sdl_window_create(WIDTH, HEIGHT)\nmouse = lv.sdl_mouse_create()\nkeyboard = lv.sdl_keyboard_create()\nkeyboard.set_group(self.group)\n```\n\nIn this example we use LVGL built in LVGL driver.  \n\nCurrently supported drivers for Micropyton are\n\n- LVGL built-in drivers such use the unix/Linux SDL (display, mouse, keyboard) and Frame Buffer (`/dev/fb0`)\n- ILI9341 driver for ESP32\n- XPT2046 driver for ESP32\n- FT6X36 (capacitive touch IC) for ESP32\n- Raw Resistive Touch for ESP32 (ADC connected to screen directly, no touch IC)\n\nDriver code is under `/driver` directory.\n\nDrivers can also be implemented in pure MicroPython, by providing callbacks (`disp_drv.flush_cb`, `indev_drv.read_cb` etc.)\nCurrently the supported ILI9341, FT6X36 and XPT2046 are pure micropython drivers.\n\n### Where are the drivers?\n\nLVGL C drivers and MicroPython drivers (either C or Python) are **separate and independent** from each other.\nThe main reason is configuration:\n- The C driver is usually configured with C macros (which pins it uses, frequency, etc.)\nAny configuration change requires rebuilding the firmware but that's understandable since any change in the application requires rebuilding the firmware anyway.\n- In MicroPython the driver is built once with MicroPython firmware (if it's a C driver) or not built at all (if it's pure Python driver). On runtime the user initializes the driver and configures it. If the user switches SPI pins or some other configuration, there is no need to rebuild the firmware, just change the Python script and initialize the driver differently **on runtime**.\n\nSo the location for MicroPython drivers is https://github.com/lvgl/lv_binding_micropython/tree/master/driver and is unrelated to https://github.com/lvgl/lv_drivers.\n\n### The Event Loop\n\nLVGL requires an Event Loop to re-draw the screen, handle user input etc.\nThe default Event Loop is implement in [lv_utils.py](https://github.com/lvgl/lv_binding_micropython/blob/master/lib/lv_utils.py) which uses MicroPython Timer to schedule calls to LVGL.\nIt also supports running the Event Loop in [uasyncio](https://docs.micropython.org/en/latest/library/uasyncio.html) if needed.  \nSome drivers start the event loop automatically if it doesn't already run. To configure the event loop for these drivers, just initialize the event loop before registering the driver.  \nLVGL native drivers, such as the SDL driver, do not start the event loop. You must start the event loop explicitly otherwise screen will not refresh.\n\nThe event loop can be started like this:\n```\nfrom lv_utils import event_loop\nevent_loop = event_loop()\n```\nand you can configure it by providing parameters, see lv_utils.py for more details.\n\n### Adding MicroPython Bindings to a project\n\nAn example project of \"MicroPython + lvgl + Bindings\" is [`lv_mpy`](https://github.com/lvgl/lv_mpy).\nHere is a procedure for adding lvgl to an existing MicroPython project. (The examples in this list are taken from [`lv_mpy`](https://github.com/lvgl/lv_mpy)):\n\n- Add [`lv_bindings`](https://github.com/lvgl/lv_binding_micropython) as a sub-module under `lib`.\n- Add `lv_conf.h` in `lib`\n- Edit the Makefile to run `gen_mpy.py` and build its product automatically. Here is [an example](https://github.com/lvgl/lv_micropython/blob/2940838bf6d4999050efecb29a4152ab5796d5b3/py/py.mk#L22-L38).\n- Register lvgl module and display/input drivers in MicroPython as a builtin module. [An example](https://github.com/lvgl/lv_micropython/blob/2940838bf6d4999050efecb29a4152ab5796d5b3/ports/unix/mpconfigport.h#L230).\n- Add lvgl roots to gc roots. [An example](https://github.com/lvgl/lv_micropython/blob/2940838bf6d4999050efecb29a4152ab5796d5b3/ports/unix/mpconfigport.h#L317-L318).\n- ~Configure lvgl to use *Garbage Collection* by setting several `LV_MEM_CUSTOM_*` and `LV_GC_*` macros [example](https://github.com/lvgl/lv_mpy/blob/bc635700e4186f39763e5edee73660fbe1a27cd4/lib/lv_conf.h#L28)~ lv_conf.h was moved to lv_binding_micropython git module.\n- Make sure you configure partitions correctly in `partitions.csv` and leave enough room for the LVGL module.\n- Something I forgot? Please let me know.\n\n### gen_mpy.py syntax\n```\nusage: gen_mpy.py [-h] [-I \u003cInclude Path\u003e] [-D \u003cMacro Name\u003e]\n                  [-E \u003cPreprocessed File\u003e] [-M \u003cModule name string\u003e]\n                  [-MP \u003cPrefix string\u003e] [-MD \u003cMetaData File Name\u003e]\n                  input [input ...]\n\npositional arguments:\n  input\n\noptional arguments:\n  -h, --help            show this help message and exit\n  -I \u003cInclude Path\u003e, --include \u003cInclude Path\u003e\n                        Preprocessor include path\n  -D \u003cMacro Name\u003e, --define \u003cMacro Name\u003e\n                        Define preprocessor macro\n  -E \u003cPreprocessed File\u003e, --external-preprocessing \u003cPreprocessed File\u003e\n                        Prevent preprocessing. Assume input file is already\n                        preprocessed\n  -M \u003cModule name string\u003e, --module_name \u003cModule name string\u003e\n                        Module name\n  -MP \u003cPrefix string\u003e, --module_prefix \u003cPrefix string\u003e\n                        Module prefix that starts every function name\n  -MD \u003cMetaData File Name\u003e, --metadata \u003cMetaData File Name\u003e\n                        Optional file to emit metadata (introspection)\n```\n\nExample:\n\n```\npython gen_mpy.py -MD lv_mpy_example.json -M lvgl -MP lv -I../../berkeley-db-1.xx/PORT/include -I../../lv_binding_micropython -I. -I../.. -Ibuild -I../../mp-readline -I ../../lv_binding_micropython/pycparser/utils/fake_libc_include ../../lv_binding_micropython/lvgl/lvgl.h\n```\n\n### Binding other C libraries\n\nThe lvgl binding script can be used to bind other C libraries to MicroPython.\nI used it with [lodepng](https://github.com/lvandeve/lodepng) and with parts of ESP-IDF.\nFor more details please read [this blog post](https://blog.lvgl.io/2019-08-05/micropython-pure-display-driver).\n\n## MicroPython Bindings Usage\n\nA simple example: [`advanced_demo.py`](https://github.com/lvgl/lv_binding_micropython/blob/master/gen/examples/advanced_demo.py).\nMore examples can be found under `/examples` folder.\n\n#### Importing and Initializing LVGL\n```python\nimport lvgl as lv\nlv.init()\n```\n#### Registering Display and Input drivers\n```python\nfrom lv_utils import event_loop\n\nWIDTH = 480\nHEIGHT = 320\n\nevent_loop = event_loop()\ndisp_drv = lv.sdl_window_create(WIDTH, HEIGHT)\nmouse = lv.sdl_mouse_create()\nkeyboard = lv.sdl_keyboard_create()\nkeyboard.set_group(self.group)\n```\nIn this example, LVGL native SDL display and input drivers are registered on a unix port of MicroPython.\n\nHere is an alternative example for ESP32 ILI9341 + XPT2046 drivers:\n\n```python\nimport lvgl as lv\n\n# Import ILI9341 driver and initialized it\n\nfrom ili9XXX import ili9341\ndisp = ili9341()\n\n# Import XPT2046 driver and initialize it\n\nfrom xpt2046 import xpt2046\ntouch = xpt2046()\n```\n\nBy default, both ILI9341 and XPT2046 are initialized on the same SPI bus with the following parameters:\n\n- ILI9341: `miso=5, mosi=18, clk=19, cs=13, dc=12, rst=4, power=14, backlight=15, spihost=esp.HSPI_HOST, mhz=40, factor=4, hybrid=True`\n- XPT2046: `cs=25, spihost=esp.HSPI_HOST, mhz=5, max_cmds=16, cal_x0 = 3783, cal_y0 = 3948, cal_x1 = 242, cal_y1 = 423, transpose = True, samples = 3`\n\nYou can change any of these parameters on ili9341/xpt2046 constructor.\nYou can also initialize them on different SPI buses if you want, by providing miso/mosi/clk parameters. Set them to -1 to use existing (initialized) spihost bus.\n\nHere's another example, this time importing and initialising display and touch drivers for the M5Stack Core2 device, which uses an FT6336 chip on the I2C bus to read from its capacitive touch screen and uses an ili9342 display controller, which has some inverted signals compared to the ili9341:\n\n```python\nfrom ili9XXX import ili9341\ndisp = ili9341(mosi=23, miso=38, clk=18, dc=15, cs=5, invert=True, rot=0x10)\n\nfrom ft6x36 import ft6x36\ntouch = ft6x36(sda=21, scl=22, width=320, height=280)\n```\n\n## Driver `init` parameters\n\nMany different display modules can be supported by providing the driver's init method with `width`,\n`height`, `start_x`, `start_y`, `colormode`, `invert` and `rot` parameters.\n\n### Display size\n\nThe `width` and `height` parameters should be set to the width and height of the display in the\norientation the display will be used. Displays may have an internal framebuffer that is larger than\nthe visible display. The `start_x` and `start_y` parameters are used to indicate where visible\npixels begin relative to the start of the internal framebuffer.\n\n### Color handling\n\nThe `colormode` and `invert` parameters control how the display processes color.\n\n### Display orientation\n\nThe `rot` parameter is used to set the MADCTL register of the display. The MADCTL register controls\nthe order that pixels are written to the framebuffer. This sets the Orientation or Rotation of the\ndisplay.\n\nSee the [README.md](examples/madctl/README.md) file in the [examples/madctl](examples/madctl/)\ndirectory for more information on the MADCTL register and how to determine the `colormode` and `rot`\nparameters for a display.\n\n### st7789 driver class\n\nBy default, the st7789 driver is initialized with the following parameters that are compatible with the TTGO T-Display:\n\n```\n    st7789(\n        miso=-1, mosi=19, clk=18, cs=5, dc=16, rst=23, power=-1, backlight=4,\n        backlight_on=1, power_on=0, spihost=esp.HSPI_HOST, mhz=40, factor=4, hybrid=True,\n        width=320, height=240, start_x=0, start_y=0, colormode=COLOR_MODE_BGR, rot=PORTRAIT,\n        invert=True, double_buffer=True, half_duplex=True, asynchronous=False, initialize=True)\n\n```\n\n  Parameter | Description\n  --------- | -----------\n  miso | Pin for SPI Data from display, -1 if not used as many st7789 displays do not have this pin\n  mosi | Pin for SPI Data to display (REQUIRED)\n  clk | Pin for SPI Clock (REQUIRED)\n  cs | Pin for display CS\n  dc | Pin for display DC (REQUIRED)\n  rst | Pin for display RESET\n  power | Pin for display Power ON, -1 if not used\n  power_on | Pin value for Power ON\n  backlight | Pin for display backlight control\n  backlight_on | Pin value for backlight on\n  spihost | ESP SPI Port\n  mhz | SPI baud rate in mhz\n  factor | Decrease frame buffer by factor\n  hybrid | Boolean, True to use C refresh routine, False for pure Python driver\n  width | Display width\n  height | Display height\n  colormode | Display colormode\n  rot | Display orientation, PORTRAIT, LANDSCAPE, INVERSE_PORTRAIT, INVERSE_LANDSCAPE or Raw MADCTL value that will be OR'ed with colormode\n  invert | Display invert colors setting\n  double_buffer | Boolean, True to use double buffering, False to use single buffer (saves memory)\n  half_duplex | Boolean, True to use half duplex SPI communications\n  asynchronous | Boolean, True to use asynchronous routines\n  initialize | Boolean, True to initialize display\n\n#### TTGO T-Display st7789 Configuration example\n\n```\nimport lvgl as lv\nfrom ili9XXX import st7789\n\ndisp = st7789(width=135, height=240, rot=st7789.LANDSCAPE)\n```\n\n#### TTGO TWatch-2020 st7789 Configuration example\n\n```\nimport lvgl as lv\nfrom ili9XXX import st7789\n\nimport axp202c\n\n# init power manager, set backlight\naxp = axp202c.PMU()\naxp.enablePower(axp202c.AXP202_LDO2)\naxp.setLDO2Voltage(2800)\n\n# init display\ndisp = st7789(\n    mosi=19, clk=18, cs=5, dc=27, rst=-1, backlight=12, power=-1,\n    width=240, height=240, rot=st7789.INVERSE_PORTRAIT, factor=4)\n```\n### st7735 driver class\n\nBy default, the st7735 driver is initialized with the following parameters. The parameter descriptions are\nthe same as the st7789.\n\n```\n    st7735(\n        miso=-1, mosi=19, clk=18, cs=13, dc=12, rst=4, power=-1, backlight=15, backlight_on=1, power_on=0,\n        spihost=esp.HSPI_HOST, mhz=40, factor=4, hybrid=True, width=128, height=160, start_x=0, start_y=0,\n        colormode=COLOR_MODE_RGB, rot=PORTRAIT, invert=False, double_buffer=True, half_duplex=True,\n        asynchronous=False, initialize=True):\n```\n\n### ST7735 128x128 Configuration Example\n\n```\nfrom ili9XXX import st7735, MADCTL_MX, MADCTL_MY\n\ndisp = st7735(\n    mhz=3, mosi=18, clk=19, cs=13, dc=12, rst=4, power=-1, backlight=15, backlight_on=1,\n    width=128, height=128, start_x=2, start_y=1, rot=PORTRAIT)\n\n```\n\n### ST7735 128x160 Configuration Example\n\n```\nfrom ili9XXX import st7735, COLOR_MODE_RGB, MADCTL_MX, MADCTL_MY\n\ndisp = st7735(\n    mhz=3, mosi=18, clk=19, cs=13, dc=12, rst=4, backlight=15, backlight_on=1,\n    width=128, height=160, rot=PORTRAIT)\n```\n\n### Creating a screen with a button and a label\n```python\nscr = lv.obj()\nbtn = lv.button(scr)\nbtn.align(lv.scr_act(), lv.ALIGN.CENTER, 0, 0)\nlabel = lv.label(btn)\nlabel.set_text(\"Button\")\n\n# Load the screen\n\nlv.scr_load(scr)\n\n```\n\n#### Creating an instance of a struct\n```python\nsymbolstyle = lv.style_t(lv.style_plain)\n```\nsymbolstyle would be an instance of `lv_style_t` initialized to the same value of `lv_style_plain`\n\n#### Setting a field in a struct\n```python\nsymbolstyle.text.color = lv.color_hex(0xffffff)\n```\nsymbolstyle.text.color would be initialized to the color struct returned by `lv_color_hex`\n\n#### Setting a nested struct using dict\n```python\nsymbolstyle.text.color = {\"red\":0xff, \"green\":0xff, \"blue\":0xff}\n```\n\n#### Creating an instance of an object\n```python\nself.tabview = lv.tabview(lv.scr_act())\n```\nThe first argument to an object constructor is the parent object, the second is which element to copy this element from.\nBoth arguments are optional.\n\n#### Calling an object method\n```python\nself.symbol.align(self, lv.ALIGN.CENTER,0,0)\n```\nIn this example `lv.ALIGN` is an enum and `lv.ALIGN.CENTER` is an enum member (an integer value).\n\n#### Using callbacks\n```python\nfor btn, name in [(self.btn1, 'Play'), (self.btn2, 'Pause')]:\n    btn.set_event_cb(lambda obj=None, event=-1, name=name: self.label.set_text('%s %s' % (name, get_member_name(lv.EVENT, event))))\n```\n\nUsing callback with `user_data` argument:\n\n```python\ndef cb(user_data):\n    print(user_data.cast()['value'])\n\nlv.async_call(cb, {'value':42})\n```\n\n#### Listing available functions/members/constants etc.\n```python\nprint('\\n'.join(dir(lvgl)))\nprint('\\n'.join(dir(lvgl.btn)))\n...\n```\n\n","funding_links":[],"categories":["Libraries"],"sub_categories":["Display"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flvgl%2Flv_binding_micropython","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flvgl%2Flv_binding_micropython","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flvgl%2Flv_binding_micropython/lists"}