Kivy Labels aus einer Forschleife generieren

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
Apfelmann
User
Beiträge: 3
Registriert: Montag 12. Juli 2021, 14:40

Hallo Ihr,

Ich habe vor ungefähr einem Monat mit dem Programmieren angefangen. An sich läuft es gut. Ich Google mir zwar nach jeden 5 Zeilen Code die Finger Blutig aber an sich läuft es. Ich bin seit 2 Tagen an einem Problem dran. Ich Lese aus einer Datenbank (firebase) Daten aus und Wandel diese in eine Liste um. Nun würde ich gerne diese Daten in Labels umwandeln und automatisch diese Labels Erstellen lassen mit einer FOR schleife.

Ich benutze ein Screenmanager der in die KV Datei schaut und dort dann die einzelnen Screen abgreift. Der Button Login (loginbtn2) wechselt in den Screen per app.root.current = "UserMenu" (so wie im Tutorial und das funktioniert auch gut). Dannach erscheinen aber keine Bildschirme. Ich weiß auch gar nicht wie ich die Button an den UserMenu Screen übergeben soll. Ich habe sowas gegoggelt wie "Kivy Creat Label with For Loop".

So sollte es aussehen

Daten:
[('Gname', 'Hans Hans'), ('User_UID', 'test123')]

FORSCHLEIFE:
(GESUCHT)

Ergebniss:
[Gname] [HANS HANS]
[User_UID] [Test123]
usw...


Code: Alles auswählen

class LoginWindow(Screen):

    def loginbtn(self):
        login = auth.sign_in_with_email_and_password(self.email2, self.password2)
        try:
            self.token = auth.current_user["localId"]
            (self.token)
            UserMenu().usm(self.token)
        except:
            pass
class UserMenu(Screen):
    def usm(self, uid1, ):
        uid = uid1
        docs = db.collection("Benchmark").where("User_UID", "==", uid)\
            .get()


        for doc in docs:

            d = doc.to_dict()
            t = list(d.items())
            print(t)

.....

      
......


class StartPrApp(App):
    def build(self):
        sm = ScreenManager()
        sm.add_widget(LoginWindow(name='LoginWindow'))
        sm.add_widget(RegWindow(name='RegWindow'))
        sm.add_widget(UserMenu(name="UserMenu"))
        return sm



if __name__ == "__main__":
    StartPrApp().run()

Code: Alles auswählen

<LoginWindow>
    name: "LoginWindow"
    email2:  email2.text
    password2: password2.text

    GridLayout:
        cols:1
        size: root.width, root.height
        GridLayout
            cols:2
            Label:
                id: l3
                text:"Email eingeben"
            TextInput:
                id:email2
                multiline:False
            Label:
                id: l4
                text:"Bitte Passwort eingeben"
            TextInput:
                id:password2
                multiline:False
                password:True
            Button:
                id:btn2
                text: "Login"
                size_hint: (.5 , .5)
                on_release:
                    root.manager.transition.direction = 'left'
                    root.loginbtn()
                    app.root.current = "UserMenu"



            Button:

                id:btn3
                text: "Regestrieren"
                size_hint: (.3 , .5)
                on_release:
                    root.manager.transition.direction = 'left'
                    app.root.current = "RegWindow"

.....
<UserMenu>
    id: "UserMenu"
    GridLayout:
        id:"gridum"
        size: root.width, root.height
        cols:2

Meine Fragen:
-Ich habe gelesen das man in der KV nur das design erstellen soll. Aber in jedem Tutorial ballern sie Button,Label,... rein. Gibt es eine Möglichkeit z.b. nur das Aussehen( Gridlayout ) zu beschreiben um dann die Labels in der .py datei zu erstellen und auf die Grid ID zu verweisen? Wie funktioniert das? (ich habe nichts auf Google gefunden). Ich glaube ich habe nach den Falschen Begrifflichkeiten gesucht.

- Kann ich Labels über die FOR Schleife erstellen?`

-Wie lasse ich die Labels dann in meinem UserMenu Screen erscheinen? Wie verweise ich darauf das die Labels im UserMenu Screen erstellt werden.



Ich bin noch am Lernen bin also für jeden Tipp oder Verbesserung dankbar

Grüße Apfelmann
Benutzeravatar
Dennis89
User
Beiträge: 1153
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

ich kann gar nicht erkennen, wo du in deinem Code die kv-Datei lädst?

Erst mal ein Minimal-Beispiel, wie du mit einem Button und dem Screenmanager zwischen den Screen's wechseln kannst und wie du Funktionen über die kv-Datei Funktionen aufrufen kannst, die in der Python-Datei geschrieben sind.

Code: Alles auswählen

#!/usr/bin/env python3

from kivy.app import App
from kivy.lang import Builder

from kivy.uix.screenmanager import Screen, ScreenManager


class MainScreen(Screen):
    pass


class TestScreen(Screen):
    def print_something(self):
        print('huhu')


class TestApp(App):
    def build(self):
        screenmanager = ScreenManager()
        screenmanager.add_widget(MainScreen(name='main'))
        screenmanager.add_widget(TestScreen(name='test'))
        return screenmanager


def main():
    Builder.load_file('kvfile.kv')
    TestApp().run()


if __name__ == "__main__":
    main()
Die kv-File dazu:

Code: Alles auswählen

# Filename: kvfile.kv

<MainScreen>:
    name: "main"

    GridLayout:
        cols: 1

        Button:
            id: button_test
            text: "Zum Test"
            on_press:
                app.root.current = "test"

<TestScreen>:
    name: "test"

    GridLayout:
        cols: 2

        Button:
            id: zurueck
            text: "Wieder zurück"
            on_press:
                app.root.current = "main"

        Button:
            id: do_something
            text: "Eine Funktion ausführen"
            on_press:
                root.print_something()
Zum Thema for-Schleife in der kv-File habe ich hier ein Beispiel gefunden:
https://stackoverflow.com/questions/517 ... 1#51790651

Bin mir jetzt ehrlich gesagt auch nicht ganz sicher, ob dir das weiter hilft?

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Apfelmann
User
Beiträge: 3
Registriert: Montag 12. Juli 2021, 14:40

Hallo Dennis,

danke für deine Antwort. Die KV Datei wird über den Namen Geladen. Daher muss ich das nicht im Code angeben. Aber gut zum Wissen.
Wenn ich das richtig verstanden habe wird im Beispiel die Forschleife in der .KV Datei angelegt. Die KV Datei sollte aber ja nur für das Design geben.

Gibt es eine Möglichkeit die Forschleife in den Screen vom UserMenu zu laden? Weil Dieser wird ja über den Screenmanager aufgerufen und der kennt ja meine Widgets nicht.

Code: Alles auswählen

 class UserMenu(Screen):
    def usm(self, uid1, ):
        uid = uid1
        docs = db.collection("Benchmark").where("User_UID", "==", uid)\
            .get()

        for doc in docs:
            d = doc.to_dict()
            t = list(d.items())
        for label in t:
            screen.add_widget(label(text=label)) 
So in der Art. Ich muss ja die Labels in den Screen reinbekommen. Im Moment führe ich den Code aus und erhalte ein Leeres Window.

Also Konkret gibt es eine möglichkeit die Labels im .PY direkt dem dannach geladenden Sceen hinzuzufügen ohne das man labels in der .KV Datei anlegt sondern hier nur das Gridlayout definiert?
Apfelmann
User
Beiträge: 3
Registriert: Montag 12. Juli 2021, 14:40

Ich habe es hinbekommen. Ich habe den momentanen Screen mit dem Screen "screen" geladen und das Widget gecleart. Dannach habe ich eine Schleife mit einer liste durchgejagdt welches die Labels zum Layout welches in der KV Datei ist hinzugefügt hat.


Code: Alles auswählen

	
	app_running = App.get_running_app()
        root_screen = app_running.root
        pr_screen = root_screen.get_screen("benchmark")
        pr_screen.layout.clear_widgets()

        for i, item in tuple(self.BenchMarkList):

            pr_screen.layout.add_widget(Label(text=i))
            pr_screen.layout.add_widget(Label(text=item + "kg"))
            
Antworten