Seite 1 von 1

[Kivy] ScreenManager: Problem beim Aufruf einer Methode

Verfasst: Freitag 24. Juni 2022, 07:58
von Hart mit Bart
Hallöchen zusammen,
ich hätte da mal ein Problem.

Ich habe mit Kivy einen Login gestaltet und möchte nun, dass nach einer erfolgreichen Authentifizierung der "innere Bereich" angezeigt wird. Das möchte ich mit dem Screenmanager realisieren.

Code: Alles auswählen

WindowManager:
    LoginWindow:
    GameWindow:
Im Bereich "LoginWindow" gibt es einen Login-Button.

Code: Alles auswählen

RoundedButton:
            text: "Login"
            pos_hint: {'center_x': .5}
            size_hint: (1, None)
            height: 50
            on_press: app.root.press()
In meiner Pythondatei gibt es die entsprechende Methode dazu.

Code: Alles auswählen

class MyLayout(Widget):

    name = ObjectProperty(None)
    password = ObjectProperty(None)

    def press(self):
        user_hash = hashlib.sha256(self.name.text.encode('utf-8')).hexdigest().upper()
        pass_hash = hashlib.sha256(self.password.text.encode('utf-8')).hexdigest().upper()
        if (user_hash == super_user) and (pass_hash == super_pass):
            print("Das hat geklappt!")
            WindowManager.current = 'GameWindow'
        else:
            print("Du kummst hier net rein!")
Anmerkung: Die Print-Ausgaben dien(t)en nur als visuelle Bestätigung in der Konsole.

Ich bekomme folgende Fehlermeldung:
AttributeError: 'WindowManager' object has no attribute 'press'
Ich meine, klar ... die Methode ist in der Klasse MyLayout und nicht etwa in ...

Code: Alles auswählen

# Define screens
class LoginWindow(Screen):
    pass


class GameWindow(Screen):
    pass


class WindowManager(ScreenManager):
    pass
Aber ich dachte, wenn ich die Methode mit ...

Code: Alles auswählen

 on_press: app.root.press()
... aufrufe, dass das funktionieren sollte.

Offenbar habe ich mal wieder ein grundsätzliches Verständnisproblem, wie das alles mit einander interagiert und vor allem, wie es das nicht tut.

Könnte jemand bitte ein Stichwort in den Raum werfen?

Liebe Grüße

Re: [Kivy] ScreenManager: Problem beim Aufruf einer Methode

Verfasst: Freitag 24. Juni 2022, 21:38
von Dennis89
Hallo,

wieso steht die Funktion nicht in der Klasse, die auf den Screen der gerade "aktiv" ist bezogen ist?
'pass' ist hier kein muss.

Grüße
Dennis

Edit: Vielleicht kannst du auch mal den vollständigen Code zeigen, das ist dann etwas übersichtlicher und man weis zum Beispiel wo das 'app' hingehört

Re: [Kivy] ScreenManager: Problem beim Aufruf einer Methode

Verfasst: Freitag 24. Juni 2022, 21:46
von Hart mit Bart
Edit, da inzwischen eine Antwort gekommen ist:
Ja, den Fehler habe ich auch bemerkt.

Ich versuche mich durchzu boxen, aber es will nicht so recht.

Die Klasse MyLayout wird gar nicht benutzt, also habe ich diese entfernt. Totaler Blödsinn. Da hatte ich wohl eine Denkblockade.

Ich denke, dass die Methode on_press in LoginWindow gehört. Das ist ja (eigentlich, aber ... siehe unten) der erste Screen, der natürlich aufgerufen wird.

Code: Alles auswählen

class LoginWindow(Screen):

    name = ObjectProperty(None)
    passw = ObjectProperty(None)

    def press(self):
        user_hash = hashlib.sha256(self.name.text.encode('utf-8')).hexdigest().upper()
        pass_hash = hashlib.sha256(self.passw.text.encode('utf-8')).hexdigest().upper()
        if (user_hash == super_user) and (pass_hash == super_pass):
            print("Das hat geklappt!")
            WindowManager.current = 'GameWindow'
        else:
            print("Du kummst hier net rein!")
Leider ergibt sich daraus ein anderes Problem. Es wird statt dem Screen LoginWindow der Screen GameWindow aufgerufen. Das sollte eigentlich erst nach einem erfolgreichen Login geschehen.

Re: [Kivy] ScreenManager: Problem beim Aufruf einer Methode

Verfasst: Freitag 24. Juni 2022, 21:48
von Hart mit Bart
Ja, ich denke die kompletten Files sind hier der Übersichtlichkeit zuliebe hilfreich:

Code: Alles auswählen

from kivy.app import App
from kivy.properties import ObjectProperty
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.screenmanager import ScreenManager, Screen
import hashlib

Window.size = (512, 512)

