Anmeldefenster mit Kivy

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
Benutzeravatar
Patsche
User
Beiträge: 43
Registriert: Samstag 23. Oktober 2021, 00:17

Hi!
Ich probiere mich gerade in Kivy einzufinden und habe ein kleines Problem.
Ich möchte ein Anmeldescreen bauen. Das habe ich geschafft.
Aber ich weiß aktuell nicht, wie ich auf die eingegebenen Texte in Textinputs zugreifen kann.
Hier ist die Doku dazu:
https://kivy.org/doc/stable/api-kivy.ui ... Input.text

Aber ich werde da nicht so schlau draus.
Ich habe in meinem Code auch schon id's vergeben, falls das benötigt wird.
Das Ziel ist es, dass Benutzer und Passort zusammen passen sollen. Ist verständlich denke ich. Das würde ich mit einer if-Abfrage bei Druck auf den Anmeldebutton realisieren.

Ich hänge mal den aktuellen Code ran. Der ist allerdings nicht fertig, da ich gerade am Anmeldefenster hänge.

Hier die main.py:

Code: Alles auswählen

from kivy.app import App
from kivy.uix.label import Label
from random import randint


class MathasticApp(App):
    def build(self):
        zahl1=randint(1,10)
        zahl2=randint(1,10)
        a= str(zahl1)
        b= str(zahl2)
        ergebnis=zahl1+zahl2
        self.root.ids['zahl1'].text = a
        self.root.ids['rechenzeichen'].text = "+"
        self.root.ids['zahl2'].text = b
        


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

Und nun die kv-Datei:

Code: Alles auswählen

#:kivy 2.0

ScreenManager:
    Screen:
        name: 'anmeldung'
        BoxLayout:
            orientation: 'vertical'
            padding: 50
            spacing: 20
            Label:
                text: "Anmeldung"
                font_size: 25
                spacing: 20
            TextInput:
                id: benutzername
                multiline: False
                focus: True
                text: 'Benutzername'
                text_size: self.size
                font_size: 20
            TextInput:
                id: passwort
                multiline:False
                text: 'Passwort'
                password: True
                text_size: self.size
                font_size: 20

            Button:
                id: anmeldebutton
                text:"Anmelden"
                on_press: app.root.current = if (TextInput.text'rechnen'

    Screen:
        name: 'rechnen'
        BoxLayout:
            orientation: 'vertical'
            BoxLayout:
                Label:
                    id: zahl1
                    text: "Zahl 1"
                    font_size: 25
                Label:
                    id: rechenzeichen
                    text: "Zahl 1"
                    font_size: 25
                Label:
                    id: zahl2
                    text: "Zahl 2"
                    font_size: 25
            TextInput:
                text: 'Ergebnis'
                text_size: self.size
                font_size: 20
            Button:
                id: pruefbutton
                text:"Prüfen"
                font_size: 20
            
Kann mir da jemand helfen?

Vielen Dank für eure Zeit und Unterstützung im vorraus.
Benutzeravatar
Patsche
User
Beiträge: 43
Registriert: Samstag 23. Oktober 2021, 00:17

Soooo.....ich habe es geschafft.

main.py

Code: Alles auswählen

from kivy.app import App
from kivy.uix.label import Label
from random import randint


class MathasticApp(App):
    def build(self):
        zahl1=randint(1,10)
        zahl2=randint(1,10)
        a= str(zahl1)
        b= str(zahl2)
        ergebnis=zahl1+zahl2
        self.root.ids['zahl1'].text = a
        self.root.ids['rechenzeichen'].text = "+"
        self.root.ids['zahl2'].text = b


    def anmeldedaten(self):
        global benutzer
        global passwort
        benutzer = self.root.ids.benutzername.text
        # print(benutzer) / Zur Eingabenüberprüfung auf der Konsole
        passwort = self.root.ids.passwort.text
        # print(passwort) / Zur Eingabenüberprüfung auf der Konsole 

    def zugangskontrolle(self):
        if (((benutzer=="Ben") and (passwort=="minion")) or ((benutzer=="Emma") and (passwort=="wendy"))):
            on_press = self.root.current = 'rechnenscreen'

    def abmeldung(self):
        global benutzer
        global passwort
        benutzer="Benutzername"
        passwort="Passwort"
        self.root.ids.benutzername.text="Benutzername"
        self.root.ids.passwort.text="Passwort"
        # print(benutzer) // Überprüfung, ob Anmeldedaten gelöscht werden
        # print(passwort) // Überprüfung, ob Anmeldedaten gelöscht werden 
        on_press = self.root.current = 'anmeldescreen'


        


if __name__=="__main__":
    MathasticApp().run()
kv-Datei:

Code: Alles auswählen

#:kivy 2.0

ScreenManager:
    Screen:
        name: 'anmeldescreen'
        BoxLayout:
            orientation: 'vertical'
            padding: 50
            spacing: 20
            Label:
                text: "Anmeldung"
                font_size: 25
                spacing: 20
            TextInput:
                id: benutzername
                multiline: False
                focus: True
                text: 'Benutzername'
                text_size: self.size
                font_size: 20
                on_text: app.anmeldedaten()
            TextInput:
                id: passwort
                multiline:False
                text: 'Passwort'
                password: True
                text_size: self.size
                font_size: 20
                on_text: app.anmeldedaten()

            Button:
                id: anmeldebutton
                text:"Anmelden"
                on_press: app.zugangskontrolle()

    Screen:
        name: 'rechnenscreen'
        BoxLayout:
            orientation: 'vertical'
            BoxLayout:
                Label:
                    id: zahl1
                    text: "Zahl 1"
                    font_size: 25
                Label:
                    id: rechenzeichen
                    text: "Zahl 1"
                    font_size: 25
                Label:
                    id: zahl2
                    text: "Zahl 2"
                    font_size: 25
            TextInput:
                text: 'Ergebnis'
                text_size: self.size
                font_size: 20
            Button:
                id: pruefbutton
                text:"Prüfen"
                font_size: 20
                on_press:
            Button:
                id: abmeldebutton
                text:"Abmelden"
                on_press: app.abmeldung()
Benutzeravatar
__blackjack__
User
Beiträge: 13063
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Patsche: Geschafft ist es erst wenn da kein ``global`` mehr drin ist. Vergiss am besten, dass es das Schlüsselwort ``global`` überhaupt gibt.

Bei der ``if``-Bedingung in `zugangskontrolle()` sind die ganzen Klammern überflüssig. ``and`` bindet stärker als ``or`` und aussen herum muss man keine Klammer setzen. Das könnte Sinn machen wenn man die Klammern verwendet um diesen langen Ausdruck auf mehrere Zeilen umzubrechen. Alternativ könnte man das mit Tupeln und ``in`` kürzer und IMHO auch ein bisschen leichter lesbar ausdrücken:

Code: Alles auswählen

        if (benutzer, passwort) in [("Ben", "minion"), ("Emma", "wendy")]:
            ...
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
Patsche
User
Beiträge: 43
Registriert: Samstag 23. Oktober 2021, 00:17

__blackjack__ hat geschrieben: Samstag 23. Oktober 2021, 11:54 @Patsche: Geschafft ist es erst wenn da kein ``global`` mehr drin ist. Vergiss am besten, dass es das Schlüsselwort ``global`` überhaupt gibt.
Ah okay. Danke für den Hinweis. Das wusste ich bisher leider nicht.
__blackjack__ hat geschrieben: Samstag 23. Oktober 2021, 11:54 Bei der ``if``-Bedingung in `zugangskontrolle()` sind die ganzen Klammern überflüssig
Habe ich entfernt. Bin da einwenig C und Java geschädigt, wo man ständig überall Klammern setzen muss ;)


Mir fehlt bei kivy noch das Hintergrundwissen, wie die kv-Datei mit der py-datei zusammenarbeitet.
Ich habe jetzt den Code geändert,a ber ein neues Problem:
Sobald Benutzername und Passwort stimmen loggt er sich sofort ein. Kann zwar auch irgendwie nützlich sein, aber ich will das man den Anmeldebutton drücken muss.
Ich dachte auch eigentlich, dass die Funktion "zugangskontrolle" erst ausgeführt wird, wenn der Button betätigt wird.
Dafür steht doch on-press.....liegt der Fehler bei mir, oder macht das Programm das falsch?
Hier nochmal der Code.

main.py

Code: Alles auswählen

from kivy.app import App
from kivy.uix.label import Label
from random import randint


class MathasticApp(App):
    def build(self):
        zahl1=randint(1,10)
        zahl2=randint(1,10)
        a= str(zahl1)
        b= str(zahl2)
        ergebnis=zahl1+zahl2
        self.root.ids['zahl1'].text = a
        self.root.ids['rechenzeichen'].text = "+"
        self.root.ids['zahl2'].text = b

    def zugangskontrolle(self):
        benutzer = self.root.ids.benutzername.text
        passwort = self.root.ids.passwort.text
        if benutzer=="Ben" and passwort=="minion" or benutzer=="Emma" and passwort=="wendy":
            on_press = self.root.current = 'rechnenscreen'

    def abmeldung(self):
        benutzer="Benutzername"
        passwort="Passwort"
        self.root.ids.benutzername.text="Benutzername"
        self.root.ids.passwort.text="Passwort" 
        on_press = self.root.current = 'anmeldescreen'


        


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

