Budaksesat2000
Budaksesat2000

Reputation: 111

Cannot display arduino data into kivy window

Im am trying to display my arduino data into my kivy window under label but it says an error " ValueError: Label.text accept only str". Anyone able to help? Arduino serial monitor

Below is my python kivy file

test.py file

import serial
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.uix.button import Button

class MainWindow(Screen):
    def tm(self):
        while (1):
            with serial.Serial('COM4', 9600) as ser:
                x = ser.readline()
                return str(x)
                ser.close()

class WindowManager(ScreenManager):
    pass

hi = Builder.load_file("test.kv")

class MyMainApp(App):
    def build(self):
        return hi

if __name__ == "__main__":
    MyMainApp().run()

test.kv file

WindowManager:
    MainWindow:

<MainWindow>:

    Label:
        size: 75, 50
        size_hint: None, None
        pos_hint: {'right': 1, 'bottom': 1}
        background_color: (1.0, 0.0, 0.0, 1.0)
        text: root.x

Upvotes: 1

Views: 501

Answers (1)

el3ien
el3ien

Reputation: 5405

I see a few problems in your example.

  1. Be careful naming your variables. x for example, is almost always a NumericProperty of the widget already.
  2. When you reference an attribute in python, use self, or the widgets x in your case wil not change.
  3. When you have a loop in kivy, you will block the application. So you either use Clock or threading. I will suggest threading instead of Clock when using serial, because readline() will also block the app if waiting for an input.
  4. You never actually call tm()

So, heres what I would change in MainWindow class, and a few more imports.

import serial
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.uix.button import Button
from kivy.properties import StringProperty
from kivy.clock import mainthread
import threading


KV = """

WindowManager:
    MainWindow:

<MainWindow>:

    Label:
        size: 75, 50
        size_hint: None, None
        pos_hint: {'right': 1, 'bottom': 1}
        background_color: (1.0, 0.0, 0.0, 1.0)
        text: root.label_text

"""


class MainWindow(Screen):
    label_text = StringProperty("")

    def __init__(self, **kwargs):
        super(MainWindow, self).__init__(**kwargs)
        threading.Thread(target=self.tm).start()

    def tm(self):
        while (1):
            with serial.Serial('COM4', 9600) as ser:
                value = ser.readline()
                ser.close()
                self.update_label(value.decode("ascii").strip())

    @mainthread
    def update_label(self, value):
        self.label_text = value

class WindowManager(ScreenManager):
    pass


class MyMainApp(App):
    def build(self):
        return Builder.load_string(KV)

if __name__ == "__main__":
    MyMainApp().run()

Be sure to use mainthread when changing any ui element in another thread. In this case when you change a stringproperty that will change the display.

Upvotes: 2

Related Questions