我在尝试使用 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 不够熟练,无法将解决方案应用于我的特定场景。
您的
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