簡體   English   中英

訪問 kivy 文件中的 python 列表

[英]Access python list in kivy file

我是物理學家,眾所周知,我們喜歡我們的雞尾酒。 因此,我正在嘗試建立一個自動調酒師。 不幸的是,我在 python 中編程的唯一經驗是進行物理模擬,而且我對編碼並不是那么精通。

My problem is now this: there is a python list in the class BartenderApp that I want to use in the kivy file, specifically in the LoadNewIngredients in the kivy file, for the spinners to take their options from. 我已經尋找了很長一段時間的解決方案,但到目前為止還沒有一個有效的解決方案。 我知道我應該能夠使用 for 循環將微調器和標簽放入 python 文件中,但我更希望它更干凈一些並將它們保留在 kivy 文件中。

因此,如果有人可以幫助我如何將列表傳遞給 kivy 文件,將不勝感激!

這是.py 文件:

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.core.window import Window
from kivy.uix.button import Button
from kivy.clock import mainthread
from functools import partial
#Import drink list
from drinks import drink_list, drink_options

class drink:
    def __init__(self,name,ingredients,amount):
        self.name = name
        self.ingredients = ingredients
        self.amount = amount

#Define the different screens
class MainMenu(Screen):
    pass

class UseLastIngredients(Screen):
    pass

class DrinkMenu(Screen):

    #Mainthread will pause shortly to give script time, the rest adds the buttons
    @mainthread
    def on_enter(self):
        self.buttons = []
        self.ids.drinks.clear_widgets()
        for btn in range(len(drink_list)):
            self.buttons.append(Button(text=str(drink_list[btn]['name'])))
            self.buttons[btn].bind(on_press = self.pour_drink)
            self.ids.drinks.add_widget(self.buttons[btn])


    def pour_drink(self, button):
        print(button.text)


class LoadNewIngredients(Screen):
    def spinner_clicked(self, ident, value):
        if ident == 1:
            pass
        if ident == 2:
            pass
        if ident == 3:
            pass
        if ident == 4:
            pass
        if ident == 5:
            pass
        if ident == 6:
            pass
        if ident == 7:
            pass
        if ident == 8:
            pass


#Define the ScreenManager
class MenuManager(ScreenManager):
    pass

#Designate the .kv design file
kv = Builder.load_file('bartenderkv.kv')

class BartenderApp(App):

    #I want to use the ingredients list in the kivy file
    global ingredients
    ingredients = []
    for drink in range(len(drink_list)):
        ings = list(drink_list[drink]['ingredients'].keys())
        for ing in range(len(ings)):
            elem = ings[ing]
            if elem not in ingredients:
                ingredients.append(elem)

    def build(self):
        return kv

if __name__ == '__main__':
    BartenderApp().run()

這是.kv 文件:

#:import Factory kivy.factory.Factory
#:import ScrollView kivy.uix.scrollview

MenuManager:
    MainMenu:
    LoadNewIngredients:
    DrinkMenu:

<MainMenu>:
    name: "MainMenu"
    GridLayout:
        rows: 3
        size: root.width, root.height
        padding: 10
        spacing: 10

        Label:
            text: "Main Menu"
            font_size: 32

        GridLayout:
            cols: 2
            size: root.width, root.height
            spacing: 10
            Button:
                text: "Use Last Ingredients"
                font_size: 32
                on_release: app.root.current = "DrinkMenu"
            Button:
                text: "Load New Ingredients"
                font_size: 32
                on_release: app.root.current = "LoadNewIngredients"
        Button:
            text: "See Permissable Ingredients"
            font_size: 32
            #on_press: print("It Works")
            on_release: Factory.PermissablePopup().open()

