Kivy MDBoxLayout 在 运行 时自动增加宽度,引发 [CRITICAL] [Clock] 警告
Kivy MDBoxLayout keeps increasing width automatically when running, raised [CRITICAL] [Clock] Warning
当我在我的应用程序中添加 ChatBubble 时,尽管 ChatBubble 的大小已经给定,但它会自动增加每毫秒的宽度。
命令提示符中显示的问题是
[CRITICAL] [Clock ] Warning, too much iteration done before the
next frame. Check your code, or increase the Clock.max_iteration
attribute
我试图找到一种方法让 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
这种行为通常意味着您的小部件的大小正在进入 inter-dependent 小部件大小的无限循环。您可以通过将 MDLabel
的 width
计算更改为 msg_content
的 id
来自:
来停止该循环
width: tc.width if self.texture_size[0] < tc.width else self.texture_size[0]
至:
width: self.texture_size[0]
这可能不是您想要的,但似乎 msg_content
对 tc
的依赖导致了循环。
我认为问题是由于内部小部件的 inter-dependencies(尤其是 MDLabel
和 id: msg_content
、MDBoxLayout
和 id: tc
、MDLabel
和 id: timed
) 在 size
、texture_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
),您可以查看一下。
当我在我的应用程序中添加 ChatBubble 时,尽管 ChatBubble 的大小已经给定,但它会自动增加每毫秒的宽度。
命令提示符中显示的问题是
[CRITICAL] [Clock ] Warning, too much iteration done before the next frame. Check your code, or increase the Clock.max_iteration attribute
我试图找到一种方法让 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
这种行为通常意味着您的小部件的大小正在进入 inter-dependent 小部件大小的无限循环。您可以通过将 MDLabel
的 width
计算更改为 msg_content
的 id
来自:
width: tc.width if self.texture_size[0] < tc.width else self.texture_size[0]
至:
width: self.texture_size[0]
这可能不是您想要的,但似乎 msg_content
对 tc
的依赖导致了循环。
我认为问题是由于内部小部件的 inter-dependencies(尤其是 MDLabel
和 id: msg_content
、MDBoxLayout
和 id: tc
、MDLabel
和 id: timed
) 在 size
、texture_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
),您可以查看一下。