Skip to content
Advertisement

Kivy: Labels not being displayed in python file with add_widget()

I’m quite new to Kivy and have been repeatedly having issues with displaying things. I am building a basic app to track students, assign them to school houses (like in Harry Potter) and display them. I created a “for” loop to add users to labels in a stack layout which would then display them in a scroll view, but for some reason, when I run the file, nothing is displayed. I have no idea what is going on. Please run the file yourself, to troubleshoot the problem

Note: The problem concerns lines 261-280 in the python file

Python file:

from os.path import join
from random import random, choice
from kivy.app import App
from kivy.config import Config
Config.set('graphics', 'width', '400')
Config.set('graphics', 'height', '600')
from kivy.storage.jsonstore import JsonStore
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.checkbox import CheckBox
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.uix.scrollview import ScrollView
from kivy.uix.dropdown import DropDown
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
from kivy.core.window import Window

class LoginScreen(Screen): #This screen is the first window displayed when the program runs
    developer_version = StringProperty('1.0.0') #Incriment with each software update/patch. Patch ex.: 1.0.1 and Update ex.: 1.1.0
    email = ObjectProperty(None)        #Email variable which will recieve text data from Kivy
    password = ObjectProperty(None)     #Password variable which will recieve text data from Kivy
    id_credentials = None               #A variabled used to identify which password file the user has sign in through
    id_name = {}                        #A dict used to assign the user an id based off which password file they sign in through
    remember_login_user = None          #A (to be) boolean used to determine whether the user wants to remember their login data
    user_found_line = None              #Identifies what line the user's data appeared in their respective password file
    specific_house = ''                 #A stringed int for which house the user has selected
    check_box_cond = ObjectProperty(None) #Checks whether the "remeber login" checkbox is active
    index_count = 0 #Keeps track of what line login credentials are on
    cred_name = '' #Stores the user's login data that is within the ..._user dict
    passwordStudents = open('passwords/passwordStudents.txt', 'r')  #40-43 all read the login text files used to check if login credentials are correct
    passwordTeachers = open('passwords/passwordTeachers.txt', 'r')
    passwordAdmin = open('passwords/passwordAdmin.txt', 'r')
    #student_char_creds = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '@', '.'] <--- Likely won't need this
    student_user = {}
    teacher_user = {}
    admin_user = {}

    for i in passwordStudents:
        first, last, email, password = i.strip().split(';')
        student_user[f'{first} {last}'] = (email, password)

    for i in passwordTeachers:
        first, last, email, password = i.strip().split(';')
        teacher_user[f'{first} {last}'] = (email, password)

    for i in passwordAdmin:
        first, last, email, password = i.strip().split(';')
        admin_user[f'{first} {last}'] = (email, password)

    passwordStudents.close()
    passwordTeachers.close()
    passwordAdmin.close()

    def loginBtn(self): #Checks eamil and password to assess whether user credentials are correct and if said user is a student, teacher, or admin
        login_email = self.email.text
        login_password = self.password.text
        login_lst = self.email.text + ', ' + self.password.text
        su = False
        tu = False
        au = False

        for i in self.student_user.values():
            if login_email in i:
                self.cred_name = i
                if i[0] + ', ' + i[1] == login_lst:
                    su = True
                    login_lst = ''
                    self.id_credentials = 'Student'
                    self.user_cred(self.student_user)
                    self.reset()
                    self.home()
                else:
                    su = True
                    self.reset()
                    self.login_error()
            self.index_count += 1

        for i in self.teacher_user.values():
            if login_email in i:
                self.cred_name = i
                if i[0] + ', ' + i[1] == login_lst:
                    tu = True
                    login_lst = ''
                    self.id_credentials = 'Teacher'
                    self.user_cred(self.teacher_user)
                    self.reset()
                    self.home()
                else:
                    tu = True
                    self.reset()
                    self.login_error()
            self.index_count += 1

        for i in self.admin_user.values():
            if login_email in i:
                self.cred_name = i
                if i[0] + ', ' + i[1] == login_lst:
                    au = True
                    login_lst = ''
                    self.id_credentials = 'Admin'
                    self.user_cred(self.admin_user)
                    self.reset()
                    self.home()
                else:
                    au = True
                    self.reset()
                    self.login_error()
            self.index_count += 1

        if su == False:
            if tu == False:
                if au == False:
                    self.reset()
                    self.login_error()

    def reset(self):    #Resets textinputs in login
        self.email.text = ''
        self.password.text = ''

    def home(self):     #Redirects user to home window
        sm.transition.direction = 'up'
        sm.current = 'home'

    def login_error(self):  #Handles login errors
        buttons = Button(text='Got It')
        labels = Label(text='Invalid username or password nn')
        grids = GridLayout(rows=2)
        grids.add_widget(labels)
        grids.add_widget(buttons)
        pop = Popup(title='Invalid Login',
                  content=grids,
                  size_hint=(None, None), size=(450, 450),
                  auto_dismiss=False)
        buttons.bind(on_press=pop.dismiss)
        pop.open()

    def user_cred(self, cred): #Gives user an id
        key_lst = list(cred.keys())
        val_lst = list(cred.values())
        pos = val_lst.index(self.cred_name)
        self.id_name[key_lst[pos]] = self.id_credentials

    def remember_login(self): #Allows users to remeber their login data for the next time they login
        '''
        a = list(str(open(f'passwords/password{self.id_credentials}.txt').readlines(self.user_found_line)))
        for i in range(2):
            a.pop(0)
            a.pop(-1)
        for i in range(2):
            a.pop(-1)
        b = ''.join(a)
        c = b.split(' ')
        remember_dir_file = c[-1]
        if remember_dir_file == 'True':
            self.email.text = 
        '''
        pass

    def check_if_box_active(self): #Allows users to access app without needing to sign in every time
        pass

