【发布时间】:2020-05-15 21:14:20
【问题描述】:
我正在尝试在我的 kivy 应用程序中制作一个屏幕,让两个用户可以互相聊天,但我在如何在屏幕上显示聊天消息时遇到了问题。
大致目标示例:(向下滚动页面约 60% 以查看) https://medium.com/flutter-community/building-a-chat-app-with-flutter-and-firebase-from-scratch-9eaa7f41782e
我已使用此答案在屏幕左侧添加标签(用户发送的消息): Label keeps running off edge of ScrollView screen x axis Kivy
但我现在正试图弄清楚如何在屏幕右侧添加标签(用户收到的消息)。我假设我需要一个有两列的GridLayout,我需要先添加一个白色标签,然后再添加消息标签,然后它应该出现在右侧。我无法让标签尽可能地显示在屏幕上。
我也无法根据每个标签中的文本量调整标签大小,我想我可能需要将每一行添加为新的GridLayout
肯定已经用 kivy 完成了类似的事情,并且有一个指南可以遵循,但我已经四处搜索,我只能找到老式的 UI 聊天屏幕设计。
py 文件
import kivy
from kivymd.app import MDApp
from kivy.properties import ObjectProperty, StringProperty, NumericProperty, ListProperty
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.core.text import Label as CoreLabel
from kivymd.uix.label import MDLabel
from kivymd.uix.button import MDFillRoundFlatButton, MDRoundFlatIconButton, MDRaisedButton, MDTextButton, MDIconButton
from kivy.core.window import Window
Window.size = (481, 600)
Window.clearcolor = (1,1,1,1)
class Chat(Screen):
chat_layout = ObjectProperty(None)
def send_message(self):
if self.ids.message.text:
lab1 = Label()
# calculate max allowable width in the GridLayout
max_width = self.chat_layout.width - self.chat_layout.spacing[0] - self.chat_layout.padding[0] - \
self.chat_layout.padding[2]
# specify font and font_size (so that the CoreLabel uses the same)
self.chat_layout.add_widget(
SmoothLabel.create_sized_label(text=self.ids.message.text, max_width=max_width, font_name='Roboto',
font_size=15))
self.chat_layout.add_widget(lab1)
self.ids.message.text = ""
else:
pass
def recv_message(self):
if self.ids.message.text:
# calculate max allowable width in the GridLayout
max_width = self.chat_layout.width - self.chat_layout.spacing[0] - self.chat_layout.padding[0] - \
self.chat_layout.padding[2]
# specify font and font_size (so that the CoreLabel uses the same)
chat_label = SmoothLabel.create_sized_label(text=self.ids.message.text, max_width=max_width, font_name='Roboto',
font_size=15)
lab1 = Label(width=max_width)
self.chat_layout.add_widget(lab1)
self.chat_layout.add_widget(chat_label)
self.ids.message.text = ""
else:
pass
class SmoothLabel(Label):
@staticmethod
def create_sized_label(**kwargs):
max_width = kwargs.pop('max_width', 0)
if max_width <= 0:
# just create a SmoothLabel without a text_size
return SmoothLabel(**kwargs)
# calculate what the SmoothLabel size will be
core_label = CoreLabel(padding=[10,10], **kwargs) # use same padding as SmoothLabel
core_label.refresh()
if core_label.width > max_width:
# width is too big, use text_size to force wrapping
return SmoothLabel(text_size=(max_width,None), **kwargs)
else:
# width is OK, no need for text_size
return SmoothLabel(**kwargs)
class WindowManager(ScreenManager):
pass
class MyApp(MDApp):
def build(self):
kv = Builder.load_file("kivy.kv")
self.sm = WindowManager()
screens = [Chat(name="chat")]
for screen in screens:
self.sm.add_widget(screen)
self.sm.current = "chat"
return self.sm
if __name__ == '__main__':
MyApp().run()
kv文件
<Chat>:
name: "chat"
chat_layout: chat_layout
GridLayout:
cols: 1
GridLayout:
cols: 2
id: chat_layout
padding: 15
GridLayout:
cols: 3
MDRaisedButton:
on_release: root.send_message()
text: "send message"
TextInput:
id: message
size_hint: None, None
size: 150,50
hint_text:
"Send message"
MDRaisedButton:
on_release: root.recv_message()
text: "receive message"
<SmoothLabel>:
size_hint: None, None
size: self.texture_size
padding: 10, 10
multiline: True
background_color: 0,0,0,0
background_normal: ""
back_color: 1,0,1,1
border_radius: [6]
canvas.before:
Color:
rgba: 0.2,0.6,1,1 #This changes the label colour
RoundedRectangle:
size: self.size
pos: self.pos
radius: self.border_radius
【问题讨论】:
-
我尝试打印
chat_label的各种宽度属性(size,size_hint_x,width,texture_size)但它们都返回None。我在想如果我能得到chat_label的宽度,那么我可以事先添加一个空白标签,即max_width减去chat_label的宽度
标签: kivy kivy-language