Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x Kivy中的可滚动动态Gridlayout_Python 3.x_Kivy - Fatal编程技术网

Python 3.x Kivy中的可滚动动态Gridlayout

Python 3.x Kivy中的可滚动动态Gridlayout,python-3.x,kivy,Python 3.x,Kivy,我拥有的: -一种动态文本包装器(GridLayout),包括从SpeciesView.data中的“描述”文本生成的图像和标签 -一个可以让我点击不同文本的循环视图 但问题是,我似乎找不到一种方法来滚动GridLayout(TextWrapper) 我认为我没有正确使用大小提示,这应该允许ScrollView能够滚动 这篇文章总是剪得很奇怪 那么如何让这个滚动视图工作呢 from kivy.app import App from kivy.uix.button import Label fro

我拥有的:
-一种动态文本包装器(GridLayout),包括从SpeciesView.data中的“描述”文本生成的图像和标签
-一个可以让我点击不同文本的循环视图

但问题是,我似乎找不到一种方法来滚动GridLayout(TextWrapper)

我认为我没有正确使用大小提示,这应该允许ScrollView能够滚动
这篇文章总是剪得很奇怪

那么如何让这个滚动视图工作呢

from kivy.app import App
from kivy.uix.button import Label
from kivy.lang import Builder
from kivy.properties import BooleanProperty, StringProperty, ObjectProperty
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.gridlayout import GridLayout
from kivy.uix.image import Image
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.recycleview import RecycleView
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.scrollview import ScrollView

Builder.load_string("""
<ScreenManagement>:
    screen_species: screen_species

    ScreenSpecies:
        id: screen_species
        name: 'screen_species'


<ScreenSpecies>:
    species_text: species_text

    Label:
        pos_hint: {"x": .45, "top": 1}
        size_hint: .1, .1
        text: "Test"

    BoxLayout:
        id: species_layout
        padding: dp(10)
        spacing: dp(10)
        orientation: 'horizontal'

        SpeciesView:
            id: species_list_view

        SpeciesText:
            id: species_text
            name_selected: "" if not species_list_view.name_selected else species_list_view.name_selected


<SpeciesView>:
    viewclass: 'SelectableLabel'
    name_selected: ""

    SelectableRecycleBoxLayout:
        orientation: 'vertical'
        default_size: None, dp(32)
        default_size_hint: .6, None
        size_hint: 1, .9
        multiselect: False
        touch_multiselect: False


<SpeciesText>:
    ScrollView:
        size_hint_y: None  


<SelectableLabel>:
    canvas.before:
        Color:
            rgba: (.05, 0.5, .9, .8) if self.selected else (.5, .5, .5, 1)
        Rectangle:
            pos: self.pos
            size: self.size


<SpeciesLabel>:      
    text_size: self.size       
    size_hint_y: None   


<SpeciesImage>:
    size_hint_y: None
    allow_stretch: True
    keep_ratio: True
    texture_size: dp(20), dp(40)


<TextWrapper>:
    minimum_height: self.height
    orientation: "vertical"
    spacing: 10
    cols: 1
    size_hint_y: None
""")

class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior,
                                 RecycleBoxLayout):
    pass


class SelectableLabel(RecycleDataViewBehavior, Label):
    ''' Add selection support to the Label '''
    index = None
    selected = BooleanProperty(False)
    selectable = BooleanProperty(True)

    def refresh_view_attrs(self, rv, index, data):
        ''' Catch and handle the view changes '''
        self.index = index
        return super(SelectableLabel, self).refresh_view_attrs(
            rv, index, data)

    def on_touch_down(self, touch):
        ''' Add selection on touch down '''
        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):
        ''' Respond to the selection of items in the view. '''
        self.selected = is_selected
        if is_selected:
            print("selection changed to {0}".format(rv.data[index]))
            rv.name_selected = rv.data[index]['text']
            App.get_running_app().root.screen_species.species_text.update(TextWrapper(rv.data[index]["description"]))
        else:
            print("selection removed for {0}".format(rv.data[index]))


class ScreenSpecies(Screen):
    pass


class SpeciesView(RecycleView):
    def __init__(self, **kwargs):
        super(SpeciesView, self).__init__(**kwargs)

        self.data = [
            {"text": "Test1", "description": "Test1.textbf\nBla\n |img=image.jpg| Test1.textaf\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla"},
            {"text": "Test2", "description": "Test2.text"},
            {"text": "Test3", "description": "Test3.text"}
        ]


class SpeciesText(ScrollView):
    def update(self, text_wrapper):
        print("Adding TextWrapper {} to SpeciesText ScrollView".format(text_wrapper))
        self.clear_widgets()
        self.add_widget(text_wrapper)


