【发布时间】:2018-11-03 18:05:30
【问题描述】:
我正在研究 kivy,并希望将图片嵌入到显示的文本中。 文本被加载一个简单的字符串,然后显示,这很容易做到,但我不知何故找不到如何在所述字符串中显示图像的线索。
这个问题的答案是为这些构建一个新的布局,在这种情况下是 TextWrapper。
示例代码:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Label, Button
from kivy.lang import Builder
from kivy.properties import BooleanProperty, StringProperty
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.scrollview import ScrollView
Builder.load_string("""
<ScreenSpecies>:
BoxLayout:
orientation: 'vertical'
Label:
pos_hint: {"x": .45, "top": 1}
size_hint: .1, .1
text: "The Species"
GridLayout:
id: species_layout
rows: 1
cols: 2
padding: dp(10)
spacing: dp(10)
orientation: 'horizontal'
SpeciesView:
id: species_list_view
SpeciesLabel:
id: species_text
text_selected: "Text" if not species_list_view.text_selected else species_list_view.text_selected
name_selected: "" if not species_list_view.name_selected else species_list_view.name_selected
<SpeciesView>:
viewclass: 'SelectableLabel'
text_selected: ""
name_selected: ""
SelectableRecycleBoxLayout:
orientation: 'vertical'
default_size: None, dp(32)
default_size_hint: .6, None
size_hint: 1, .9
multiselect: False
touch_multiselect: False
<SpeciesLabel>:
size_hint_y: .85
Label:
halign: 'left'
valign: 'middle'
size_hint_y: None
height: self.texture_size[1]
text_size: self.width, None
text: root.text_selected
<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 TextWrapper(BoxLayout):
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(Image(source=text[i][4:]))
else:
self.add_widget(Label(text=text[i]))
return text
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']
rv.text_selected = 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.species_data = [
{"text": "Test1", "description": "Test1.textbf |img=serveimage.png| Test1.textaf"},
{"text": "Test2", "description": "Test2.text"},
{"text": "Test3", "description": "Test3.text"}
]
for species in self.species_data:
species["description"] = TextWrapper(species["description"])
# clean keywords out
self.data = self.species_data
class SpeciesLabel(ScrollView):
text_selected = StringProperty("")
name_selected = StringProperty("")
screen_manager = ScreenManager()
screen_manager.add_widget(ScreenSpecies(name="screen_species"))
class TestApp(App):
def build(self):
return screen_manager
test_app = TestApp()
test_app.run()
此代码不起作用!因为您不能在不破坏程序的情况下单击标签,这就是问题所在。 text_selected 只接受 str
ValueError: SpeciesView.text_selected accept only str
我不知道如何显示视图每个元素的描述中的TextWrapper。
这一切的目的是,我可以根据例如更改文本一个可选择的选项列表,并且每个文本中仍然有图像。
结果应该类似于:
同样,问题是如何根据最后按下的按钮动态更改右侧的文本并更改其中的图像。
感谢您的帮助!
【问题讨论】:
-
我已经编辑了我的答案来回答你的一些新问题。
标签: python-3.x kivy