class HomeScreen(Screen):   #The main page that the user is directed to
    def return_to_login_Btn(self):
        sm.transition.direction = 'down'
        sm.current = 'login'
        LoginScreen().id_name.clear()

    def check_user_id_1(self):
        if list(LoginScreen().id_name.values())[0] == 'Student':
            StudentsGridList().foo('1')
            sm.transition.direction = 'left'
            sm.current = 'studentHome'

        elif list(LoginScreen().id_name.values())[0] == 'Teacher':
            StudentsGridList().foo('1')
            sm.transition.direction = 'left'
            sm.current = 'teacherHome'

        elif list(LoginScreen().id_name.values())[0] == 'Admin':
            StudentsGridList().foo('1')
            sm.transition.direction = 'left'
            sm.current = 'adminHome'

    def check_user_id_2(self):
        if list(LoginScreen().id_name.values())[0] == 'Student':
            StudentsGridList().foo('2')
            sm.transition.direction = 'left'
            sm.current = 'studentHome'

        elif list(LoginScreen().id_name.values())[0] == 'Teacher':
            StudentsGridList().foo('2')
            sm.transition.direction = 'left'
            sm.current = 'teacherHome'

        elif list(LoginScreen().id_name.values())[0] == 'Admin':
            StudentsGridList().foo('2')
            sm.transition.direction = 'left'
            sm.current = 'adminHome'

    def check_user_id_3(self):
        if list(LoginScreen().id_name.values())[0] == 'Student':
            StudentsGridList().foo('3')
            sm.transition.direction = 'left'
            sm.current = 'studentHome'

        elif list(LoginScreen().id_name.values())[0] == 'Teacher':
            StudentsGridList().foo('3')
            sm.transition.direction = 'left'
            sm.current = 'teacherHome'

        elif list(LoginScreen().id_name.values())[0] == 'Admin':
            StudentsGridList().foo('3')
            sm.transition.direction = 'left'
            sm.current = 'adminHome'

    def check_user_id_4(self):
        if list(LoginScreen().id_name.values())[0] == 'Student':
            StudentsGridList().foo('4')
            sm.transition.direction = 'left'
            sm.current = 'studentHome'

        elif list(LoginScreen().id_name.values())[0] == 'Teacher':
            StudentsGridList().foo('4')
            sm.transition.direction = 'left'
            sm.current = 'teacherHome'

        elif list(LoginScreen().id_name.values())[0] == 'Admin':
            StudentsGridList().foo('4')
            sm.transition.direction = 'left'
            sm.current = 'adminHome'

    def foobar(self):
        sm.current = 'spec'

