我有一个自定义小部件Message
,其中包含TextInput
,Button
和Label
。 TextInput
是不可编辑的,其目的只是显示文字。但我无法调整大小以适应文本。我见过有人询问动态身高,他得到了像wdg.height = (len(wdg._lines) + 1) * wdg.line_height
这样的答案。虽然这确实适用于高度,但我不确定如何实现宽度类似的东西。也许有某种line_width
财产?我想也许可以将font_size和最长的行相乘,但不同字母占用的大小并不一致,我也没有看到预测包装的方法,所以这是一个问题。有没有更好的变种?
这是我的一段代码,用于定义小部件:
Builder.load_string('''
<Message>:
FloatLayout:
pos: root.pos
width: self.width
height: self.height
canvas:
Color:
rgba: 0, 0, 0, 1
RoundedRectangle:
pos: root.pos
size: self.size
Color:
rgba: 1, 1, 1, 1
RoundedRectangle:
pos: root.x + 1, root.y + 1
size: self.width - 2, self.height - 2
Button:
id: bt
pos: root.pos
size: self.size
background_normal: ''
background_down: ''
background_color: 0, 0, 0, 0
on_press: root.test()
MyTextInput:
pos: root.pos
size: bt.size
id: msg
background_color: 0, 0, 0, 0
readonly: True
text: str(msg)
cursor_color: 0, 0, 0, 0
Label:
x: root.x + 65
y: root.y - 15
size: 40, 2
id: time
color: 0, 0, 0, 1
font_size: 10
''')
class Message(Widget):
def __init__(self, **kwargs):
super(Message, self).__init__(**kwargs)
def test(self, *args, **kwargs):
print("Touch received")
负责创建这些小部件的build
方法中的函数:
def msg_in(*args, **kwargs):
global pr_msg_y, msg_stack
msg = tx1_main.text.strip("\n ")
if msg not in string.whitespace:
msg_stack.append(Message())
time = datetime.now().strftime("%H:%M")
msg_stack[-1].ids['time'].text = time
msg_stack[-1].ids['msg'].text = msg
msg_stack[-1].width = 500
msg_stack[-1].ids['msg'].height = (len(msg_stack[-1].ids['msg']._lines) + 1) * msg_stack[-1].ids['msg'].line_height
for i in msg_stack[-1].children:
i.height = (len(msg_stack[-1].ids['msg']._lines) + 1) * msg_stack[-1].ids['msg'].line_height
msg_stack[-1].y = sv1_main.height - 5 - pr_msg_y - msg_stack[-1].height
msg_stack[-1].x = 5
tx1_main.text = ''
msg_float.add_widget(msg_stack[-1])
pr_msg_y += msg_stack[-1].height + 5
其中tx1_main
是我从(TextInput
)获取文字的地方,而sv1_main
是ScrollView
,显示FloatLayout
(msg_float
)显示这些消息小部件。
答案 0 :(得分:0)
首先,TextInput
有一个属性minimum_height
。您只需将以下内容添加到kv即可使任何TextInput
正确的高度:
size_hint_y: None
height: self.minimum_height
关于宽度,没有等价物。通常不需要这个(通常需要minimum_height
,特别是对于单行输入)。如果您的目的是允许将文本复制到剪贴板,我建议您只使用Label
并在其旁边放一个小Button
,将整个文本复制到剪贴板。对于Label
,您可以像这样调整大小:
size_hint: None, None
size: self.texture_size
更好的是,您还可以添加填充:
size_hint: None, None
height: self.texture_size[1] + dp(8)
width: self.texture_size[0] + dp(8)
答案 1 :(得分:0)
实际上,有一种方法。显然,TextInput
有一个受保护的属性_lines_labels
,它是一个纹理列表,可能代表这些行。这些纹理有大小,所以我可以访问它以找到最大值并适当调整我的小部件大小。