<LoadNewIngredients>:
    name: "LoadNewIngredients"
    GridLayout:
        cols: 2
        size: root.width, root.height
        padding: 10
        spacing: 10

        GridLayout:
            size: root.width, root.height
            size_hint_x: 0.4
            rows: 2
            Button:
                text: "Continue"
                font_size: 24
                on_release: app.root.current = "DrinkMenu"
            Button:
                text: "Main Menu"
                font_size: 24
                on_release: app.root.current = "MainMenu"
        GridLayout:
            
            #This is where I want the spinners to take in the ingredients list as options.

            id: choices
            rows: 4
            orientation: 'tb-lr'
            Label:
                id: pump_1
                text: "Pump 1"
                font_size: 24
            Label:
                id: pump_2
                text: "Pump 2"
                font_size: 24
            Label:
                id: pump_3
                text: "Pump 3"
                font_size: 24
            Label:
                id: pump_4
                text: "Pump 4"
                font_size: 24
            #Spinner is the easy drop down version in kivy, lets see how it looks.
            Spinner:
                id: spinner_id_1
                text: "Pump_1"
                values: ["1", "2", "3"]
                on_text: root.spinner_clicked(1,spinner_id_1.text)

            Spinner:
                id: spinner_id_2
                text: "Pump_2"
                values: ["1", "2", "3"]
                on_text: root.spinner_clicked(2,spinner_id_2.text)

            Spinner:
                id: spinner_id_3
                text: "Pump_3"
                values: ["1", "2", "3"]
                on_text: root.spinner_clicked(3,spinner_id_3.text)

            Spinner:
                id: spinner_id_4
                text: "Pump_4"
                values: ["1", "2", "3"]
                on_text: root.spinner_clicked(4,spinner_id_4.text)

            Label:
                id: pump_5
                text: "Pump 5"
                font_size: 24
            Label:
                id: pump_6
                text: "Pump 6"
                font_size: 24
            Label:
                id: pump_7
                text: "Pump 7"
                font_size: 24
            Label:
                id: pump_8
                text: "Pump 8"
                font_size: 24
            #Spinner is the drop down version, lets see how it looks.
            Spinner:
                id: spinner_id_5
                text: "Pump_5"
                values: ["1", "2", "3"]
                on_text: root.spinner_clicked(5,spinner_id_5.text)

            Spinner:
                id: spinner_id_6
                text: "Pump_6"
                values: ["1", "2", "3"]
                on_text: root.spinner_clicked(6,spinner_id_6.text)

            Spinner:
                id: spinner_id_7
                text: "Pump_7"
                values: ["1", "2", "3"]
                on_text: root.spinner_clicked(7,spinner_id_7.text)

            Spinner:
                id: spinner_id_8
                text: "Pump_8"
                values: ["1", "2", "3"]
                on_text: root.spinner_clicked(8,spinner_id_8.text)

<DrinkMenu>:
    name: "DrinkMenu"
    GridLayout:
        cols: 2
        width: root.width
        height: self.minimum_height
        padding: 10
        spacing: 10
        GridLayout:
            height: root.height
            size_hint_x: 0.4
            rows: 2
            Button:
                text: "Top Up"
                font_size: 24
                on_release:
            Button:
                text: "Main Menu"
                font_size: 24
                on_release: app.root.current = "MainMenu"
        ScrollView:
            size_hint_y: 0.73
            pos_hint: {'x':0, 'y': 0.11}
            do_scroll_x: False
            do_scroll_y: True

            GridLayout:
                id: drinks
                orientation: 'lr-tb'
                size_hint_y: None
                size_hint_x: 1.0
                cols: 3
                height: self.minimum_height
                row_default_height: 180
                row_force_default: True

#Create a rounded button, the @Button is what it inherits
<RoundedButton@Button>
    background_color: (0,0,0,0)
    background_normal: ''
    canvas.before:
        Color:
            rgba:
                (48/255,84/255,150/255,1)\
                if self.state == 'normal' else (0.6,0.6,1,1) # Color is red if button is not pressed, otherwise color is green
        RoundedRectangle:
            size: self.size
            pos: self.pos
            radius: [58]

<PermissablePopup@Popup>
    auto_dismiss: False
    #size_hint: 0.6,0.2
    #pos_hint: {"x":0.2, "top":0.9}
    title: "Permissable Ingredients"
    GridLayout:
        rows: 2
        size: root.width, root.height
        spacing: 10
        GridLayout:
            cols: 2
            Label:
                text: "Sodas"
                font_size: 32
                #Add list of sodas
            Label:
                text: "Alcohol"
                font_size: 32
                #Add list of alcohols

        Button:
            text: "Done"
            font_size: 24
            on_release: root.dismiss()

