[Python] How to link kivy code (that isn't in a kivy file, but is in the python code) to...

Discussão em 'Python' iniciado por Stack, Março 20, 2025.

  1. Stack

    Stack Membro Participativo

    I'm codding a simple app. Right now, I made a log in page. But the buttons seems to not be working. The issues is that the buttons are not "linked" to the python class. And so, they don't have acess to the functions that describe their behavior.

    When it was a .kv file, this issues didn't happen. I know I could just stranfer it back into a kivy file. But I am still knew at kivy, and I want to learn (and not find an easy way out).

    Here is my code.

    from kivymd.app import MDApp
    from kivy.lang.builder import Builder
    from kivy.uix.screenmanager import ScreenManager, Screen
    from kivy.lang import Builder
    from kivymd.app import MDApp
    import pymongo
    from kivy.properties import StringProperty
    import hashlib
    from pymongo.errors import ConnectionFailure, DuplicateKeyError
    from kivy.uix.widget import Widget

    screen_helper = """

    ScreenManager:
    MenuScreen:
    LoginScreen:
    SignupScreen:

    <MenuScreen>:
    name: 'menu'
    MDRectangleFlatButton:
    text: 'Sign up'
    pos_hint: {'center_x':0.5,'center_y':0.6}
    on_press: root.manager.current = 'Sign up page'
    MDRectangleFlatButton:
    text: 'log in'
    pos_hint: {'center_x':0.5,'center_y':0.5}
    on_press: root.manager.current = 'Log in page'

    <SignupScreen>:
    name: 'Sign up page'
    MDLabel:
    text: 'Sign up here'
    halign: 'center'
    MDRectangleFlatButton:
    text: 'Back'
    pos_hint: {'center_x':0.5,'center_y':0.1}
    on_press: root.manager.current = 'menu'

    <LoginScreen>:
    name: 'Log in page'
    Screen:
    MDCard:
    size_hint: None, None
    size: 500,600
    pos_hint: { "center_x": 0.5, "center_y": 0.5}
    elevation: 10
    padding:25
    spacing:25
    orientation: 'vertical'

    MDLabel:
    id: welcome_label
    text: "Welcome"
    font_size: 40
    halign: 'center'
    size_hint_y: None
    height: self.texture_size[1]
    padding_y: 15

    MDTextField:
    id: name
    hint_text: "write your name"
    icon_right: "account"
    size_hint_x: None
    width: 300
    font_size: 20
    pos_hint:{'center_x': 0.5}
    line_color_normal: (0, 0, 0, 1) # Change line color if you want it
    line_color_focus: (0, 0, 0, 1) # Line color when focused
    multiline: False

    MDTextField:
    id: number
    hint_text: "e.g: +243 123 209 977"
    icon_right: "numeric"
    size_hint_x: None
    width: 300
    font_size: 20
    pos_hint:{'center_x': 0.5}
    line_color_normal: (0, 0, 0, 1) # Change line color if you want it
    line_color_focus: (0, 0, 0, 1) # Line color when focused
    multiline: False

    MDTextField:
    id: password
    hint_text: "write your password"
    icon_right: "eye-off"
    size_hint_x: None
    width: 300
    font_size: 20
    pos_hint:{'center_x': 0.5}
    line_color_normal: (0, 0, 0, 1) # Change line color if you want it
    line_color_focus: (0, 0, 0, 1) # Line color when focused
    multiline: False
    password:True

    MDRoundFlatButton:
    text: "log in"
    font_size: 20
    pos_hint:{"center_x": 0.5}
    on_press: LogingScreen.login()
    MDRoundFlatButton:
    text: "reset"
    font_size: 20
    pos_hint:{"center_x": 0.5}
    on_press: LoginScreen.reseting_login()

    """


    class MenuScreen(Screen):
    pass


    class LoginScreen(Screen):
    def build(self):
    self.theme_cls.theme_style = "Dark"
    self.theme_cls.primary_palette = 'BlueGray'
    try:
    self.client = pymongo.MongoClient(
    "mongodb+srv://gyanyoni25:yonigyan@patnouv.hhopv.mongodb.net/?retryWrites=true&w=majority&appName=PatNouv" # Correct format
    )
    self.db = self.client["Users"] # Replace with your DB name
    self.collection = self.db["Clients"] # Replace with your collection name
    # Test connection (optional)
    self.client.admin.command('ping')
    print("Successfully connected to MongoDB Atlas!")
    except ConnectionFailure as e:
    print(f"Connection failed during startup: {e}")
    self.root.ids.welcome_label.text = "Database Connection Error" # Show error in UI
    return # Prevent app from loading if connection fails
    except Exception as e:
    print(f"An unexpected error occurred during startup: {e}")
    self.root.ids.welcome_label.text = "Database Connection Error" # Show error in UI
    return

    return Builder.load_file('loginpage.kv')

    def login(self):
    name_data = self.root.ids.name.text
    number_data = self.root.ids.number.text
    password_data = self.root.ids.password.text

    if name_data and number_data and password_data:
    try:
    hashed_password = hashlib.sha256(password_data.encode()).hexdigest()

    user_data = {
    "name": name_data,
    "number": number_data,
    "password": hashed_password
    }

    self.collection.insert_one(user_data)
    print("Login Successful")
    self.root.ids.welcome_label.text = f"Hey, {name_data}"
    self.reseting_login()

    except ConnectionFailure as e:
    print(f"Connection error during login: {e}")
    self.root.ids.welcome_label.text = "Connection Error"
    except DuplicateKeyError as e:
    print(f"Duplicate key error: {e}")
    self.root.ids.welcome_label.text = "Username/Number already exists"
    except Exception as e:
    print(f"An error occurred during login: {e}")
    self.root.ids.welcome_label.text = "An error occurred"

    else:
    print("Please fill in all fields.")
    self.root.ids.welcome_label.text = "Please fill in all fields"

    def reseting_login(self):
    self.root.ids.name.text = ""
    self.root.ids.number.text = ""
    self.root.ids.password.text = ""
    self.root.ids.welcome_label.text = "Welcome" # Reset welcome message



    class SignupScreen(Screen):
    pass


    # Create the screen manager
    sm = ScreenManager()
    sm.add_widget(MenuScreen(name='menu'))
    sm.add_widget(LoginScreen(name='Login'))
    sm.add_widget(SignupScreen(name='SignUp'))


    class egy (MDApp):

    def build(self):
    screen = Builder.load_string(screen_helper)
    return screen


    What I tried:

    1. At first it was app.reseting_login(). So I changed app to LoginScreen (name of my function).
    2. I made sure that the screen in the kivy code and the class had the same name
    3. Changing into a .kv file (worked, but I don't want to take the easy way out).

    Continue reading...

Compartilhe esta Página