最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

button - How to link kivy code (that isn't in a kivy file, but is in the python code) to classes? - Stack Overflow

programmeradmin2浏览0评论

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:[email protected]/?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.adminmand('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).

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:[email protected]/?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.adminmand('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).
Share Improve this question asked Mar 19 at 13:40 capitaine yoyoytbcapitaine yoyoytb 12 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

Your code for the reset button in the kv should be:

on_press: root.reseting_login()

If you use app instead of root, then the reseting_login() method will be expected to be in the app class, which is egy. If you use LoginScreen instead of root, then you are calling the reseting_login() method as if it were a static method, which it is not. You haven't included your non-kv approach, so I cannot comment on that.

The root in the above snippet refers to the root of the current kv rule, which is <LoginScreen>:

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论