如何从字典中添加按钮,但前提是字典声明它已启用?

How to add buttons from a dictionary but only if the dictionary states it's enabled?

我正在使用 Raspberry Pi 构建饮料机并使用 Kivy 构建 UI。 如果“启用”了每种所需成分的泵,我只想在主屏幕上显示可用的饮料。如果将制作饮料所需的任何成分分配给未启用的泵,那么我不希望创建该饮料的按钮。简而言之,只应显示具有所有必需成分“已启用:True”的饮料。作为 python 和 kivy 的新手,我找不到办法做到这一点。这是我目前所拥有的...

main.py:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from kivy.app import App
from kivy.config import Config
from kivy.clock import *

Config.set('graphics', 'width', '480')
Config.set('graphics', 'height', '800')
Config.set('kivy', 'keyboard_mode', 'dock')
from kivy.uix.screenmanager import *
from kivy.uix.button import *
from kivy.uix.label import *
from kivy.clock import *

pinList = [11, 13, 15, 19, 21, 23, 29, 31, 33, 35, 37, 38, 36, 32, 26, 24]

drink_list = {'Rum & Pepsi': {'ingredients': {'Rum': 50, 'Pepsi': 100}},
              'Cherry Pepsi': {'ingredients': {'Cherry syrup': 40, 'Pepsi': 150}},
              'Lemon Pepsi': {'ingredients': {'Lemon Syrup': 10, 'Pepsi': 113}}}

test_list = {
    'Pump 1': {'Pin': [11], 'Ingredient': ['Pepsi'], 'Pumptime': [0.15], 'Enabled': [True]},
    'Pump 2': {'Pin': [13], 'Ingredient': ['Rum'], 'Pumptime': [0.15], 'Enabled': [True]},
    'Pump 3': {'Pin': [15], 'Ingredient': ['Cherry syrup'], 'Pumptime': [0.15], 'Enabled': [True]},
    'Pump 4': {'Pin': [19], 'Ingredient': ['Lemon syrup'], 'Pumptime': [0.15], 'Enabled': [True]},
    'Pump 5': {'Pin': [21], 'Ingredient': ['Unused'], 'Pumptime': [0.15], 'Enabled': [True]},
    'Pump 6': {'Pin': [23], 'Ingredient': ['Unused'], 'Pumptime': [0.15], 'Enabled': [True]},
    'Pump 7': {'Pin': [29], 'Ingredient': ['Unused'], 'Pumptime': [0.15], 'Enabled': [True]},
    'Pump 8': {'Pin': [31], 'Ingredient': ['Unused'], 'Pumptime': [0.15], 'Enabled': [True]},
    'Pump 9': {'Pin': [33], 'Ingredient': ['Unused'], 'Pumptime': [0.15], 'Enabled': [True]},
    'Pump 10': {'Pin': [35], 'Ingredient': ['Unused'], 'Pumptime': [0.15], 'Enabled': [True]},
    'Pump 11': {'Pin': [37], 'Ingredient': ['Unused'], 'Pumptime': [0.15], 'Enabled': [True]},
    'Pump 12': {'Pin': [38], 'Ingredient': ['Unused'], 'Pumptime': [0.15], 'Enabled': [True]},
    'Pump 13': {'Pin': [36], 'Ingredient': ['Unused'], 'Pumptime': [0.15], 'Enabled': [True]},
    'Pump 14': {'Pin': [32], 'Ingredient': ['Unused'], 'Pumptime': [0.15], 'Enabled': [True]},
    'Pump 15': {'Pin': [26], 'Ingredient': ['Unused'], 'Pumptime': [0.15], 'Enabled': [True]},
    'Pump 16': {'Pin': [24], 'Ingredient': ['Unused'], 'Pumptime': [0.15], 'Enabled': [True]}
}

class HomeScreen(Screen):

    @mainthread
    def on_enter(self):

        # add drink buttons (only if needed pumps are enabled)
        for drink in drink_list:
            ingredients_needed = [*(drink_list[drink]['ingredients'])]
            for x in ingredients_needed:
                for pump in test_list.keys():
                    if x in test_list[pump]['Ingredient'] and test_list[pump]['Enabled'] == [True]:
                        print('yes')
                        button = Button(text=drink, size_hint=(None, None))
                        self.ids.grid1.add_widget(button)
                    else:
                        pass


        # add settings button
        button = Button(text='Settings Page', size_hint=(None, None))
        button.bind(on_press=self.go_first_screen)
        self.ids.grid1.add_widget(button)

    def go_first_screen(self, event):
        self.manager.current = 'settings_screen'


class SettingsScreen(Screen):

    @mainthread
    def on_enter(self):
        # Drink Manager Tab
        for drink in drink_list:
            drink_buttons = Button(text=str(drink), size_hint=(None, None))
            self.ids.grid.add_widget(drink_buttons)
        btn = Button(text='Change Screen', size_hint=(None, None))
        self.ids.grid.add_widget(btn)

        # Pump Assignment Tab
        for pump in test_list:
            pump_buttons = Button(text=str(pump) + ' - \n ' + str(*test_list[pump]['Ingredient']), size_hint=(None, None))
            self.ids.pump_grid.add_widget(pump_buttons)

    def on_leave(self, *args):
        self.ids.grid.clear_widgets()


class Test(App):
    pass


Test().run()

test.kv...

#:kivy 1.9.0
ScreenManager:
    HomeScreen:
    SettingsScreen:

<HomeScreen>:
    name: 'home_screen'

    StackLayout:
        id: grid1
        orientation: 'lr-tb'
        padding: 10
        spacing: 5

<SettingsScreen>:
    name: 'settings_screen'

    TabbedPanel:
        do_default_tab: False
        tab_pos: 'top_mid'
        tab_height: 70
        tab_width: self.width/3
        canvas.before:
            Color:
                rgba: 1, 1, 1, 1
            Rectangle:
                pos: self.pos
                size: self.size

        TabbedPanelItem:
            text: 'Drink Manager'

            StackLayout:
                id: grid
                orientation: 'lr-tb'
                padding: 10
                spacing: 10

        TabbedPanelItem:
            text: 'Pump Assignment'

            StackLayout:
                id: pump_grid
                orientation: 'lr-tb'
                padding: 15
                spacing: 15

目前它正在为每种饮料创建 2 个按钮(出于某种原因,柠檬除外?)我只需要为每种饮料创建 1 个按钮:

为什么您当前会收到重复的按钮

我在应该创建按钮的地方添加了一个 print 语句,执行代码并看到以下结果:

drink=Rum & Pepsi, x=Rum, pump=Pump 2
drink=Rum & Pepsi, x=Pepsi, pump=Pump 1
drink=Cherry Pepsi, x=Cherry syrup, pump=Pump 3
drink=Cherry Pepsi, x=Pepsi, pump=Pump 1
drink=Lemon Pepsi, x=Lemon Syrup, pump=[no pump]
drink=Lemon Pepsi, x=Pepsi, pump=Pump 1

这表明您正在为饮料中的每种成分创建按钮。此外,对于柠檬百事可乐,您找不到“柠檬糖浆”泵,因为 drink_list Syrup 是大写的。

如何修复

例如像这样:

class HomeScreen(Screen):

    @mainthread
    def on_enter(self):

        # either define this function here, or at module level,
        # or as a @staticmethod in this class
        def _get_pump_by_ingredient(ingredient):
            for name, pump in test_list.items():
                if pump["Ingredient"] == [ingredient]:
                    return pump

        for drink in drink_list:
            ingredients_needed = [*(drink_list[drink]['ingredients'])]
            if all(_get_pump_by_ingredient(item)["Enabled"] == [True]
                   for item
                   in ingredients_needed):
                  print('yes')
                  button = Button(text=drink, size_hint=(None, None))
                  self.ids.grid1.add_widget(button)

        # add settings button
        ...

请注意,如果找不到泵(例如“柠檬糖浆”),上述代码将抛出异常,但这可能是件好事。

更多反馈

  • 创建一个 Pump class 可能有意义,因为 dict 在这种复杂程度下很尴尬
  • 你把很多东西放到单元素列表中有点奇怪('Pumptime': [0.15] 而不仅仅是 'Pumptime': 0.15