嘗試向您的應用程序 class 添加 ListProperty ( https://kivy.org/doc/stable/api-kivy.properties.html )。 像這樣:

class BartenderApp(App):

    ingredients = ListProperty() 
    
    for drink in range(len(drink_list)):
        ings = list(drink_list[drink]['ingredients'].keys())
        for ing in range(len(ings)):
            elem = ings[ing]
            if elem not in self.ingredients:
                self.ingredients.append(elem)

在 Python 和 KV 文件中都可以訪問列表屬性。 更重要的是,它們可以綁定到回調,以便您可以創建自己的事件!

在 KV 文件中,您現在可以引用app.ingredients並且列表定義的任何 object 將在app.ingredients更改時自動更新。 例如,如果您的 KV 文件中有以下 label:

Label:
    text: app.ingredients[0]

當您更改列表時,文本會自動更新。 但請注意,如果您引用的索引中沒有 object,您可能會遇到索引錯誤。

讓我知道你是如何處理這個問題的,以及它是否能解決你的問題。

我終於設法解決了它,也許不是最好的解決方案,但它確實有效。

在 class LoadNewIngredients 中,我寫了一個 function 檢查哪些成分可用並返回一個包含成分的列表。 然后使用 root.function_name() 在 kivy 應用程序中引用此 function。

.py 文件:

#Everything needed for kivy
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.core.window import Window
from kivy.uix.button import Button
from kivy.clock import mainthread
from functools import partial
#Import drink list
from drinks import drink_list, drink_options

class drink:
    def __init__(self,name,ingredients,amount):
        self.name = name
        self.ingredients = ingredients
        self.amount = amount

#Define the different screens
class MainMenu(Screen):
    pass

class UseLastIngredients(Screen):
    pass

class DrinkMenu(Screen):

    #Mainthread will pause shortly to give script time, the rest adds the buttons
    @mainthread
    def on_enter(self):
        self.buttons = []
        self.ids.drinks.clear_widgets()
        for btn in range(len(drink_list)):
            self.buttons.append(Button(text=str(drink_list[btn]['name'])))
            self.buttons[btn].bind(on_press = self.pour_drink)
            self.ids.drinks.add_widget(self.buttons[btn])

    def pour_drink(self, button):
        print(button.text)

class LoadNewIngredients(Screen):
    def spinner_clicked(self, ident, value):
        if ident == 1:
            pass
        if ident == 2:
            pass
        if ident == 3:
            pass
        if ident == 4:
            pass
        if ident == 5:
            pass
        if ident == 6:
            pass
        if ident == 7:
            pass
        if ident == 8:
            pass
    #I want to use the ingredients list in the kivy file
    def get_ingredients(self,*args,**kwargs):
        global ingredients
        ingredients = []
        for drink in range(len(drink_list)):
            ings = list(drink_list[drink]['ingredients'].keys())
            for ing in range(len(ings)):
                elem = ings[ing]
                if elem not in ingredients:
                    ingredients.append(elem)
        return ingredients


#Define the ScreenManager
class MenuManager(ScreenManager):
    pass

#Designate the .kv design file
kv = Builder.load_file('bartenderkv.kv')

class BartenderApp(App):

    def build(self):
        return kv

if __name__ == '__main__':
    BartenderApp().run()

這是.kv 文件:

#Need to define everything, the ScreenManager is the entity that keeps tabs
#on all the different menu windows

#This is for the popup, lets you instansiate a class from anywhere
#:import Factory kivy.factory.Factory
#:import ScrollView kivy.uix.scrollview

MenuManager:
    MainMenu:
    LoadNewIngredients:
    DrinkMenu:

<MainMenu>:
    name: "MainMenu"
    GridLayout:
        rows: 3
        size: root.width, root.height
        padding: 10
        spacing: 10

        Label:
            text: "Main Menu"
            font_size: 32

        GridLayout:
            cols: 2
            size: root.width, root.height
            spacing: 10
            Button:
                text: "Use Last Ingredients"
                font_size: 32
                on_release: app.root.current = "DrinkMenu"
            Button:
                text: "Load New Ingredients"
                font_size: 32
                on_release: app.root.current = "LoadNewIngredients"
        Button:
            text: "See Permissable Ingredients"
            font_size: 32
            on_release: Factory.PermissablePopup().open()

<LoadNewIngredients>:
    name: "LoadNewIngredients"
    GridLayout:
        cols: 2
        size: root.width, root.height
        padding: 10
        spacing: 10
        #size hint sets relative sized, x-dir, y-dir
        GridLayout:
            size: root.width, root.height
            size_hint_x: 0.4
            rows: 2
            Button:
                text: "Continue"
                font_size: 24
                on_release: app.root.current = "DrinkMenu"
            Button:
                text: "Main Menu"
                font_size: 24
                on_release: app.root.current = "MainMenu"
        GridLayout:
            id: choices
            rows: 4
            orientation: 'tb-lr'
            Label:
                id: pump_1
                text: "Pump 1"
                font_size: 24
            Label:
                id: pump_2
                text: "Pump 2"
                font_size: 24
            Label:
                id: pump_3
                text: "Pump 3"
                font_size: 24
            Label:
                id: pump_4
                text: "Pump 4"
                font_size: 24
            Spinner:
                id: spinner_id_1
                text: "Pump_1"
                #This references the get_ingredients function in the main py file
                values: root.get_ingredients()
                on_text: root.spinner_clicked(1,spinner_id_1.text)

            Spinner:
                id: spinner_id_2
                text: "Pump_2"
                values: root.get_ingredients()
                on_text: root.spinner_clicked(2,spinner_id_2.text)

            Spinner:
                id: spinner_id_3
                text: "Pump_3"
                values: root.get_ingredients()
                on_text: root.spinner_clicked(3,spinner_id_3.text)

            Spinner:
                id: spinner_id_4
                text: "Pump_4"
                values: root.get_ingredients()
                on_text: root.spinner_clicked(4,spinner_id_4.text)

            Label:
                id: pump_5
                text: "Pump 5"
                font_size: 24
            Label:
                id: pump_6
                text: "Pump 6"
                font_size: 24
            Label:
                id: pump_7
                text: "Pump 7"
                font_size: 24
            Label:
                id: pump_8
                text: "Pump 8"
                font_size: 24
            Spinner:
                id: spinner_id_5
                text: "Pump_5"
                values: root.get_ingredients()
                on_text: root.spinner_clicked(5,spinner_id_5.text)

            Spinner:
                id: spinner_id_6
                text: "Pump_6"
                values: root.get_ingredients()
                on_text: root.spinner_clicked(6,spinner_id_6.text)

            Spinner:
                id: spinner_id_7
                text: "Pump_7"
                values: root.get_ingredients()
                on_text: root.spinner_clicked(7,spinner_id_7.text)

            Spinner:
                id: spinner_id_8
                text: "Pump_8"
                values: root.get_ingredients()
                on_text: root.spinner_clicked(8,spinner_id_8.text)

<DrinkMenu>:
    name: "DrinkMenu"
    GridLayout:
        cols: 2
        width: root.width
        height: self.minimum_height
        padding: 10
        spacing: 10
        GridLayout:
            height: root.height
            size_hint_x: 0.4
            rows: 2
            Button:
                text: "Top Up"
                font_size: 24
                on_release:
            Button:
                text: "Main Menu"
                font_size: 24
                on_release: app.root.current = "MainMenu"
        ScrollView:
            size_hint_y: 0.1
            pos_hint: {'x':0, 'y': 0.11}
            do_scroll_x: False
            do_scroll_y: True

            GridLayout:
                id: drinks
                orientation: 'lr-tb'
                size_hint_y: None
                size_hint_x: 1.0
                cols: 3
                height: self.minimum_height
                row_default_height: 100
                row_force_default: True

<RoundedButton@Button>
    background_color: (0,0,0,0)
    background_normal: ''
    canvas.before:
        Color:
            rgba:
                (48/255,84/255,150/255,1)\
                if self.state == 'normal' else (0.6,0.6,1,1)
        RoundedRectangle:
            size: self.size
            pos: self.pos
            radius: [58]

<PermissablePopup@Popup>
    auto_dismiss: False
    #size_hint: 0.6,0.2
    #pos_hint: {"x":0.2, "top":0.9}
    title: "Permissable Ingredients"
    GridLayout:
        rows: 2
        size: root.width, root.height
        spacing: 10
        GridLayout:
            cols: 2
            Label:
                text: "Sodas"
                font_size: 32
                #Add list of sodas
            Label:
                text: "Alcohol"
                font_size: 32
                #Add list of alcohols

        Button:
            text: "Done"
            font_size: 24
            on_release: root.dismiss()

如果其他人有同樣的問題,希望這會有所幫助。 但是,如果有人有任何其他解決方案(或關於一般代碼的建議),請告訴我!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM