How to properly assign Kivy label text from Python file? - python

I'm pretty new to Kivy and Python so apologies for any glaring error.
I'm trying to make a home screen which displays the name used to login on the previous screen. Code snippets as follows:
My main app class;
class ProDuck(App):
logged_in_user = StringProperty()
print(logged_in_user)
def build(self):
self.icon = "LogoIcon.png"
GUI = Builder.load_file("GUI.kv")
return GUI
(Correctly formatted with indentation though)
Part of the login which changes the StringProperty, which inside another screen class. The logging_in_user is from self.username.text within that screen class;
if attempt == target_pass_hash[0]:
print("Login successful!")
print(logging_in_user)
ProDuck.logged_in_user = logging_in_user
print("New variable = " + ProDuck.logged_in_user)
Relevant part of .kv file;
GridLayout:
Label:
id: nametag
text: app.logged_in_user #<---
color: "grey"
The app runs, and prints the right variables, however the label which gets displayed is blank. I am really not sure why the label is not showing any text, am I assigning the StringProperty wrong in the login part? Appreciate any help :)

The expression ProDuck.logged_in_user is not the correct way to access a Property. You need to reference it through the instance of ProDuck. One way to do that is to use App.get_running_app().logged_in_user. So your code block could be:
if attempt == target_pass_hash[0]:
print("Login successful!")
print(logging_in_user)
App.get_running_app().logged_in_user = logging_in_user
print("New variable = " + App.get_running_app().logged_in_user)

Related

Display Kivy Color Wheel only

I am writing an app that has a need for the Kivy Color Wheel (https://kivy.org/doc/stable/api-kivy.uix.colorpicker.html) to choose a color value to assign to different users. However, I intend for it to be used on a phone screen, and as such I do not need the various sliders and color codes that make up the second half of the widget - simply tapping the desired colour is sufficient. I know that there is a question very similar to this that is answered, however this does not account for the .kv language that I am using in my program.
This is my .kv code:
<ColourScreen>:
Label:
text: 'Please Choose the colour for Team 1'
ColorPicker:
and my .py file:
class ColourScreen(Screen):
pass
class TheApp(App):
def build(self):
sm = ScreenManager()
sm.add_widget(ColourScreen(name='colour_screen'))
sm.current ='colour_screen'
return sm
def main():
Builder.load_file('menu.kv')
app = TheApp()
app.run()
if __name__ == '__main__':
main()
Could anybody help? Thanks in advance
Try using ColorWheel instead. You can use it in the kv as:
<ColourScreen>:
Label:
text: 'Please Choose the colour for Team 1'
ColorWheel:
on_color: root.color_selected(self.color)
And the color_selected() method:
class ColourScreen(Screen):
def color_selected(self, color):
print('got color', color)

How can I pre-fill a text input when I open the app?

I heard that I can pre-fill text input when I open an app with text property, but I am unsure how to do it without it being a class method. Does anyone know a way I could do this?
Python:
class LoginScreen(Screen): #This screen is
has_the_user_already_saved_login = open('saved/checkbox.txt', 'r')
user_previous_login = open('saved/rLD.txt', 'r')
if has_the_user_already_saved_login.read() == 'True':
has_the_user_already_saved_login.close()
print('User has selected the checkbox in the past')
s_email, s_password = user_previous_login.read().strip().split(';')
user_previous_login.close()
print(s_email)
print(s_password)
manager.root.ids.email.text = s_email
manager.root.ids.psswrd = s_password
def loginBtn(self):
login_email = self.email.text
login_password = self.password.text
Kivy:
TextInput:
id: email
TextInput:
id: psswrd
I've edited this post for clarity. This is my actual code (as seen above) with the non important lines removed. I want the if statement in the class to take the s_email and s_password and fill the two text inputs with them. As you can see I tried various approaches such as using root and manager, but so far I haven't found a solution. Currently the text inputs' data is collected in the loginBtn section action a user presses a button. How can I fill the text inputs with these new variables?
Wherever you define the TextInput, you can define its text attribute. If it is in py:
TextInput(text='Abba Dabba Doo')
If it is in kv:
TextInput:
text: 'Abba Dabba Doo'

In kivy2 or kivymd, is there a way to create a screen dynamically without adding them to a kv file

for example... lets say i have alot of products.
i want to be able to have the program know a certain products was clicked... easy enough
but then i want the program to create a screen based off of a template
basically on the fly.
thanks for the help
this is what i have tried so far.
def Create_New_Product_Screen(self,question,Screen_Name):
print(self,Screen_Name+'Made it here')
sm = ScreenManager()
screen = Screen(name=Screen_Name)
sm.add_widget(screen)
#sm.current = Screen_Name
app = MDApp.get_running_app()
app.change_screen(Screen_Name)
def Create_New_Screen(self,Screen_Name):
app = MDApp.get_running_app()
sm = app.root.ids['screen_manager']
screen = Screen(name=Screen_Name)
sm.add_widget(screen)
sm.current = Screen_Name
Now i just need to figure out how to make templates for the screens
but this worked... i had to find the screen manager in the kivy file
and then call it and create the screen then change to it.

Kivy app exiting on screen change

I'm trying to port my code from the .kv file all to Python (it seems easier for me that way). I've got two screens and I've been switching to the next one using root.manager.current = "main" in the kv file. However, when writing this bit in Python code, I've run into the crash of my app. This is the code I have:
class CustomScreenManager(ScreenManager):
def switch_view(self):
self.current = 'main'
class Intro(Screen):
pass
class Chat(Screen):
pass
class ChatApp(App):
def build(self):
Screens = CustomScreenManager(transition = NoTransition())
intro = Intro()
chat = Chat(name = "main")
bt1_intro = Button(on_press = Screens.switch_view())
intro.add_widget(bt1_intro)
Screens.add_widget(intro)
Screens.add_widget(chat)
return Screens
if __name__ == "__main__":
ChatApp().run()
ChatApp().screen_manager
I've also tried the switch_to method but it also crashes the app. What can I do to avoid the crashing and get the expected behaviour? Thanks in advance.
Change the definition of switch_view to
def switch_view(self, *args):
and add the Button with
bt1_intro = Button(on_press = Screens.switch_view)
The app crashes because in your original assignment of bt1_intro switch_view gets called (rather than passed to the function), and at the time the screen does not exist.

What's the idea behind ObjectProperty in this example from the Kivy docs?

I really try to get the concept of Kivy. I'm aware it's powerful and useful, but for me at some points also hard to understand, at least by the given examples in here. In the section "Designing with the Kivy Language" I found following example:
Python-file
from kivy.uix.floatlayout import FloatLayout
from kivy.app import App
from kivy.properties import ObjectProperty, StringProperty
class Controller(FloatLayout):
''' Create a controller that receives a custom widget from the kv lang file.
Add an action to be called from the kv lang file. '''
# label_wid = ObjectProperty()
info = StringProperty()
def do_action(self):
self.label_wid.text = 'My label after button press'
self.info = 'New info text'
class ControllerApp(App):
def build(self):
return Controller(info='Hello world')
if __name__ == '__main__':
ControllerApp().run()
controller.kv
<Controller>:
label_wid: my_custom_label
BoxLayout:
orientation: 'vertical'
padding: 20
Button:
text: 'My controller info is: ' + root.info
on_press: root.do_action()
Label:
id: my_custom_label
text: 'My label before button press'
There is some little deviation from the original: I made the line # label_wid = ObjectProperty() a comment, trying out to get the idea behind it, expecting the code not to run. But it is running! So would someone with a better understanding of Kivy be so kind to explain, why this line of code is useful (maybe at least for educational reasons), if not yet required (by any circumstance, of which I'm not aware of)?
When you add a kv line for a property that doesn't exist, it is automatically created, so the kv is actually the same in this case as putting label_wid = ObjectProperty() in the python. However, adding the property in Python is more explicit (especially if you will access it from python) and lets you be certain that a property of the right type will be created.

Categories