Kivy MDBoxLayout在运行时自动增加宽度,引发[CCRITICAL][Clock]警告



当我在应用程序中添加一个ChatBubble时,尽管已经给定了它的大小,但该ChatBubble将自动增加每毫秒的宽度。

命令提示符中显示的问题是

[CCRITICAL][Clock]警告,在下一帧。检查代码,或增加Clock.max_迭代属性

我正试图找到一种方法,使ChatBubble像Messenger或Whatsapp等任何其他聊天框一样正常工作,我也试图在我的代码中找到问题,但无法找到。如有任何帮助,我们将不胜感激。

我把问题代码的一部分转换成了一个小应用程序,让你更容易看到问题。

.py文件

from kivy.lang import Builder
from kivy.properties import BooleanProperty, DictProperty, OptionProperty, StringProperty
from kivymd.app import MDApp 
#from components.label import PLabel
from kivymd.uix.boxlayout import MDBoxLayout, BoxLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.screenmanager import Screen
from kivy.uix.stacklayout import StackLayout
from kivy.uix.button import Button
class ChatBubble(MDBoxLayout):
send_by_user = BooleanProperty()
msg = StringProperty()
time = StringProperty()
class Container(MDBoxLayout):
def on_button_click(self):
self.on_start()
def on_start(self):
self.c = ChatBubble()
self.c.send_by_user = True
self.c.msg = "hello world"
self.c.time = "11:22AM"
self.ids["lst"].add_widget(self.c)

class MainApp(MDApp):
def build(self):
self.root = Builder.load_file("chat_bubble.kv")
if __name__ == "__main__":
MainApp().run()

.kv文件

Container:

<Container>:
orientation: "vertical"
ScrollView:
MDList:
id: lst
spacing: 5
padding: [0, 10, 0, 10]
Button:
text: "Click"
on_press:
root.on_button_click()
<ChatBubble>:
id: chtbld
md_bg_color: [0, 0, 0, 0]
size_hint_y: None
height: 60
adaptive_height: True
width: root.width
padding: [10, 0, 10, 0]
orientation: 'vertical'
MDBoxLayout:
height: msg_content.height + timed.height + 10
width: msg_content.width + wid1.width + wid2.width
size_hint: None, None
pos_hint: {'right': 1} if chtbld.send_by_user == True else {'left': 1}
radius: [10, 10, (1, -5), 10] if self.pos_hint == {'right': 1} else [10, 10, 10, (1, -5)]
md_bg_color: app.theme_cls.primary_dark if root.send_by_user else app.theme_cls.primary_color
Spacer:
id: wid1
MDBoxLayout:
orientation: 'vertical'
height: msg_content.height + tc.height + wid3.height
width: msg_content.width
MDLabel:
id: msg_content
text: root.msg
width: tc.width if self.texture_size[0] < tc.width else self.texture_size[0]
height: self.texture_size[1]
size_hint_y: None
text_size: chtbld.width-30 if self.width >= chtbld.width-30 else None, None
halign: 'left'
color: app.theme_cls.opposite_bg_normal
MDBoxLayout:
id: tc
size_hint_y: None
height: timed.height
width: timed.width + 3
spacing: 3
MDLabel:
id: timed
text: root.time
size: self.texture_size
size_hint_y: None
font_size: 9
bold: True
halign: 'right'
text_size: None, None
color: [.8, .8, .8, 1]
Spacer:
id: wid3
height: 5
Spacer:
id: wid2
<Spacer@Widget>:
id: wid
width: 5
size_hint: None, None

这种行为通常意味着小部件的大小正在进入相互依赖的小部件大小的无限循环。您可以通过将MDLabelwidth计算更改为msg_contentid来停止该循环:

width: tc.width if self.texture_size[0] < tc.width else self.texture_size[0]

至:

width: self.texture_size[0]

这可能不是您想要的,但似乎是msg_contenttc的依赖导致了循环。

我认为问题是由于内部小部件(尤其是MDLabelid: msg_contentMDBoxLayoutid: tcMDLabelid: timed(在sizetexture_size等字段中的相互依赖性,而没有单独处理这些属性。

在设置自定义size之前禁用size_hint似乎有效。

...
MDBoxLayout:
id: tc
size_hint: None, None # To set custom size.
height: timed.height
width: timed.width + 3
pos_hint: {'right': 1} # To hold itself and text on right.
spacing: 3
MDLabel:
id: timed
text: root.time
size_hint: None, None # To set custom size.
size: self.texture_size
font_size: 9
bold: True
halign: 'right' # This wouldn't work since its size is set to its texture_size.
...

您还应该将pos_hint值更改为{'left': 1}(这是一个无效密钥,可能是您想要的{"x" : 0}(。


但是我发现你的设计过于复杂。kivy的一位核心开发人员tshirtman提供了一个示例(messenger.py(,您可以查看一下。

最新更新