如何修复此 Kivy 错误。它从不说明为什么它会中断并循环错误(一个错误,导致错误,循环到同一个文件)
How do I fix this Kivy error. It never tells why it breaks and loops the error (an error, causing an error, that loops to the same file)
我正在尝试使用 Kivy python 框架为 android 开发应用程序。目前我正在测试 Windows 并且当前代码(希望很快能够扫描条形码和其他东西)正在犯一个错误,它只是循环又循环,从不给出类似 TypeError 或类似的原因。
循环错误:
Traceback (most recent call last):
File "C:\Program Files (x86)\Python36-32\lib\site-packages\kivy\lang\builder.py", line 601, in _apply_rule
setattr(widget_set, key, value)
File "kivy\weakproxy.pyx", line 33, in kivy.weakproxy.WeakProxy.__setattr__ (kivy\weakproxy.c:1471)
File "kivy\properties.pyx", line 478, in kivy.properties.Property.__set__ (kivy\properties.c:5572)
File "kivy\properties.pyx", line 1342, in kivy.properties.ReferenceListProperty.set (kivy\properties.c:21169)
File "kivy\properties.pyx", line 494, in kivy.properties.Property.set (kivy\properties.c:6520)
File "kivy\properties.pyx", line 516, in kivy.properties.Property.set (kivy\properties.c:6405)
File "kivy\properties.pyx", line 571, in kivy.properties.Property.dispatch (kivy\properties.c:7105)
File "kivy\_event.pyx", line 1225, in kivy._event.EventObservers.dispatch (kivy\_event.c:14035)
File "kivy\_event.pyx", line 1107, in kivy._event.EventObservers._dispatch (kivy\_event.c:12788)
File "C:\Program Files (x86)\Python36-32\lib\site-packages\kivy\lang\builder.py", line 76, in call_fn
setattr(element, key, e_value)
File "kivy\weakproxy.pyx", line 33, in kivy.weakproxy.WeakProxy.__setattr__ (kivy\weakproxy.c:1471)
File "kivy\properties.pyx", line 478, in kivy.properties.Property.__set__ (kivy\properties.c:5572)
File "kivy\properties.pyx", line 1342, in kivy.properties.ReferenceListProperty.set (kivy\properties.c:21169)
File "kivy\properties.pyx", line 494, in kivy.properties.Property.set (kivy\properties.c:6520)
File "kivy\properties.pyx", line 516, in kivy.properties.Property.set (kivy\properties.c:6405)
File "kivy\properties.pyx", line 571, in kivy.properties.Property.dispatch (kivy\properties.c:7105)
File "kivy\_event.pyx", line 1225, in kivy._event.EventObservers.dispatch (kivy\_event.c:14035)
File "kivy\_event.pyx", line 1107, in kivy._event.EventObservers._dispatch (kivy\_event.c:12788)
File "C:\Program Files (x86)\Python36-32\lib\site-packages\kivy\lang\builder.py", line 76, in call_fn
setattr(element, key, e_value)
等等
这是我当前的代码:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ListProperty
from kivy.uix.screenmanager import ScreenManager, Screen
Builder.load_string("""
<ResultsScreen>:
id: rw
percentage: 50
FloatLayout:
canvas:
Color:
rgb: 1, 1, 1
Rectangle:
pos: self.pos
size: self.size
Color:
rgb: 0, 0, 0
Line:
circle: self.width * 0.5, self.height * 0.75, self.width * 0.40, 0, 360 * (rw.percentage / 100)
width: 15
cap: 'square'
joint: 'round'
Label:
id: percentage_label
text: '[color=#000000]' + str(rw.pecentage) + '%[/color]'
markup: True
pos_hint: {'center_x': 0.5, 'center_y': 0.75}
size_hint: 0.1, 0.1
halign: 'center'
valign: 'center'
Button:
text: 'Scan Again'
on_press: root.manager.current = 'camerascan'
size: self.width * 0.4, self.height * 0.05
pos_hint: {'center_x': 0.5, 'center_y': 0.1}
<CameraScreen>:
BoxLayout:
Button:
text: 'Cancel'
on_press: root.manager.current = 'results'
""")
class ResultsScreen(Screen):
pass
class CameraScreen(Screen):
pass
sm = ScreenManager()
sm.add_widget(CameraScreen(name='camerascan'))
sm.add_widget(ResultsScreen(name='results'))
class SweetTruthApp(App):
def build(self):
return sm
if __name__ == '__main__':
SweetTruthApp().run()
我不知道这个问题是什么或可能是什么,我对 Kivy 和 python 类 的想法不太满意,所以不胜感激。
你实际上 运行 陷入了递归问题(因此错误循环)。在我告诉你问题是什么之前,我想告诉你我是如何发现它的(我会给你一根钓鱼竿而不是给你鱼)。
该方法非常简单,您可以自己轻松完成,并为我们提供了有关问题所在的重要提示。技巧如下:您只需开始删除 .kv 语言字符串中的代码。它主要影响设计,因此程序无需大量代码即可运行良好。我删除了 CameraScreen
按钮 - 同样的错误。没有 ResultsScreen
canvas,标签 - 仍然是同样的错误。没有 ResultsScreen
按钮 - 一个不同的错误。您在第 29 行将 "percentage" 拼错为 "pecentage"。更正它 - 程序运行正常。使用相同的方法,您可能会发现错误在第 39 行:size: self.width * 0.4, self.height * 0.05
。为什么这里出错?现在这是我们本可以开始的真正问题,所以下次做功课吧(不要气馁 - 到目前为止,该应用程序看起来很有前途!)
想想你在这里做什么:self.size = self.width * x, self.height * y
。来自 kivy Widget docs:
size is a ReferenceListProperty of (width, height) properties.
这基本上意味着当您更新 size
属性 时,属性 width
和 height
也会更新。反之亦然。所以你是说:"Update the size by a percantage of the previous size" 并且 kivy 进入 "oh, this widget has a new size, better update width and height" 然后进入 "oh, this widget has a new height and width, better update its size" 等等,在一个无限循环中。
我希望这不会让您感到困惑,如果是的话,这里有一篇很好的 video 解释了属性在 kivy 中的工作原理。
如果答案对您来说还不是很明显:将第 39 行更改为 size: self.parent.width * 0.4, self.parent.height * 0.05
或 size: root.width * 0.4, root.height * 0.05
,具体取决于您要执行的操作。并且不要忘记将 size_hint: None, None
添加到该按钮,因为如果有 size_hint_x
或 size_hint_y
,您的 width
和 height
将分别被忽略。
现在是这样的:
SweetTruth fixed pic
我正在尝试使用 Kivy python 框架为 android 开发应用程序。目前我正在测试 Windows 并且当前代码(希望很快能够扫描条形码和其他东西)正在犯一个错误,它只是循环又循环,从不给出类似 TypeError 或类似的原因。
循环错误:
Traceback (most recent call last):
File "C:\Program Files (x86)\Python36-32\lib\site-packages\kivy\lang\builder.py", line 601, in _apply_rule
setattr(widget_set, key, value)
File "kivy\weakproxy.pyx", line 33, in kivy.weakproxy.WeakProxy.__setattr__ (kivy\weakproxy.c:1471)
File "kivy\properties.pyx", line 478, in kivy.properties.Property.__set__ (kivy\properties.c:5572)
File "kivy\properties.pyx", line 1342, in kivy.properties.ReferenceListProperty.set (kivy\properties.c:21169)
File "kivy\properties.pyx", line 494, in kivy.properties.Property.set (kivy\properties.c:6520)
File "kivy\properties.pyx", line 516, in kivy.properties.Property.set (kivy\properties.c:6405)
File "kivy\properties.pyx", line 571, in kivy.properties.Property.dispatch (kivy\properties.c:7105)
File "kivy\_event.pyx", line 1225, in kivy._event.EventObservers.dispatch (kivy\_event.c:14035)
File "kivy\_event.pyx", line 1107, in kivy._event.EventObservers._dispatch (kivy\_event.c:12788)
File "C:\Program Files (x86)\Python36-32\lib\site-packages\kivy\lang\builder.py", line 76, in call_fn
setattr(element, key, e_value)
File "kivy\weakproxy.pyx", line 33, in kivy.weakproxy.WeakProxy.__setattr__ (kivy\weakproxy.c:1471)
File "kivy\properties.pyx", line 478, in kivy.properties.Property.__set__ (kivy\properties.c:5572)
File "kivy\properties.pyx", line 1342, in kivy.properties.ReferenceListProperty.set (kivy\properties.c:21169)
File "kivy\properties.pyx", line 494, in kivy.properties.Property.set (kivy\properties.c:6520)
File "kivy\properties.pyx", line 516, in kivy.properties.Property.set (kivy\properties.c:6405)
File "kivy\properties.pyx", line 571, in kivy.properties.Property.dispatch (kivy\properties.c:7105)
File "kivy\_event.pyx", line 1225, in kivy._event.EventObservers.dispatch (kivy\_event.c:14035)
File "kivy\_event.pyx", line 1107, in kivy._event.EventObservers._dispatch (kivy\_event.c:12788)
File "C:\Program Files (x86)\Python36-32\lib\site-packages\kivy\lang\builder.py", line 76, in call_fn
setattr(element, key, e_value)
等等
这是我当前的代码:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ListProperty
from kivy.uix.screenmanager import ScreenManager, Screen
Builder.load_string("""
<ResultsScreen>:
id: rw
percentage: 50
FloatLayout:
canvas:
Color:
rgb: 1, 1, 1
Rectangle:
pos: self.pos
size: self.size
Color:
rgb: 0, 0, 0
Line:
circle: self.width * 0.5, self.height * 0.75, self.width * 0.40, 0, 360 * (rw.percentage / 100)
width: 15
cap: 'square'
joint: 'round'
Label:
id: percentage_label
text: '[color=#000000]' + str(rw.pecentage) + '%[/color]'
markup: True
pos_hint: {'center_x': 0.5, 'center_y': 0.75}
size_hint: 0.1, 0.1
halign: 'center'
valign: 'center'
Button:
text: 'Scan Again'
on_press: root.manager.current = 'camerascan'
size: self.width * 0.4, self.height * 0.05
pos_hint: {'center_x': 0.5, 'center_y': 0.1}
<CameraScreen>:
BoxLayout:
Button:
text: 'Cancel'
on_press: root.manager.current = 'results'
""")
class ResultsScreen(Screen):
pass
class CameraScreen(Screen):
pass
sm = ScreenManager()
sm.add_widget(CameraScreen(name='camerascan'))
sm.add_widget(ResultsScreen(name='results'))
class SweetTruthApp(App):
def build(self):
return sm
if __name__ == '__main__':
SweetTruthApp().run()
我不知道这个问题是什么或可能是什么,我对 Kivy 和 python 类 的想法不太满意,所以不胜感激。
你实际上 运行 陷入了递归问题(因此错误循环)。在我告诉你问题是什么之前,我想告诉你我是如何发现它的(我会给你一根钓鱼竿而不是给你鱼)。
该方法非常简单,您可以自己轻松完成,并为我们提供了有关问题所在的重要提示。技巧如下:您只需开始删除 .kv 语言字符串中的代码。它主要影响设计,因此程序无需大量代码即可运行良好。我删除了 CameraScreen
按钮 - 同样的错误。没有 ResultsScreen
canvas,标签 - 仍然是同样的错误。没有 ResultsScreen
按钮 - 一个不同的错误。您在第 29 行将 "percentage" 拼错为 "pecentage"。更正它 - 程序运行正常。使用相同的方法,您可能会发现错误在第 39 行:size: self.width * 0.4, self.height * 0.05
。为什么这里出错?现在这是我们本可以开始的真正问题,所以下次做功课吧(不要气馁 - 到目前为止,该应用程序看起来很有前途!)
想想你在这里做什么:self.size = self.width * x, self.height * y
。来自 kivy Widget docs:
size is a ReferenceListProperty of (width, height) properties.
这基本上意味着当您更新 size
属性 时,属性 width
和 height
也会更新。反之亦然。所以你是说:"Update the size by a percantage of the previous size" 并且 kivy 进入 "oh, this widget has a new size, better update width and height" 然后进入 "oh, this widget has a new height and width, better update its size" 等等,在一个无限循环中。
我希望这不会让您感到困惑,如果是的话,这里有一篇很好的 video 解释了属性在 kivy 中的工作原理。
如果答案对您来说还不是很明显:将第 39 行更改为 size: self.parent.width * 0.4, self.parent.height * 0.05
或 size: root.width * 0.4, root.height * 0.05
,具体取决于您要执行的操作。并且不要忘记将 size_hint: None, None
添加到该按钮,因为如果有 size_hint_x
或 size_hint_y
,您的 width
和 height
将分别被忽略。
现在是这样的: SweetTruth fixed pic