【问题标题】:Adding Kivy recycleview to screenmanager breaks example将 Kivy recycleview 添加到 screenmanager 中断示例
【发布时间】:2021-11-25 18:59:01
【问题描述】:

我正在尝试将this recycleview examplethis screenmanager example 结合起来,以便recycleview 示例可以成为我应用程序中的屏幕之一。应用程序运行,但所有控制按钮都显示在 UI 的底部(它们应该在顶部)并且被禁用或隐藏,不允许输入。因此,无法填充和/或查看回收视图。

这是我的尝试:

import asyncio
from random import sample, randint
from string import ascii_lowercase

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.recycleview.views import RecycleDataViewBehavior

kv = '''
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
#:import BoxLayout kivy.uix.boxlayout.BoxLayout
#:import RecycleDataViewBehavior kivy.uix.recycleview.views.RecycleDataViewBehavior

ScreenManagement:
    transition: FadeTransition()
    ContactsScreen:
        name: 'contacts'
    MessengerScreen:
        name: 'messenger'
    
<Row@RecycleKVIDsDataViewBehavior+BoxLayout>:
    canvas.before:
        Color:
            rgba: 0.5, 0.5, 0.5, 1
        Rectangle:
            size: self.size
            pos: self.pos
    value: ''
    Label:
        id: name
    Label:
        text: root.value

<ContactsScreen>:
    canvas:
        Color:
            rgba: 0.3, 0.3, 0.3, 1
        Rectangle:
            size: self.size
            pos: self.pos
    rv: rv
    orientation: 'vertical'
    GridLayout:
        cols: 3
        rows: 2
        size_hint_y: None
        height: dp(108)
        padding: dp(8)
        spacing: dp(16)
        Button:
            text: 'Populate list'
            on_press: root.populate()
        Button:
            text: 'Sort list'
            on_press: root.sort()
        Button:
            text: 'Clear list'
            on_press: root.clear()
        BoxLayout:
            spacing: dp(8)
            Button:
                text: 'Insert new item'
                on_press: root.insert(new_item_input.text)
            TextInput:
                id: new_item_input
                size_hint_x: 0.6
                hint_text: 'value'
                padding: dp(10), dp(10), 0, 0
        BoxLayout:
            spacing: dp(8)
            Button:
                text: 'Update first item'
                on_press: root.update(update_item_input.text)
            TextInput:
                id: update_item_input
                size_hint_x: 0.6
                hint_text: 'new value'
                padding: dp(10), dp(10), 0, 0
        Button:
            text: 'Remove first item'
            on_press: root.remove()

    RecycleView:
        id: rv
        scroll_type: ['bars', 'content']
        scroll_wheel_distance: dp(114)
        bar_width: dp(10)
        viewclass: 'Row'
        RecycleBoxLayout:
            default_size: None, dp(56)
            default_size_hint: 1, None
            size_hint_y: None
            height: self.minimum_height
            orientation: 'vertical'
            spacing: dp(2)
            
<MessengerScreen>:
    

    Button:
        on_release: app.root.current = 'contacts'
        text: 'back to the home screen'
        font_size: 50
'''


class ContactsScreen(Screen):
    def populate(self):
        self.rv.data = [
            {'name.text': ''.join(sample(ascii_lowercase, 6)),
             'value': str(randint(0, 2000))}
            for x in range(50)]

    def sort(self):
        self.rv.data = sorted(self.rv.data, key=lambda x: x['name.text'])

    def clear(self):
        self.rv.data = []

    def insert(self, value):
        self.rv.data.insert(0, {
            'name.text': value or 'default value', 'value': 'unknown'})

    def update(self, value):
        if self.rv.data:
            self.rv.data[0]['name.text'] = value or 'default new value'
            self.rv.refresh_from_data()

    def remove(self):
        if self.rv.data:
            self.rv.data.pop(0)

class MessengerScreen(Screen):
    pass

class ScreenManagement(ScreenManager):
    pass

presentation = Builder.load_string(kv)

class MainApp(App):
    def build(self):
        return presentation

    def main_runner(self):

        async def run_wrapper():
            # we don't actually need to set asyncio as the lib because it is
            # the default, but it doesn't hurt to be explicit
            await self.async_run(async_lib='asyncio')
            print('App done')
            #self.other_task.cancel()

        return asyncio.gather(run_wrapper())

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(MainApp().main_runner())
    loop.close()

问题似乎来自&lt;Row@RecycleKVIDsDataViewBehavior+BoxLayout&gt; 指令,但无论我把它放在哪里,我似乎都无法修复它。

【问题讨论】:

    标签: python-3.x kivy kivy-language


    【解决方案1】:

    您可以使用pos_hint 定位Buttons,如下所示:

    GridLayout:
        id: grid
        pos_hint: {'center_x': 0.5, 'top': 1}
    

    然后,您需要调整RecycleView 的大小,使其不超过Buttons,如下所示:

    RecycleView:
        id: rv
        size_hint_y: None
        height: root.height - grid.height
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多