简体   繁体   中英

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)

I'm am trying to develop an app for android with the Kivy python framework. Currently I am testing on Windows and the current code (that will hopefully soon be able to scan barcodes and stuff) is making an error that just loops around and around, never giving a reason like TypeError or similar.

Looped Error:

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)

etc.

Here's my current code:

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()

I have no idea what the probelm is or could be and I'm not great with Kivy and the idea of python classes in general so help is appreciated.

You actually ran into a recursion problem (hence the error looping). Before I tell you what the problem is I'd like to show you how I discovered it myself (I'll give you a fishing rod instead of giving you the fish).

The method is so simple you could have easily done it yourself and given us a big hint as to where the problem lies. Here's the trick: you just start removing code in the .kv language string. It mostly affects the design so the program runs fine without a chunk of the code. I deleted the CameraScreen button - same error. No ResultsScreen canvas, label - same error still. No ResultsScreen button - a different error. You misspelled "percentage" as "pecentage" on line 29. Correct it - the program runs fine. Using the same method you could have figured out that the error is on line 39: size: self.width * 0.4, self.height * 0.05 . Why an error here? Now that is the real question here that we could have started with, so do your homework next time (not to discourage you - the app looks promising so far!)

Think about what you're doing here: self.size = self.width * x, self.height * y . From the kivy Widget docs :

size is a ReferenceListProperty of (width, height) properties.

What this basically means is that when you update size property, the properties width and height are updated as well. And vice-versa. So you're saying: "Update the size by a percantage of the previous size" and kivy goes "oh, this widget has a new size, better update width and height" and then goes "oh, this widget has a new height and width, better update its size" and on, and on, in an infinite loop.

I hope this wasn't confusing to you, if it was, here's an excellent video explaining how properties work in kivy.

If the answer isn't obvious to you already: change line 39 to either size: self.parent.width * 0.4, self.parent.height * 0.05 or to size: root.width * 0.4, root.height * 0.05 , depending on what you are trying to do. And don't forget to add size_hint: None, None to that button as your width and height are ignored respectively if there is a size_hint_x or a size_hint_y .

Here's how it looks now: SweetTruth fixed pic

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM