很抱歉在我之前的帖子中有部分错误(约翰安德森正确解决了这个问题(谢谢!))。
预期行为: 下面的代码应该使recycleview创建的按钮的大小适应每个按钮的文本。
现实生活中的行为: 在按钮七 (7) 之后滚动,使下一个按钮跳跃。请慢慢滚动,让字体大一些,效果更明显。
问题: 这是正常行为,也许是错误?还是代码错了?如果无法修复,我不应该开始我想到的项目。
谢谢一百万,对不起,即使您有解决方案,我也无法投票给您,因为我是论坛的新手!
from kivy.config import Config
from kivy.properties import partial
Config.set('graphics', 'width', '270')
Config.set('graphics', 'height', '550')
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.recycleview import RecycleView
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.lang import Builder
# I included this in case you have to use it for the answer instead of the python code:
Builder.load_string("""
<MyRecycleBoxLayout>:
# orientation: 'vertical'
# default_size: None, None
# default_size_hint: 1, None
# size_hint_y: None
# height: self.minimum_height
<MyButton>:
# font_size: 30
# text_size: self.width, None
# size_hint_y: None
# height: self.texture_size[1]
""")
class MyRecycleBoxLayout(RecycleBoxLayout):
def __init__(self,**kwargs):
super().__init__(**kwargs)
self.orientation= 'vertical'
self.default_size= (None, None)
self.default_size_hint=( 1, None)
self.size_hint_y= None
self.bind(minimum_height=self.setter("height"))
class MyButton(Button):
def __init__(self,**kwargs):
super().__init__(**kwargs)
self.font_size=60
self.bind(width=lambda s, w: s.setter("text_size")(s, (w, None)))
self.size_hint_y = None
self.bind(texture_size=self.setter("size"))
class RV(RecycleView):
def __init__(self,**kwargs):
super().__init__(**kwargs)
self.myRecycleBoxLayout=MyRecycleBoxLayout()
self.data.clear()
for i in range(150):
self.data.append({f"text":f"{i} "*50,"id": f"btn_{i}","on_release": partial(self.on_release_m,i)})
self.add_widget(self.myRecycleBoxLayout)
def on_release_m (self,i,*args):
# Print clicked buttons id:
print(self.data[i]["id"])
class RecApp(App):
def build(self):
self.rv=RV()
self.rv.viewclass=MyButton
return self.rv
RecApp().run()
编辑: 这可能有点接近问题的解决方法吗?你能帮我改进一下吗?我试图根据其文本长度、字数和字体大小以及一个真正的基本方程来计算每个按钮的正确高度。
# from kivy._event import partial
from kivy.config import Config
from kivy.properties import partial
from kivy.uix.boxlayout import BoxLayout
Config.set('graphics', 'width', '270')
Config.set('graphics', 'height', '550')
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.recycleview import RecycleView
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.lang import Builder
Builder.load_string("""
<MyRecycleBoxLayout>:
# orientation: 'vertical'
# default_size: None, None
# default_size_hint: 1, None
# size_hint_y: None
# height: self.minimum_height
<MyButton>:
# font_size: 30
# text_size: self.width, None
# size_hint_y: None
# height: self.texture_size[1]
""")
class EverythingBoxLayout(BoxLayout):
def __init__(self,**kwargs):
super().__init__(**kwargs)
self.orientation="vertical"
self.fontUpBtn=Button(text="+",on_release=self.on_fontUp)
self.fontDownBtn=Button(text="-",on_release=self.on_fontDown)
self.topBarBoxLayout=BoxLayout()
self.topBarBoxLayout.size_hint = (1, 0.1)
self.rv=RV()
self.myRecycleBoxLayout = MyRecycleBoxLayout()
self.multiplyer=0.002
for i in range(20):
myText = f"{i * 10} " * 50
myFontSize = 40
btnDict = {f"text": myText, "id": f"btn_{i}", "font_size": myFontSize}
btnDict["size_hint_y"]=None
#Desperately, trying to calculate each button's correct height, based on its text length,words count and font size:
btnDict["height"] =len(myText)* len(myText.split()) * myFontSize * self.multiplyer
self.rv.data.append(btnDict)
self.rv.add_widget(self.myRecycleBoxLayout)
self.rv.viewclass = MyButton
self.topBarBoxLayout.add_widget(self.fontUpBtn)
self.topBarBoxLayout.add_widget(self.fontDownBtn)
self.add_widget(self.topBarBoxLayout)
self.add_widget(self.rv)
def on_fontUp(self,obj,*args):
print("up")
for j in range(0,20):
self.rv.data[j]["font_size"]+=2
self.rv.data[j]["height"] = len( self.rv.data[j]["text"])*len( self.rv.data[j]["text"].split()) * self.rv.data[j]["font_size"] * self.multiplyer
print(self.rv.data)
self.rv.refresh_from_data()
def on_fontDown(self,obj,**args):
print("down")
for j in range(0, 20):
self.rv.data[j]["font_size"] -= 2
self.rv.data[j]["height"] = len( self.rv.data[j]["text"])*len( self.rv.data[j]["text"].split()) * self.rv.data[j]["font_size"] * self.multiplyer
print(self.rv.data)
self.rv.refresh_from_data()
class MyRecycleBoxLayout(RecycleBoxLayout):
def __init__(self,**kwargs):
super().__init__(**kwargs)
self.orientation= 'vertical'
self.default_size= (None, None)
self.default_size_hint=( 1, None)
self.size_hint_y= None
self.bind(minimum_height=self.setter("height"))
class MyButton(Button):
def __init__(self,**kwargs):
super().__init__(**kwargs)
# self.font_size=40
self.bind(width=lambda s, w: s.setter("text_size")(s, (w, None)))
# self.size_hint_y = None
# self.bind(texture_size=self.setter("size"))
class RV(RecycleView):
pass
class RecApp(App):
def build(self):
self.everythingBoxLayout=EverythingBoxLayout()
return self.everythingBoxLayout
recApp=RecApp()
recApp.run()
编辑2: 我发现这篇文章可能是一个解决方案,但我不知道如何在我的示例中实现它:https ://gist.github.com/tito/4201bc10d9752eb2762d31ce8fb699b6