Kivy 屏幕管理器 kivy\properties.pyx KeyError 和 AttributeError:“super”对象没有属性“__getattr__”。您的意思是:“__setattr__”吗?

问题描述 投票:0回答:1

我在尝试使用 Kivy 实现屏幕管理器时遇到了问题。正如您所看到的“聊天”id 是在 main.kv 中定义的,所以我无法理解为什么会发生错误。我是 Kivy 的新手,以前从未使用过屏幕管理器..请帮忙!

app_cleaned.py

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.core.window import Window
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.clock import mainthread

from range_key_dict import RangeKeyDict

from math import inf

from threading import Thread

from powerBot import ChatBot

#remove
from kivy.clock import Clock

Window.size = (500, 500)

class SignupScreen(Screen):
    pass

class MainScreen(Screen):
    pass

class Message(Label):
    pass

class User:
    def __init__(self, years_lifting, weight, height, unavailable_equipment, unavailable_muscle_groups, aim):

        # Lifting experience classification
        expClassDict = RangeKeyDict({
            (0.0, 1.9): 1, # beginner
            (2.0, 3.9): 2, # intermediate
            (4, inf): 3 # advanced
        })
        expClass = expClassDict[years_lifting]

        # BMI classification
        bmiClassDict = RangeKeyDict({
            (0.0, 9.9): 1, # severely underweight
            (10.0, 18.5): 2, # underweight
            (18.6, 24.9): 3, # healthy weight
            (25.0, 34.9): 2, # overweight
            (35.0, inf): 1, # severely overweight
        })
        bmi = weight/(height/100)**2 # calculate BMI
        bmiClass = bmiClassDict[bmi]

        self.experience_level = expClass
        self.bmi_level = bmiClass
        self.unavailable_equipment = unavailable_equipment
        self.unavailable_muscle_groups = unavailable_muscle_groups
        self.aim = aim



class ExampleApp(App):
    def build(self):
        sm = ScreenManager()

        # Load the signup.kv file and add its content to the SignupScreen
        Builder.load_file('signup.kv')

        # Create the SignupScreen instance and add it to the ScreenManager
        signup_screen = SignupScreen(name='signup')
        sm.add_widget(signup_screen)
        
        # Load the main application screen from main.kv
        Builder.load_file('main.kv')
        main_screen = MainScreen(name='main')
        sm.add_widget(main_screen)

        return sm

    def switch_to_main_screen(self):
        self.root.current = 'main'
    
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.ai = ChatBot("PowerBot")

    def on_start(self):
        print("Root IDs:", self.root.ids)
        # Assuming you expect 'chat' to be available here, you can print its contents as well
        if 'chat' in self.root.ids:
            print("Chat Widget:", self.root.ids.chat)
        self.root.current = 'signup'
        initial_messages = ["PowerBot is initializing, please wait (this could take a minute)"]
        for message in initial_messages:
            self.system_message(message)
        message = "000000"
        thread = Thread(target=self.background_message_receiver,args=(message,))
        thread.start()
        self.root.ids.sv.scroll_y = 0

    def sign_up(self, years_lifting, weight, height):
        # Convert input values to appropriate data types (e.g., int, float)
        years_lifting = float(years_lifting)
        weight = float(weight)
        height = float(height)

        # Create a User object with the provided sign-up details
        user = User(years_lifting, weight, height)  # Pass other sign-up details as needed

        self.root.ids.years_lifting_input.text = ''
        self.root.ids.weight_input.text = ''
        self.root.ids.height_input.text = ''

    def background_message_receiver(self, message):
        response = self.ai.message_to_bot(message)
        self.incoming_message(response)

    def send_message(self, message):
        self.root.ids.ti.text = ""
        if message:
            m = Message(text=f"[color=dd2020]You[/color] > {message}")
            self.root.ids.chat.add_widget(m)
            self.root.ids.ti.focus = True
            thread = Thread(target=self.background_message_receiver,args=(message,))
            thread.start()

    @mainthread
    def incoming_message(self, message):
        m = Message(text=f"[color=20dd20]PowerBot[/color] > {message}")
        self.root.ids.chat.add_widget(m)
        self.root.ids.ti.focus = True

    def system_message(self, message):
        m = Message(text=f"[color=ffffff]System[/color] > {message}")
        self.root.ids.chat.add_widget(m)
        self.root.ids.ti.focus = True
    
# Execute
if __name__ == '__main__':
    ExampleApp().run()

主.kv

<Message>:
    size_hint: 1, None
    text_size: self.width, None
    size: self.texture_size
    markup: True
    
<MainScreen>:
    BoxLayout:
        orientation: 'vertical'
        padding: 10
        ScrollView:
            id: sv
            BoxLayout:
                id: chat  # Add the ID for the chat messages
                spacing: 5
                padding: 10
                orientation: 'vertical'
                size_hint_y: None
                height: self.minimum_height
                Widget: # used as a spacer, push message to bottom
                    size_hint_y: None
                    height: sv.height
        BoxLayout:
            size_hint_y: None
            height: 40
            spacing: 10
            TextInput:
                id: ti
                multiline: False
                on_text_validate: app.send_message(self.text)
            Button:
                text: 'submit'
                size_hint_x: None
                width: 75
                on_release: app.send_message(ti.text)

注册.kv

<SignupScreen>:
    BoxLayout:
        orientation: 'vertical'
        padding: 10
        
        Button:
            text: 'Continue'
            size_hint_y: None
            height: '48dp'
            on_release: app.switch_to_main_screen()

我在这里看到了关于类似问题的其他问题,但不幸的是我对 Kivy 不够熟练,无法将解决方案应用于我的特定场景。

python kivy kivy-language
1个回答
0
投票

您的

chat
id 在
MainScreen
类中定义,但您试图在
self.root.ids
ExampleApp
中访问它。由于该 id 是在
<MainScreen>
规则中定义的,因此您必须通过
MainScreen
实例访问它。一种方法是仅保存对
MainScreen
实例的引用。在您的
build()
方法中,您可以更改:

    # Load the main application screen from main.kv
    Builder.load_file('main.kv')
    main_screen = MainScreen(name='main')
    sm.add_widget(main_screen)

至:

    # Load the main application screen from main.kv
    Builder.load_file('main.kv')
    self.main_screen = MainScreen(name='main')
    sm.add_widget(self.main_screen)

然后,在任何非静态

ExampleApp
方法内的任何位置,您都可以访问
chat
id,如下所示:

self.main_screen.ids.chat
© www.soinside.com 2019 - 2024. All rights reserved.