kv-datei

Code: Alles auswählen

#:kivy 2.0

ScreenManager:
    Screen:
        name: 'anmeldescreen'
        BoxLayout:
            orientation: 'vertical'
            padding: 50
            spacing: 20
            Label:
                text: "Anmeldung"
                font_size: 25
                spacing: 20
            TextInput:
                id: benutzername
                multiline: False
                focus: True
                text: 'Benutzername'
                text_size: self.size
                font_size: 20
                on_text: app.zugangskontrolle()
            TextInput:
                id: passwort
                multiline:False
                text: 'Passwort'
                password: True
                text_size: self.size
                font_size: 20
                on_text: app.zugangskontrolle()

            Button:
                id: anmeldebutton
                text:"Anmelden"
                on_press: app.zugangskontrolle()

    Screen:
        name: 'rechnenscreen'
        BoxLayout:
            orientation: 'vertical'
            BoxLayout:
                Label:
                    id: zahl1
                    text: "Zahl 1"
                    font_size: 25
                Label:
                    id: rechenzeichen
                    text: "Zahl 1"
                    font_size: 25
                Label:
                    id: zahl2
                    text: "Zahl 2"
                    font_size: 25
            TextInput:
                text: 'Ergebnis'
                text_size: self.size
                font_size: 20
            Button:
                id: pruefbutton
                text:"Prüfen"
                font_size: 20
                on_press:
            Button:
                id: abmeldebutton
                text:"Abmelden"
                on_press: app.abmeldung()

            
Benutzeravatar
__blackjack__
User
Beiträge: 13063
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Patsche: Warum dachtest Du das `zugangskontrolle()` nur ausgeführt wird wenn der Button gedrückt wird? Also ja, da steht das für das `on_press`-Ereignis. Und wenn es *nur dort* stehen würde, dann würde es auch nur bei dem Ereignis ausgeführt, aber Du hast das ja explizit noch an zwei anderen Stellen für Ereignisse registriert. Und da wird das dann halt auch ausgeführt.

Die beiden Zuweisungen an ein lokales `on_press` in `zugangskontrolle()` und `abmeldung()` machen keinen Sinn. Der Name wird danach ja nirgends verwendet.

Neben `on_<ereignisname>` für Rückruffunktionen/-methoden sind bei Funktionen und Methoden eher Tätigkeiten als Namen üblich. Also beispielsweise `anmelden()` und `abmelden()`.

`ergebnis` in `build()` und `benutzer` und `passwort` in `abmeldung()` werden definiert aber nirgends verwendet.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
Patsche
User
Beiträge: 43
Registriert: Samstag 23. Oktober 2021, 00:17

__blackjack__ hat geschrieben: Samstag 23. Oktober 2021, 20:28 @Patsche: Warum dachtest Du das `zugangskontrolle()` nur ausgeführt wird wenn der Button gedrückt wird? Also ja, da steht das für das `on_press`-Ereignis. Und wenn es *nur dort* stehen würde, dann würde es auch nur bei dem Ereignis ausgeführt, aber Du hast das ja explizit noch an zwei anderen Stellen für Ereignisse registriert. Und da wird das dann halt auch ausgeführt.
Ok. das habe ich mir fast gedacht, dass es daran liegt. Ich dachte, dass die beiden anderen Textinputs, die die Funktion "zugangskontrolle" ebenfalls aufrufen, nur ihren Text dort reinschreiben, sobald der Anmeldeknopf gedrückt wird.
__blackjack__ hat geschrieben: Samstag 23. Oktober 2021, 20:28 Die beiden Zuweisungen an ein lokales `on_press` in `zugangskontrolle()` und `abmeldung()` machen keinen Sinn. Der Name wird danach ja nirgends verwendet.
Ich dachte, dass ich das noch davor schreiben musste, damit ein Screenwechsel erst beim Drücken des Buttons ausgeführt wird. Habe es mal entfernt und es funktioniert auch so. Danke für den Hinweis.
Wie gesagt: Mit fehlt noch das Verständniss, wie kv-datei und main.py zusammen arbeiten.
__blackjack__ hat geschrieben: Samstag 23. Oktober 2021, 20:28 Neben `on_<ereignisname>` für Rückruffunktionen/-methoden sind bei Funktionen und Methoden eher Tätigkeiten als Namen üblich. Also beispielsweise `anmelden()` und `abmelden()`.
Super. Vielen Dank für deine Hilfe. Werde ich mir merken. Habe ich ebenfalls geändert.
__blackjack__ hat geschrieben: Samstag 23. Oktober 2021, 20:28 `ergebnis` in `build()` und `benutzer` und `passwort` in `abmeldung()` werden definiert aber nirgends verwendet.
ergebnis steht erstmal nur so drin. das Programm ist ja noch nicht fertig. Das ganze soll nachher eine kleines Matheprogramm für meine Kinder werden.
Habe das Programm so schon fertig, allerdings nur für die Konsole. Jetzt versuche ich mit kivy das ganze in eine gui zu packen. Mit Levelaufstieg und täglichen Aufgaben und so weiter. Ich scheitere halt gerade nur an kivy.
benutzer und passwort habe ich in der abmelden-Funktion nochmal initiiert, weil ich dachte, dass die Anmeldewerte sonst noch vorhanden sind und man nach der Abmeldung direkt wieder auf Anmelden klicken kann ohne seine Daten einzugeben. Deshalb wollte ich die Variablen mit dem jeweiligen String überschreiben. Aber auch hier hast du wieder Recht. Habe es entfernt.

Hier der geänderte Code:

main.py

Code: Alles auswählen

from kivy.app import App
from kivy.uix.label import Label
from random import randint


class MathasticApp(App):
    def build(self):
        zahl1=randint(1,10)
        zahl2=randint(1,10)
        a= str(zahl1)
        b= str(zahl2)
        ergebnis=zahl1+zahl2
        self.root.ids['zahl1'].text = a
        self.root.ids['rechenzeichen'].text = "+"
        self.root.ids['zahl2'].text = b

    def anmelden(self):
        benutzer = self.root.ids.benutzername.text
        passwort = self.root.ids.passwort.text
        if benutzer=="Ben" and passwort=="minion" or benutzer=="Emma" and passwort=="wendy":
            self.root.current = 'rechnenscreen'

    def abmelden(self):
        self.root.ids.benutzername.text="Benutzername"
        self.root.ids.passwort.text="Passwort" 
        self.root.current = 'anmeldescreen'


        


if __name__=="__main__":
    MathasticApp().run()
kv-Datei

Code: Alles auswählen

#:kivy 2.0

ScreenManager:
    Screen:
        name: 'anmeldescreen'
        BoxLayout:
            orientation: 'vertical'
            padding: 50
            spacing: 20
            Label:
                text: "Anmeldung"
                font_size: 25
                spacing: 20
            TextInput:
                id: benutzername
                multiline: False
                focus: True
                text: 'Benutzername'
                text_size: self.size
                font_size: 20
                on_text: app.anmelden()
            TextInput:
                id: passwort
                multiline:False
                text: 'Passwort'
                password: True
                text_size: self.size
                font_size: 20
                on_text: app.anmelden()

            Button:
                id: anmeldebutton
                text:"Anmelden"
                on_press: app.anmelden()

    Screen:
        name: 'rechnenscreen'
        BoxLayout:
            orientation: 'vertical'
            BoxLayout:
                Label:
                    id: zahl1
                    text: "Zahl 1"
                    font_size: 25
                Label:
                    id: rechenzeichen
                    text: "Zahl 1"
                    font_size: 25
                Label:
                    id: zahl2
                    text: "Zahl 2"
                    font_size: 25
            TextInput:
                text: 'Ergebnis'
                text_size: self.size
                font_size: 20
            Button:
                id: pruefbutton
                text:"Prüfen"
                font_size: 20
                on_press:
            Button:
                id: abmeldebutton
                text:"Abmelden"
                on_press: app.abmelden()

            
Benutzeravatar
__blackjack__
User
Beiträge: 13063
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Wenn es das schon als Konsolen-Anwendung gibt, könnte man vielleicht auch die Programmlogik entsprechend isolieren, so dass man das am Ende über Konsole *oder* GUI bedienen kann. Wenn man zwei Benutzerschnittstellen verwendet, hat man damit automatisch eine gute Kontrolle das man UI und Programmlogik sauber getrennt hat, und da nichts vermischt.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
Patsche
User
Beiträge: 43
Registriert: Samstag 23. Oktober 2021, 00:17

Puh, dafür reichen meine Kentnisse nicht aus. Ich habe ja jetzt schon Probleme......
Antworten