super_user = "9279F4A7C1C145D5AE930FDA23EF386168F6720B4E0F0D3DEE383C5AD8535737"
super_pass = "EE22032527082315A747781829EF1F9195F6AEAC09C0D52DE06EBF9D8C463918"


# Define screens
class LoginWindow(Screen):

    name = ObjectProperty(None)
    passw = ObjectProperty(None)

    def press(self):
        user_hash = hashlib.sha256(self.name.text.encode('utf-8')).hexdigest().upper()
        pass_hash = hashlib.sha256(self.passw.text.encode('utf-8')).hexdigest().upper()
        if (user_hash == super_user) and (pass_hash == super_pass):
            print("Das hat geklappt!")
            WindowManager.current = 'GameWindow'
        else:
            print("Du kummst hier net rein!")


class GameWindow(Screen):
    pass


class WindowManager(ScreenManager):
    pass


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


class Affenquiz(App):

    def build(self):
        Window.clearcolor = (0.8, 0.8, 0.8, 1)
        return kv


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

Code: Alles auswählen

WindowManager:
    LoginWindow:
        name: "login"
    GameWindow:
        name: "game"

<LoginWindow>:

    name:name
    passw:passw

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

        spacing: 20
        padding: 20

        canvas.before:
            Rectangle:
                pos: self.pos
                size: self.size
                source: 'monkey.png'

        AnchorLayout:
            anchor_y: 'top'
            BoxLayout:
                orientation: "horizontal"
                size_hint: (1, None)
                height: 50

                Label:
                    text: "Der Quizfelsen"
                    font_size: 50

        BoxLayout:
            orientation: "horizontal"
            size_hint: (1, None)
            height: 50

            Label:
                text: "Benutzer:"
            TextInput:
                id: name
                multiline:False
                background_color: (241/255.0,241/255.0,241/255.0,0.9)

        BoxLayout:
            orientation: "horizontal"
            size_hint: (1, None)
            height: 50

            Label:
                text: "Passwort:"
            TextInput:
                id: passw
                multiline:False
                background_color: (241/255.0,241/255.0,241/255.0,0.9)

        RoundedButton:
            text: "Login"
            pos_hint: {'center_x': .5}
            size_hint: (1, None)
            height: 50
            on_press: root.press()

<GameWindow>:
    Label:
        text: "Der Quizfelsen"
        font_size: 50

<Label>
    font_size: 32
    background_normal: ''
    background_color: (0.9,0.9,0.9,0)
    canvas.before:
        Color:
            rgba: self.background_color
        Rectangle:
            size: self.size
            pos: self.pos
    color: (184/255.0,70/255.0,35/255.0,1)
    bold: True
    outline_color: (1,1,1,1)
    outline_width: 2

<RoundedButton@Button>
    background_color: (0,0,0,0)
    background_normal: ''
    canvas.before:
        Color:
            rgba: (184/255.0,70/255.0,35/255.0,0.9)
        RoundedRectangle:
            size: self.size
            pos: self.pos
            radius: [25]
ich gehe mal ins Bett. Vielleicht trifft mich der Hammer der Erkenntnis ja spontan im Schlaf.

Re: [Kivy] ScreenManager: Problem beim Aufruf einer Methode

Verfasst: Samstag 25. Juni 2022, 12:34
von Dennis89
Hallo,

in 'build' musst du deinen ScreenManager unterbringen. Die anderen Klassen bekommen als Argument nur 'Screen' .

Vielleicht hilft dir ein früheres Projekt von mir als Vorlage. Dort arbeite ich auch mit dem ScreenManager:
https://forum-raspberrypi.de/forum/thre ... hgeraeten/

Grüße und viel Erfolg
Dennis

Re: [Kivy] ScreenManager: Problem beim Aufruf einer Methode

Verfasst: Samstag 25. Juni 2022, 16:00
von Hart mit Bart
Selbst wenn ich das mache ...

Code: Alles auswählen

WindowManager = ScreenManager()
WindowManager.add_widget(LoginWindow(name='login'))
WindowManager.add_widget(GameWindow(name='game'))
... wird noch immer der zweite Screen (GameWindow) beim Start geladen statt dem ersten.

Ich weiß gerade echt nicht, wo mein Denkfehler ist.

Re: [Kivy] ScreenManager: Problem beim Aufruf einer Methode

Verfasst: Sonntag 26. Juni 2022, 09:56
von Hart mit Bart
Hach, ein blöder Fehler.

Code: Alles auswählen

<LoginWindow>:

    name:name
    passw:passw
"name" darf ich da nicht verwenden. Das ist ein reserviertes Attribut. :oops:

Jetzt erscheint das LoginWindow, wie es sein sollte.

Re: [Kivy] ScreenManager: Problem beim Aufruf einer Methode

Verfasst: Sonntag 26. Juni 2022, 17:04
von Dennis89
Hallo,

super, sind dann alle Probleme beseitigt?


Grüße
Dennis