Невозможно отобразить данные Arduino в окне KIVY - PullRequest
1 голос
/ 30 октября 2019

Я пытаюсь отобразить мои данные arduino в моем окне kivy под меткой, но он говорит об ошибке «ValueError: Label.text accept only str». Кто-нибудь может помочь? Arduino serial monitor

Ниже приведен мой файл python kivy

файл test.py

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

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

1 Ответ

2 голосов
/ 30 октября 2019

Я вижу несколько проблем в вашем примере.

  1. Будьте осторожны с именами переменных. Например, x почти всегда является NumericProperty виджета.
  2. Когда вы ссылаетесь на атрибут в python, используйте self, или виджеты x в вашем случае не изменятся.
  3. Если у вас есть цикл в kivy, вы заблокируете приложение. Таким образом, вы либо используете Clock или threading. Я буду предлагать threading вместо Clock при использовании последовательного порта, потому что readline() также заблокирует приложение при ожидании ввода.
  4. Вы на самом деле никогда не звоните tm()

Итак, вот что я хотел бы изменить в MainWindow классе, и еще несколько импортов.

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()

Обязательно используйте mainthread при изменении любого элемента пользовательского интерфейса в другом потоке. В этом случае при изменении свойства строки будет меняться отображение.

...