[Python] How to create an buttonloop with parameter in kivy, after the GUI has generated?

Discussão em 'Python' iniciado por Stack, Fevereiro 4, 2025.

  1. Stack

    Stack Membro Participativo

    I have an problem with the Kivy library. I'm currently writing the front end for a ShoppinglistApp. I have an main menu, where you can select what you want to do (add List/ Shop) from where you can get to the Shop selection.

    1. In the shop selection Menu are 4 shops
    2. all items (Produkt) are stored in a list
    3. If you select the shop, then for each item (from this shop), a button should be created.

    I tried this solution:

    from kivy.app import App
    from kivy.metrics import dp
    from kivy.lang import Builder
    from kivy.properties import StringProperty
    from kivy.uix.stacklayout import StackLayout
    from kivy.uix.boxlayout import BoxLayout
    from kivy.uix.button import Button
    from kivy.uix.screenmanager import ScreenManager, Screen

    # the rest
    class Produkt:
    def __init__(self, name, amount, market):
    self.name = name
    self.amount = amount
    self.market = market

    eklist = []
    for i in range(0, 100):
    nn = "Banane" + str(i)
    eklist.append(Produkt(nn, 0, "Baumarkt"))

    # Define Screens

    class FirstWindow(Screen):
    pass

    class SecondWindow(Screen):
    pass

    class ThirdWindow(Screen):
    pass

    class WindowManager(ScreenManager):
    pass

    """Anfang der Chose"""

    class Box(BoxLayout):
    pass

    # Gvar is a class I created for the purpose of transporting variable(s). Especially the selected shop.

    class Gvar:
    def __init__(self, var1):
    self.var1 = var1

    def get(self):
    return self.var1

    gvar = Gvar("default")

    # SetBox ist the Class for changing the variable through the shop selection menu.
    class SetBox(BoxLayout):

    def set(self, market):
    gvar.var1 = market
    print("Set")
    print(gvar.var1)


    class BLE(BoxLayout):
    pass

    # This is the Menus which makes Problems.
    class SLE(StackLayout):

    def __init__(self, **kwargs):
    super().__init__(**kwargs)

    for p in eklist:
    # In theory, this if request should always be triggered. In reality, I made the else Request to debug.
    # for Text normally would appear p.name, but I changed it for debugging. Text shown(gvar.var1) is "default".
    if p.market == str(gvar.get()):
    b = Button(text=str(gvar.get()), size_hint=(None, None), color="blue", size=(dp(200), dp(100)),
    on_press=lambda *args: self.test1(*args, str(p.name)))
    b.prod = p
    self.add_widget(b)

    else:
    b = Button(text=str(gvar.get()), size_hint=(None, None), color="green", size=(dp(200), dp(100)),
    on_press=lambda *args: self.test1(*args, str(p.name)))
    b.prod = p
    self.add_widget(b)
    market = None

    # test 1 is a placeholder for a backend function
    # Here I print the Produkt and gvar.var1, to debug. Here it get for gvar.var1 the in the GUI selected Value.
    def test1(self, b, i):
    print("Initialize test2, please wait...")
    print(b.prod.name, b.prod.amount, b.prod.market, gvar.var1)

    """Ende der Chose"""

    kv = Builder.load_file('einkaufsliste.kv')

    class EinkaufsApp(App):
    def build(self):
    return kv

    if __name__ == '__main__':
    EinkaufsApp().run()
    </code></pre> +


    Here is the Kivy file:

    WindowManager:
    FirstWindow:
    SecondWindow:
    ThirdWindow:


    &ltFirstWindow&gt:
    name: "first"

    Box:
    orientation: "vertical"
    size :root.width, root.height

    Label:
    text: "Hauptmenü"
    size_hint: 1, .2
    font_size: 32

    Button:
    text: "Einkaufen"
    font_size: 32
    background_normal: ' '
    background_color: "#666e00"
    on_release:
    app.root.current = "third"
    root.manager.transition.direction = "left"

    Button:
    text: "Einkaufsliste updaten"
    font_size: 32
    background_normal: ' '
    background_color: "#660000"
    on_release:
    app.root.current = "second"
    root.manager.transition.direction = "left"

    &ltSecondWindow&gt:
    name: "second"

    BLE:
    id: BLE
    orientation: "vertical"
    Button:
    text: "to first"
    size_hint: 1, .1
    font_size: 24
    on_release:
    app.root.current = "first"
    root.manager.transition.direction = "right"
    TextInput:
    multiline: False
    size_hint: 1, .1
    SVE:

    &ltThirdWindow&gt:
    name: "third"

    SetBox:
    orientation: "vertical"
    size :root.width, root.height
    id:SetBox

    Box:
    orientation: "horizontal"
    size_hint: 1, .4
    Button:
    text: "to first"
    size_hint: .2, 1
    font_size: 24
    on_release:
    app.root.current = "first"
    root.manager.transition.direction = "right"

    Label:
    text: "Markt auswählen"
    size_hint: .8, 1
    font_size: 32

    Button:
    text: "Supermarkt"
    font_size: 32
    background_normal: ' '
    background_color: "#a1b2e3"
    on_release:
    app.root.current = "second"
    root.manager.transition.direction = "left"
    on_press: SetBox.set("Supermarkt")

    Button:
    text: "Drogerie"
    font_size: 32
    background_normal: ' '
    background_color: "#c7bbc9"
    on_release:
    app.root.current = "second"
    root.manager.transition.direction = "left"
    on_press: SetBox.set("Drogerie")

    Button:
    text: "Baumarkt"
    font_size: 32
    background_normal: ' '
    background_color: "#b4eeb4"
    on_release:
    app.root.current = "second"
    root.manager.transition.direction = "left"
    on_press: SetBox.set("Baumarkt")

    Button:
    text: "Elektrogerätefachhandel"
    font_size: 32
    background_normal: ' '
    background_color: "#f4c2c2"
    on_release:
    app.root.current = "second"
    root.manager.transition.direction = "left"
    on_press: SetBox.set("Elektrogerätefachhandel")

    &ltSVE@ScrollView&gt:
    SLE:
    id: Scrollwin
    size_hint: 1, None
    height: self.minimum_height

    &ltSLE&gt:
    # orientation: "rl-bt"
    # spacing: "1dp", "1dp"


    I think the problem is that kivy creates the whole GUI before I can change the variable.

    Is there a way to reload the screen or do I have to make for each market/shop another screen?

    Continue reading...

Compartilhe esta Página