Issue
The Problem: I want to display a table with data on the raspberry, that gets updated after clicking on a button. I use the MDDatatable form kivymd for the table. The app is not lagging on my Windows-PC. When I run it on the Raspberry Pi 3+ moving the cursor causes the app to lag. When I click on the button it takes a few seconds to update the table.
The Windows System is running on Windows 10 Pro. The CPU is a Intel(R) Core(TM) i7-7700. It has 3.60 GHz. The GPU is a Intel(R) HD Graphics 630 and has 7.9 GB GPU memory.
Im using python 3.7.3 and the Buster OS on the Raspberry. The processor is a "Broadcom BCM2837B0 4-Core-Processor ARM Cortex-A53". On a raspberry you can designate how much of this processor should be used as GPU or CPU. Currently I have designated 64 MB as GPU. It has a clock frequency of 1.2 GHz and 1 GB Ram.
What I need help with: Does someone know another module I should try? Can I optimize the code to make it run faster? I think that multi threading wouldn't help, since there isn't any code that could run in parallel. Is that correct?
Python File
from kivymd.app import MDApp
from kivy.uix.widget import Widget
from kivymd.uix.datatables import MDDataTable
from kivy.metrics import dp
from kivy.lang import Builder
from memory_profiler import profile
#Designate .kv design file
Builder.load_file('mdapp.kv')
class MyLayout(Widget):
pass
class GUI(MDApp):
def build(self):
return MyLayout()
@profile
def on_start(self):
#create Datatable
self.data_tables = MDDataTable(
pos_hint={'center_x': 10,'center_y': 2.7},
size_hint=(None, None),
size = (460, 460),
use_pagination=True,
column_data=[("No.", dp(10)),
("UID", dp(30)),
("Reichweite in cm", dp(30))],
row_data=[
("1", "x100", "30")])
mylayout = self.root.ids.mylayout
mylayout.add_widget(self.data_tables)
pass
def add_data(self):
self.data_tables.add_row(("1","2","3"))
pass
@profile
def Start(self):
#Logikschicht.drive50cm()
self.add_data()
pass
if __name__ == '__main__':
GUI().run()
kv file
<MyLayout>:
FloatLayout:
id: mylayout
Button:
text: 'Start'
on_press: app.Start()
pos: 1050, 650
size_hint: None, None
size: 200, 80
FloatLayout:
size_hint: None, None
size: 800,800
id: container
What I have tried so far: This thread (Kivy ui is very slow on a RPI) suggests trying a simple app with only one button. This app runs lag free. I tried increasing the GPU Memory from 64 MB to 256 MB which also didn't help. Increasing the GPU Memory to 512 MB seems to help a little bit, but the app is still laggy.
I have added the profiler modul to see the Memory usage. Im not quite sure if 220 MB memory usage is an unnormal amount of memory usage. The output on the Windows System is:
Line # Mem usage Increment Occurrences Line Contents
=============================================================
19 153.5 MiB 153.5 MiB 1 @profile
20 def on_start(self):
21 #create Datatable
22 153.5 MiB 0.0 MiB 1 self.data_tables = MDDataTable(
23 153.5 MiB 0.0 MiB 1 pos_hint={'center_x': 10,'center_y': 2.7},
24 153.5 MiB 0.0 MiB 1 size_hint=(None, None),
25 153.5 MiB 0.0 MiB 1 size = (460, 460),
26 153.5 MiB 0.0 MiB 1 use_pagination=True,
27 153.5 MiB 0.0 MiB 1 column_data=[("No.", dp(10)),
28 153.5 MiB 0.0 MiB 1 ("UID", dp(30)),
29 153.5 MiB 0.0 MiB 1 ("Reichweite in cm", dp(30))],
30 row_data=[
31 156.2 MiB 2.7 MiB 1 ("1", "x100", "30")])
32 156.2 MiB 0.0 MiB 1 mylayout = self.root.ids.mylayout
33 156.2 MiB 0.0 MiB 1 mylayout.add_widget(self.data_tables)
34 156.2 MiB 0.0 MiB 1 pass
Filename: i:\sebastian\bachelorarbeit\code\gui\datatableminimalexample\gui_kivymd.py
Line # Mem usage Increment Occurrences Line Contents
=============================================================
40 216.2 MiB 216.2 MiB 1 @profile
41 def Start(self):
42 #Logikschicht.drive50cm()
43 216.2 MiB 0.0 MiB 1 self.add_data()
44 216.2 MiB 0.0 MiB 1 pass
Solution
Update: I haven't found any other module for creating tabels. I however found, that normaly people use Labels to create tabels.
I created a seperate file I can import that handels the content of the label to create the table:
class SimpleTabel:
def __init__(self,header):
#create header row
self.header = header
self.header_row = ""
self.header_row_length = []
self.row_nr = 0
for head in header:
self.header_row = self.header_row + head + " "
self.header_row_length.append(len(head))
self.header_row = self.header_row[:-2]
#create tabel
self.content = f"{self.header_row}\n"
#add break line
for i in range(1,len(self.content)):
self.content = self.content + "_"
self.content = self.content +"\n"
pass
def add_row(self, data_row):
# add data row
self.row_nr += 1
data_row.insert(0, str(self.row_nr))
for data,head_len in zip(data_row,self.header_row_length):
if len(data) <= head_len:
self.content = self.content + data + " "
for i in range (0, head_len- len(data)):
self.content = self.content + " "
else:
print("Data is too long")
self.content = self.content + "\n"
print(self.content)
pass
def remove_row(self, row_nr):
row_nr += 1
row_counter = 0
index1 = 0
index2 = 0
index = 0
for char, index in zip(self.content, range(len(self.content))):
if char == "\n":
row_counter += 1
pass
if row_counter == row_nr:
if index1 == 0:
index1 = index
pass
pass
if row_counter > row_nr:
if index2 == 0:
index2 = index
pass
pass
pass
self.content = self.content[:index1] + self.content[index2:]
print("index1 " + str(index1))
print("index2 " + str(index2))
print(self.content)
pass
Answered By - Sebastian Hösing Answer Checked By - Marie Seifert (WPSolving Admin)