class StudentSpecificHomeScreen(Screen):    #Students can access their students' house pages
    def return_to_home_Btn(self):
        sm.transition.direction = 'right'
        sm.current = 'home'

class TeacherSpecificHomeScreen(Screen):    #Teachers can access their teachers' house pages
    def return_to_home_Btn(self):
        sm.transition.direction = 'right'
        sm.current = 'home'

class AdminSpecificHomeScreen(Screen):  #Admin can access their admins' house pages
    def return_to_home_Btn(self):
        sm.transition.direction = 'right'
        sm.current = 'home'

class StudentsGridList(StackLayout):    #Lists and orders students into a StackLayout
    def foo(self, specific_house):
        print(specific_house)
        if int(specific_house) == int:
            house_users = open(f'houses/house{specific_house}.txt', 'r')
            for user in house_users:
                user = user.split('n')[0]
                if user == 'Griffin Neal':
                    user = f'[color=#000000][b]Dev:[/b] [color=#028A0F][i]{user}[/i]'
                else:
                    user = f'[color=#000000]{user}'
                size = dp(150)
                labels = Label(text=user, size_hint=(None,None), size=(size, size), bold=True, markup=True)
                self.add_widget(labels)
            house_users.close()
        else:
            pass

class StudentsList(ScrollView): #Lists all students in a scroll view
    pass

def SortingHat():   #Admins can use this to randomly sort students into houses
    pass

class WindowManager(ScreenManager):
    pass

sm = WindowManager()

class MyApp(App):
    def build(self):
        screens = [LoginScreen(name='login'), 
            HomeScreen(name='home'), 
            StudentSpecificHomeScreen(name='studentHome'), 
            TeacherSpecificHomeScreen(name='teacherHome'), 
            AdminSpecificHomeScreen(name='adminHome')]
        for screen in screens:
            sm.add_widget(screen)
        sm.current = 'login'
        Window.clearcolor = (230/255,230/255,230/255,1)
        return sm

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

Kivy file:

LoginScreen:

<LoginScreen>:
    name: "login"
    email: email
    password: psswrd
    check_box_cond: checks
    BoxLayout:
        orientation: "vertical"
        canvas.before:
            Color:
                rgba: 1,1,1,1
        Label:
            text: "Login"
            pos: 0, root.height/3
            font_size: 100
            color: 50/255,50/255,50/255,1
        GridLayout:
            cols: 2
            Label:
                size_hint: None, None
                width: "175dp"
                height: "50dp"
                text: "Email:"
                font_size: 50
                color: 50/255,50/255,50/255,1
            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
                color: 50/255,50/255,50/255,1
            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
        GridLayout:
            cols: 3
            row_force_default: True
            row_default_height: "40"
            Label:
                text: ""
                size_hint_x: None
                width: "100dp"
            CheckBox:
                id: checks
                color: 0,0,0,1
                size_hint_x: None
                width: "40dp"
                on_active: 
                    root.remember_login()
            Label:
                font_size: (root.width**2 + root.height**2) / 14**4 - 20
                text: "Remeber sign in?"
                color: 50/255,50/255,50/255,1
                size_hint_x: None
                width: "160dp"
        FloatLayout:
            Button:
                background_color: 1,1,1,1
                size_hint: None, None
                width: "150dp"
                height: "100dp"
                pos: root.width/2 - 150, root.height/4 - 250
                text: "Submit"
                font_size: (root.width**2 + root.height**2) / 14**4
                color: 10/255,10/255,10/255,1
                on_release:
                    root.loginBtn()
            Label:
                size_hint: None, None
                width: "150dp"
                height: "100dp"
                pos: root.width/2 - 150, root.height/4 - 375
                color: 10/255, 10/255, 10/255, 1
                text: f"Version: {root.developer_version}"