class SpeciesLabel(Label):
    pass


class SpeciesImage(Image):
    pass


class TextWrapper(GridLayout):
    def __init__(self, text="", **kwargs):
        super(TextWrapper, self).__init__(**kwargs)
        self.content = self.wrap_text(text)

    def wrap_text(self, source):
        text = source.split("|")

        for i in range(0, len(text)):
            if "img=" in text[i]:
                self.add_widget(SpeciesImage(source=text[i][4:]))
            else:
                self.add_widget(SpeciesLabel(text=text[i]))
        return text


class ScreenManagement(ScreenManager):
    screen_species = ObjectProperty(None)


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


test_app = TestApp()
test_app.run()
从kivy.app导入应用
从kivy.uix.button导入标签
从kivy.lang导入生成器
从kivy.properties导入BooleanProperty、StringProperty、ObjectProperty
从kivy.uix.behaviors导入焦点行为
从kivy.uix.gridlayout导入gridlayout
从kivy.uix.image导入图像
从kivy.uix.recycleboxlayout导入recycleboxlayout
从kivy.uix.recycleview导入recycleview
从kivy.uix.recycleview.layout导入LayoutSelectionBehavior
从kivy.uix.recycleview.views导入RecycleDataViewBehavior
从kivy.uix.screenmanager导入screenmanager,屏幕
从kivy.uix.scrollview导入scrollview
生成器。加载\u字符串(“”)
:
筛选物种:筛选物种
筛选种类:
id:筛网
名称:'screen_species'
:
种类文字:种类文字
标签:
pos_提示:{“x”:.45,“top”:1}
大小提示:.1,.1
文本:“测试”
盒子布局:
id:物种分布图
填充:dp(10)
间距:dp(10)
方向:“水平”
物种视图:
id:物种列表视图
规格文字:
id:种类/文本
名称\u选定:“如果不是物种\u列表\u视图。名称\u选定其他物种\u列表\u视图。名称\u选定”
:
viewclass:“SelectableLabel”
所选名称:“
可选择的可循环利用布局:
方向:“垂直”
默认大小:无,dp(32)
默认大小提示:.6,无
尺寸提示:1.9
多重选择:错误
触摸多选:错误
:
滚动视图:
尺寸提示:无
:
在以下情况之前:
颜色:
rgba:(.05,0.5,9,8)如果自选,则为其他(.5,5,5,1)
矩形:
pos:self.pos
大小:self.size
:      
文本大小:self.size
尺寸提示:无
:
尺寸提示:无
允许拉伸:真
保持比率:真
纹理大小:dp(20),dp(40)
:
最小高度:自身高度
方向:“垂直”
间距:10
科尔斯:1
尺寸提示:无
""")
类SelectableRecycleBoxLayout(焦点行为、布局选择行为、,
可回收性布局):
通过
类SelectableLabel(RecycleDataViewBehavior,Label):
''将选择支持添加到标签''
索引=无
selected=布尔属性(False)
可选=布尔属性(真)
def刷新\视图\属性(自身、rv、索引、数据):
''捕获并处理视图更改''
self.index=索引
返回超级(SelectableLabel,self)。刷新\u视图\u属性(
rv、索引、数据)
def on_触控向下(自身,触控):
''在触地时添加选择''
如果是超级(SelectableLabel,self)。打开时触摸下(触摸):
返回真值
如果自碰撞点(*touch.pos)和自选择:
返回self.parent。使用触摸键选择(self.index,touch)
def应用选项(选择了自身、rv、索引):
''响应视图中的项目选择''
self.selected=是否选中
如果选择了以下选项:
打印(“选择更改为{0}”。格式(rv.data[index]))
rv.name_selected=rv.data[索引]['text']
App.get_running_App()
其他:
打印(“删除了对{0}的选择”。格式(rv.data[index]))
类别和种类(屏幕):
通过
类别规格视图(回收视图):
定义初始(自我,**kwargs):
super(SpeciesView,self)。\uuuuuu init\uuuuuuuuu(**kwargs)
self.data=[
{“text”:“Test1”,“description”:“Test1.textbf\nBla\n|img=image.jpg | Test1.textaf\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla,
{“text”:“Test2”,“description”:“Test2.text”},
{“text”:“Test3”,“description”:“Test3.text”}
]
类规格文本(滚动视图):
def更新(自我,文本包装):
打印(“将TextWrapper{}添加到SpeciesText ScrollView”。格式(text_wrapper))
self.clear_widgets()
self.add\u小部件(文本\u包装器)
类别规格标签(标签):
通过
类别SpeciesImage(图像):
通过
类TextWrapper(GridLayout):
定义初始值(self,text=“”,**kwargs):
超级(TextWrapper,self)。\uuuuu init\uuuuu(**kwargs)
self.content=self.wrap_text(文本)
def wrap_文本(自身、源):
text=source.split(“|”)
对于范围(0,len(text))中的i:
如果“img=”在文本[i]中:
self.add_小部件(SpeciesImage(source=text[i][4:]))
其他:
self.add_小部件(SpeciesLabel(text=text[i]))
返回文本
类屏幕管理(屏幕管理器):
screen\u species=ObjectProperty(无)
类TestApp(应用程序):
def生成(自):
返回屏幕管理()
test_app=TestApp()
测试应用程序运行()
一如既往地谢谢你

SpeciesText-使用RstDoc 下面的例子说明了这一点。它支持长文本,并且文档可以滚动

片段 kv文件
:
容器:容器
方向:“垂直”
尺寸提示:1.9
RST文件:
id:集装箱
示例:SpeciesText-使用RstDoc main.py
从kivy.app导入应用
从kivy.uix.button导入标签
从kivy.lang导入生成器
从kivy.properties导入BooleanProperty、ObjectProperty
来自kivy
<SpeciesText>:
    container: container
    orientation: 'vertical'
    size_hint: 1, .9

    RstDocument:
        id: container
from kivy.app import App
from kivy.uix.button import Label
from kivy.lang import Builder
from kivy.properties import BooleanProperty, ObjectProperty
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.image import Image
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.recycleview import RecycleView
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.boxlayout import BoxLayout

Builder.load_string("""
<ScreenManagement>:
    screen_species: screen_species

    ScreenSpecies:
        id: screen_species
        name: 'screen_species'


