Trying to make Kivy button pop-up a text box - python

Similar/relevant links that didn't help much:
How to get a text input box to display with Kivy?
https://kivy.org/doc/stable/api-kivy.uix.textinput.html
Getting started with Kivy: getting user input using Kivy
I have been at this for several hours and I have found questions similar to mine but nothing has actually worked.
Here's what I'm trying to do: Create a button that when pressed, pulls up a text input box and then displays whatever you type on the button after a short string.
E.G.
Button starts like: "LP: "
You enter text: "4000"
Button now shows: "LP: 4000"
How would I accomplish this? If that's not totally possible I'd also be okay with just getting the input after hitting the button. I can't even seem to get that far. Very new to Kivy and fairly new to Python.
Button code (KV File):
<FloatLayout>:
Button:
name: 'LP'
id: LP
text: "LP: 4000"
size_hint: 0.14, 0.15
pos_hint: {"left": 1, "top": 0.8105}
Class (Py File):
class LPInput(Widget):
pass
Code for the input (KV File):
<LPInput>:
size_hint: 0.14, 0.15
pos_hint: {"left": 1, "top": 0.8105}
TextInput:
id: lifepoint
text: ""
Label:
id: currlp #not sure this is doing anything
text: "LP: "
I've written some other coding pieces to attempt to create this via different methods but in my frustration I saved over my file that was holding those so this is all I have at the moment.

The solution below is assuming LPInput is the root widget.
<LPInput>:
size_hint: 0.14, 0.15
pos_hint: {"left": 1, "top": 0.8105}
TextInput:
id: lifepoint
text: ""
Label:
id: currlp #not sure this is doing anything
text: "LP: "
<FloatLayout>:
Button:
name: 'LP'
id: LP
text: "LP: "
size_hint: 0.14, 0.15
pos_hint: {"left": 1, "top": 0.8105}
on_release:
self.text = "LP: " + app.root.ids.lifepoint.text
Kv language » Rule context
There are three keywords specific to Kv language:
app: always refers to the instance of your application.
root: refers to the base widget/template in the current rule
self: always refer to the current widget
Example
main.py
from kivy.lang import Builder
from kivy.base import runTouchApp
runTouchApp(Builder.load_string('''
#:kivy 1.11.0
FloatLayout:
TextInput:
id: lifepoint
text: ""
size_hint: 0.14, 0.15
pos_hint: {"left": 1, "top": 0.8105}
Button:
name: 'LP'
id: LP
text: "LP: "
size_hint: 0.14, 0.15
pos_hint: {"right": 1, "top": 0.8105}
on_release:
self.text = "LP: " + root.ids.lifepoint.text
'''))
Output

Related

Kivy Access ids from .kv file to .py file

