If you want to organize a lot of text on your screen, then usually you need lots of processing power, but there is another way. LVGL has a widget called the table.
The table organizes text into rows and columns. It generates and styles the text on the fly, so its fast and memory efficient. The side affect of doing it this way is that it can be hard to style individual cells. Highlighting a single piece of text or changing its size takes a lot of code.
Today I will show you how to create and modify a table. Below is some example code on tables and an explanation on how that code works.
To get this example to work you will need to add your screen code to the beginning of the code below. If you want more information, you can try How to get a LVGL Micropython screen to work.
Here is the example
import lvgl
table = lvgl.table(lvgl.scr_act())
table.set_col_width(0,185)
table.set_height(240)
table.set_row_cnt(10)
table.set_col_cnt(2)
style = lvgl.style_t()
style.init()
style.set_border_side(lvgl.BORDER_SIDE.LEFT | lvgl.BORDER_SIDE.RIGHT | lvgl.BORDER_SIDE.TOP | lvgl.BORDER_SIDE.BOTTOM)
style.set_border_color(lvgl.color_hex(0x004422))
table.add_style(style,lvgl.STATE.DEFAULT | lvgl.PART.ITEMS)
table.set_cell_value(0,0,'Equation')
table.set_cell_value(0,1,'Sum')
table.set_cell_value(1,0,'0')
table.add_cell_ctrl(1,0,lvgl.table.CELL_CTRL.MERGE_RIGHT)
for x in range(8):
table.set_cell_value(x+2,0,str(x+1)+'+'+str(x+1))
table.set_cell_value(x+2,1,str(x+x+2))
def clicked(data):
col = lvgl.C_Pointer()
row = lvgl.C_Pointer()
tar = data.get_target()
tar.get_selected_cell(row,col)
col = col.uint_val
row = row.uint_val
print(row,col)
table.add_event_cb(clicked,lvgl.EVENT.VALUE_CHANGED,None)
How Does This Code Work?
Since you’ve seen the program above, why don’t we walk through the code and see how it works. This should make it clearer how you can modify this code for your own uses…
The Setup
To be able to use LVGL, we need to import it.
import lvgl
Creating the Table
The first thing we need to do is create an empty table object.
table = lvgl.table(lvgl.scr_act())
To make the table look more interesting, we are going to make the first column bigger than the second.
The first column has the id of 0, and we will set its width to 185 pixels which is a little bigger than a normal column.
table.set_col_width(0,185)
By setting the height of the table, we can force it to stay the same size, normally it would grow to the size of the data you give it.
If not all the data fits into the restricted table size, then the table will become scroll able so you can reach the rest of the data.
table.set_height(240)
We are going to tell the table how many rows and columns we will eventually create. This is not required, but it will speed up the process latter.
table.set_row_cnt(10)
table.set_col_cnt(2)
Styling the Borders
We want the table to have lines separating the rows and columns, so we need to create a new style.
style = lvgl.style_t()
Styles need to be initialized before use, so we do that as well.
style.init()
The way we are going to create the lines is with borders. To make that work, we first have to enable boarders on all sides.
style.set_border_side(lvgl.BORDER_SIDE.LEFT | lvgl.BORDER_SIDE.RIGHT | lvgl.BORDER_SIDE.TOP | lvgl.BORDER_SIDE.BOTTOM)
We are also going to set the boarder color to a greenish-black.
style.set_border_color(lvgl.color_hex(0x004422))
Now that we have created the style we need to add it to the table.
To make the border appear around the individual cells instead of one boarder around the entire table, we need to target the cells.
We do that by applying the style to lvgl.PART.ITEMS (aka. the cells).
table.add_style(style,lvgl.STATE.DEFAULT | lvgl.PART.ITEMS)
Adding the First Data
To demonstrate how tables work we need some data. For this example, the data we are using is a list of equations and their answers.
The equations will follow the form 0+0, 1+1, 2+2, 3+3, etc. and the answers will simply be numbers like 0, 2, 4, 6, etc.
At the top of the page we also want two boxes one that says ‘Equation‘ and another that says ‘Sum‘.
We will start by creating the ‘Equation’ label, it’s position is the first cell on the table which has the address 0,0.
table.set_cell_value(0,0,'Equation')
Then we will add the ‘Sum’ label to the address 0,1.
table.set_cell_value(0,1,'Sum')
Merging Cells
The first equation would be 0+0 = 0 which is a bit boring, so to make things interesting we will combine the Equation and Sum cells together into one big cell that has the text 0.
To begin we set the first cell to the value of 0.
table.set_cell_value(1,0,'0')
Then we will merge the first cell and the cell to the right of it to create the new over sized cell.
table.add_cell_ctrl(1,0,lvgl.table.CELL_CTRL.MERGE_RIGHT)
The Rest of the Cells
Instead of manually adding each cell, we will use a For Loop that creates the equations and the answers.
first we create a loop that runs 8 times.
for x in range(8):
Then we will generate and add the text to the Equation cell.
table.set_cell_value(x+2,0,str(x+1)+'+'+str(x+1))
After that we calculate the answer, and put the result in the Sum cell.
table.set_cell_value(x+2,1,str(x+x+2))
Getting the Clicked Cell
Being able to figure out if a cell is clicked is extremely useful , but takes a little bit of work.
First we need to create is a function to process if any cells are clicked.
def clicked(data):
In that function, we need to create two pointers one for that column and one for the row.
col = lvgl.C_Pointer()
row = lvgl.C_Pointer()
Then we will retrieve the table that called this function. Because we have only one table, this is pointless, but if you create additional tables then this will keep the program working.
tar = data.get_target()
Then we load the row and column of the clicked cell.
tar.get_selected_cell(row,col)
The row and column variables now contain the address of the clicked cell, but they are still pointers, which aren’t easy to use, so we will reset the pointers to be normal integers.
col = col.uint_val
row = row.uint_val
Finally the program knows the exact cell that was clicked. For now we will simply print that data to the terminal but you could do whatever you wanted with it.
print(row,col)
Connecting the Table
To make the function we just created work we need it to be called whenever the table is clicked, which we do like this.
table.add_event_cb(clicked,lvgl.EVENT.VALUE_CHANGED,None)
What Next?
That you have seen how the code works, try running it. You should see a table that has 2 columns and 10 rows. About six of the rows will be visible, the rest you will have to scroll down to see. If you tap on any of the cells, the board will print to your terminal the coordinates of the cell that you clicked.
Tables can be used for a lot of different projects. Because of how light weight they are, you can use them to simply optimize a program you have already made or you could experiment even further and give them more complex styles to make a spread sheet or something else.
Tables are useful in displaying lots of text, but if you have a lot of numbers then micropython LVGL charts may be a better tool.