Python Kivy TextInput not working? - python

I have created a simple login and registration screen using kivy, but the TextInput do not let me type inside of it? This error is occuring on both the LoginScreen and the RegistrationScreen. I tried looking up past questions on here, but i couldn't find anything.
The Python file:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
class Login_Screen(Screen):
def login(self):
if self.ids.username.text == "root" and\
self.ids.passwrd.text == "123":
print("Direct Entry")
self.manager.current = "Login_Successful"
else:
print("Wrong Password")
self.manager.current = "Login_Failed"
def registration(self):
self.manager.current = "Registration_Screen"
class LoginConfirmationScreen(Screen):
pass
class Registration_Screen(Screen):
def MainScreen(self):
self.manager.current = "Login_Screen"
class Login_Failed(Screen):
def MainScreen(self):
self.manager.current = "Login_Screen"
class RootWidget(ScreenManager):
pass
Builder.load_file("MainApp.kv")
class MainApp(App):
def build(self):
return RootWidget()
if __name__ == "__main__":
MainApp().run()
And the MainApp.kv file:
<RootWidget>:
id: Main
Login_Screen:
id: login
name: "Login_Screen"
Login_Failed:
id: Failed
name: "Login_Failed"
Registration_Screen:
id: register
name: 'Registration_Screen'
<Login_Screen>:
GridLayout:
rows:3
cols:2
Label:
text: "Username:"
font_size: 20
TextInput:
id: username
multiline: False
hint_text: 'Enter your Username'
Label:
text: "Password"
font_size: 20
TextInput:
id: passwrd
multiline: False
hint_text: 'Enter your Password'
password: True
Button:
text: "Register"
on_press: root.registration()
Button:
text: "Sign In"
on_press: root.login()
<Registration_Screen>:
GridLayout:
rows:3
cols:2
Label:
text: 'First Name:'
font_size: 20
TextInput:
id: FirstName
multiline: False
hint_text: 'Enter your First Name'
Label:
text: 'Surname'
font_size: 20
TextInput:
id: Surname
multiline: False
hint_text: 'Enter your Surname'
Button:
text: "Create Account"
on_press: root.MainScreen()
<Login_Failed>:
BoxLayout:
orientation: "vertical"
Label:
text: "Login Failed"
Button:
text: "Try again"
on_press: root.MainScreen()
Thanks for help :)

Remove this:
Builder.load_file("MainApp.kv")
from your py file because you're App instance, ie:
class MainApp(App):
Loads it automatically already.

Related

Why does Kivy ScreenManager not recognize my screen in Kivy?

This is my first time asking a question, and a beginner to Python and Kivy.
While running a program using Kivy, I developed some screens which operated as planned. However, when adding a new screen, it was not recognized and this error was returned.
File "kivy_event.pyx", line 1154, in kivy._event.EventObservers._dispatch
File "C:\Users\MyName\AppData\Local\Programs\Python\Python39\lib\site-packages\kivy\uix\screenmanager.py", line 1045, in on_current
screen = self.get_screen(value)
File "C:\Users\MyName\AppData\Local\Programs\Python\Python39\lib\site-packages\kivy\uix\screenmanager.py", line 1071, in get_screen
raise ScreenManagerException('No Screen with name "%s".' % name)
kivy.uix.screenmanager.ScreenManagerException: No Screen with name "sign_up_screen_success".
Here is my main.py code:
import os
os.chdir(r"C:\Users\MyName\Documents\mobile app")
from kivy.app import App
import json
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from datetime import datetime
Builder.load_file('design.kv')
class LoginScreen(Screen):
def sign_up(self):
self.manager.current = "sign_up_screen"
class RootWidget(ScreenManager):
pass
class SignUpScreen(Screen):
def add_user(self, uname, pword):
with open("users.json") as file:
users = json.load(file)
users[uname] = {'username': uname, 'password': pword,
'created': datetime.now().strftime("%Y-%m-%d %H-%M-%S")}
with open("users.json", 'w') as file:
json.dump(users, file)
self.manager.current = "sign_up_screen_success"
class SignUpScreenSuccess(Screen):
pass
class MainApp(App):
def build(self):
return RootWidget()
if __name__ == "__main__":
MainApp().run()
And here is my .kv code:
<LoginScreen>:
GridLayout:
cols: 1
GridLayout:
cols: 1
Label:
text: "User Login"
TextInput:
hint_text: "Username"
TextInput:
hint_text: "Password"
Button:
text: "Login"
GridLayout:
cols: 2
Button:
text: "Forgot Password?"
Button:
text: "Sign Up"
on_press: root.sign_up()
<SignUpScreen>:
GridLayout:
cols: 1
Label:
text: "Sign up for a space journey!"
TextInput:
id: username
hint_text: "Username"
TextInput:
id: password
hint_text: "Password"
Button:
text: "Submit"
on_press: root.add_user(root.ids.username.text, root.ids.password.text)
<SignUpScreenSuccess>:
GridLayout:
cols: 1
Label:
text: "Sign up successful!"
Button:
text: "Login page"
<RootWidget>:
LoginScreen:
name: "login_screen"
SignUpScreen:
name: "sign_up_screen"
SignUpScreenSuccess:
name: "sign_up_screen_success"
From what I gathered, since I defined "sign_up_screen_success" to correspond with SignUpScreenSuccess in the RootWidget of my .kv code, I should proceed to a different screen. So, why is this not working?
SignUpScreen and LoginScreen worked fine, but I could not see any difference in code between those and SignUpScreenSuccess.
If I need to clarify anything else, let me know.
Thanks.
Im not sure that it solves the problem, but in examples I've seen and according to the documentation:
https://kivy.org/doc/stable/guide/lang.html
The root widget in the kv doesn't have the <> brackets.
like so:
RootWidget:
LoginScreen:
name: "login_screen"
SignUpScreen:
name: "sign_up_screen"
SignUpScreenSuccess:
name: "sign_up_screen_success"
Hey I've been working on Kivy aswell the last weeks. Could you try initialising the names like this:
<LoginScreen>:
name: "login_screen"
GridLayout:
cols: 1
GridLayout:
cols: 1
Label:
text: "User Login"
TextInput:
hint_text: "Username"
TextInput:
hint_text: "Password"
Button:
text: "Login"
GridLayout:
cols: 2
Button:
text: "Forgot Password?"
Button:
text: "Sign Up"
on_press: root.sign_up()
<SignUpScreen>:
name: "sign_up_screen"
GridLayout:
cols: 1
Label:
text: "Sign up for a space journey!"
TextInput:
id: username
hint_text: "Username"
TextInput:
id: password
hint_text: "Password"
Button:
text: "Submit"
on_press: root.add_user(root.ids.username.text, root.ids.password.text)
<SignUpScreenSuccess>:
name: "sign_up_screen_success"
GridLayout:
cols: 1
Label:
text: "Sign up successful!"
Button:
text: "Login page"
<RootWidget>:
LoginScreen:
SignUpScreen:
SignUpScreenSuccess:
I coded my screens like this, this should work I think

Kivy Unknown class <NavigationDrawerIconButton>

Trying kv using the example https://github.com/FranciscoCarbonell/kivymd-login-example but got `kivy.factory.FactoryException: Unknown class
Problem is in
MainNavigationLayout:
MDNavigationDrawer:
id: navigation_drawer
drawer_logo: "menu.png"
NavigationDrawerIconButton:
icon: "home"
text: "Inicio"
on_release: screen_manager.current = "screen_inicio"
NavigationDrawerIconButton:
icon: "lock"
text: "Pagina segunda"
on_release: screen_manager.current = "screen_segundo"
You are getting this error because the usage of navigation drawer has changed refer to
https://github.com/kivymd/KivyMD/wiki/Components-Navigation-Drawer#using-mdnavigationdrawer-has-changed
If you are looking for a login example.
Here is a login form I have designed earlier (username:admin, password:admin) :
login.py
from kivymd.app import MDApp
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager as scr_mngr
from kivymd.toast import toast
from kivy.core.window import Window
from kivymd.uix.tab import MDTabsBase
from kivy.uix.floatlayout import FloatLayout
class Tab(FloatLayout, MDTabsBase):
pass
class MyLayout(BoxLayout):
def check_data_login(self):
self.ids['spinner'].active=True
username = self.ids['username'].text
password = self.ids['password'].text
print(username)
print(password)
if not username and not password:
toast("Username and password are required")
elif not username:
toast("Username is required ")
elif not password:
toast("Password is required")
else:
if username == "admin" and password == "admin":
self.ids['spinner'].active=False
self.change_screen("screen2")
else:
self.ids['spinner'].active=False
toast("Wrong username or password")
def change_screen(self, screen, *args):
self.scr_mngr.current = screen
class DemoApp(MDApp):
pass
if __name__ == '__main__':
Window.show_cursor = True
Window.size = (360, 680)
DemoApp().run()
demo.kv
MyLayout:
scr_mngr: scr_mngr
orientation: 'vertical'
ScreenManager:
id: scr_mngr
Screen:
id: screen1
name: 'screen1'
MDSpinner:
id:spinner
size_hint: None, None
size: dp(46), dp(46)
pos_hint: {'center_x': .5, 'center_y': .5}
active: False
MDToolbar:
md_bg_color: 0, 0, 1, 1
title: "Login Screen"
pos_hint:{"top": 1}
elevation: 11
BoxLayout:
orientation: "vertical"
padding: "16dp"
spacing: "16dp"
size_hint_y: None
height: self.minimum_height
pos_hint: {"center_y": .6}
MDLabel:
text: "Log In"
halign: "center"
font_style: "H4"
size_hint_y: None
MDTextField:
id: username
hint_text: "Username "
helper_text_mode: "on_focus"
required: True
MDTextField:
id: password
hint_text: "Password "
helper_text_mode: "on_focus"
required: True
password: True
MDRaisedButton:
text: "LOGIN"
pos_hint: {"center_x": 0.5, "center_y": 0.3}
on_release: root.check_data_login()
Screen:
id: screen2
name: 'screen2'
BoxLayout:
orientation: 'vertical'
MDToolbar:
md_bg_color: 0, 0, 1, 1
id: toolbar
title: "Page 2"
BoxLayout:
orientation: 'vertical'
MDTabs:
Tab:
text: "Tab1"
Tab:
text: "Tab2"

errors in results after launching program

this is my 1st time posting here and am so amazed how genius people here are.
i have written a python code using kivy and it works perfectly on my computer even on kivy launcher for android, but the problem is that the result on my phone is always ignoring the float numbers and show just the 1s one.
thanks in advance
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.config import Config
import time
Builder.load_string("""
<Main>:
GridLayout:
cols:2
Button:
text: "Engine Consumption"
on_press: root.manager.current = "test1"
Button:
text: "Apu Consumption"
on_press: root.manager.current = "test2"
<Test1>
GridLayout:
cols: 2
Label:
text: "Flight Hours: "
TextInput:
id: FH
multiline: False
Label:
text: "Flight Minutes:"
TextInput:
id: FM
multiline: False
Label:
text: "Added Quantity:"
TextInput:
id: AQ
multiline: False
Button:
text: "get result"
on_press: root.get_result()
Label:
id: result
Button:
text: "To Main Page"
on_release: root.manager.current = "main"
Button:
text: "Apu Consumption:"
on_release: root.manager.current = "test2"
<Test2>
GridLayout:
cols: 2
Label:
text: "Apu hours In Last Refill: "
TextInput:
id: FH
multiline: False
Label:
text: "Current Apu Hours:"
TextInput:
id: FM
multiline: False
Label:
text: "Added Quantity:"
TextInput:
id: AQ
multiline: False
Button:
text: "get result"
on_press: root.get_result()
Label:
id: result
Button:
text: "To main Page"
on_release: root.manager.current = "main"
Button:
text: "Engine Consumption"
on_release: root.manager.current = "test1"
""")
class Main(Screen):
pass
class Test1(Screen):
def get_result(self):
fh = self.ids.FH.text
fm = self.ids.FM.text
ad = self.ids.AQ.text
result = int(ad) / (int(fh) + int(fm) / 60)
self.ids.result.text = str(result)
self.ids.result.color = 1,0,1,1
class Test2(Screen):
def get_result(self):
fh = self.ids.FH.text
fm = self.ids.FM.text
ad = self.ids.AQ.text
result = int(ad) / (int(fm) - int(fh))
self.ids.result.text = "the result is: " + str(float(result))
class Test(App):
def build(self):
sm = ScreenManager()
sm.add_widget(Main(name = "main"))
sm.add_widget(Test1(name = "test1"))
sm.add_widget(Test2(name = "test2"))
return sm
Config.set("graphics", "height", "150")
if __name__ == "__main__":
Test().run()
on computer result is 0,4444
and on phone 0