<ScreenSpecies>:
    species_text: species_text

    Label:
        pos_hint: {"x": .45, "top": 1}
        size_hint: .1, .1
        text: "Test"

    BoxLayout:
        id: species_layout
        padding: dp(10)
        spacing: dp(10)
        orientation: 'horizontal'

        SpeciesView:
            id: species_list_view

        SpeciesText:
            id: species_text
            name_selected: "" if not species_list_view.name_selected else species_list_view.name_selected


<SpeciesView>:
    viewclass: 'SelectableLabel'
    name_selected: ""

    SelectableRecycleBoxLayout:
        orientation: 'vertical'
        default_size: None, dp(32)
        default_size_hint: .6, None
        size_hint: 1, .9
        multiselect: False
        touch_multiselect: False

<SpeciesText>:
    container: container
    orientation: 'vertical'
    size_hint: 1, .9

    RstDocument:
        id: container

<SelectableLabel>:
    canvas.before:
        Color:
            rgba: (.05, 0.5, .9, .8) if self.selected else (.5, .5, .5, 1)
        Rectangle:
            pos: self.pos
            size: self.size

""")


class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior,
                                 RecycleBoxLayout):
    pass


class SelectableLabel(RecycleDataViewBehavior, Label):
    ''' Add selection support to the Label '''
    index = None
    selected = BooleanProperty(False)
    selectable = BooleanProperty(True)

    def refresh_view_attrs(self, rv, index, data):
        ''' Catch and handle the view changes '''
        self.index = index
        return super(SelectableLabel, self).refresh_view_attrs(
            rv, index, data)

    def on_touch_down(self, touch):
        ''' Add selection on touch down '''
        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):
        ''' Respond to the selection of items in the view. '''
        self.selected = is_selected
        if is_selected:
            print("selection changed to {0}".format(rv.data[index]))
            rv.name_selected = rv.data[index]['text']
            App.get_running_app().root.screen_species.species_text.update(rv.data[index]["description"])
        else:
            print("selection removed for {0}".format(rv.data[index]))


class ScreenSpecies(Screen):
    species_text = ObjectProperty(None)


class SpeciesView(RecycleView):
    def __init__(self, **kwargs):
        super(SpeciesView, self).__init__(**kwargs)

        self.data = [
            {"text": "Test1", "description": "./rstDocs/bearwithus.rst"},
            {"text": "Test2", "description": "./rstDocs/kvDoc.rst"},
            {"text": "Test3", "description": "./rstDocs/sphinxDoc.rst"}
        ]


class SpeciesText(BoxLayout):
    container = ObjectProperty(None)

    def update(self, source):
        print("Adding TextWrapper {} to SpeciesText ScrollView".format(source))
        self.container.source = source


class SpeciesLabel(Label):
    pass


class SpeciesImage(Image):
    pass


class ScreenManagement(ScreenManager):
    screen_species = ObjectProperty(None)


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


test_app = TestApp()
test_app.run()
<SpeciesText>:
    container: container

    bar_width: 10
    bar_color: 0, 1, 0, 1   # green
    bar_inactive_color: 1, 0, 0, 1   # red
    effect_cls: "ScrollEffect"
    scroll_type: ['bars']
    size_hint: (1, None)

    # TextWrapper
    GridLayout:
        id: container
        cols: 1
        spacing: 10
        size_hint_y: None
        height: self.minimum_height
from kivy.app import App
from kivy.uix.button import Label
from kivy.lang import Builder
from kivy.properties import BooleanProperty, StringProperty, ObjectProperty
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.gridlayout import GridLayout
from kivy.uix.image import Image
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.recycleview import RecycleView
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.scrollview import ScrollView

Builder.load_string("""
<ScreenManagement>:
    screen_species: screen_species

    ScreenSpecies:
        id: screen_species
        name: 'screen_species'


