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()