Button to print the the Text Input is not working

The whole code is working well. But when u go to:
student > Add New student > > Fill all columns of new student > then submit
it's not working and I can't figure out the issue. Here is the following code. Any help will be appreciated
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen ,FadeTransition
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
import csv
from kivy.uix.textinput import TextInput
Builder.load_string("""
<MenuScreen>:
BoxLayout:
Button:
text: 'Teacher'
on_press: root.manager.current = 'screen1'
Button:
text: 'Student '
on_press:root.manager.current = 'screen2'
Button:
text: 'Quit'
<Screen1>:
BoxLayout:
Button:
text: 'Teacher Info'
#on_press:root.manager.current = 'login'
Button:
text: 'Teacher Attandance'
Button:
text: 'Add New Teacher'
on_press:root.manager.current = 'add_teacher'
Button:
text: 'Back'
on_press:root.manager.current ='menu'
<add_new_teacher>:
GridLayout:
cols:2
Label:
text:'Name'
TextInput:
id: name_input
multiline: False
Label:
text:'Father Name'
TextInput:
id: name_input
multiline: False
Label:
text: 'Mother Name'
TextInput:
id: name_input
multiline: False
Label:
text: 'Class'
TextInput:
id: name_input
multine: False
Label:
text:'Roll no.'
text: 'Student Info'
on_press:root.csv_std()
Button:
text: 'Student Attandance'
# on_press:root.manager.current ='login'
Button:
text: 'Add New Student'
on_press:root.manager.current = 'add_student'
Button
text: 'Back'
on_press:root.manager.current = 'menu'
<add_new_student>:
GridLayout:
cols:2
Label:
text:'Name'
TextInput:
id: self.name
multiline: False
Label:
text:'Father Name'
TextInput:
id: self.fname
multiline: False
Label:
text: 'Mother Name'
TextInput:
id: self.mname
multiline: False
Label:
text: 'Class'
TextInput:
id: self.c
multine: False
Label:
text:'Roll no.'
TextInput:
id: self.r
multiline:False
Button:
text:'Print'
Button:
text:'Submit'
on_press:root.print_text()
Button:
text:'Back'
on_press:root.manager.current= 'screen2'
""")
# Declare both screens
class MenuScreen(Screen):
pass
class add_new_teacher(Screen):
pass
class Screen1(Screen):
pass
class Screen2(Screen):
def csv_std(self):
f = open("a.csv", 'r')
reader = csv.reader(f)
for row in reader:
print(" ".join(row))
pass
class add_new_student(Screen):
def print_text(self):
for child in reversed(self.children):
if isinstance(child, TextInput):
print child.text
pass
# Create the screen manager
sm = ScreenManager()
sm.add_widget(MenuScreen(name='menu'))
sm.add_widget(add_new_teacher(name='add_teacher'))
sm.add_widget(add_new_student(name='add_student'))
sm.add_widget(Screen1(name='screen1'))
sm.add_widget(Screen2(name='screen2'))
class TestApp(App):
def build(self):
return sm
if __name__ == '__main__':
TestApp().run()
You code formatting was horrible, but at least you didn't use backticks. For future cases, copy&paste your whole example you want to show here, then select that example(whole) and press Ctrl + K, which will indent all selected lines, so that it'd look ok.
The code works exactly how it supposed to work, because root.print_text() targets add_new_student class and its children - not GridLayout which you want to access.
Edit the line with for to this: for child in reversed(self.children[0].children): and you are good to go. :)
Or more efficient solution would be to get that Screen to behave as a layout too, which you can get with inheritting both from Screen and some layout, but ensure the layout is first:
class add_new_student(GridLayout, Screen):
def print_text(self):
for child in reversed(self.children):
if isinstance(child, TextInput):
print child.text
kv:
<add_new_student>:
cols:2
Label:
text:'Name'

Showing widget before SOAP connection

Problem is in LoginForm.log_in() (code below)
I would like in that order:
clear widgets
show MenuWindow widget
connect via SOAP.
Unfortunately I can't. I don't know why but my app first tries to connect to SOAP server and then cleans widget tree and creates new.
main.py:
# coding=utf-8
from kivy.app import App
from kivy.properties import ObjectProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.factory import Factory
from kivy.storage.jsonstore import JsonStore
from suds.client import Client
import sys
import os
import time, threading
class LoginForm(BoxLayout):
login_input = ObjectProperty()
password_input = ObjectProperty()
def log_in(self):
self.clear_widgets()
menu = Factory.MenuWindow()
self.add_widget(menu)
MenuWindow.change_caption(MenuWindow)
def show_settings(self):
self.clear_widgets()
pokaz = Factory.SettingsWindow()
self.add_widget(pokaz)
def set_written_data_ip():
store = JsonStore('anakonda_mobile.json')
if store.exists('Adres'):
print(store.get('Adres'))
if store.get('Adres')['ip'].strip() != '':
return store.get('Adres')['ip']
else:
return ''
def set_written_data_port():
store = JsonStore('anakonda_mobile.json')
if store.exists('Adres'):
if store.get('Adres')['port'].strip() != '':
return store.get('Adres')['port']
else:
return ''
class SettingsWindow(BoxLayout):
ip_value = ObjectProperty(set_written_data_ip())
port_value = ObjectProperty(set_written_data_port())
def show_logging(self):
self.clear_widgets()
self.add_widget(LoginForm())
def save_ip_port(self):
store = JsonStore('anakonda_mobile.json')
store.put('Adres', ip=self.ip_input.text, port=self.port_input.text)
python = sys.executable
os.execl(python, python, *sys.argv)
class MenuWindow(BoxLayout):
def soap_connect(self):
try:
self.a = Client('http://192.168.1.1:7789/ASOAPService?wsdl')
except Exception as g:
return ''
def change_caption(self):
self.soap_connect(self)
return 'SOAP connected'
class MobileApp(App):
pass
if __name__ == '__main__':
MobileApp().run()
mobile.kv
LoginForm:
<LoginForm>:
login_input: _login
password_input: _password
orientation: "vertical"
BoxLayout:
height: "40dp"
size_hint_y: None
Label:
text: 'Login: '
TextInput:
focus: True
multiline: False
id: _login
Label:
text: 'Hasło: '
TextInput:
multiline: False
id: _password
password: True
BoxLayout:
height: "40dp"
size_hint_y: None
Button:
text:'Zaloguj'
on_press: root.log_in()
Button:
text: 'Ustawienia'
on_press: root.show_settings()
BoxLayout:
<SettingsWindow>:
ip_input: _ip
port_input: _port
orientation: 'vertical'
BoxLayout:
height: "40dp"
size_hint_y: None
Label:
text: 'IP: '
TextInput:
focus: True
multiline: False
id: _ip
text: root.ip_value
Label:
text: 'Port: '
TextInput:
multiline: False
id: _port
text: root.port_value
Button:
text: 'Cofnij'
on_press: root.show_logging()
Button:
text: 'Zapisz'
on_press: root.save_ip_port()
<MenuWindow>
orientation: 'vertical'
BoxLayout:
BoxLayout:
height: "40dp"
size_hint_y: None
Label:
id: _napis
text: 'polaczenie'
#text: root.change_caption()
Button:
text: 'Cofnij'

Categories