ScrollView 子部件在 Kivy 中不显示

问题描述 投票:0回答:1

我是编程新手,正在设计一个字典应用程序框架,您可以在窗口左侧搜索和选择单词,并可以在窗口右侧读取所选单词的信息。我试图使用左侧的 TextInput 和 Recycle 以及右侧的 ScrollView 来实现这些对象,一切进展顺利,直到我开始处理右侧部分:右侧部分,即 ScrollView 部分,始终是不知何故空白。

整个脚本在这里:

from kivy.app import App
from kivy.lang import Builder
from kivy.properties import BooleanProperty
from kivy.uix.label import Label
from kivy.uix.scrollview import ScrollView
from kivy.uix.recycleview import RecycleView
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout

kv_string = '''
<MainLayout>:
    orientation: 'horizontal'
    BoxLayout:
        orientation: 'vertical'
        size_hint_x: 0.35
        TextInput:
            hint_text: 'Search'
            size_hint_y: 0.05
            multiline: False
            padding_y: 10
        RV:
            size_hint_y: 0.95
            viewclass: 'SelectableLabel'
            SelectableRecycleBoxLayout:
                default_size: None, dp(56)
                default_size_hint: 1, None
                size_hint_y: None
                height: self.minimum_height
                orientation: 'vertical'
                multiselect: False
                touch_multiselect: False                              
<SelectableLabel>:
    color: (0, 0, 0, 1)
    canvas.before:
        Color:
            rgba: (.5, .7, .6, .5) if self.selected else (1, 1, 1, 1)
        Rectangle:
            pos: self.pos
            size: self.size        
'''

my_dict = {'A': {'info': 'a'}, 'B': {'info': 'b'}, 'C': {'info': 'c'}, 'D': {'info': 'd'}, 'E': {'info': 'e'}}

class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior, RecycleBoxLayout):
    pass

class SelectableLabel(RecycleDataViewBehavior, Label):
    index = None
    selected = BooleanProperty(False)
    selectable = BooleanProperty(True)
    def refresh_view_attrs(self, rv, index, data):
        self.index = index
        self.data = data
        self.text = data['letter']
        return super(SelectableLabel, self).refresh_view_attrs(rv, index, data)
    
    def on_touch_down(self, touch):
        if super(SelectableLabel, self).on_touch_down(touch):
            return True
        if self.collide_point(*touch.pos) and self.selectable:
            return self.parent.select_with_touch(self.index, touch)
        
    def apply_selection(self, rv, index, is_selected):
        self.selected = is_selected
        if is_selected:
            MyApp().display_info(self.data)

class RV(RecycleView):
    def __init__(self, **kwargs):
        super(RV, self).__init__(**kwargs)  
        for letter, info in my_dict.items():
            data_piece = {'letter': letter, 'info': info}
            self.data.append(data_piece)

class MainLayout(BoxLayout):
    pass

class MyApp(App):
    def __init__(self, **kwargs):
        super(MyApp, self).__init__(**kwargs)
        self.info_layout = GridLayout(
            size_hint = (1, None),
            cols = 1,
            height = 500
        )
    def build(self):   
        Builder.load_string(kv_string)
        root = MainLayout()
        info_sv = ScrollView(
            size_hint_x = 0.65
        )
        info_sv.add_widget(self.info_layout)
        root.add_widget(info_sv)
        return root
    
    def display_info(self, data):
        self.info_layout.clear_widgets()
        label = Label(
            text = data['info']['info'],
            color = (0, 0, 1, 1)
        )
        self.info_layout.add_widget(label)
        print(data)
        
if __name__ == '__main__':
    MyApp().run()

如您所见,我在 displayinfo() 方法中添加了一个“print(data)”来测试它是否可以接收数据,结果工作得很好。我尝试在 info_layout 中添加一个按钮,但它也没有显示。所以我想问题是 info_layout 没有显示或没有更新。

python kivy
1个回答
0
投票

问题出在您的

apply_selection()
代码中。在该代码中,有一行:

MyApp().display_info(self.data)

其中的

MyApp()
部分创建了
MyApp
的新实例,并调用该新实例的
display_info()
方法。但是,该新实例与您在屏幕上看到的内容无关。您实际上需要使用屏幕上显示的
MyApp
实例。尝试将该方法更改为:

def apply_selection(self, rv, index, is_selected):
    self.selected = is_selected
    if is_selected:
        App.get_running_app().display_info(self.data)
        # MyApp().display_info(self.data)
© www.soinside.com 2019 - 2024. All rights reserved.