Kivy:调整按钮大小以适应下拉列表中的包装文本
Kivy: Sizing Buttons to fit wrapped text within dropdown
我在为文本启用了自动换行的情况下构建 Kivy 下拉菜单时遇到问题,这样按钮小部件的大小就会相应地容纳全文。
我遵循了下面的堆栈溢出线程和同样链接的类似博客 post 的指导。
文本按预期换行,但是随着文本字符串变长,呈现按钮时文本上方和下方的 "padding" 数量也在增加。我不确定是什么原因造成的,希望消除这种影响。
更新:(编辑代码使问题更简洁。编辑图像以匹配)
"extra padding" 与文本长度无关,而是与添加到下拉列表的循环索引 and/or 小部件计数有关。
进一步编辑这行代码:
btn2 = WrapButton(text=('|' + str('long text..is long...%d' % (21-index) * index) + '|') , size_hint=(1,None))
收件人:
btn2 = WrapButton(text=('|' + str('long text..is long...%d' % (21-index) * index) + '|') , size_hint=(None,None),width=700)
(设置 size_hint=(none,none) 而不是 (1,none) 并添加 width=700)
消除了这个问题。我无法理解导致这种行为的原因。编辑后的代码失去了按钮的自动宽度调整,我无法想象宽度 size_hint 是如何导致垂直 "padding".
显示问题的屏幕截图
这段代码演示了这个问题:
from kivy.uix.button import Button
from kivy.uix.dropdown import DropDown
from kivy.uix.boxlayout import BoxLayout
from kivy.base import runTouchApp
from kivy.lang import Builder
Builder.load_string('''
<WrapButton>:
halign: "center"
valign: "center"
font_size: 20
size_hint_y: None
text_size : self.size
height: self.texture_size[1]
''')
class WrapButton(Button):
pass
dropdown2 = DropDown()
layout = BoxLayout(padding=0,orientation='vertical')
mainbutton2 = WrapButton(text='Select...', size_hint=(1, None),height=95,pos_hint={'center_x': .5, 'center_y': 0})
mainbutton2.bind(on_release=dropdown2.open)
layout.add_widget(mainbutton2)
for index in range(20):
btn2 = WrapButton(text=('|' + str('long text..is long...%d' % (21-index) * index) + '|') , size_hint=(1,None))
btn2.bind(on_release=lambda btn2: dropdown2.select(btn2.text))
dropdown2.add_widget(btn2)
dropdown2.bind(on_select=lambda instance, x: setattr(mainbutton2, 'text', x))
runTouchApp(layout)
截图
更新:
下面接受的答案会导致 Android 上出现伪影。我正在努力在其他设备上进行测试以排除设备本身。我们将不胜感激来自社区的任何意见!
Artifacts..broken Kivy install?
解决办法是将text_size : self.size
换成text_size : self.width, None
。详情请参考示例和输出。
例子
main.py
from kivy.uix.button import Button
from kivy.uix.dropdown import DropDown
from kivy.uix.boxlayout import BoxLayout
from kivy.base import runTouchApp
from kivy.lang import Builder
Builder.load_string('''
<WrapButton>:
halign: "center"
valign: "center"
font_size: 20
size_hint_y: None
text_size : self.width, None
height: self.texture_size[1]
''')
class WrapButton(Button):
pass
dropdown2 = DropDown()
layout = BoxLayout(padding=0, orientation='vertical')
mainbutton2 = WrapButton(text='Select...', size_hint=(1, None), height=95, pos_hint={'center_x': .5, 'center_y': 0})
mainbutton2.bind(on_release=dropdown2.open)
layout.add_widget(mainbutton2)
for index in range(20):
btn2 = WrapButton(text=('|' + str('long text..is long...%d' % (21-index) * index) + '|'), size_hint=(1, None))
btn2.bind(on_release=lambda btn2: dropdown2.select(btn2.text))
dropdown2.add_widget(btn2)
dropdown2.bind(on_select=lambda instance, x: setattr(mainbutton2, 'text', x))
runTouchApp(layout)
输出
我在为文本启用了自动换行的情况下构建 Kivy 下拉菜单时遇到问题,这样按钮小部件的大小就会相应地容纳全文。
我遵循了下面的堆栈溢出线程和同样链接的类似博客 post 的指导。
文本按预期换行,但是随着文本字符串变长,呈现按钮时文本上方和下方的 "padding" 数量也在增加。我不确定是什么原因造成的,希望消除这种影响。
更新:(编辑代码使问题更简洁。编辑图像以匹配)
"extra padding" 与文本长度无关,而是与添加到下拉列表的循环索引 and/or 小部件计数有关。
进一步编辑这行代码:
btn2 = WrapButton(text=('|' + str('long text..is long...%d' % (21-index) * index) + '|') , size_hint=(1,None))
收件人:
btn2 = WrapButton(text=('|' + str('long text..is long...%d' % (21-index) * index) + '|') , size_hint=(None,None),width=700)
(设置 size_hint=(none,none) 而不是 (1,none) 并添加 width=700)
消除了这个问题。我无法理解导致这种行为的原因。编辑后的代码失去了按钮的自动宽度调整,我无法想象宽度 size_hint 是如何导致垂直 "padding".
显示问题的屏幕截图
这段代码演示了这个问题:
from kivy.uix.button import Button
from kivy.uix.dropdown import DropDown
from kivy.uix.boxlayout import BoxLayout
from kivy.base import runTouchApp
from kivy.lang import Builder
Builder.load_string('''
<WrapButton>:
halign: "center"
valign: "center"
font_size: 20
size_hint_y: None
text_size : self.size
height: self.texture_size[1]
''')
class WrapButton(Button):
pass
dropdown2 = DropDown()
layout = BoxLayout(padding=0,orientation='vertical')
mainbutton2 = WrapButton(text='Select...', size_hint=(1, None),height=95,pos_hint={'center_x': .5, 'center_y': 0})
mainbutton2.bind(on_release=dropdown2.open)
layout.add_widget(mainbutton2)
for index in range(20):
btn2 = WrapButton(text=('|' + str('long text..is long...%d' % (21-index) * index) + '|') , size_hint=(1,None))
btn2.bind(on_release=lambda btn2: dropdown2.select(btn2.text))
dropdown2.add_widget(btn2)
dropdown2.bind(on_select=lambda instance, x: setattr(mainbutton2, 'text', x))
runTouchApp(layout)
截图
更新: 下面接受的答案会导致 Android 上出现伪影。我正在努力在其他设备上进行测试以排除设备本身。我们将不胜感激来自社区的任何意见!
Artifacts..broken Kivy install?
解决办法是将text_size : self.size
换成text_size : self.width, None
。详情请参考示例和输出。
例子
main.py
from kivy.uix.button import Button
from kivy.uix.dropdown import DropDown
from kivy.uix.boxlayout import BoxLayout
from kivy.base import runTouchApp
from kivy.lang import Builder
Builder.load_string('''
<WrapButton>:
halign: "center"
valign: "center"
font_size: 20
size_hint_y: None
text_size : self.width, None
height: self.texture_size[1]
''')
class WrapButton(Button):
pass
dropdown2 = DropDown()
layout = BoxLayout(padding=0, orientation='vertical')
mainbutton2 = WrapButton(text='Select...', size_hint=(1, None), height=95, pos_hint={'center_x': .5, 'center_y': 0})
mainbutton2.bind(on_release=dropdown2.open)
layout.add_widget(mainbutton2)
for index in range(20):
btn2 = WrapButton(text=('|' + str('long text..is long...%d' % (21-index) * index) + '|'), size_hint=(1, None))
btn2.bind(on_release=lambda btn2: dropdown2.select(btn2.text))
dropdown2.add_widget(btn2)
dropdown2.bind(on_select=lambda instance, x: setattr(mainbutton2, 'text', x))
runTouchApp(layout)