.
I'm new into kivy and I want to make an android app. I almost finish GUI, the front-end part, but I have a very big problem. I've searched all over the internet but without answer. I don't know how to access ids from .kv to use them into .py functions.
I've tried all of what I've found on the internet, but didn't work. I want to access ids from .kv file to work with them. For exemple, I have a profile screen, where user write his first name, and last name, and in the next page I want to show his first and last name by using a function.
Here's the .kv profile page:
<Profile>
FloatLayout:
canvas.before:
Color:
rgba:(1,1,1,1)
Rectangle:
source:"CreateProfileImg.png"
size: root.width, root.height
pos: self.pos
Label:
pos_hint: {"top": 1, "left": 1}
size_hint: 1, .1
text:"Create your profile"
font_size: 65
font_name:"FreeSansBoldOblique-BYJ3.otf"
color: rgba(247,251,246,255)
id: profile_label
Label:
text: "First Name: "
font_size: 45
color: rgba(247,251,246,255)
size_hint: 0.1, 0.1
pos_hint: {"x":0.20, "top":0.8}
TextInput:
id: name
multiline: False
size_hint: 0.5, 0.1
pos_hint: {"x": 0.35, "top": 0.8}
Label:
text: "Last Name: "
font_size: 45
color: rgba(247,251,246,255)
size_hint: 0.1, 0.1
pos_hint: {"x":0.16, "top":0.7}
TextInput:
id: prenume
multiline: False
size_hint: 0.5, 0.1
pos_hint: {"x": 0.35, "top": 0.7}
Label:
text: "Currency: "
font_size: 45
color: rgba(247,251,246,255)
size_hint: 0.1, 0.1
pos_hint: {"x":0.18, "top":0.6}
Spinner:
id: moneda
text:"Select currency"
color: 0, 0, 0 ,1
background_normal:"MoneyButton.png"
size_hint: 0.5, 0.1
pos_hint: {"x":0.35, "top":0.6}
values: ['Ron', 'Euro', 'Dolar','Lira Sterlina']
sync_height: True
#on_text: root.currency_clicked(moneda.text)
GridLayout:
rows:1
pos_hint:{"top": .2, "left": 1}
size_hint: 1, .2
ImageButton:
source:"Next_Button_On_Press.png"
on_press:
self.source = "Next_Button_On_Release.png"
app.printname()
on_release:
self.source = "Next_Button_On_Press.png"
app.change_screen("page1")
I have more .kv files with lots of ids, but I think if I learn how to work with thise two, next will be easier.
I want to specify that I have a 'main.kv' which contains: 1. name
2.ids
from all over my .kv files. I use those ids to navigate between pages.
Here's the code:
#:include homescreen.kv
#:include page1.kv
#:include profile.kv
GridLayout:
cols: 1
ScreenManager:
id: screen_manager
HomeScreen:
name: "home_screen"
id: home_screen
Profile:
name: "profile"
id: profile
Page1:
name: "page1"
id: page1
Let me explain for the last time what I want to do, maybe will be usefull for you to understand and trying to help me. As you see, into 'profile' I have 3 ids. When get TextInput from user, those ids store the information. I want to use those information into next page, where I want to say [[[" Hello " + ids]]].
So, please help me!! Make me to understand!
I also had trouble with this as well when I was first leaning Kivy a couple years back, but I finally figured out the way. there is a bit of boilier-plate required to maintain the connection.
in this example my_label is a kivy id and I am connecting it to a Python object of the same name. this is done with the line: my_label: my_label
<Screen2>:
# Python: KIVY id(s)
my_label: my_label
BoxLayout:
Label:
text: "Screen2"
MDLabel:
id: my_label
text: "-"
and in the Python code matching that object there is a line in the class definitionl my_label: MDLabel
which is providing a type hint. If you are using an IDE such as PyCharm this can help you to have auto-complete in your code according to the object type.
class Screen2(Screen):
my_label: MDLabel
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.my_label.text = "test"
and the line self.my_label.text = "test" is of course to show how you can use the object.
you can also do more complicated things such as put multiple items from a kv layout into a list or even a dictionary.
kivy code:
# a list of spinners kv_spinner_list is a ListProperty
kv_spinner_list: [kv_spinner_0, kv_spinner_1, kv_spinner_2,]
and this can be a more organized way to bring multiple items into the Python code.

How to change the value of a python variable from a .kv file

