Kivy:添加屏幕后,我的标签文本未更新

时间:2019-04-05 07:52:37

标签: python arduino kivy

因此,我想从Arduinoserial port读取数据,并将读取的数据更新为标签文本以显示。当我只有简单的代码可以读取和更新时,它可以工作,但是当我添加ScreenManagerScreen时,它将停止更新文本。

最终我将需要根据接收到的数据制作不同的动画,这更多地是在测试此功能是否有效

预先感谢!

这是我的完整代码

import os
os.environ['KIVY_GL_BACKEND'] ='gl'

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.widget import Widget
from kivy.properties import (NumericProperty, StringProperty, ReferenceListProperty, ObjectProperty, ListProperty)
from kivy.clock import Clock
from kivy.vector import Vector
from kivy.core.text import LabelBase
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition


LabelBase.register(name='Sans',fn_regular="Sansation-Regular.ttf")

import serial

kivy = Builder.load_string("""
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
<MyManager>:
    transition: FadeTransition()
    MainScreen:
    OperationScreen:

<MainScreen>:
    name: 'main'
    Label:
        text: 'Welcome'
        font_size: 40
        on_touch_up : app.root.current = 'operation'

    Label:
        text: 'dafault'
        font_size: 20
        pos: -200,-100
        id: data_label


<OperationScreen>:
    name: 'operation'
    Label:
        text: 'Youre in'
        font_size: 40
""")   

class OperationScreen(Screen):
    pass

class MainScreen(Screen):
    def __init__(self,**kwargs):
        super(MainScreen,self).__init__(**kwargs)

    def Read(self,dt):
        Clock.unschedule(self.Read)
        data = arduino.readline()
        if data != '':
            self.ids.data_label.text = data
        Clock.schedule_once(self.Read)
    pass

class MyManager(ScreenManager):
    pass

class mainApp(App):
    Main = MainScreen()
    def build(self):
        Clock.schedule_once(self.Main.Read)
        return MyManager()

if __name__ == '__main__':
    try:
        arduino = serial.Serial('/dev/ttyACM0', 9600, timeout=1)
    except:
        print("failed to connect")
    mainApp().run()

我希望带有“默认”文本的标签会相应地更改,但只是被“默认”冻结了

1 个答案:

答案 0 :(得分:1)

问题

您的应用运行时,有两个class MainScreen的实例。一个已在kv文件中实例化。另一个是手动实例化的,位于Main = MainScreen()中的class mainApp

方法Read()的调度是在手动创建的实例Main = MainScreen()中创建的,没有与此相关的模态视图。

解决方案

  • 在kv文件中,为id: main_screen添加MainScreen:
  • 删除Main = MainScreen()中的class mainApp
  • class MyManager()实现构造函数
  • 将调度从class mainApp移到class MyManager()的构造函数中
  • 对于您而言,最好使用Clock.create_trigger()而不是Clock.schedule_once()
  • 取消Clock事件的正确方法是event.cancel()Clock.unschedule(event)

示例

main.py

import os

os.environ['KIVY_GL_BACKEND'] = 'gl'

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.widget import Widget
from kivy.properties import (NumericProperty, StringProperty, ReferenceListProperty, ObjectProperty, ListProperty)
from kivy.clock import Clock
from kivy.vector import Vector
from kivy.core.text import LabelBase
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition

# LabelBase.register(name='Sans', fn_regular="Sansation-Regular.ttf")

import serial

kivy = Builder.load_string("""
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
<MyManager>:
    transition: FadeTransition()
    MainScreen:
        id: main_screen
    OperationScreen:

<MainScreen>:
    name: 'main'
    Label:
        text: 'Welcome'
        font_size: 40
        on_touch_up : app.root.current = 'operation'

    Label:
        text: 'dafault'
        font_size: 20
        pos: -200,-100
        id: data_label


<OperationScreen>:
    name: 'operation'
    Label:
        text: 'Youre in'
        font_size: 40
""")


class OperationScreen(Screen):
    pass


class MainScreen(Screen):

    def Read(self, dt):
        data = str(dt)
        # data = arduino.readline()
        if data != '':
            self.ids.data_label.text = data
            self.manager.event_trigger()
        else:
            self.manager.event_trigger.cancel()


class MyManager(ScreenManager):
    event_trigger = ObjectProperty(None)

    def __init__(self, **kwargs):
        super(MyManager, self).__init__(**kwargs)
        self.event_trigger = Clock.create_trigger(self.ids.main_screen.Read)
        self.event_trigger()


class mainApp(App):

    def build(self):
        return MyManager()


if __name__ == '__main__':
    # try:
    #     arduino = serial.Serial('/dev/ttyACM0', 9600, timeout=1)
    # except:
    #     print("failed to connect")
    mainApp().run()

输出

Result

相关问题