Home > database >  Kivy: How to fix screens not displaying GUI
Kivy: How to fix screens not displaying GUI

Time:06-23

I'm very new to Kivy and have been constantly running into issues and errors. A common problem I have is running a python program, seeing that the .kv file is displaying a window, but there is nothing inside the window. The purpose of the code is to display a window starting on the LoginScreen and switching between a separate HomeScreen with a press of a button. Any solutions would be helpful. Thanks.

Python file:

import os
from kivy.app import App
from kivy.config import Config
Config.set('graphics', 'width', '400')
Config.set('graphics', 'height', '600')
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.popup import Popup
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.stacklayout import StackLayout
from kivy.metrics import dp
from kivy.properties import ObjectProperty, StringProperty, BooleanProperty, Clock
from kivy.graphics.vertex_instructions import Line, Rectangle, Ellipse
from kivy.graphics.context_instructions import Color

#transition_direction = StringProperty('down') <--- Ignore this

class HomeScreen(Screen):
    def returnBtn(self):
        sm.current = 'LoginScreen'

class LoginScreen(Screen):

    email = ObjectProperty(None)
    password = ObjectProperty(None)
    login_lst = []
    passwordStudents = open('passwords/passwordStudents.txt').read()
    passwordTeachers = open('passwords/passwordTeachers.txt').read()
    passwordAdmin = open('passwords/passwordAdmin.txt').read()

    def loginBtn(self):
        self.login_lst.append(self.email.text)
        self.login_lst.append(self.password.text)
        if self.login_lst[0] and self.login_lst[-1] in self.passwordStudents:
            print('Student: True')
            print('Teacher: False')
            print('Admin: False')
            self.reset()
            self.home()
        elif self.login_lst[0] and self.login_lst[-1] in self.passwordTeachers:
            print('Student: False')
            print('Teacher: True')
            print('Admin: False')
            self.reset()
            self.home()
        elif self.login_lst[0] and self.login_lst[-1] in self.passwordAdmin:
            print('Student: False')
            print('Teacher: False')
            print('Admin: True')
            self.home()
            self.reset()
        else:
            print('Student: False')
            print('Teacher: False')
            print('Admin: False')
            self.reset()

    def reset(self):
        self.email.text = ''
        self.password.text = ''

    def home(self):
        #transition_direction = 'down' <--- Ignore this
        sm.current = 'HomeScreen'

class WindowManager(ScreenManager):
    pass

sm = WindowManager()

screens = [LoginScreen(name='login'), HomeScreen(name='home')]
for screen in screens:
    sm.add_widget(screen)

sm.current = 'login'

class MyApp(App):
    def build(self):
        return sm

if __name__ == '__main__':
    MyApp().run()

Kivy file:

    <LoginScreen>:
    name: "login"
    email: email
    password: psswrd
    BoxLayout:
        orientation: "vertical"
        Label:
            text: "Login"
            pos: 0, root.height/3
            font_size: 100
        GridLayout:
            cols: 2
            Label:
                size_hint: None, None
                width: "175dp"
                height: "50dp"
                text: "Email:"
                font_size: 50
            TextInput:
                id: email
                multiline: False
                size_hint: None, None
                width: "200dp"
                height: "50dp"
                font_size: (root.width**2   root.height**2) / 14**4
        GridLayout:
            cols: 2
            Label:
                size_hint: None, None
                width: "175dp"
                height: "50dp"
                text: "Password:"
                font_size: 50
            TextInput:
                id: psswrd
                multiline: False
                size_hint: None, None
                width: "200dp"
                height: "50dp"
                password: True
                font_size: (root.width**2   root.height**2) / 14**4
        FloatLayout:
            Button:
                size_hint: None, None
                width: "150dp"
                height: "100dp"
                pos: root.width/2 - 150, root.height/4 - 150
                text: "Submit"
                font_size: 60
                on_release:
                    root.loginBtn()

<HomeScreen>:
    name: "home"
    Button:
        text: "Go back"
        on_release:
            root.returnBtn()

Edit: I have noticed that the code runs when I comment out these three lines. Why is that?

class MyApp(App):
    #def build(self):
    #   return sm
    pass

#if __name__ == '__main__':
MyApp().run()

CodePudding user response:

You are building your screens before your kv file is loaded, so the LoginScreen and the HomeScreen have nothing in them. If your kv file is correctly named (my.kv) then it will be automatically loaded when MyApp().run() is run and you can build your screens inside the build() method. If your kv file is not named that way, you can just add a call to Builder.load_file() in your build() method before your create the screens.

  • Related