I am new fairly new to python and have just started using the kivy library. I am trying to change the value of a variable in the .py file when a button from the .kv file is pressed. I am unsure how to instigate this.
The code I currently have is:
python file:
from kivy.app import App
from kivy.uix.widget import Widget
class experienceScreen(Widget):
pass
experience=""
class workoutApp(App):
def build(self):
return experienceScreen()
workoutApp().run()
def beginnerpressed(self, instance):
experience==1
if experience == 1:
print("test code works.")
if experience == 2:
print("test code works.")
if experience == 3:
print("test code works.")
kivy file:
#: kivy 2.1.0
<experienceScreen>:
FloatLayout:
pos:0,0
size: root.width, root.height
Label:
text: "What level of gym go-er are you?"
pos_hint: {'x':.4,'y':.85}
size_hint:0.2,0.1
Button:
text: "Beginner"
pos_hint: {'x':.25,'y':.6}
size_hint:0.5,0.1
on_press: experience=1
Button:
text: "Intermediate"
pos_hint: {'x':.25,'y':.4}
size_hint:0.5,0.1
on_press: experience=2
Button:
text: "Advanced"
pos_hint: {'x':.25,'y':.2}
size_hint:0.5,0.1
on_press: experience=3
I had expected that when I pressed any of the buttons that the "test code works" text would display in the console. However, this is not the case. I expect this is because variables are assigned differently within the .kv file.
The on_press item needs to be connected to a method (function) in your code. One can use root.something to reach the widget or app.something to reach a method in the app object.
Kivy file
<experienceScreen>:
FloatLayout:
pos:0,0
size: root.width, root.height
Label:
text: 'What level of gym go-er are you?'
pos_hint: {'x':.4,'y':.85}
size_hint:0.2,0.1
Button:
text: 'Beginner'
pos_hint: {'x':.25,'y':.6}
size_hint:0.5,0.1
on_press: root.beginnerpressed(1)
Button:
text: 'Intermediate'
pos_hint: {'x':.25,'y':.4}
size_hint:0.5,0.1
on_press: root.beginnerpressed(2)
Button:
text: 'Advanced'
pos_hint: {'x':.25,'y':.2}
size_hint:0.5,0.1
on_press: root.beginnerpressed(3)
python
class experienceScreen(Widget):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.experience = 0
def beginnerpressed(self, experience: int):
self.experience = experience
print(f"test code works. {self.experience}")
class workoutApp(App):
def build(self):
return experienceScreen()
workoutApp().run()

How to display the content of a file on a screen using kivy and python?

This is the code in python for reading the particular file.
class Display2(Screen):
def data_even(self):
w_f = "abc.docs"
try:
with open(f"{w_f}") as w:
f = w.readlines()
self.ids.display.text = str(f)
except FileNotFoundError:
self.ids.display.text = "Not found, Sorry, the user has no data entered yet."
In KIVY
KV= '''
:
name: "Display2"
GridLayout:
cols: 1
Label:
id: display
text: "I will be displaying your data"
color: "#1e272e"
MDFloatLayout:
MDFillRoundFlatButton:
pos_hint: {'center_x': 0.1, 'center_y': 0.1}
id:data
text: "Show Data"
on_press: root.data_even()
MDFillRoundFlatButton:
pos_hint: {'center_x': 0.9, 'center_y': 0.1}
text: "Close"
on_release:
app.root.current = "Evening"
root.manager.transition.direction = "left"
'''
When I am trying to run this above code snippet I am not able to see the text which is present in the file instead only a black colored label is coming. I hope I explained myself clear. Thanks!!
Please note this is not the full code only some snippets of the program
How to display the content of a file on a screen using kivy and python ?
from kivy.app import App
from kivy.uix.label import Label
def get_text(file_path):
try:
with open(f"{file_path}") as w:
f = w.readlines()
return str(f)
except:
return "Not found, Sorry, the user has no data entered yet."
class MyApp(App):
def build(self):
return Label(text=get_text("abc.txt"), color="#ffc100")
MyApp().run()
I got the answer to my question!!!
I replaced the label with texinput and now the program is working fine.
This is the code in python for reading the particular file.
class Display2(Screen):
def data_even(self):
w_f = "abc.docs"
try:
with open(f"{w_f}") as w:
f = w.readlines()
self.ids.display.text = str(f)
except FileNotFoundError:
self.ids.display.text = "Not found, Sorry, the user has no data entered yet."
In KIVY
KV= ''' :
name: "Display2"
GridLayout:
cols: 1
**TextInput:**
id: display
text: "I will be displaying your data"
color: "#1e272e"
MDFloatLayout:
MDFillRoundFlatButton:
pos_hint: {'center_x': 0.1, 'center_y': 0.1}
id:data
text: "Show Data"
on_press: root.data_even()
MDFillRoundFlatButton:
pos_hint: {'center_x': 0.9, 'center_y': 0.1}
text: "Close"
on_release:
app.root.current = "Evening"
root.manager.transition.direction = "left"

Can not load kivy file from kv variable

So I'm working on my first app and when learning about kivy and watching youtube videos I was seeing different ways people would load in their KV file and one was putting in in a variable and returning it from the build method. Anytime I do this, no errors are necessarily thrown but it doesn't load the window properly and it makes no sense why the KV file isnt loading. If anyone can point me in the right direction I'd appreciate it, the code is below.
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
class LoginLayout(Widget):
def login(self, **kwargs):
print("Login function working")
username = self.ids.username.text
password = self.ids.password.text
print(username)
print(password)
kv = Builder.load_file('loginScreen.kv')
class LoginScreen(App):
def build(self):
return kv
app = LoginScreen()
app.run()
kv file
<LoginLayout>:
BoxLayout:
orientation: 'vertical'
size: root.width, root.height
Label:
text: 'Username'
TextInput:
id: username
multiline: False
size_hint: (.5, .3)
pos_hint: {'center_x' : .5}
Label:
text: 'Password'
TextInput:
id: password
multiline: False
size_hint: (.5, .3)
pos_hint: {'center_x' : .5}
Button:
text: 'Login'
size_hint: (.2, .8)
pos_hint: {'center_x' : 0.5}
on_release: root.login()
Button:
text: 'Create Account'
size_hint: (.2, .8)
pos_hint: {'center_x' : 0.5}
Button:
text: 'Forgot login Info'
size_hint: (.2, .8)
pos_hint: {'center_x' : 0.5}
The problem is that your kv does not define a root widget, it only defines rules for how to build the LoginLayout. An easy fix is to remove the <> from around LoginLayout.

Kivy can't get text input using ScreenManager

I'me working on a project and I'm using kivy.
I want to crete an app and I need multiple pages so I'm using ScreenManages.
I also need to take User Input in one of the pages and save it, so I've used MDTextField for take the text and a button to save the data.
When i press the button the app should take the data from the text field and save it in a file with sqlite3, but when I press the button it give me a really strange error.
I've tried to rewrite only that page of the app without the ScreenManager and it works.
How can I make it work also with the ScreenManager ?
(How can I get the User Input using MDTextField and ScreenManager)
I will show you some lines of code to make you understand better:
This is the Kivy Code:
<AddWindow>:
name: "add"
MDTextField:
id: account_link
hint_text: "Link"
helper_text: "Insert the Link of the WebSite to enter in the website from this app"
helper_text_mode: "on_focus"
line_color_normal: app.theme_cls.accent_color
pos_hint: {"center_x": 0.5, "center_y": 0.8}
size_hint_x: None
width: 1200
This is the code to take the data from the Text Field (that part of code it's executed when the user presses the submit button):
data = self.root.ids["account_link"].text
This is the error i get when i press the button:
data = self.root.ids["account_link"].text
KeyError: 'account_link'
Note that the documentation says:
ids are added to the root widget’s ids dictionary.
Poorly worded documentation, because they elsewhere refer to "root widget" as the root of the entire GUI. But in this case "root widget" is the root of the rule where the ids are defined. In your case that might be the AddWindow rule (not 100% sure due to the indentation of your kv snippet). If that is the case, then you need a reference to the instance of AddWindow that appears in your GUI:
data = addwindow_instance.ids["account_link"].text
Without seeing more of your code, I can only guess at the appropriate method to access the instance of AddWindow.
With the addition of a complete code, I can now help you. Here is a modified version of your add_passwd() method:
def add_passwd(self):
# get a reference to the AddWindow Screen
addwindow_instance = self.root.get_screen('add')
# use that instance to access the MDTextFields
account_link = addwindow_instance.ids["account_link"].text
account_name = addwindow_instance.ids["md_account_name"].text
account_nickname = addwindow_instance.ids["md_account_nickname"].text
email = addwindow_instance.ids["md_email"].text
passwd = addwindow_instance.ids["md_passwd"].text
#TEST
print(account_link)
print(account_name)
print(account_nickname)
print(email)
print(passwd)
Note that this also requires a couple corrections to your kv. Wherever you have anything like:
id: "some_id"
it should be changed to:
id: some_id
One example is id: "md_account_name".
This is More of my code:
# Screens
class MainWindow(Screen):
pass
class AddWindow(Screen):
pass
class WindowManager(ScreenManager):
pass
KV = """
WindowManager:
MainWindow:
AddWindow:
<MainWindow>:
name: "main"
MDRoundFlatButton:
text: "Add"
pos_hint: {"center_x": 0.5, "center_y": 0.7}
on_press:
app.root.current = "add"
root.manager.transition.direction = "left"
MDRoundFlatButton:
text: "Show"
pos_hint: {"center_x": 0.5, "center_y": 0.6}
on_press:
app.root.current = "show"
MDTextButton:
text: "Account"
pos_hint: {"center_x": 0.5, "center_y": 0.1}
on_press:
app.root.current = "settings"
root.manager.transition.direction = "up"
<AddWindow>:
name: "add"
MDRaisedButton:
text: "BACK"
md_bg_color: 0, 0, 0, 1
pos_hint: {"x": 0.01, "y": 0.93}
on_release:
app.root.current = "main"
root.manager.transition.direction = "right"
MDTextField:
id: account_link
hint_text: "Link"
helper_text: "Insert the Link of the WebSite to enter in the website from
this app"
helper_text_mode: "on_focus"
line_color_normal: app.theme_cls.accent_color
pos_hint: {"center_x": 0.5, "center_y": 0.8}
size_hint_x: None
width: 1200
MDTextField:
id: "md_account_name"
hint_text: "Account"
helper_text: "Insert the Name of the Account You Want to Save"
helper_text_mode: "on_focus"
line_color_normal: app.theme_cls.accent_color
pos_hint: {"center_x": 0.5, "center_y": 0.7}
size_hint_x: None
width: 1200
MDTextField:
id: "md_account_nickname"
hint_text: "Nickname"
helper_text: "Insert the Nickname You Have in the Account"
helper_text_mode: "on_focus"
line_color_normal: app.theme_cls.accent_color
pos_hint: {"center_x": 0.5, "center_y": 0.6}
size_hint_x: None
width: 1200
MDTextField:
id: "md_email"
hint_text: "Email"
helper_text: "Insert the Email You Created the Account with"
helper_text_mode: "on_focus"
line_color_normal: app.theme_cls.accent_color
pos_hint: {"center_x": 0.5, "center_y": 0.5}
size_hint_x: None
width: 1200
MDTextField:
id: "md_passwd"
hint_text: "Password"
helper_text: "Insert Your Password of the Account"
helper_text_mode: "on_focus"
line_color_normal: app.theme_cls.accent_color
pos_hint: {"center_x": 0.5, "center_y": 0.4}
size_hint_x: None
width: 1200
MDFillRoundFlatButton:
text: "Submit"
pos_hint: {"center_x": 0.5, "center_y": 0.1}
on_press: app.add_passwd()
"""
class App(MDApp):
def build(self):
self.title = "Safed" #The Name of the App is "Safed": "Save" + "Saved"
self.theme_cls.theme_style = "Dark" # Light
self.theme_cls.primary_palette = "Blue"
return Builder.load_string(KV)
def add_passwd(self):
account_link = AddWindow_istance.ids["account_link"].text
account_name = self.root.ids["md_account_name"].text
account_nickname = self.root.ids["md_account_nickname"].text
email = self.root.ids["md_email"].text
passwd = self.root.ids["md_passwd"].text
#TEST
print(account_link)
print(account_name)
print(account_nickname)
print(email)
print(passwd)
if __name__ == "__main__":
App().run()

Categories

Resources