Kivy食谱应用问题:食材齐全但点击Pot按钮无对应餐品显示
问题:Kivy食谱应用点击"pot"按钮错误提示"No meals can be made"
我正在开发一款基于Kivy的食谱应用,当我的ingredients_list中包含制作餐品所需的全部食材时,点击"pot"按钮却弹出"No meals can be made"的提示。我尝试过调整ingredients_list中的食材,但问题依然存在。
以下是我的代码:
from kivy.app import App from kivy.uix.button import Button from kivy.uix.floatlayout import FloatLayout from kivy.uix.image import Image from kivy.uix.popup import Popup from kivy.uix.label import Label from kivy.uix.textinput import TextInput from kivy.uix.boxlayout import BoxLayout from kivy.uix.gridlayout import GridLayout from kivy.uix.dropdown import DropDown class IngredientPopup(Popup): def __init__(self, **kwargs): super(IngredientPopup, self).__init__(**kwargs) def load_ingredients_list(self): # Ingredients list ingredients_list = ['salt', 'pepper', 'sugar', 'flour', 'rice', 'chicken', 'carrots', 'onion'] # Update the label to display the current ingredients list self.current_ingredients_label.text = 'Current Ingredients:\n' + '\n'.join(ingredients_list) def update_ingredient_list(self, instance): # Update the list of ingredients displayed in the pop-up window self.load_ingredients_list() class RemoveIngredientPopup(Popup): def __init__(self, **kwargs): super(RemoveIngredientPopup, self).__init__(**kwargs) def load_ingredients_list(self): # Ingredients ingredients_list = ['salt', 'pepper', 'sugar', 'flour', 'rice', 'chicken', 'carrots', 'onion'] # Add the ingredients to the dropdown menu for ingredient in ingredients_list: self.ingredient_dropdown.add_widget(Button(text=ingredient, on_release=self.remove_ingredient, size_hint_y=None, height=44)) class Pot(Button): def __init__(self, **kwargs): super().__init__(**kwargs) self.opacity = 1 self.size_hint = (None, None) self.size = (0, 0) def on_press(self): ingredients = ['rice', 'chicken', 'carrots', 'onion'] meals = ['chicken and rice', 'chicken stew', 'chicken curry'] possible_meals = [meal for meal in meals if set(ingredients).issuperset(set(meal.split()))] content = Label(text='\n'.join(possible_meals) if possible_meals else 'No meals can be made') popup = Popup(title='Possible Meals', content=content, size_hint=(0.8, 0.8)) popup.open() class MyApp(App): def build(self): # Create the main layout layout = FloatLayout() # Create the background image background = Image(source='C:/Users/Nikola/Desktop/KuhinjaV2.jpg') # Create the buttons button4 = Pot(text='pot') # Position the buttons on top of the background image button4.pos_hint = {'x': 0.094, 'y': 0.38} button4.size_hint = (0.07, 0.07) # Add the background and buttons to the layout layout.add_widget(background) layout.add_widget(button4) return layout if __name__ == '__main__': MyApp().run()
问题分析
- 餐品匹配逻辑错误:你在
Pot类的on_press方法中,直接把餐名字符串按空格分割成食材集合,比如'chicken and rice'会被分割成{'chicken', 'and', 'rice'},但你的ingredients列表里没有'and'这个食材,导致set(ingredients).issuperset(...)始终返回False,没有匹配的餐品。 - 食材列表不共享:弹窗里的
ingredients_list和Pot类里的ingredients是完全独立的两个列表,你修改前者不会影响后者的判断逻辑,相当于判断时用的是硬编码的固定列表,不是你调整后的内容。
解决方法
1. 修正餐品匹配逻辑
不要直接分割餐名,改用字典明确存储每个餐品对应的所需食材,这样能精准匹配:
class Pot(Button): def __init__(self, **kwargs): super().__init__(**kwargs) self.opacity = 1 self.size_hint = (None, None) self.size = (0, 0) def on_press(self): # 这里先暂时用弹窗里的完整食材列表,后续改成共享列表 ingredients = {'salt', 'pepper', 'sugar', 'flour', 'rice', 'chicken', 'carrots', 'onion'} # 用字典存储餐品和对应的必需食材 meals = { 'chicken and rice': {'chicken', 'rice'}, 'chicken stew': {'chicken', 'carrots', 'onion'}, 'chicken curry': {'chicken', 'onion'} } # 筛选出当前食材能制作的餐品 possible_meals = [meal for meal, required_ingredients in meals.items() if ingredients.issuperset(required_ingredients)] content = Label(text='\n'.join(possible_meals) if possible_meals else 'No meals can be made') popup = Popup(title='Possible Meals', content=content, size_hint=(0.8, 0.8)) popup.open()
2. 实现共享食材列表
把食材列表变成全局共享的,让弹窗的修改能同步到Pot的判断逻辑中:
class MyApp(App): def build(self): # 定义共享的食材集合(用集合方便后续判断) self.ingredients = {'salt', 'pepper', 'sugar', 'flour', 'rice', 'chicken', 'carrots', 'onion'} layout = FloatLayout() background = Image(source='C:/Users/Nikola/Desktop/KuhinjaV2.jpg') button4 = Pot(text='pot') button4.pos_hint = {'x': 0.094, 'y': 0.38} button4.size_hint = (0.07, 0.07) layout.add_widget(background) layout.add_widget(button4) return layout
然后在Pot类中调用这个共享列表:
def on_press(self): # 获取当前应用的共享食材集合 ingredients = App.get_running_app().ingredients meals = { 'chicken and rice': {'chicken', 'rice'}, 'chicken stew': {'chicken', 'carrots', 'onion'}, 'chicken curry': {'chicken', 'onion'} } possible_meals = [meal for meal, required in meals.items() if ingredients.issuperset(required)] content = Label(text='\n'.join(possible_meals) if possible_meals else 'No meals can be made') popup = Popup(title='Possible Meals', content=content, size_hint=(0.8, 0.8)) popup.open()
3. 修复弹窗的增删逻辑
当前弹窗只是显示硬编码的食材,没有实际修改共享列表,以RemoveIngredientPopup为例,添加实际删除逻辑:
class RemoveIngredientPopup(Popup): def __init__(self, **kwargs): super(RemoveIngredientPopup, self).__init__(**kwargs) self.load_ingredients_list() def load_ingredients_list(self): # 清空下拉菜单旧内容 self.ingredient_dropdown.clear_widgets() # 获取共享食材列表 ingredients = App.get_running_app().ingredients # 添加食材到下拉菜单 for ingredient in ingredients: self.ingredient_dropdown.add_widget(Button(text=ingredient, on_release=self.remove_ingredient, size_hint_y=None, height=44)) def remove_ingredient(self, instance): # 从共享列表中删除选中的食材 ingredients = App.get_running_app().ingredients ingredients.remove(instance.text) # 更新下拉菜单显示 self.load_ingredients_list()
内容的提问来源于stack exchange,提问作者Sythee
相关产品推荐
相关产品推荐