<ScreenSpecies>:
    species_text: species_text

    Label:
        pos_hint: {"x": .45, "top": 1}
        size_hint: .1, .1
        text: "Test"

    BoxLayout:
        id: species_layout
        padding: dp(10)
        spacing: dp(10)
        orientation: 'horizontal'

        SpeciesView:
            id: species_list_view

        SpeciesText:
            id: species_text
            name_selected: "" if not species_list_view.name_selected else species_list_view.name_selected


<SpeciesView>:
    viewclass: 'SelectableLabel'
    name_selected: ""

    SelectableRecycleBoxLayout:
        orientation: 'vertical'
        default_size: None, dp(32)
        default_size_hint: .6, None
        size_hint: 1, .9
        multiselect: False
        touch_multiselect: False

<SpeciesText>:
    container: container

    bar_width: 10
    bar_color: 0, 1, 0, 1   # green
    bar_inactive_color: 1, 0, 0, 1   # red
    effect_cls: "ScrollEffect"
    scroll_type: ['bars']
    size_hint: (1, None)

    GridLayout:
        id: container
        cols: 1
        spacing: 10
        size_hint_y: None
        height: self.minimum_height

<SelectableLabel>:
    canvas.before:
        Color:
            rgba: (.05, 0.5, .9, .8) if self.selected else (.5, .5, .5, 1)
        Rectangle:
            pos: self.pos
            size: self.size


<SpeciesLabel>:      
    size: self.texture_size       
    size_hint_y: None   


<SpeciesImage>:
    size_hint_y: None
    allow_stretch: True
    keep_ratio: True
    texture_size: dp(20), dp(40)

""")


class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior,
                                 RecycleBoxLayout):
    pass


class SelectableLabel(RecycleDataViewBehavior, Label):
    ''' Add selection support to the Label '''
    index = None
    selected = BooleanProperty(False)
    selectable = BooleanProperty(True)

    def refresh_view_attrs(self, rv, index, data):
        ''' Catch and handle the view changes '''
        self.index = index
        return super(SelectableLabel, self).refresh_view_attrs(
            rv, index, data)

    def on_touch_down(self, touch):
        ''' Add selection on touch down '''
        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):
        ''' Respond to the selection of items in the view. '''
        self.selected = is_selected
        if is_selected:
            print("selection changed to {0}".format(rv.data[index]))
            rv.name_selected = rv.data[index]['text']
            App.get_running_app().root.screen_species.species_text.wrap_text(rv.data[index]["description"])
        else:
            print("selection removed for {0}".format(rv.data[index]))


class ScreenSpecies(Screen):
    species_text = ObjectProperty(None)


class SpeciesView(RecycleView):
    def __init__(self, **kwargs):
        super(SpeciesView, self).__init__(**kwargs)

        self.data = [
            {"text": "Test1", "description": "Test1.textbf\nBla\n |img=kivy_logo.jpg| Test1.textaf\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla"},
            {"text": "Test2", "description": "Test2.text"},
            {"text": "Test3", "description": "Test3.text"}
        ]


class SpeciesText(ScrollView):
    container = ObjectProperty(None)

    def wrap_text(self, source):
        print("Adding TextWrapper {} to SpeciesText ScrollView".format(source))
        self.container.clear_widgets()
        text = source.split("|")

        for txt in text:
            if "img=" in txt:
                self.container.add_widget(SpeciesImage(source=txt[4:]))
            else:
                self.container.add_widget(SpeciesLabel(text=txt))


class SpeciesLabel(Label):
    pass


class SpeciesImage(Image):
    pass


class ScreenManagement(ScreenManager):
    screen_species = ObjectProperty(None)


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


test_app = TestApp()
test_app.run()