<HomeScreen>:
    name: "home"
    GridLayout:
        rows: 3
        BoxLayout:
            size_hint: 1, 0.15
            Label:
                text: ""
            Button:
                size_hint: 0.4, 1
                text: "Logout"
                font_size: (root.width**2 + root.height**2) / 14**4
                on_release:
                    root.return_to_login_Btn()
        GridLayout:
            cols: 2
            rows: 2
            Button:
                text: "House 1"
                font_size: (root.width**2 + root.height**2) / 14**4
                on_release:
                    root.check_user_id_1()
            Button:
                text: "House 2"
                font_size: (root.width**2 + root.height**2) / 14**4
                on_release:
                    root.check_user_id_2()
            Button:
                text: "House 3"
                font_size: (root.width**2 + root.height**2) / 14**4
                on_release:
                    root.check_user_id_3()
            Button:
                text: "House 4"
                font_size: (root.width**2 + root.height**2) / 14**4
                on_release:
                    root.foobar()

<StudentSpecificHomeScreen>:
    GridLayout:
        rows: 2
        name: "studentHome"
        FloatLayout:
            size_hint: 1, None
            height: root.height/6
            Button:
                pos: root.width/2 - root.width/4, root.height*3/4 + 85
                size_hint: None, None
                width: root.width/2
                height: "100dp"
                text: "Return Home"
                font_size: (root.width**2 + root.height**2) / 14**4
                on_release:
                    root.return_to_home_Btn()
        StudentsList:
            StudentsGridList:
                padding: ('20dp', '20dp', '20dp', '20dp')
                spacing: ('20dp', '20dp')
                size_hint: 1, None
                height: self.minimum_height

<TeacherSpecificHomeScreen>:
    name: "teacherHome"
    GridLayout:
        rows: 2
        Button:
            size_hint: None, None
            width: "175dp"
            height: "100dp"
            text: "Return Home"
            font_size: (root.width**2 + root.height**2) / 14**4
            on_release:
                root.return_to_home_Btn()

<AdminSpecificHomeScreen>:
    name: "adminHome"
    GridLayout:
        rows: 2
        Button:
            size_hint: None, None
            width: "175dp"
            height: "100dp"
            text: "Return Home"
            font_size: (root.width**2 + root.height**2) / 14**4
            on_release:
                root.return_to_home_Btn()

Fake student credentials text file (put it into a text file called “passwordStudents.txt” in a folder called “passwords”):

Griffin;Neal;griffin@taguspark.org;1234
Ela;Talor;ela1265@taguspark.org;4321
Lucas;Dore;lucas@taguspark.org;0987
Matilde;Obrien;matilde@taguspark.org;7890
Mia;McCabian;mia@gmail.com;9078
Eli;Cobbb;eli@gmail.com;6785
James;May;jame@gmail.com;4132
Connor;McCarren;connor@gmail.com;1626
Gabe;Newell;gaben@steam.com;0000

Student houses (create four text files with the students’ first and last names at random called “house1.txt”, “house2.txt”, etc. in a folder called “houses”)

Advertisement

Answer

A couple problems with your code:

  1. Everywhere you use code like StudentsGridList().foo('4'), you are creating a new instance of StudentsGridList and calling the foo() method of that new instance. Doing so will have no effect on the StudentsGridList instance that is in the StudentSpecificHomeScreen of your GUI.
  2. The if statement if int(specific_house) == int: in your foo() method will always be False, since your are comparing an integer to a built-in method.

To correct the first problem, you will probably need to use the get_screen() method of ScreenManager along with some ids in order to access the instance of StudentsGridList that is actually in your GUI. You will probably need to assign an id to the StudentsGridList. This can be done in your kv file:

    StudentsList:
        StudentsGridList:
            id: sgl  # added id
            padding: ('20dp', '20dp', '20dp', '20dp')
            spacing: ('20dp', '20dp')
            size_hint: 1, None
            height: self.minimum_height

Then, in your code you can replace:

StudentsGridList().foo('4')

with:

sm.get_screen('studentHome').ids.sgl.foo('4')

And similarly for the other occurrences of StudentsGridList().foo().

As for the second problem, I am not sure of the purpose of that if statement. Perhaps that if statement should just be removed.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement