所以我是一个初学者。我写了一个程序,从列表中读取句子,并在Boxlayout中显示它们作为按钮。Boxlayout是Floatlayout,所以我可以控制句子的位置。如果我点击其中一个句子,它会为每个单词分裂成按钮。到目前为止一切顺利。现在我想创建一个标签,它显示在Boxlayout下面的某个地方。它应该在点击单词按钮时显示,并显示与按钮相同的文本。假设我用这个句子作为按钮:
| Hello World,这是一个例句。|
如果我点击句子:
| Hello || World || this | is | an | example |句子|
文字应该分割成单独的按钮。例如,当我点击"句子"按钮时,下面应该会出现一个标签,上面写着"句子">
. py:
import kivy
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Widget, Label
from kivy.config import Config
sentences = ['This is example sentence 1.', 'This is example sentence 2.', 'This is example sentence 3.', 'This is example sentence 4.', 'This is example sentence 5.', 'This is example sentence 6.']
words = [ ['This', 'is' , 'example' , 'sentence' , '1' ], ['This', 'is' , 'example' , 'sentence' , '2' ], ['This', 'is' , 'example' , 'sentence' , '3' ], ['This', 'is' , 'example' , 'sentence' , '4' ], ['This', 'is' , 'example' , 'sentence' , '5' ], ['This', 'is' , 'example' , 'sentence' , '6' ] ]
class AdaptiveButton(Button):
"""This button takes as much space as it needs to contain its text."""
def __init__(self, **kwargs):
super(AdaptiveButton, self).__init__(**kwargs)
self.size_hint = (None, None)
self.bind(texture_size = self.setter("size"))
class Boxlayout(BoxLayout):
"""This will arrange all the necessary widgets."""
def __init__(self, **kwargs):
super(Boxlayout, self).__init__(**kwargs)
self.orientation = "vertical"
self.spacing = "10dp"
for i, line in enumerate(sentences):
abtn = AdaptiveButton(text = line, font_size=30)
abtn.bind(on_press = lambda btn, j = i : self.destroy_then_create(btn, j))
self.add_widget(abtn)
def destroy_then_create(self, btn, index):
self.remove_widget(btn)
box = BoxLayout(size_hint = (None, None), spacing = "10dp")
box.bind(minimum_size = box.setter("size"))
sentence = words[index]
i = len(sentences)-index-1
for word in sentence:
abtn = AdaptiveButton(text = word)
abtn.bind(on_press=lambda btn, j=i: show(word)) # Here is the function for #the label being binded
box.add_widget(abtn)
self.add_widget(box, i)
class Meaningclass(Label): # Label class
pass
def show(k): #function for the Label
MeC = Meaningclass()
Meaning = Label(text=k, font_size=30)
MeC.add_widget(Meaning)
class MyApp(App):
def build(self):
self.icon = 'budspencer.png'
# creating Floatlayout
Fl = FloatLayout()
Box = Boxlayout(pos_hint={'x': .23, 'y': .58})
meaning = Meaningclass(pos_hint={'x': .9, 'y': .1})
Fl.add_widget(Box)
Fl.add_widget(meaning) #Here we add the Label to the FloatLayout
# return the layout
return Fl
# run the App
if __name__ == "__main__":
MyApp().run()
问题是,你实际上是在你的功能show
中添加一个标签到另一个标签,但你从未访问过你已经添加到应用程序子类的标签。
修复如下:
- 首先为标签创建一个引用,
def build(self):
...
Box = Boxlayout(pos_hint={'x': .23, 'y': .58})
# Create a reference of the label with 'self'.
self.meaning = Meaningclass(pos_hint={'x': .2, 'y': .1}, font_size=30) # Reduce it so that it doesn't go out of the screen.
Fl.add_widget(Box)
Fl.add_widget(self.meaning) #Here we add the Label to the FloatLayout
- 通过完全"词"的方法
destroy_then_create
使用kwarg之前。 - 现在对功能
show
, 进行以下更改
...
for word in sentence:
abtn = AdaptiveButton(text = word)
abtn.bind(on_press=lambda btn, w=word: show(w)) # Pass the word only as before using kwarg.
box.add_widget(abtn)
...
def show(k): #function for the Label
# Grab the running app instance.
app = App.get_running_app()
# Access the label you already added to the app's subclass and set the text.
app.meaning.text = k
你可以在代码的任何地方添加这个函数show
,但记住以任何合适的方式访问应用程序实例。