0

In the end, the labels.text should display sensor data. The data is generated within a separate process and is transferred to kivy via a pipe. Currently I am trying to implement a very simple minimal example. However, I do not get my head around the update concept for dynamically generated labels:

from math import sin

"""
Activate the touch keyboard. It is important that this part is on top
because the global config should be initiated first.
"""
from kivy.config import Config
Config.set('kivy', 'keyboard_mode', 'multi')

from kivy.app import App

from kivy.clock import Clock
# The Builder is used to define the main interface.
from kivy.lang import Builder

from kivy.properties import StringProperty, ObjectProperty, NumericProperty
from kivy.uix.label import Label
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.stacklayout import StackLayout


import numpy as np

class MainScreen(Screen):
    pass


class DataScreen(Screen):

    def __init__(self, **kwargs):
        layout = StackLayout()
        super(DataScreen, self).__init__(**kwargs)
        self.n_probes = 8
        self.label_text = []
        for i in range(self.n_probes):
            self.label_text.append(StringProperty())
            self.label_text[i] = str(i)

        for i in range(self.n_probes):
            l = Label(id='l_{}'.format(i),
                      name='l_{}'.format(i),
                      text=self.label_text[i],
                      font_size='60sp',
                      height=20,
                      width=20,
                      size_hint=(0.5, 0.2))
            self.ids.stack.add_widget(l)

    def change_text(self):
        for i in range(self.n_probes):
            self.label_text[i] = str(2)



Builder.load_file('phapp.kv')

class MyApp(App):
    """
    The settings App is the main app of the pHBot application.
    It is initiated by kivy and contains the functions defining the main interface.
    """


    def build(self):
        """
        This function initializes the app interface and has to be called "build(self)".
        It returns the user interface defined by the Builder.
        """

        sm = ScreenManager()
        sm.add_widget(MainScreen())
        sm.add_widget(DataScreen())
        # returns the user interface defined by the Builder
        return sm


if __name__ == '__main__':
    MyApp().run()

The .kv file:

<MainScreen>:
    name: 'main'
    BoxLayout:
        orientation: 'vertical'
        Button:
            text: 'Go to data'
            font_size: 40
            on_release: app.root.current = 'data'
        Button:
            text: 'Exit'
            font_size: 40
            on_release: app.stop()

<DataScreen>:
    name: 'data'
    StackLayout:
        id: stack
        orientation: 'lr-tb'
    BoxLayout:
        Button:
            size_hint: (0.5, 0.1)
            text: 'Update'
            font_size: 30
            on_release: root.change_text()
        Button:
            size_hint: (0.5, 0.1)
            text: 'Back to main menu'
            font_size: 30
            on_release: app.root.current = 'main'

The labels are not updating with this version. Any ideas why ?

Moritz
  • 5,130
  • 10
  • 40
  • 81

1 Answers1

0

This version is working. I still do not now why the first one did not work out. Maybe it has to to something with the scope ? If I code everthing statically in the .kv file and the .py file (e.g. like in this SO post) everything works fine.

from math import sin

"""
Activate the touch keyboard. It is important that this part is on top
because the global config should be initiated first.
"""
from kivy.config import Config
Config.set('kivy', 'keyboard_mode', 'multi')

from kivy.app import App

from kivy.clock import Clock
# The Builder is used to define the main interface.
from kivy.lang import Builder

from kivy.properties import StringProperty, ObjectProperty, NumericProperty
from kivy.uix.label import Label
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.stacklayout import StackLayout


import numpy as np

class MainScreen(Screen):
    pass


class DataScreen(Screen):

    def __init__(self, **kwargs):
        layout = StackLayout()
        super(DataScreen, self).__init__(**kwargs)
        self.n_probes = 8
        self.label_text = []
        for i in range(self.n_probes):
            self.label_text.append(StringProperty())
            self.label_text[i] = str(i)
        self.l = []
        for i in range(self.n_probes):
            self.l.append(Label(id='l_{}'.format(i),
                          text='Start {}'.format(i),
                          font_size='60sp',
                          height=20,
                          width=20,
                          size_hint=(0.5, 0.2)))
            self.ids.stack.add_widget(self.l[i])

    def change_text(self):
        for i in range(self.n_probes):
            self.l[i].text = 'Update' + str(2)


Builder.load_file('phapp.kv')

class MyApp(App):
    """
    The settings App is the main app of the pHBot application.
    It is initiated by kivy and contains the functions defining the main interface.
    """


    def build(self):
        """
        This function initializes the app interface and has to be called "build(self)".
        It returns the user interface defined by the Builder.
        """

        sm = ScreenManager()
        sm.add_widget(MainScreen())
        sm.add_widget(DataScreen())
        # returns the user interface defined by the Builder
        return sm


if __name__ == '__main__':
    MyApp().run()


<MainScreen>:
    name: 'main'
    BoxLayout:
        orientation: 'vertical'
        Button:
            text: 'Go to data'
            font_size: 40
            on_release: app.root.current = 'data'
        Button:
            text: 'Exit'
            font_size: 40
            on_release: app.stop()

<DataScreen>:
    name: 'data'
    StackLayout:
        id: stack
        orientation: 'lr-tb'
    BoxLayout:
        Button:
            size_hint: (0.5, 0.1)
            text: 'Update'
            font_size: 30
            on_release: root.change_text()
        Button:
            size_hint: (0.5, 0.1)
            text: 'Back to main menu'
            font_size: 30
            on_release: app.root.current = 'main'
Community
  • 1
  • 1
Moritz
  • 5,130
  • 10
  • 40
  • 81