基维刷新具有不同数据的屏幕

时间:2019-04-25 15:51:39

标签: python-3.x kivy

当我单击按钮时,我需要代码中的数据显示在不同的屏幕上。尽管Clock每秒添加小部件,但下面的代码仍满足我的需要。我希望TextInput是可编辑的,因此当我在“行”中键入一些值时,它将保持键入状态。我尝试使用Clock.schedule_once(),但是未显示小部件。我什至尝试过以下方法:

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

witch锁定添加新的小部件(我知道的嘲笑),但是当我返回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 个答案:

答案 0 :(得分:2)

运行该应用程序将产生以下内容:

问题1-实例化的行太多

  • Rows:根据kv文件
  • Rows(),方法为show_data1()show_data2()中的Python脚本。创建的这些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_enterScreen函数的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(),例如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()