Im relatively new to Kivy/KivyMD. I cant figure out how to take the values from the username and password text fields and turn them into variable in my python file when the sign up button is pressed.
Currently when the Signup button is clicked it just prints "clicked".
Any help would be greatly appreciated!
Below is my python file:
from kivymd.app import MDApp
from kivymd.uix.relativelayout import MDRelativeLayout
from kivy.lang import Builder
from kivy.properties import StringProperty, ObjectProperty
from kivy.uix.screenmanager import ScreenManager, Screen, SwapTransition
Builder.load_file('ALevelNEA.kv')
##Below are the classes for my different screens
class SignupScreen(Screen):
pass
class MenuScreen(Screen):
pass
class SigninScreen(Screen):
pass
## Below are the classes for my custom buttons, widgets and text fields
class PasswordField(MDRelativeLayout):
text = StringProperty()
hint_text = StringProperty()
pass
class EmailField(MDRelativeLayout):
text = StringProperty()
hint_text = StringProperty()
#email_field = ObjectProperty(None)
##Below is the code for my main app
class MainApp(MDApp):
def build(self):
sm = ScreenManager(transition= SwapTransition())
sm.add_widget(MenuScreen(name='menu'))
sm.add_widget(SigninScreen(name = 'signin'))
sm.add_widget(SignupScreen(name='signup'))
return sm
def RecordCheck(self):
print("clicked")
def AddToRecord(self):
print("clicked")
if __name__ == '__main__':
MainApp().run()
Below is my KV file:
#Below are my different screens
#Below is the Menu Screen
<MenuScreen>:
Screen:
Image:
source: "Logonb.png"
size_hint_x: 0.4
size_hint_y: 0.6
allow_stretch: True
pos_hint: {"center_x": 0.5, "center_y": 0.6 }
MDFillRoundFlatButton:
id: SignIn
text: "Sign in with email"
pos_hint: {"center_x": 0.5, "center_y": 0.2}
md_bg_color: 0.3607, 0.3882, 1
size_hint: 0.225, 0
on_release:
root.manager.current = "signin"
MDRoundFlatButton:
text: "Sign up"
pos_hint: {"center_x": 0.5, "center_y": 0.12}
text_color: 0.3607, 0.3882, 1
line_color: 0, 0, 0
on_release:
root.manager.current = "signup"
MDLabel:
text: "by continuing you agree to the"
font_size: 15
halign: 'center'
pos_hint: {"center_y": 0.07}
MDTextButton:
text: "Terms and Conditions"
font_size: 15
pos_hint: {"center_x": 0.5, "center_y": 0.0525}
theme_text_color: "Custom"
text_color: 0.3607, 0.3882, 1
# Below is my sign in Screen
<SigninScreen>:
Screen:
MDIconButton:
icon: "keyboard-backspace"
pos_hint: {"center_x": 0.35, "center_y": 0.95}
on_release:
root.manager.current = "menu"
Image:
source: "LoginImage.png"
size_hint_x: 0.4
size_hint_y: 0.6
allow_stretch: True
pos_hint: {"center_x": 0.5, "center_y": 0.7 }
MDLabel:
text: "Sign in"
halign: "center"
pos_hint: {"center_x": 0.387, "center_y": 0.45}
font_size: 30
font_style: "H5"
EmailField:
hint_text: "Email ID"
pos_hint: {"center_x": 0.5, "center_y": 0.375}
size_hint_x: None
width: "250dp"
PasswordField:
size_hint_x: None
width: "250dp"
hint_text: "Password"
pos_hint: {"center_x": 0.5, "center_y": 0.3}
MDTextButton:
text: "Forgot password?"
font_size: 15
pos_hint: {"center_x": 0.62, "center_y": 0.255}
theme_text_color: "Custom"
text_color: 0.3607, 0.3882, 1
MDFillRoundFlatButton:
text: "Sign in"
pos_hint: {"center_x": 0.5, "center_y": 0.2}
md_bg_color: 0.3607, 0.3882, 1
size_hint: 0.225, 0
on_release: app.RecordCheck()
MDLabel:
text: "by continuing you agree to the"
font_size: 15
halign: 'center'
pos_hint: {"center_y": 0.15}
MDTextButton:
text: "Terms and Conditions"
font_size: 15
pos_hint: {"center_x": 0.5, "center_y": 0.1325}
theme_text_color: "Custom"
text_color: 0.3607, 0.3882, 1
#Below is the sign up screen
<SignupScreen>:
Screen:
EmailField:
hint_text: "Email"
pos_hint: {"center_x": 0.5, "center_y": 0.375}
size_hint_x: None
width: "250dp"
on_text: root.email = self.text
PasswordField:
size_hint_x: None
width: "250dp"
hint_text: "Password"
pos_hint: {"center_x": 0.5, "center_y": 0.3}
on_text: root.password = self.text
MDRoundFlatButton:
text: "Sign up"
pos_hint: {"center_x": 0.5, "center_y": 0.12}
text_color: 0.3607, 0.3882, 1
line_color: 0, 0, 0
on_release: app.AddToRecord()
#Custom buttons and text fields are located below
<PasswordField>:
size_hint_y: None
height: text_field.height
MDTextField:
id: text_field
hint_text: root.hint_text
text: root.text
password: True
icon_left: "lock"
MDIconButton:
icon: "eye-off"
pos_hint: {"center_y": .5}
pos: text_field.width - self.width + dp(8), 0
theme_text_color: "Hint"
on_release:
self.icon = "eye" if self.icon == "eye-off" else "eye-off"
text_field.password = False if text_field.password is True else True
<EmailField>:
size_hint_y: None
height: email_field.height
MDTextField:
id: email_field
hint_text: root.hint_text
text: root.text
icon_left: "email"
Add id attribute both to email and password widgets:
EmailField:
id: email_widget
PasswordField:
id: pass_widget
And you can pass any additional parameters to your method, for example replace:
on_release: app.AddToRecord()
with
on_release: app.AddToRecord(root.ids.email_widget.ids.email_field.text, root.ids.pass_widget.ids.text_field.text)
then change your AddToRecord method definition to:
def AddToRecord(self, email, passw):
print("clicked")
print(f'email: {email}, password: {passw}')
For the email, you can use the get_screen() method of ScreenManager and some ids to access the MDTextField that contains the text. First, add an id to the EmailField:
EmailField:
id: emailfield # added id
hint_text: "Email ID"
pos_hint: {"center_x": 0.5, "center_y": 0.375}
size_hint_x: None
width: "250dp"
Then use that new id and get_screen() to access the MDTextField in your RecordCheck() method:
def RecordCheck(self):
print("clicked")
signinScreen = self.root.get_screen('signin')
email = signinScreen.ids.emailfield.ids.email_field.text
print('email:', email)
Very similar approach can be used to access the password.
I have a ScreenManager problem (Lack of knowledge).
I can't call another screen from a button on my RecycleView.
Note that I have 2 ScreenManager, on the first I login and I am directed to other screens of another ScreenManager.
Note in the line that contains "# <<<< HERE" the way I call the new screen.
import json
from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.properties import StringProperty
from kivy.properties import ObjectProperty
from kivy.uix.relativelayout import RelativeLayout
from random import sample, choice
from string import ascii_lowercase
from kivy.uix.screenmanager import Screen
from kivy.uix.boxlayout import BoxLayout
sample_images = [
"https://cdn.neemo.com.br/uploads/settings_webdelivery/logo/5591/No-Image.jpg",
"https://upload.wikimedia.org/wikipedia/commons/thumb/5/5f/SL_Bundala_NP_asv2020-01_img08.jpg/640px-SL_Bundala_NP_asv2020-01_img08.jpg",
"https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Palaeobranchiostoma_hamatotergum.jpg/482px-Palaeobranchiostoma_hamatotergum.jpg",
"https://upload.wikimedia.org/wikipedia/commons/thumb/a/ac/No_image_available.svg/1024px-No_image_available.svg.png",
]
KV = '''
<ContentNavigationDrawer>:
orientation: 'vertical'
FloatLayout:
size_hint_y: None
height: "200dp"
BoxLayout:
id: box_image
x: root.x
pos_hint: {"top": 1}
FloatLayout:
# Imagem de fundo
FitImage:
pos_hint: {'center_x': .5, 'center_y': .5}
source: "./images/menu.png"
# Imagem do usuário
FitImage:
pos_hint: {'center_x': .5, 'center_y': .5}
source: "./images/user.png"
size_hint: None, None
width: dp(150)
height: dp(150)
radius: [99, 99, 99, 99]
MDLabel:
text: "Coletor de dados Postgres"
size_hint_y: None
height: self.texture_size[1]
# Define a posição do Label
x: root.x + 10
y: root.height - box_image.height + dp(10)
ScrollView:
MDList:
OneLineIconListItem:
text: "Tela Inicial"
on_press:
root.nav_drawer.set_state("close")
root.screen_manager.current = 'tela_item'
IconLeftWidget:
icon: "view-list"
## Tamanho do ícone user_font_size: "72sp"
OneLineIconListItem:
text: "Outra Tela"
on_press:
root.nav_drawer.set_state("close")
root.screen_manager.current = 'tela_signup'
IconLeftWidget:
icon: "database-export-outline"
OneLineIconListItem:
text: "Imagem maior"
on_press:
root.nav_drawer.set_state("close")
root.screen_manager.current = 'tela_login'
IconLeftWidget:
icon: "database-export-outline"
<MainScreen>:
MDToolbar:
id: toolbar
pos_hint: {"top": 1}
elevation: 10
title: "Pesquise e compre."
left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]]
right_action_items: [['lightbulb-outline', lambda x: app.color()], ['cart', lambda x: app.compras()]]
MDNavigationLayout:
x: toolbar.height
ScreenManager:
id: screen_manager
ScreenRecycleView
TelaLogin
TelaSingUp
TelaItem
MDNavigationDrawer:
id: nav_drawer
ContentNavigationDrawer:
screen_manager: screen_manager
nav_drawer: nav_drawer
<MyImageCard>:
name: 'my_image_card'
AsyncImage:
source: root.source
Label:
size_hint_y: None
height: dp(48)
text: root.text
color: 'black'
canvas:
Color:
rgba: 0, 0, 0, .3
Rectangle:
size: self.size
MDFlatButton:
text: "New Screen Here"
increment_width: "164dp"
#app.root.ids.sm.get_screen('main').ids.screenmanager.current = 'new_screen'
on_release:
root.screen_manager.current = 'tela_item' # <<<< HERE
<TelaItem>:
name: 'tela_item'
FloatLayout:
orientation: "vertical"
id: body_tela_item
FitImage:
pos_hint: {'center_x': .5, 'center_y': .85}
source: "./images/eu.jpeg"
size_hint: None, None
width: dp(90)
height: dp(90)
radius: [99, 99, 99, 99]
MDRaisedButton:
text: 'Add'
size_hint: .9, None
pos_hint: {'center_x': .5, 'center_y': .5}
on_release: root.singup()
MDRaisedButton:
text: 'Back'
size_hint: .9, None
pos_hint: {'center_x': .5, 'center_y': .3}
on_release: root.singup()
<ScreenRecycleView>:
name: 'recycle_view'
FloatLayout:
MDBoxLayout:
pos_hint: {'center_x': 0.5, 'center_y': 0.4}
RecycleView:
id: rv
viewclass: "MyImageCard"
RecycleGridLayout:
cols: 2
row_default_height: (self.width - self.cols*self.spacing[0]) / self.cols
padding: dp(4), dp(4)
spacing: dp(4)
size_hint_y: None
height: self.minimum_height
default_size_hint: 1, None
default_size: None, dp(500)
<TelaLogin>:
name: 'tela_login'
FloatLayout:
orientation: "vertical"
id: body_tela_login
FitImage:
pos_hint: {'center_x': .5, 'center_y': .85}
source: "./images/eu.jpeg"
size_hint: None, None
width: dp(90)
height: dp(90)
radius: [99, 99, 99, 99]
MDRaisedButton:
text: 'Login'
size_hint: .9, None
pos_hint: {'center_x': .5, 'center_y': .5}
on_release: root.login()
<TelaSingUp>:
name: 'tela_singup'
id: body_tela_singup
FloatLayout:
MDIconButton:
icon: "arrow-left-bold"
pos_hint: {"center_x": .1, "center_y": .9}
on_release: app.root.current = 'tela_login'
FitImage:
pos_hint: {'center_x': .5, 'center_y': .8}
source: "./images/user.png"
size_hint: None, None
width: dp(150)
height: dp(150)
radius: [99, 99, 99, 99]
MDRaisedButton:
text: 'Cadastrar'
size_hint: .9, None
pos_hint: {'center_x': .5, 'center_y': .1}
on_release: root.singup()
ScreenManager:
id: sm:
TelaLogin:
name: 'tela_login'
MainScreen:
name: 'main'
'''
class ContentNavigationDrawer(BoxLayout):
screen_manager = ObjectProperty()
nav_drawer = ObjectProperty()
class MainScreen(Screen):
pass
class TelaSingUp(Screen):
pass
class TelaItem(Screen):
pass
class TelaLogin(Screen):
def login(self):
self.manager.current = 'main'
class MyImageCard(RelativeLayout):
text = StringProperty()
source = StringProperty()
class ScreenRecycleView(Screen):
def on_kv_post(self, base_widget):
self.ids.rv.data = [
{
'source': choice(sample_images),
'text': ''.join(sample(ascii_lowercase, 6))
}
for x in range(50)
]
class MyApp(MDApp):
def build(self):
root = Builder.load_string(KV)
return root
MyApp().run()
I am trying to build a simple messaging app, that uses rabbitmq as its message broker and kivy as its UI. So to receive incoming messages I have a receive function that is a loop, But when I try to multi-process the app and run it, kivy seems to be opening multiple windows. Kindly advise how I can tackle this issue.
.py file
import pika
from kivymd.app import MDApp
from kivy.lang import Builder
from kivymd.uix.card import MDCard
from database import Database as D
from kivy.core.window import Window
from multiprocessing import Process
from kivymd.uix.label import MDLabel
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.button import MDRectangleFlatButton
from kivy.uix.screenmanager import ScreenManager,Screen
Window.size = (400,700)
global logged_in_user
logged_in_user = ""
def receive():
CREDENTIALS = pika.PlainCredentials('redbarker', 'Redbarker#20-21')
PARAMETERS = pika.ConnectionParameters(credentials=CREDENTIALS)
connection = pika.BlockingConnection(PARAMETERS)
channel = connection.channel()
channel.exchange_declare(exchange='system_exchange', exchange_type='topic', durable=True)
result = channel.queue_declare(queue='', exclusive=True)
queue_name = result.method.queue
channel.queue_bind(exchange='system_exchange', queue=queue_name, routing_key="command.#")
def callback(ch, method, properties, body):
print(body)
channel.basic_consume(queue=queue_name, on_message_callback=callback, auto_ack=True)
channel.start_consuming()
class LoginScreen(Screen):
def validate_user(self):
uname = self.ids.uname_input.text
pword = self.ids.pword_input.text
is_found = D().login(uname,pword)
self.ids.uname_input.text = ""
self.ids.pword_input.text = ""
if is_found:
logged_in_user = uname
self.parent.current = "users_screen"
class SignupScreen(Screen):
def signin(self):
uname = self.ids.uname_input.text
pword1 = self.ids.pword_input1.text
pword2 = self.ids.pword_input2.text
D().signup(uname,pword1,pword2)
self.parent.current = "login_screen"
class UsersScreen(Screen):
def to_inbox(self,text):
InboxScreen().change_header(text)
self.parent.current = 'inbox_screen'
def add_user(self,name):
container = self.ids.user_field
button = MDRectangleFlatButton(
text = name,
font_style = "H6",
text_color = (.95,.44,.49,1),
line_color = (.95,.44,.49,1),
pos_hint = {"center_x": .5, "center_y": .5},
on_press = self.to_inbox(self.text),
)
container.add_widget(button)
class CreateGroupScreen(Screen):
def add_group(self):
container = self.ids.user_field
name = self.ids.username.text
if len(name) > 0:
card = MDCard(
size_hint_y = None,
height = 50,
line_color = (.95,.44,.49,1),
radius = 10,
padding = 10
)
label = MDLabel(
halign = "left",
text = name,
theme_text_color = "Custom",
text_color = (.95,.44,.49,1)
)
card.add_widget(label)
container.add_widget(card)
self.ids.username.text = ""
def remove_all_users(self):
for child in [child for child in self.ids.user_field.children]:
self.ids.user_field.remove_widget(child)
class AddUserScreen(Screen):
users = []
def add_user(self):
for name in self.users:
pass
def append_user(self):
name = self.ids.username.text
if len(name) > 0:
container = self.ids.user_field
card = MDCard(
size_hint_y = None,
height = 50,
line_color = (.95,.44,.49,1),
radius = 10,
padding = 10
)
label = MDLabel(
halign = "left",
text = name,
theme_text_color = "Custom",
text_color = (.95,.44,.49,1)
)
card.add_widget(label)
container.add_widget(card)
self.users.append(name)
self.ids.username.text = ""
def remove_all_users(self):
for child in [child for child in self.ids.user_field.children]:
self.ids.user_field.remove_widget(child)
class InboxScreen(Screen):
def change_header(self, text):
self.ids.header.text = text
def build_widget(self,message):
container = self.ids.text_field
layout = MDBoxLayout(
size_hint_y = None,
height = 50,
padding = (10,0),
)
card = MDCard(
radius = (0,10,0,10),
padding = 10
)
place_holder = MDBoxLayout()
label = MDLabel(
halign = "right",
text = message,
font_style = "H6",
theme_text_color = "Custom",
text_color = (.95,.44,.49,1)
)
card.add_widget(label)
layout.add_widget(place_holder)
layout.add_widget(card)
container.add_widget(layout)
def send(self):
message = self.ids.message_input.text
if len(message) > 0:
CREDENTIALS = pika.PlainCredentials('redbarker', 'Redbarker#20-21')
PARAMETERS = pika.ConnectionParameters(credentials=CREDENTIALS)
consumer = self.ids.header.text
connection = pika.BlockingConnection(PARAMETERS)
channel = connection.channel()
channel.exchange_declare(exchange = 'system_exchange', exchange_type='topic', durable= True)
channel.basic_publish(exchange='system_exchange', routing_key=f"Temesgen.{consumer}", body=message)
self.build_widget(message)
class WindowManager(ScreenManager):
pass
class ChatApp(MDApp):
def build(self):
return Builder.load_file('test.kv')
#if __name__ == "__main__":
# ChatApp().run()
if __name__ == '__main__':
ChatApp().run()
p1 = Process(target=receive)
p1.start()
.kv file
WindowManager:
LoginScreen:
SignupScreen:
AddUserScreen:
UsersScreen:
CreateGroupScreen:
InboxScreen:
<LoginScreen>:
name: "login_screen"
MDBoxLayout:
orientation: "vertical"
padding: 0,1
MDCard:
size_hint_y: .1
line_color: (.95,.44,.49,1)
spacing: 20
padding: 20,10
Widget:
size_hint_y: .33
MDLabel:
halign: "center"
text: "Login"
font_style: "H4"
theme_text_color: "Custom"
text_color: (.95,.44,.49,1)
Widget:
size_hint_y: .33
MDBoxLayout:
orientation: "vertical"
size_hint_y: .4
spacing: 20
MDTextField:
id: uname_input
pos_hint: {"center_x": .5}
size_hint_x: None
width: 250
hint_text: 'Username'
mode: 'rectangle'
color: (0,1,1,1)
line_color_normal: (0,1,0,1)
text_color: (.95,.44,.49,1)
MDTextField:
id: pword_input
pos_hint: {"center_x": .5}
size_hint_x: None
width: 250
hint_text: 'Password'
mode: 'rectangle'
color: (0,1,1,1)
line_color_normal: (0,1,0,1)
text_color: (.95,.44,.49,1)
MDTextButton:
text: 'Sign Up'
underline: True
theme_text_color: "Custom"
text_color: (.95,.44,.49,1)
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
on_press: app.root.current = "signup_screen"
MDBoxLayout:
orientation: "vertical"
size_hint_y: .5
Widget:
size_hint_y: .33
MDRectangleFlatButton:
text: "Login"
font_size: 20
text_color: (.95,.44,.49,1)
line_color: (.95,.44,.49,1)
pos_hint: {"center_x": .5, "center_y": .5}
on_press: root.validate_user()
Widget:
size_hint_y: .6
<SignupScreen>:
name: "signup_screen"
MDBoxLayout:
orientation: "vertical"
padding: 0,1
MDCard:
size_hint_y: .1
line_color: (.95,.44,.49,1)
spacing: 20
padding: 20,10
MDBoxLayout:
size_hint_x: .25
MDIconButton:
size_hint_x: .25
icon: "keyboard-backspace"
pos_hint: {"center_x": .5, "center_y": .5}
on_press: app.root.current = "login_screen"
MDLabel:
size_hint_x: .5
halign: "center"
text: "Signin"
font_style: "H4"
theme_text_color: "Custom"
text_color: (.95,.44,.49,1)
MDBoxLayout:
size_hint_x: .25
Widget:
size_hint_y: .25
MDBoxLayout:
orientation: "vertical"
size_hint_y: .4
spacing: 20
MDTextField:
id: uname_input
pos_hint: {"center_x": .5}
size_hint_x: None
width: 250
hint_text: 'Username'
mode: 'rectangle'
color: (0,1,1,1)
line_color_normal: (0,1,0,1)
text_color: (.95,.44,.49,1)
MDTextField:
id: pword_input1
pos_hint: {"center_x": .5}
size_hint_x: None
width: 250
hint_text: 'Password'
mode: 'rectangle'
color: (0,1,1,1)
line_color_normal: (0,1,0,1)
text_color: (.95,.44,.49,1)
MDTextField:
id: pword_input2
pos_hint: {"center_x": .5}
size_hint_x: None
width: 250
hint_text: 'Confirm Password'
mode: 'rectangle'
color: (0,1,1,1)
line_color_normal: (0,1,0,1)
text_color: (.95,.44,.49,1)
MDBoxLayout:
orientation: "vertical"
size_hint_y: .5
Widget:
size_hint_y: .33
MDRectangleFlatButton:
text: "Signin"
font_size: 20
text_color: (.95,.44,.49,1)
line_color: (.95,.44,.49,1)
pos_hint: {"center_x": .5, "center_y": .5}
on_press: root.signin()
Widget:
size_hint_y: .6
<UsersScreen>:
name: "users_screen"
MDBoxLayout:
orientation: "vertical"
padding: 0,1
MDCard:
size_hint_y: .1
line_color: (.95,.44,.49,1)
spacing: 20
padding: 20,10
MDIconButton:
size_hint_x: .3
icon: "logout"
pos_hint: {"center_x": .5, "center_y": .5}
on_press: app.root.current = "login_screen"
MDLabel:
halign: "center"
text: "Users"
font_style: "H4"
theme_text_color: "Custom"
text_color: (.95,.44,.49,1)
MDBoxLayout:
size_hint_x: .4
MDIconButton:
icon: "account-plus"
pos_hint: {"center_x": .5, "center_y": .5}
on_press: app.root.current = "add_user_screen"
MDIconButton:
icon: "account-multiple-plus"
pos_hint: {"center_x": .5, "center_y": .5}
on_press: app.root.current = "create_group_screen"
MDBoxLayout:
orientation: "vertical"
size_hint_y: .9
ScrollView:
size: self.size
pos: self.pos
MDList:
id: user_field
spacing: 10
padding: 10
MDRectangleFlatButton:
text: 'User-1 '
font_style: "H6"
text_color: (.95,.44,.49,1)
line_color: (.95,.44,.49,1)
pos_hint: {"center_x": .5, "center_y": .5}
on_press: root.to_inbox(self.text)
MDRectangleFlatButton:
text: 'User-2 '
font_style: "H6"
text_color: (.95,.44,.49,1)
line_color: (.95,.44,.49,1)
pos_hint: {"center_x": .5, "center_y": .5}
on_press: root.to_inbox(self.text)
MDRectangleFlatButton:
text: 'User-3 '
font_style: "H6"
text_color: (.95,.44,.49,1)
line_color: (.95,.44,.49,1)
pos_hint: {"center_x": .5, "center_y": .5}
on_press: root.to_inbox(self.text)
<CreateGroupScreen>:
name: "create_group_screen"
MDBoxLayout:
orientation: "vertical"
padding: 0,1
MDCard:
size_hint_y: .1
line_color: (.95,.44,.49,1)
spacing: 20
padding: 20,10
MDIconButton:
id: remove_button
size_hint_x: .2
icon: "keyboard-backspace"
pos_hint: {"center_x": .5, "center_y": .5}
on_press: app.root.current = "users_screen"
MDLabel:
halign: "center"
text: "Create Group"
font_style: "H4"
theme_text_color: "Custom"
text_color: (.95,.44,.49,1)
MDBoxLayout:
orientation: "vertical"
size_hint_y: .9
padding: 20
spacing: 40
MDCard:
size_hint_y: .1
line_color: (.95,.44,.49,1)
radius: 10
padding: 25,3
MDTextField:
id: username
pos_hint: {"center_x": .5, "center_y": .4}
size_hint_x: None
width: 250
hint_text: 'Username'
MDIconButton:
id: add_button
size_hint_x: .2
icon: "account-multiple-plus"
pos_hint: {"center_x": .5, "center_y": .5}
on_press: root.add_user()
MDIconButton:
id: remove_button
size_hint_x: .2
icon: "account-multiple-remove"
pos_hint: {"center_x": .5, "center_y": .5}
on_press: root.remove_all_users()
MDCard:
orientation: "vertical"
size_hint_y: .6
line_color: (.95,.44,.49,1)
radius: 10
MDLabel:
size_hint_y: .1
halign: "center"
text: "Add Users"
theme_text_color: "Custom"
text_color: (.95,.44,.49,1)
MDBoxLayout:
size_hint_y: .9
ScrollView:
size: self.size
pos: self.pos
MDList:
id: user_field
spacing: 10
padding: 10
MDBoxLayout:
orientation: "vertical"
size_hint_y: .3
Widget:
size_hint_y: .33
MDRectangleFlatButton:
text: "Create Group"
text_color: (.95,.44,.49,1)
line_color: (.95,.44,.49,1)
pos_hint: {"center_x": .5, "center_y": .5}
Widget:
size_hint_y: .33
<AddUserScreen>:
name: "add_user_screen"
MDBoxLayout:
orientation: "vertical"
padding: 0,1
MDCard:
size_hint_y: .1
line_color: (.95,.44,.49,1)
spacing: 20
padding: 20,10
MDIconButton:
size_hint_x: .33
icon: "keyboard-backspace"
pos_hint: {"center_x": .5, "center_y": .5}
on_press: app.root.current = "users_screen"
MDLabel:
halign: "center"
text: "Add Users"
font_style: "H4"
theme_text_color: "Custom"
text_color: (.95,.44,.49,1)
Widget:
size_hint_x: .33
MDBoxLayout:
orientation: "vertical"
size_hint_y: .9
padding: 20
spacing: 40
MDCard:
size_hint_y: .1
line_color: (.95,.44,.49,1)
radius: 10
padding: 25,3
MDTextField:
id: username
pos_hint: {"center_x": .5, "center_y": .4}
size_hint_x: None
width: 250
hint_text: 'Username'
MDIconButton:
id: add_button
size_hint_x: .2
icon: "account-multiple-plus"
pos_hint: {"center_x": .5, "center_y": .5}
on_press: root.append_user()
MDIconButton:
id: remove_button
size_hint_x: .2
icon: "account-multiple-remove"
pos_hint: {"center_x": .5, "center_y": .5}
on_press: root.remove_all_users()
MDCard:
orientation: "vertical"
size_hint_y: .6
line_color: (.95,.44,.49,1)
radius: 10
MDLabel:
size_hint_y: .1
halign: "center"
text: "Add Users"
theme_text_color: "Custom"
text_color: (.95,.44,.49,1)
MDBoxLayout:
size_hint_y: .9
ScrollView:
size: self.size
pos: self.pos
MDList:
id: user_field
spacing: 10
padding: 10
MDBoxLayout:
orientation: "vertical"
size_hint_y: .3
Widget:
size_hint_y: .33
MDRectangleFlatButton:
text: "Add Users"
text_color: (.95,.44,.49,1)
line_color: (.95,.44,.49,1)
pos_hint: {"center_x": .5, "center_y": .5}
on_press: root.add_user()
Widget:
size_hint_y: .33
<InboxScreen>:
name: "inbox_screen"
MDBoxLayout:
orientation: "vertical"
padding: 0,1
MDCard:
size_hint_y: .1
line_color: (.95,.44,.49,1)
spacing: 20
padding: 20,10
MDIconButton:
size_hint_x: .2
icon: "keyboard-backspace"
pos_hint: {"center_x": .5, "center_y": .5}
on_press: app.root.current = "users_screen"
MDLabel:
id: header
halign: "center"
text: ""
font_style: "H4"
theme_text_color: "Custom"
text_color: (.95,.44,.49,1)
MDBoxLayout:
orientation: "vertical"
size_hint_y: .9
ScrollView:
size: self.size
pos: self.pos
MDList:
id: text_field
spacing: 10
MDCard:
size_hint_y: .075
line_color: (.95,.44,.49,1)
padding: 10,0
MDTextField:
id: message_input
size_hint: None,None
height: 100
width: 325
hint_text: 'Write'
color: (0,1,1,1)
line_color_normal: (.95,.44,.49,1)
text_color: (.95,.44,.49,1)
pos_hint: {"center_x": .5, "center_y": .3}
MDIconButton:
id: send_button
icon: "send"
pos_hint: {"center_x": .5, "center_y": .5}
on_press: root.send()
What you are pretending to do is to run kivy concurrently. The best choice for async events in kivy is to use asyncio (as the oficcial documentation suggest). First at all you have to be sure your app runs from asyncio.run() instead of App.run(). To do this, you have to import asyncio and also you have to add a method to your App class. See the example below:
import asyncio
######## MAIN APP ########
class ExampleApp(App):
def build(self):
#Your app stuff here
async def kivyCoro(self): #This is the method that's gonna launch your kivy app
await self.async_run(async_lib='asyncio')
print('Kivy async app finished...')
# This func will start all the "tasks", in this case the only task is the kivy app
async def base(self):
(done, pending) = await asyncio.wait({self.kivyCoro()},
return_when='FIRST_COMPLETED')
if __name__ == '__main__':
instanceApp = ExampleApp() #You have to instanciate your App class
asyncio.run(instanciaApp.base()) # Run in async mode
With the code above you'll be able to run tour kivy app as a task (concurrently).
So far, we just have run the kivy app in async mode (concurrently). To add other task inside the Kivy running loop:
import asyncio
######## MAIN APP ########
class ExampleApp(App):
def build(self):
#Your app stuff here
async def kivyCoro(self): #This is the method that's gonna launch your kivy app
await self.async_run(async_lib='asyncio')
print('Kivy async app finished...')
async def task2InsideKivyLoop(self): #Here you declare the other task
print('Another task running inside the kivy loop')
await asyncio.sleep(1)
# This func will start all the "tasks", in this case the only task is the kivy app
async def base(self):
(done, pending) = await asyncio.wait({self.kivyCoro(), task2InsideKivyLoop()},
return_when='FIRST_COMPLETED')
if __name__ == '__main__':
instanceApp = ExampleApp() #You have to instanciate your App class
asyncio.run(instanciaApp.base()) # Run in async mode
As you can see, to add another task inside the KivyLoop we just have to declare it as a async method of the App class, then just add it to asyncio.wait()
If you want to run the other task outside the kivyLoop you have to do the fllowing:
import asyncio
######## MAIN APP ########
class ExampleApp(App):
def build(self):
#Your app stuff here
async def kivyCoro(self): #This is the method that's gonna launch your kivy app
await self.async_run(async_lib='asyncio')
print('Kivy async app finished...')
# This func will start all the "tasks", in this case the only task is the kivy app
async def base(self):
(done, pending) = await asyncio.wait({self.kivyCoro()},
return_when='FIRST_COMPLETED')
######### GLOBAL COROUTINE #######
# Here you can import functions from other python files or just declare a global func
async def GlobalTask():
for i in range(10):
print('Other concurrently global task... ',i)
await asyncio.sleep(1)
if __name__ == '__main__':
async def mainThread():
instanceApp = ExampleApp() #Instanciate your App class
a = asyncio.create_task(instanceApp.base()) #Run kivyApp as a task
b = asyncio.create_task(GlobalTask()) #Run Global func as a task
(done, pending) = await asyncio.wait({a}, return_when='FIRST_COMPLETED')
asyncio.run(mainThread())
The examples above would let you do any async task during the kv loop wheter inside the kvLoop or not
The code:
if __name__ == '__main__':
ChatApp().run()
p1 = Process(target=receive)
p1.start()
will run your ChatApp, and then after you close the ChatApp, it will run the receive process. They will not run at the same time because the ChatApp().run() will not return until the ChatApp closes. Try changing the order to:
if __name__ == '__main__':
p1 = Process(target=receive)
p1.start()
ChatApp().run()
Not sure where I'm going wrong, When changing the value of MDSlider it should update a label but I receive the error
the kv is loaded as a string within my py file, if I test out the slider by simply printing the value to the console it works. but when I try to update a label get the following error??
AttributeError: 'Level' object has no attribute 'training_level'
here's my code
from kivy.lang import Builder
from kivymd.uix.screen import MDScreen
from kivymd.app import MDApp
KV = """
ScreenManager:
Profile:
Level:
Routine:
Start:
<Profile>:
name: "Profile"
canvas.before:
Color:
rgba: (1,1,1,1)
Rectangle:
source: "bg.jpg"
size: root.width, root.height
pos: self.pos
MDLabel:
text: "Select a Profile"
font_size: "32"
pos_hint: {"center_x": .5, "center_y": .95}
MDRectangleFlatButton:
text: "Guest"
font_size: "32"
pos_hint: {"center_x": .5, "center_y": .5}
on_release: app.root.current = "Level"
MDBottomAppBar:
MDToolbar:
title: "HIIT"
icon: "account-cog"
type: "bottom"
left_action_items: [["menu", lambda x: x]]
mode: "center"
<Level>:
name: "Level"
canvas.before:
Color:
rgba: (1,1,1,1)
Rectangle:
source: "bg.jpg"
size: root.width, root.height
pos: self.pos
MDLabel:
text: "What is your Level of training?"
font_size: "32"
pos_hint: {"center_x": .5, "center_y": .95}
MDLabel:
id: "training_level"
theme_text_color: "Custom"
text_color: 1,1,1,1
halign: "center"
text: "2"
font_size: "128"
pos_hint: {"center_x": .5, "center_y": .65}
MDSlider:
min: 1
max: 3
value: 2
size: 500, 50
size_hint: None, None
hint: False
step: 1
orientation: "horizontal"
pos_hint: {"center_x": .5, "center_y": .40}
on_value: root.change_height(*args)
MDRectangleFlatButton:
text: "Next"
font_size: "32"
pos_hint: {"center_x": .92, "center_y": .18}
on_release: app.root.current = "Routine"
MDBottomAppBar:
MDToolbar:
title: "HIIT"
icon: "account-cog"
type: "bottom"
left_action_items: [["menu", lambda x: x]]
mode: "center"
<Routine>:
name: "Routine"
canvas.before:
Color:
rgba: (1,1,1,1)
Rectangle:
source: "bg.jpg"
size: root.width, root.height
pos: self.pos
MDLabel:
text: "Select a Routine"
font_size: "32"
pos_hint: {"center_x": .5, "center_y": .95}
MDRectangleFlatButton:
text: "10 Minute Beginner"
font_size: "32"
pos_hint: {"center_x": .5, "center_y": .5}
on_release: app.root.current = "Start"
MDBottomAppBar:
MDToolbar:
title: "HIIT"
icon: "account-cog"
type: "bottom"
left_action_items: [["menu", lambda x: x]]
mode: "center"
<Start>:
name: "Start"
canvas.before:
Color:
rgba: (1,1,1,1)
Rectangle:
source: "bg.jpg"
size: root.width, root.height
pos: self.pos
MDRectangleFlatButton:
text: "Stop"
font_size: "32"
pos_hint: {"center_x": .5, "center_y": .5}
on_release: app.root.current = "Profile"
MDBottomAppBar:
MDToolbar:
title: "HIIT"
icon: "account-cog"
type: "bottom"
left_action_items: [["menu", lambda x: x]]
mode: "center"
"""
class Profile(MDScreen):
pass
class Level(MDScreen):
def change_height(self, *args):
#print(str(round(args[1],1)))
self.training_level.text = str(round(args[1],1))
pass
class Routine(MDScreen):
pass
class Start(MDScreen):
pass
class MainApp(MDApp):
def build(self):
self.theme_cls.theme_style = "Dark"
self.theme_cls.primary_palette = "Blue"
return Builder.load_string(KV)
MainApp().run()
I am a beginner and I am trying to make a personality test in kivymd. There are 24 questions where you can choose one of the 4 options (d, i, s, n).
Evaluating the test, I want to write out how many certain letters an user choose. I want to save it to a file. I already write a test name from textfield, but I want it as tuple or list.
I think something like this:
Test1[d=2,i=5,s=8,n=9]
Do you have any idea how can I do that? I tried it with functions d(),.. but it doesn't work
main.py
class ItemConfirm(OneLineAvatarIconListItem):
divider = None
def set_icon(self, choice):
choice.active = True
check_list = choice.get_widgets(choice.group)
for check in check_list:
if check != choice:
check.active = False
class HomeScreen(Screen):
choose_dialog= None
choice = None
help_dialog= None
def show_ChooseDialog(self):
self.choose_dialog = MDDialog(title="Aim:", type="confirmation",
size_hint=[0.9, 0.5], auto_dismiss=False,
items=[ItemConfirm(text="personaly",on_release= self.next_page_me,
on_press= self.close_choose_dialog,)],)
self.choose_dialog.open()
def close_choose_dialog(self, obj):
self.choose_dialog.dismiss()
print(self.choose_dialog.items)
def next_page_me (self,obj):
self.manager.current = "motivationme"
def show_HelpDialog(self):
ok_button = MDRectangleFlatButton (text= "ok",on_release=self.close_help_dialog)
self.help_dialog = MDDialog(title="info about test", text="bla bla",
size_hint=[0.8, 0.5], auto_dismiss=False,
buttons=[ok_button])
self.help_dialog.open()
def close_help_dialog(self,obj):
self.help_dialog.dismiss()
class MotivationScreenMe(Screen):
def add_test(self):
file = open("package.txt", "w")
file.write(self.ids.nazov_testu.text)
class TestConfirm(OneLineAvatarIconListItem):
divider = None
def set_icon(self, choice):
choice.active = True
check_list = choice.get_widgets(choice.group)
for check in check_list:
if check != choice:
check.active = False
class TestScreenV(Screen):
d= 0
i= 0
s=0
n=0
snackbar = None
p = 0
r = 0
def d(self,d):
self.d= d+1
print(d)
def i(self,i):
self.i=i+1
print(i)
def s(self,s):
self.s=s+1
print(s)
def n(self,n):
self.n=n+1
print(n)
def show_example_snackbar(self):
self.snackbar = Snackbar(text="finish?",
snackbar_x="10dp",
snackbar_y="10dp",
bg_color= (0.96,0.79,0.09, 1),)
self.snackbar.size_hint_x = ( Window.width -
(self.snackbar.snackbar_x * 2)) / Window.width
self.snackbar.buttons = [MDFlatButton(text="yes",text_color=(1, 1, 1, 1),
on_release=self.evaluate,
on_press= self.snackbar.dismiss),]
self.snackbar.open()
def evaluate (self,obj):
self.manager.current= "testm"
self.manager.transition.direction = 'left'
def plus(self):
self.p = self.p +4.16
self.ids.progress.value = self.p
class MainApp(MDApp):
def build(self):
self.theme_cls.primary_palette = "Red"
self.theme_cls.primary_hue = "500"
self.theme_cls.theme_style = "Light"
screen = Builder.load_string(screen_helper)
return screen
MainApp().run()
.kv
screen_helper = """
ScreenManager:
HomeScreen:
MotivationScreenMe:
TestScreenV:
<HomeScreen>:
name: "home"
Image:
source: "all.png"
pos_hint: { "center_x" :0.5, "center_y":0.5}
size_hint: (1,1)
MDFloatingActionButton:
icon: "play-circle-outline"
size_hint: None, None
pos_hint: {"center_x" :0.5, "center_y":0.08}
md_bg_color: app.theme_cls.primary_color
on_release: root.show_ChooseDialog()
MDFloatingActionButton:
icon: "help-circle-outline"
md_bg_color: app.theme_cls.primary_color
pos_hint: { "center_x" :0.15, "center_y":0.08}
on_release: root.show_HelpDialog()
<ItemConfirm>
on_release: root.set_icon(check)
CheckboxLeftWidget:
id: check
group: "check"
<MotivationScreenMe>:
name: "motivationme"
nazov_testu: nazov_testu
MDCard:
orientation: "vertical"
pos_hint:{ "center_x" :0.5, "center_y": 0.6}
size_hint: 0.8, 0.7
padding: "8dp"
MDLabel:
text: "why.."
font_size: (root.width**2 + root.height**2) / 13**4
halign: "center"
pos_hint: { "center_x" :0.3, "center_y":0.95}
size_hint: 0.8, 0.1
theme_text_color: "Custom"
text_color: app.theme_cls.primary_color
MDSeparator:
height: "1dp"
MDLabel:
text: "bla bla bla bla bla "
font_size: (root.width**2 + root.height**2) / 13**4
halign: "center"
MDTextField:
id: nazov_testu
hint_text:"nazov_testu(it means) = test_name"
helper_text: "eg. Test 1"
helper_text_mode: "on_focus"
pos_hint: { "center_x" :0.5, "center_y":0.2}
size_hint: 0.8,0.1
MDFloatingActionButton:
icon: "play-circle-outline"
pos_hint: { "center_x" :0.5, "center_y":0.08}
md_bg_color: app.theme_cls.primary_color
on_release:
root.manager.current = "testv"
root.manager.transition.direction = 'up'
on_press: root.add_test()
<TestConfirm>
on_release: root.set_icon(check)
CheckboxLeftWidget:
id: check
<TestScreenV>:
name: "testv"
MDCard:
orientation: "vertical"
padding: "8dp"
size_hint: 0.9,0.7
pos_hint: {"center_x": .5, "center_y": .6}
OneLineListItem:
text: "chose option which fits on you the best"
theme_text_color: "Custom"
text_color: app.theme_cls.primary_color
font_size: (root.width**2 + root.height**2) / 13**4
ScrollView:
do_scroll_x: False
BoxLayout:
orientation: 'vertical'
size_hint_y: None
height: dp(350)
OneLineListItem:
text: "1/24 "
theme_text_color: "Custom"
text_color: app.theme_cls.primary_color
TestConfirm:
text: "option which means point s"
font_size: (root.width**2 + root.height**2) / 13**4
on_press:
root.plus()
root.s()
TestConfirm:
text: "option which means point n"
font_size: (root.width**2 + root.height**2) / 13**4
on_press:
root.plus()
root.n()
TestConfirm:
text: "option which means point d"
font_size: (root.width**2 + root.height**2) / 13**4
on_press:
root.plus()
root.d()
TestConfirm:
text: "option i"
font_size: (root.width**2 + root.height**2) / 13**4
on_press:
root.plus()
root.i()
MDFloatingActionButton:
icon: "check-circle-outline"
pos_hint: { "center_x" :0.5, "center_y":0.08}
md_bg_color: app.theme_cls.primary_color
on_release: root.show_example_snackbar()
MDProgressBar:
id: progress
size_hint_x: 0.8
size_hint_y: 0.08
color: app.theme_cls.accent_color
pos_hint: { "center_x" :0.5, "center_y":0.2}