saul
August 18, 2021, 8:29pm
1
Not sure what I’m doing wrong but it seems like some objects like ldrop down list or roller do not return a string with the get_selected_str method?
I don’t get the expected behavior when either doing a string compare or typecasting to an int.
test code:
import lvgl as lv
from ili9XXX import ili9341
from xpt2046 import xpt2046
# Initialize drivers
lv.init()
ili9341()
xpt2046()
# Simple Roller
def event_handler(obj, event):
if event == lv.EVENT.VALUE_CHANGED:
option = " "*20
obj.get_selected_str(option, len(option))
option_string = option.rstrip()
print(type(option_string))
option_string = str(option_string)
#option_string = ''.join([chr(b) for b in option_string])
option_int = int(option_string)
print("Selected number: |%s|" % option_string)
if option_string == "22":
print("found string: %s" % option_string)
roller1 = lv.roller(lv.scr_act())
roller1.set_options("\n".join([
"1",
"22",
"333",
"4444",
"55555",
"666666",
"7777777",
"88888888",
"999999999",
]), lv.roller.MODE.INIFINITE)
roller1.set_visible_row_count(4)
roller1.align(None, lv.ALIGN.CENTER, 0, 0)
roller1.set_event_cb(event_handler)
embeddedt note: simulator link
Error:
>>> import roller
ILI9341 initialization completed
Enable backlight
Double buffer
>>> <class 'str'>
Traceback (most recent call last):
File "roller.py", line 21, in event_handler
ValueError: invalid syntax for integer with base 10
I’m sure I’m missing something
Hi @saul !
get_selected_str
actually copies bytes, including the null-termination of the string.
If you check out option_string
you’ll find out it’s '22\x00'
and not '22'
, for example.
The correct way to handle this is to provide get_selected_str
a bytearray, decode this bytearray to string and strip the trailing null termination:
option = bytearray(20)
obj.get_selected_str(option, len(option))
option_string = option.decode("utf-8").rstrip('\0')
Link to simulator
saul
August 19, 2021, 10:41pm
3
Thank you for reply Amirgon I really appreciate it.
I updated the the event handler:
if event == lv.EVENT.VALUE_CHANGED:
option = bytearray(20)
obj.get_selected_str(option, len(option)) << Line 16
option_string = option.decode("utf-8").rstrip('\0')
#option_string = ''.join([chr(b) for b in option_string])
option_int = int(option_string)
if option_string == "22":
print("found string: %s" % option_string)
if option_int == 333:
print("found int: %d" % option_int)
This is the error I’m getting now:
>>> import roller
ILI9341 initialization completed
Enable backlight
Double buffer
>>> Traceback (most recent call last):
File "roller.py", line 16, in event_handler
TypeError: can't convert 'bytearray' object to str implicitly
If I leave option as:
if event == lv.EVENT.VALUE_CHANGED:
option = " "*20
obj.get_selected_str(option, len(option))
option_string = option.decode("utf-8").rstrip('\0') << Line 17
I get:
>>> import roller
ILI9341 initialization completed
Enable backlight
Double buffer
>>> Traceback (most recent call last):
File "roller.py", line 17, in event_handler
AttributeError: 'str' object has no attribute 'decode'
saul:
This is the error I’m getting now:
>>> import roller
ILI9341 initialization completed
Enable backlight
Double buffer
>>> Traceback (most recent call last):
File "roller.py", line 16, in event_handler
TypeError: can't convert 'bytearray' object to str implicitly
That’s strange, because it is working for me on the simulator (link )
Are you using an up-to-date version of lv_micropython?
Are you able to reproduce this on the online simulator?
saul
August 19, 2021, 11:22pm
5
I compiled from the lv_miropython repo:
The firmware I’m using was complied back in 09/23/2020 when they had lvgl 7 bindings.
I’m working on compiling from the latest git build which has lvgl 8 bindings, but I’m still working through some issues there as the build process has changed from the last time I compiled it.
Maybe its not worth working this out on such an old build I can just open a new conversation if I have the same issue with the latest build.
Latest v7 is available on GitHub on GitHub - lvgl/lv_micropython at release/v7
Of course, it you can, it’s best to use the latest v8 on master branch.
saul
August 21, 2021, 4:45pm
7
Thanks again Amirgon!!
I was able to compile the latest version version of lv_micropything which I think has the 8.1 bindings and now the following example is working:
# Simple Roller
def event_handler(e):
code = e.get_code()
obj = e.get_target()
if code == lv.EVENT.VALUE_CHANGED:
option = bytearray(20)
obj.get_selected_str(option, len(option))
option_string = option.decode("utf-8").rstrip('\0')
#option_string = ''.join([chr(b) for b in option_string])
option_int = int(option_string)
if option_string == "22":
print("found string: %s" % option_string)
if option_int == 333:
print("found int: %d" % option_int)
roller1 = lv.roller(lv.scr_act())
roller1.set_options("\n".join([
"1",
"22",
"333",
"4444",
"55555",
"666666",
"7777777",
"88888888",
"999999999"
]), lv.roller.MODE.INFINITE)
roller1.set_visible_row_count(4)
roller1.align(lv.ALIGN.CENTER, 0, 0)
roller1.add_event_cb(event_handler, lv.EVENT.ALL, None)
output:
>>> found string: 22
found int: 333
There must have been some issue with either the micropython or lvgl version I previously compiled