Kivy.Обновление экрана с разными данными - PullRequest
0 голосов
/ 25 апреля 2019

Когда я нажимаю на кнопку, мне нужно, чтобы данные из кода отображались на другом экране.Ниже код делает то, что мне нужно, несмотря на то, что Clock добавляет виджеты каждую секунду.Я бы хотел, чтобы TextInput был редактируемым, поэтому, когда я набираю какое-то значение в строке, оно останется напечатанным.Я пытался использовать Clock.schedule_once(), но тогда виджеты не появляются.Я даже пробовал что-то вроде ниже:

clock = 1
def fill_with_data(self, dt)
    if clock == 1: 
    for item ...
    clock +=1

ведьма блокирует добавление новых виджетов (я знаю, что это насмешки), но когда я возвращаюсь к MainScreen, чтобы показать другие данные, они не появляются на экране.Ниже вы найдете весь код.

from kivy.config import Config
Config.set('graphics', 'multisamples', '0')
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import Screen
from kivy.clock import Clock


kv = """
#:import FadeTransition kivy.uix.screenmanager.FadeTransition

ScreenManager:
    MainScreen:
    ShowData:    

<DataSwitch>

    Button:
        text: 'Data 1'
        on_press: app.root.current = 'ShowData'
        on_press: root.show_data1()
    Button:
        text: 'Data 2'
        on_press: app.root.current = 'ShowData'
        on_press: root.show_data2()

<Row>
    TextInput:
        id: text_input
        size_hint_y: None
        height: 30

<Rows>        
    orientation: 'vertical'

<MainScreen>   
    name: 'MainScreen'
    DataSwitch:

<ShowData>:
    name: 'ShowData'
    Rows:
    Button:
        text: 'Go back'
        size_hint_y: None
        height: 20
        on_press: app.root.current = 'MainScreen'

"""

class Row(BoxLayout):
    text = ''
    def __init__(self, **kwargs):
        super(Row, self).__init__(**kwargs)
        self.set_text()

    def set_text(self):
        print('set', self.text)
        self.ids.text_input.text = self.text

class Rows(BoxLayout):

    data =[]

    def __init__(self, **kwargs):
        super(Rows, self).__init__(**kwargs)
        #self.fill_with_data()
        Clock.schedule_interval(self.fill_with_data, 1)
        #Clock.schedule_once(self.fill_with_data)
    def fill_with_data(self, dt):
        for item in self.data:
            Row.text = item
            row = Row()
            self.add_widget(row)
            #self._rows[str(self.row_id)] = weakref.ref(row)

class MainScreen(Screen):
    pass

class DataSwitch(BoxLayout):

    data1 = ['1', '2', '3', '4']
    data2 = ['5', '6', '7', '8']

    def __init__(self, **kwargs):
        super(DataSwitch, self).__init__(**kwargs)

    def show_data1(self):
        print('data1', self.data1)
        Rows.data = self.data1
        Rows()

    def show_data2(self):
        Rows.data = self.data2
        Rows()

class ShowData(Screen):
    pass

sm = Builder.load_string(kv)

class TestApp(App):
    def build(self):
        return sm

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

1 Ответ

2 голосов
/ 25 апреля 2019

Запуск приложения приведет к следующему:

Проблема 1 - создание слишком большого количества строк

  • Rows: согласно файлу kv
  • Rows() какна каждый скрипт Python в методах show_data1() и show_data2().Эти Rows созданные экземпляры не имеют связанных ModalView.

Проблема 2 - переключаемый экран перед заполнением списка, данные

Button:
    text: 'Data 1'
    on_press: app.root.current = 'ShowData'
    on_press: root.show_data1()
Button:
    text: 'Data 2'
    on_press: app.root.current = 'ShowData'
    on_press: root.show_data2()

Решение

Следующий пример является просто иллюстрацией.

kv файл - Добавить id: rows

Добавить id: rows к Rows: в правило класса , <ShowData>:.Это будет использоваться для ссылки на атрибуты или методы в class Rows().

kv файле - вызовите fill_with_data()

Используйте on_pre_enter событие Screen и Clock.schedule_once() для вызова методаfill_with_data()

Примечание : Row будет добавляться каждый раз, когда отображается экран.Другими словами, Row виджет будет удваиваться каждый раз.Чтобы предотвратить это, можно удалить виджеты, добавленные в on_pre_leave событие .

Фрагменты - файл kv

<ShowData>:
    name: 'ShowData'
    on_pre_enter:
        Clock.schedule_once(self.ids.rows.fill_with_data, 0.1)
    Rows:
        id: rows

py файл - Доступ к атрибутам / методам в class Rows()

  • Получить объект, app, используя App.get_running_app()
  • Получить объект, ShowData, используя функцию get_screen() Screen Manager, например, root.get_screen('ShowData')
  • Доступатрибут data с использованием ids.rows.data

Фрагменты

def show_data1(self):
    App.get_running_app().root.get_screen('ShowData').ids.rows.data = self.data1

def show_data2(self):
    App.get_running_app().root.get_screen('ShowData').ids.rows.data = self.data2

Пример

main.py

from kivy.config import Config

Config.set('graphics', 'multisamples', '0')
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import Screen

kv = """
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
#:import Clock kivy.clock.Clock

ScreenManager:
    MainScreen:
    ShowData:    

<DataSwitch>

    Button:
        text: 'Data 1'
        on_press: root.show_data1()
        on_press: app.root.current = 'ShowData'
    Button:
        text: 'Data 2'
        on_press: root.show_data2()
        on_press: app.root.current = 'ShowData'

<Row>:
    TextInput:
        id: text_input
        size_hint_y: None
        height: 30

<Rows>:   
    orientation: 'vertical'

<MainScreen>:
    name: 'MainScreen'
    DataSwitch:

<ShowData>:
    name: 'ShowData'
    on_pre_enter:
        Clock.schedule_once(self.ids.rows.fill_with_data, 0.1)
    Rows:
        id: rows
    Button:
        text: 'Go back'
        size_hint_y: None
        height: 20
        on_press: app.root.current = 'MainScreen'

"""


class Row(BoxLayout):

    def __init__(self, text, **kwargs):
        super(Row, self).__init__(**kwargs)
        self.ids.text_input.text = text


class Rows(BoxLayout):
    data = []

    def fill_with_data(self, dt):
        for item in self.data:
            row = Row(text=str(item))
            self.add_widget(row)


class MainScreen(Screen):
    pass


class DataSwitch(BoxLayout):
    data1 = ['1', '2', '3', '4']
    data2 = ['5', '6', '7', '8']

    def show_data1(self):
        App.get_running_app().root.get_screen('ShowData').ids.rows.data = self.data1

    def show_data2(self):
        App.get_running_app().root.get_screen('ShowData').ids.rows.data = self.data2


class ShowData(Screen):
    def on_pre_leave(self):
        self.ids.rows.clear_widgets()


sm = Builder.load_string(kv)


class TestApp(App):
    def build(self):
        return sm


if __name__ == '__main__':
    TestApp().run()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...