I was in the process of moving all the initialisation python code to the main.py file that i have and in the process of doing so, my login page went from looking like this, to this. The top bar was a box layout which is not working. I wanted to check whether it was the .kv file or the python that i wrote, so I changed the position of the BoxLayout and put it at the bottom and it worked. See here. I want to know what went wrong with the code and how i can go about fixing it because this has never happened to me before.
Here is the main.py file
from kivy.app import App
from kivy.core.window import Window
from kivy.uix.screenmanager import Screen, ScreenManager
from LogInWindow import LogInWindow # importing the class from Login.py
class WindowManager(ScreenManager):
pass
sm = WindowManager()
screens = [LogInWindow(name="Login_window")]
for screen in screens:
sm.add_widget(screen)
sm.current = "Login_window"
class FitnessApp(App):
def build(self):
App.title = "Fitness App"
Window.size = (1080, 720)
return sm
if __name__ == '__main__': # The value of __name__ attribute is set to “__main__” when module is run as main program
FitnessApp = FitnessApp()
FitnessApp.run()
And here is the kivy file (with the box layout on top where is does not work)
<LogInWindow>:
id: Login_window ## setting the id to Login_window
orientation: "vertical" ## setting orientation to vertical
space_x: self.size[0]/4.5 ## setting space to a 1/4.5 of the screen either side
BoxLayout: ## setting up a box layout for the top bar
size_hint_y: None ## setting size hint to none so it can be set to anything
height: 100 ## setting height to 100
canvas.before:
Color:
rgba: (0, 0, 0, 1) ## changing the colour of the top bar
Rectangle:
size: self.size ## setting position of rect to the position of the box
pos: self.pos ## setting size of rect to the size of the box
Label: ## creating the "title"
text: "Login" ## setting the text
font_size: 48 ## changing the font size
bold: True ## changing it to bold
size_hint_x: .9 ## setting hint to 90%
BoxLayout: ## setting up a box layout for the rest of the page
orientation: 'vertical' ## setting orientation to vertical
padding: Login_window.space_x, 10 ## setting the padding between box and children
spacing: 20 ## adding a spacing between the child widgets
canvas.before:
Color:
rgba: (212/255,212/255,212/255, 1) ## setting colour to light grey
Rectangle:
size: self.size ## setting size to the size of the box layout
pos: self.pos ## setting position to the position of the box layout
BoxLayout:
orientation: "vertical" ## setting orientation to vertical
spacing: 30 ## adding a spacing between the child widgets
size_hint_y: None ## setting size hint to none so it can be set to anything
height: 170 ## setting height to 170
canvas.before:
Color:
rgba: (212/255,212/255,212/255, 1) ## setting colour to light grey
Rectangle:
size: self.size ## setting size to the size of the box layout
pos: self.pos ## setting position to the position of the box layout
Label:
id: info ## setting id to info
text: '' ## setting the text to empty
markup: True ## allows styling of text
size_hint_y: None ## setting size hint to none so it can be set to anything
height: 20 ## setting height to 20
TextInput: ## creating a text input for username
id: username_field ## setting the id to username_field
size_hint_x: 1 ## setting the size hint to 1 so it spans the whole box
hint_text: "Username" ## setting the translucent text to username
font_size: 24 ## setting font size to 24
multiline: False ## not allowing multiline inputs
write_tab: False ## making tab go to the password field, not create 4 spaces
focus: True ## lets the tab key work
on_text_validate: password_field.focus = True ## will check if password is filled if enter key pressed
TextInput: ## creating a text input for password
id: password_field ## setting the id to password_field
hint_text: "Password" ## setting the translucent text to Password
font_size: 24 ## setting font size to 24
multiline: False ## not allowing multiline inputs
write_tab: False ## does not allow the tab to create 4 spaces
password: True ## sets characters to *
on_text_validate: root.validate_user() ## runs the function to validate
Label: ## creating a label for spacing
id: spacing ## set the id to spacing
size_hint_y: None ## setting size hint to none so it can be set to anything
height: 40 ## setting height to 40
Button:
text: "Don't have an account? Sign Up Here!" ## setting the text to the sign up
font_size:20 ## changing font size
size_hint_y: None ## setting size hint to none so it can be set to anything
height: 60 ## setting height to 60
background_color: (0, 0, 0, 1) ## setting background colour
background_normal: '' ## changing the background_normal to nothing
on_release: root.validate_user() ##will change to put it to sign up screen
Button:
text: "Sign In" ## setting the text to the sign in
bold: True ## changing it to bold
font_size:48 ## changing font size
size_hint_y: None ## setting size hint to none so it can be set to anything
height: 100 ## setting height to 100
background_color: (0, 0, 0, 1) ## setting background color to white
background_normal: '' ## background normal to nothing
on_release: root.validate_user() ## setting the button to validate the user
Label: ## creating a label for spacing
id: spacing2 ## setting id to spacing2
And just for reference, here is the first few lines of the class that main.py opens when it is started.
class LogInWindow(Screen, BoxLayout): # creating LogInWindow class
kv = Builder.load_file("LogInWindow.kv") # loading the kivy file which has all the
Any help would be greatly appreciated.
Your LoginWindow
is using multiple inheritance of both Screen
and BoxLayout
. The Screen
class extends RelativeLayout
and therefore has a do_layout()
method that follows its own rules for laying out its children. The BoxLayout
also has a do_layout()
that follows the BoxLayout
rules for laying out its children. So, how do the children of your LoginWindow
get laid out?
Python has a Method Resolution Order that determines which do_layout()
method is called in this situation. In your case the do_layout()
of the Screen
class will be called. So, the result is that the children of LoginWindow
are not laid out using BoxLayout
rules, but rather using RelativeLayout
rules. Which means that the last child is likely to be drawn over previous children (as you are seeing).
You must carefully consider this whenever you use multiple inheritance to avoid this common problem. I would suggest changing LoginWindow
to only inherit from Screen
, and just use a top level BoxLayout
in its kv
rule.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments