Related
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 an App with 3 screens managed by a ScreenManager: MainScreen, ScanScreen, PinScreen. From MainScreen I have 2 buttons, 1 to go to ScanScreen, 1 to go to PinScreen. In ScanScreen I have a button to go into PinScreen and in PinScreen I have a button to go in ScanScreen. I want to go to MainScreen after some interval of time. I managed to make it works only if I go to secondary screens from MainScreen. If I go from MainScreen to ScanScreen and from ScanScreen to PinScreen then it wont work. I get this error:
line 16, in timeout
self.parent.current = 'mainScreen'
AttributeError: 'NoneType' object has no attribute 'current'
This is what I got so far:
kv file
ScreenManagement:
id:'screenManager'
MainScreen:
ScanScreen:
PinScreen:
FinalScreen:
<MainScreen>:
name: "mainScreen"
MDCard:
radius: [36, ]
size_hint: .8, .9
pos_hint: {"center_x": 0.5, "center_y": 0.5}
elevation: 10
padding: [20, 50, 20, 150]
spacing: 50
orientation: 'vertical'
MDIcon:
icon: "face-recognition"
font_size: 120
halign: 'center'
size_hint: 1, .5
MDFillRoundFlatButton:
text: "Scan Face"
font_size: 32
pos_hint: {"center_x": 0.5}
#size_hint: 1, .25
on_release:
root.manager.current = 'scanScreen'
root.manager.transition.direction = 'left'
MDFillRoundFlatButton:
text: "Access with PIN"
font_size: 32
pos_hint: {"center_x": 0.5}
#size_hint: 1, .25
on_release:
root.manager.current = 'pinScreen'
root.manager.transition.direction = 'left'
<ScanScreen>:
on_pre_enter: app.title = 'Scan Screen'
name: "scanScreen"
#on_enter: TODO timer function
MDCard:
radius: [36, ]
size_hint: .9, .95
pos_hint: {"center_x": 0.5, "center_y": 0.5}
elevation: 10
padding: [20, 50, 20, 150]
spacing: 50
orientation: 'vertical'
Image:
id: "frame_feed"
size_hint: 1, .8
MDFillRoundFlatButton:
text: "Access with PIN"
font_size: 32
pos_hint: {"center_x": 0.5}
on_release:
root.manager.current = 'pinScreen'
root.manager.transition.direction = 'left'
<PinScreen>:
on_pre_enter: app.title = 'PIN Screen'
name: "pinScreen"
MDBoxLayout:
orientation: 'vertical'
MDBoxLayout:
orientation: 'vertical'
size_hint: (1, .5)
MDIconButton:
icon: "arrow-left-drop-circle"
#icon_size: '32sp' this should be the right way but its not working
user_font_size: '32sp' #this should be deprecated but it's working
on_release:
root.manager.current = 'scanScreen'
root.manager.transition.direction = 'right'
MDIcon:
icon: "account-lock"
font_size: 60
halign: 'center'
MDLabel:
text: "Enter your passcode"
halign: "center"
font_style: "Body1"
MDGridLayout:
size_hint: (.5, 1)
pos_hint: {"center_x": .5}
cols: 6
#padding: [80,0,80,0]
#halign: "center"
MDIcon:
icon:"checkbox-blank-circle-outline"
MDIcon:
icon:"checkbox-blank-circle-outline"
MDIcon:
icon:"checkbox-blank-circle-outline"
MDIcon:
icon:"checkbox-blank-circle-outline"
MDIcon:
icon:"checkbox-blank-circle-outline"
MDIcon:
icon:"checkbox-blank-circle-outline"
Widget:
size_hint_y: None
height: 100
MDBoxLayout:
orientation: 'vertical'
size_hint: (1, .5)
MDGridLayout:
size_hint: (.5, 1)
pos_hint: {"center_x": .385}
cols:3
spacing: 20
MDFillRoundFlatButton:
text: "1"
text_color: .95,.953,.956,1
font_size: 20
font_style: 'H4'
md_bg_color: .4, .4, .4, 1
MDFillRoundFlatButton:
text: "2"
text_color: .95,.953,.956,1
font_size: 20
font_style: 'H4'
md_bg_color: .4, .4, .4, 1
MDFillRoundFlatButton:
text: "3"
text_color: .95,.953,.956,1
font_size: 20
font_style: 'H4'
md_bg_color: .4, .4, .4, 1
MDFillRoundFlatButton:
text: "4"
text_color: .95,.953,.956,1
font_size: 20
font_style: 'H4'
md_bg_color: .4, .4, .4, 1
MDFillRoundFlatButton:
text: "5"
text_color: .95,.953,.956,1
font_size: 20
font_style: 'H4'
md_bg_color: .4, .4, .4, 1
MDFillRoundFlatButton:
text: "6"
text_color: .95,.953,.956,1
font_size: 20
font_style: 'H4'
md_bg_color: .4, .4, .4, 1
MDFillRoundFlatButton:
text: "7"
text_color: .95,.953,.956,1
font_size: 20
font_style: 'H4'
md_bg_color: .4, .4, .4, 1
MDFillRoundFlatButton:
text: "8"
text_color: .95,.953,.956,1
font_size: 20
font_style: 'H4'
md_bg_color: .4, .4, .4, 1
MDFillRoundFlatButton:
text: "9"
text_color: .95,.953,.956,1
font_size: 20
font_style: 'H4'
md_bg_color: .4, .4, .4, 1
MDFillRoundFlatButton:
text: ""
md_bg_color: 1,0,0,0
MDFillRoundFlatButton:
text: "0"
text_color: .95,.953,.956,1
font_size: 20
font_style: 'H4'
md_bg_color: .4, .4, .4, 1
MDFillRoundFlatIconButton:
icon: "backspace"
padding: [40,0,0,0]
font_style: 'H4'
icon_color: .827,.827,.827,1
md_bg_color: 1,0,0,0
<FinalScreen>:
on_pre_enter: app.title = 'Final Screen'
name: "finalScreen"
python file
from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.core.window import Window
from kivy.clock import Clock
Window.size = (414, 736) #This is the viewport of iPhone 6 Plus/6S Plus/7 Plus/8 Plus
import cv2
class MainScreen(Screen):
pass
class ScanScreen(Screen):
def timeout(self, *args):
self.parent.current = 'mainScreen'
def on_enter(self, *args):
Clock.schedule_once(self.timeout, 2)
class PinScreen(Screen):
def timeout(self, *args):
self.parent.current = 'mainScreen'
def on_enter(self, *args):
Clock.schedule_once(self.timeout, 2)
class FinalScreen(Screen):
def timeout(self, *args):
self.parent.current = 'mainScreen'
def on_enter(self, *args):
Clock.schedule_once(self.timeout, 2)
class ScreenManagement(ScreenManager):
pass
class MainApp(MDApp):
def __init__(self, **kwargs):
self.title = "Main Screen"
super().__init__(**kwargs)
def build(self):
self.theme_cls.theme_style = "Dark"
self.theme_cls.primary_palette = "Green"
self.theme_cls.accent_palette = "Teal"
return Builder.load_file('main.kv')
def return_to_main_screen(self):
pass
if __name__ == "__main__":
MainApp().run()
I also tried this:
class ScanScreen(Screen):
def timeout(self, *args):
MDApp.get_running_app().root.manager.current = 'mainScreen'
#self.parent.current = 'mainScreen'
def on_enter(self, *args):
Clock.schedule_once(self.timeout, 2)
but I get this error:
MDApp.get_running_app().root.manager.current = 'mainScreen'
AttributeError: 'ScreenManagement' object has no attribute 'manager'
So to clarify, I managed to do what I wanted by using get_running_app() method and accessing the root, which in my case is the ScreenManager. I made some changes to my code so it would reset the countdown after activity. This is what I have in each of the screen that I want to return to MainScreen after 30s of inactivity:
class ScanScreen(Screen):
def timeout(self, *args):
MDApp.get_running_app().root.current = 'mainScreen'
MDApp.get_running_app().root.transition.direction = 'right'
def reset_timeout(self, *args):
Clock.unschedule(self.timeout)
Clock.schedule_once(self.timeout, 30)
def on_enter(self, *args):
Clock.schedule_once(self.timeout, 30)
def on_leave(self, *args):
Clock.unschedule(self.timeout)
def on_touch_down(self, touch):
self.reset_timeout()
return super().on_touch_down(touch)
def on_touch_move(self, touch):
self.reset_timeout()
return super().on_touch_move(touch)
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()
So im trying to get a variable added to screen and the id fro that is in a widget Im going to add,
so if for example I have this:
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import StringProperty
kv = """
Screen:
cal:cal
side: side
GridLayout:
rows: 1
cols:2
spacing:0
GridLayout:
rows: 5
cols:1
Button:
text: "Cube"
# on_press: app.mode = self.text
on_press: app.setMode(self)
Button:
text: "Cuboid"
on_press: app.setMode(self)
Button:
text: "Cylinder"
on_press: app.setMode(self)
Button:
text: "Cone"
on_press: app.setMode(self)
Button:
text: "Sphere"
on_press: app.setMode(self)
FloatLayout:
Label:
text: "The Volume and surface area of a {}:".format(app.mode)
pos_hint: {"x":0.1, "y":0.8}
text_size: self.size
FloatLayout:
id:cal
Label:
text:"Side:"
pos_hint: {"x":1.1, "y":0.7}
text_size: self.size
Label:
text:"Volume:"
pos_hint: {"x":1.1, "y":0.65}
text_size: self.size
Label:
text:"Surface Area:"
pos_hint: {"x":1.1, "y":0.6}
text_size: self.size
TextInput:
size_hint: (.4, None)
height: 26
multiline: False
pos_hint: {"x":1.24, "y":0.7}
id: side
text: app.sideText
on_text_validate: app.Cube_on_side_change(self)
Label:
text: app.volume
pos_hint: {"x":1.27, "y":0.65}
text_size: self.size
Label:
text: app.surface_area
pos_hint: {"x":1.355, "y":0.6}
text_size: self.size
"""
cube = """
FloatLayout:
Label:
text:"Side:"
pos_hint: {"x":1.1, "y":0.7}
text_size: self.size
Label:
text:"Volume:"
pos_hint: {"x":1.1, "y":0.65}
text_size: self.size
Label:
text:"Surface Area:"
pos_hint: {"x":1.1, "y":0.6}
text_size: self.size
TextInput:
size_hint: (.4, None)
height: 26
multiline: False
pos_hint: {"x":1.24, "y":0.7}
id: side
text: app.sideText
on_text_validate: app.Cube_on_side_change(self)
Label:
text: app.volume
pos_hint: {"x":1.27, "y":0.65}
text_size: self.size
Label:
text: app.surface_area
pos_hint: {"x":1.355, "y":0.6}
text_size: self.size"""
cuboid = """
FloatLayout:
id:main
Label:
text:"Length:"
pos_hint: {"x":1.1, "y":0.7}
text_size: self.size
Label:
text:"Breadth:"
pos_hint: {"x":1.1, "y":0.65}
text_size: self.size
Label:
text:"Height:"
pos_hint: {"x":1.1, "y":0.6}
text_size: self.size
TextInput:
size_hint: (.4, None)
height: 26
multiline: False
pos_hint: {"x":1.24, "y":0.7}
id: length
text: app.sideText
on_text_validate: app.Cuboid_on_side_change(self)
TextInput:
size_hint: (.4, None)
height: 26
multiline: False
pos_hint: {"x":1.24, "y":0.65}
id: breadth
text: app.sideText
on_text_validate: app.Cube_on_side_change(self)
TextInput:
size_hint: (.4, None)
height: 26
multiline: False
pos_hint: {"x":1.24, "y":0.6}
id: height
text: app.sideText
on_text_validate: app.Cuboid_on_side_change()
Label:
text: "Volume:"
pos_hint: {"x":1.1, "y":0.55}
text_size: self.size
Label:
text: "Surface Area:"
pos_hint: {"x":1.1, "y":0.5}
text_size: self.size
Label:
text: app.volume
pos_hint: {"x":1.27, "y":0.55}
text_size: self.size
Label:
text: app.surface_area
pos_hint: {"x":1.355, "y":0.5}
text_size: self.size"""
cone = """
FloatLayout:
Label:
text:"Radius:"
pos_hint: {"x":1.1, "y":0.7}
text_size: self.size
Label:
text:"Height:"
pos_hint: {"x":1.1, "y":0.65}
text_size: self.size
TextInput:
size_hint: (.4, None)
height: 26
multiline: False
pos_hint: {"x":1.24, "y":0.7}
id: Radius
text: app.sideText
on_text_validate: app.Cuboid_on_side_change(self)
TextInput:
size_hint: (.4, None)
height: 26
multiline: False
pos_hint: {"x":1.24, "y":0.65}
id: height
text: app.sideText
on_text_validate: app.Cube_on_side_change(self)
Label:
text: "Volume:"
pos_hint: {"x":1.1, "y":0.6}
text_size: self.size
Label:
text: "Surface Area:"
pos_hint: {"x":1.1, "y":0.55}
text_size: self.size
Label:
text: app.volume
pos_hint: {"x":1.27, "y":0.6}
text_size: self.size
Label:
text: app.surface_area
pos_hint: {"x":1.355, "y":0.55}
text_size: self.size
"""
screens = {
"Cube": cube,
"Cuboid": cuboid,
"Cone": cone
}
class MyApp(App):
sideText = StringProperty("")
surface_area = StringProperty("0 cm²")
volume = StringProperty("0 cm³")
mode = StringProperty("Cube")
def build(self):
self.screen = Builder.load_string(kv)
return self.screen
def setMode(self, btn):
self.volume = "0 cm³"
self.surface_area = "0 cm³"
self.mode = btn.text
self.screen.cal.clear_widgets()
self.screen.cal.add_widget(Builder.load_string(screens[self.mode]))
def Cube_on_side_change(self, instance):
try:
value = float(instance.text)
num = True
except ValueError:
# failed to convert
num = False
print("Numbers only idiot.")
def cubeCalc(val):
return {
"volume": val * val * val,
"surface_area": (val * val) * 6
}
if num:
result = cubeCalc(value)
self.volume = "{:.2f} cm³".format(result["volume"])
self.surface_area = "{:.2f} cm²".format(result["surface_area"])
def Cuboid_on_side_change(self):
height = self.screen.cal.ids.main.height.text
try:
value = float(height)
num = True
except ValueError:
# failed to convert
num = False
print("Numbers only idiot.")
def cubeCalc(val):
return {
"volume": val * val * val,
"surface_area": (val * val) * 6
}
if num:
result = cubeCalc(value)
self.volume = "{:.2f} cm³".format(result["volume"])
self.surface_area = "{:.2f} cm²".format(result["surface_area"])
if __name__ == "__main__":
MyApp().run()
on_text_validate of the TextInput with id:height in the string cuboid, I want to get the text from the text input with something like: self.screen.main.height.text, however, to do that I would have to add main:main and height:height to Screen. How would I do this?
I suggest refactoring your code. Rather than re-inventing the capabilities of ScreenManager, just use ScreenManager. In your kv string, replace the FloatLayout with:
ScreenManager:
CubeScreen:
CuboidScreen:
ConeScreen:
and use your additional kv strings (like cube) as the basis for additional rules in your kv string. Something like:
<CubeScreen>:
Label:
text: "The Volume and surface area of a Cube:"
pos_hint: {"x":0.1, "y":0.8}
text_size: self.size
FloatLayout:
Label:
text:"Side:"
pos_hint: {"x":0.1, "y":0.7}
text_size: self.size
.
.
.
And define each Screen class in your py, like:
class CubeScreen(Screen):
def get_cube_area(self):
.
.
.
And in each of the new classes (like CubeScreen) you can define methods for calculating area, volume, etc, and you can access the TextInputs easily using their ids. And your on_text_validate in each Screen can just call the appropriate method from that Screen (like on_text_validate: root.get_cube_area()).
I tried to show the list in my second screen after I click the button in the main screen. but the list won't show but I have no error. is there anything wrong with my kivy code?
this is my code
def rumus_power_np(radius, air_density, efficiency_factor, kecepatan_angin):
return 3.14/2 * pow(radius, 2) * np.power(kecepatan_angin, 3) * air_density * efficiency_factor
class MainWindow(Screen):
def btn(self):
print("name: ",self.radius.text)
predicted_power = rumus_power_np(int(self.radius.text), float(self.air_density.text), float(self.efficiency_factor.text)/100, predictions)
data = {'time': series.date[-109:].dt.time,'power': predicted_power}
df = pd.DataFrame (data, columns = ['time','power'])
plt.plot(df.time,df.power, color='orange', label = 'predicted power')
plt.xlabel("time")
plt.ylabel("power (watt)")
plt.legend()
print(predicted_power)
self.manager.get_screen('second').ids.rv.data = [{'time': df.time}, {'power': df.power}]
class SecondWindow(Screen):
def btndu(self):
self.ids.destination.add_widget(FigureCanvasKivyAgg(plt.gcf()))
class WindowManager(ScreenManager):
pass
kv = Builder.load_file("my.kv")
class MyMainApp(App):
def build(self):
return kv
if __name__=="__main__":
MyMainApp().run()
the predicted_power data exist from code above it and it must have 109 rows from that data.
and this is my kv code
#:kivy 1.9.1
WindowManager:
MainWindow:
SecondWindow:
<MainWindow>:
name: "main"
radius: radius
air_density: air_density
efficiency_factor: efficiency_factor
FloatLayout:
Label:
text:"Radius: "
size_hint: 0.5,0.12
pos_hint: {"x":0, "top":0.8}
font_size: (root.width**2 + root.height**2) / 14**4
TextInput:
id: radius
multinline:False
pos_hint: {"x":0.5, "top":0.78}
size_hint: 0.3, 0.06
font_size: (root.width**2 + root.height**2) / 14**4
Label:
text:"Meter"
size_hint: 0.5,0.12
pos_hint: {"x":0.62, "top":0.8}
font_size: (root.width**2 + root.height**2) / 16**4
Label:
text:"Air\nDensity: "
size_hint: 0.5,0.12
pos_hint: {"x":0, "top":0.8-0.13}
font_size: (root.width**2 + root.height**2) / 14**4
TextInput:
id: air_density
multinline:False
pos_hint: {"x":0.5, "top":0.78-0.13}
size_hint: 0.3, 0.06
font_size: (root.width**2 + root.height**2) / 14**4
Label:
text:"kg/m³"
size_hint: 0.5,0.12
pos_hint: {"x":0.62, "top":0.8-0.13}
font_size: (root.width**2 + root.height**2) / 16**4
Label:
text:"efficiency\nfactor: "
size_hint: 0.5,0.12
pos_hint: {"x":0, "top":0.8-0.13*2}
font_size: (root.width**2 + root.height**2) / 14**4
TextInput:
id: efficiency_factor
multinline:False
pos_hint: {"x":0.5, "top":0.78-0.13*2}
size_hint: 0.3, 0.06
font_size: (root.width**2 + root.height**2) / 14**4
Label:
text:"%"
size_hint: 0.5,0.12
pos_hint: {"x":0.62, "top":0.8-0.13*2}
font_size: (root.width**2 + root.height**2) / 16**4
Button:
text:"Submit"
pos_hint:{"x":0.3,"y":0.25}
size_hint: 0.4, 0.1
font_size: (root.width**2 + root.height**2) / 14**4
on_release:
root.btn()
app.root.current = "second"
root.manager.transition.direction = "left"
<SecondWindow>:
name: "second"
GridLayout:
cols:1
BoxLayout:
id: destination
RecycleView:
id: rv
viewclass: 'Label'
RecycleBoxLayout:
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
Button:
text: "show plot"
on_release:
root.btndu()
please help me if there is something wrong? Because this is my first time
The keys in your data must be attributes of your viewclass. If you are using Label as your viewclass, then the keys in your data are likely to be text, since that is the attribute of Label that can display a string. You can create your own viewclass to meet your specific needs. I have taken the liberty to create a viewclass that I call DataDisplay to demonstrate what I mean:
class DataDisplay(BoxLayout):
time = NumericProperty(0.0)
power = NumericProperty(0.0)
And using kv to plan the layout of the DataDisplay:
<DataDisplay>:
orientation: 'horizontal'
Label:
text: 'time: ' + str(root.time)
Label:
text: 'power: ' + str(root.power)
In this arrangement, each data element should contain two keys, a time and a power. Using this, the following code will display two sets of time and power in the RecycleView:
class MainWindow(Screen):
def btn(self):
self.manager.get_screen('second').ids.rv.data = [{'time': 2.3, 'power': 4.5}, {'time': 0.1, 'power':9.356}]