Using value from textinput in python - python

I want to make an app which would print text entered in TextInput when I press Print.
After a couple of hours of searching the web I still can't understand how to assing value of TextInput to variable in python script.
This is Kivy code:
<SimpleRoot>:
orientation:"vertical"
padding: root.width * .02, root.height * .02
spacing: "10dp"
TextInput:
id: txt
Button:
text: 'Print'
on_press: root.printTxt(txt.text)
Python script:
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.boxlayout import BoxLayout
class SimpleRoot(BoxLayout): # 2
def printTxt(text):
print txt.text
pass
class SimpleApp(App): # 1
def build(self):
# Return root widget
return SimpleRoot()
if __name__ == "__main__":
SimpleApp().run()

Try changing this:
class SimpleRoot(BoxLayout): # 2
def printTxt(text):
print txt.text
To this
class SimpleRoot(BoxLayout): # 2
def printTxt(self, text):
print text

Related

kivy positioning all items in a single box

I am writing a program that requires a label, a text_input, and a checkbox to be aligned on screen in that order. They should span the width of the screen and be at the same y level.
I have written this code in my .kv file which uses identical pos_hint values, but only the text_input box moves
Below is my .kv code:
<Union>:
BoxLayout:
orientation: "vertical"
BoxLayout:
orientation: "horizontal"
pos_hint_y: {"top":.85}
Label:
text: 'Session Length'
pos_hint: {"x":.3, "top":.85}
TextInput:
id: input
text: "test"
pos_hint: {"x":.5, "top":.85}
size_hint: 0.3, 0.05
background_disabled_normal: ""
disabled: not checkbox.active
on_text: app.return_text()
CheckBox:
id: checkbox
pos_hint: {"x":.7, "top":.85}
and here is my main.py
from kivy.core.window import Window
from kivy.lang import Builder
from kivy.uix.button import Button
from kivy.uix.dropdown import DropDown
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.screenmanager import Screen, ScreenManager
Window.size = (309, 555)
class MenuScreen(Screen):
pass
class SetupScreen(Screen):
pass
class drop_content(DropDown):
pass
class UnionScreen(Screen):
class Checkbox_Setup(FloatLayout):
pass
class TheApp(App):
def build(self):
# Create the screen manager
sm = ScreenManager()
sm.add_widget(MenuScreen(name='menu'))
sm.add_widget(SetupScreen(name='setup'))
sm.add_widget(UnionScreen(name='union'))
return sm
def return_text(self):
text = self.root.get_screen('union').ids.input.text
print(text)
def main():
Builder.load_file('menu.kv')
app = TheApp()
app.run()
if __name__ == '__main__':
main()
Finally, here is the output I am currently getting, with the label and checkbox in line but underneath the text_input which is in the right place.
I am relatively new to kivy so any help would be greatly appreciated. Thanks in advance!

kivy change attributes of a class using code and not the kv file

To change an attribute of a class, say font_size of the Label class, I can do add this in the kv file:
<Label>
font_size: "15sp"
How do I access the font_size attribute via code?
Your question is too vague... in what context do you want to access the attribute? If it is at the instantiation then you could do this ...
from kivy.app import App
from kivy.uix.label import Label
class TestApp(App):
def build(self):
return Label(text='hello world',
font_size= '70sp')
if __name__ == '__main__':
TestApp().run()
But if you want to access the font size of a label that is created in kV... Probably best to assign the label a NumericProperty as font size in the KV file and then change the NumericProperty as needed...
from kivy.app import App
from kivy.uix.label import Label
from kivy.properties import NumericProperty
class TestApp(App):
FontSize = NumericProperty(50)
def ChangeFont(self):
self.FontSize +=10
if __name__ == '__main__':
TestApp().run()
KV...
BoxLayout:
Button:
text: 'press me'
on_press: app.ChangeFont()
Label:
text: 'Hello'
font_size: app.FontSize
And if you want to access a specific label widget you can make the label a class attribute and then modify it's text directly, if you had many labels you could add each to a list, assign the list as a class attribute and loop over the list changing each label.font_size, the example here only has one label...
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
class MyButton(Button):
pass
class TestApp(App):
L = Label(text = 'hello', font_size = 20)
def ChangeFont(self):
self.L.font_size +=10
def build(self):
B = BoxLayout()
B.add_widget(MyButton())
B.add_widget(self.L)
return B
if __name__ == '__main__':
TestApp().run()
KV...
<MyButton>:
text: 'press me'
on_press: app.ChangeFont()
As John said in the comment, use ids to identify your label.
kv file
<MyBoxLayout>
Label:
id: mylabel
font_size: '15dp'
Button:
on_release: root.change_font_size()
python file
class MyBoxLayout(BoxLayout):
def change_font_size(self):
self.ids.mylabel.font_size = '12dp'
Obviously you can do more with it than just change the size once, but thats the basic idea.

Black screen on kivy how to fix

when I try to run the code it just displays a blank screen I tried to find answers everywhere but nothing works
This is my main.py file:
import kivy
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.graphics import *
from kivy.lang import *
from kivy.uix.screenmanager import *
class MyWidgets(Widget):
pass
kv = Builder.load_file('math.kv')
class Calculator(App):
def build(self):
return kv
if __name__ == '__main__':
Calculator().run()
And this is my math.kv file:
<MyWidgets>
num: num
GridLayout:
cols: 1
TextInput:
id: num
multiline: False
GridLayout:
cols: 3
Button:
text: '1'
font_size: 25
Button:
text: '2'
font_size: 25
Button:
text: '3'
font_size: 25
Looks like you have an indent error in build function. Still, that should have shown some error instead of showing a blank screen. Then in your .kv file, I don't know what that num is. After removing num from .kv and correcting indentation error I run the file and it works fine.
Here's the code I used:
.py
import kivy
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.graphics import *
from kivy.lang import *
from kivy.uix.screenmanager import *
class MyWidgets(Widget):
pass
class Calculator(App):
def build(self):
kv = Builder.load_file('math.kv')
return kv
if __name__ == '__main__':
Calculator().run()
.kv
<MyWidgets>
GridLayout:
cols: 1
TextInput:
id: num
multiline: False
GridLayout:
cols: 3
Button:
text: '1'
font_size: 25
Button:
text: '2'
font_size: 25
Button:
text: '3'
font_size: 25

Kivy: How can I loop through data from a text file and paste it as a list on my screen all within their own label?

I am able to display text from the text file on to the UI but I don't know how to give each piece of text its own label so I am able to evenly spread the text out on screen.
*.py
#imported from kivy framework
from kivy.app import App
from kivymd.app import MDApp
from kivy.app import App
from kivy.uix.label import Label
from datetime import datetime
from datetime import timedelta
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.image import Image
import dictionaryData
from kivy.lang import Builder
from kivy.base import runTouchApp
import os
class Main_Screen(Screen):
pass
class Dictionary_Screen(Screen):
def on_enter(self):
self.Data()
def Data(self):
i = 0
print("trigger")
file1 = open('dict.txt','r')
for lines in file1:
i +=1
fields = lines.split(',')
print('I draw label')
Data = (fields[0], fields[1])
Title,Description = Data
# page is an object
page = dictionaryData.Dictionary(Title,Description)
page.formatData()
work = page.placeholder()
flipper = page.placeholder()
self.add_widget(Label(text = flipper, pos=(i*00, 100)))
self.ids["textFile"].text += flipper + '\n'
#class for all screens
class ScreenManagement(ScreenManager):
pass
class MainApp(MDApp):
pass
MainApp().run()
*.kv
#:kivy 1.0
#:import hex kivy.utils.get_color_from_hex
#styles that will apply to all intences for each tag
<MDRaisedButton>:
font_size:18
<Label>:
color: 0,0,0,1
#declaring screen managers and printing them in this order
ScreenManagement:
Main_Screen:
name: "Main_Screen"
Dictionary_Screen:
name: "Dictionary_Screen"
<Main_Screen>:
Button:
text: "Dictionary"
on_release:
app.root.current = "Dictionary_Screen"
<Dictionary_Screen>:
BoxLayout:
orientation: 'vertical'
spacing: 10
padding: 50
canvas.before:
Color:
rgba: hex('#000')
Rectangle:
size: self.size
pos: self.pos
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
size_hint: 0.5, 0.5
GridLayout:
rows: 3
cols: 3
padding: 10
spacing: 10
Label:
id:textFile
color: (1,0,1,1)
Data from the text file goes through a class where it get properly formatted and as you can see by the image it appears fine on screen but its all packed together and not evenly separated.
The purple text is just me hard coding the text using a label in the kv file but I plan to have more than 50 lines that I want to display and hard coding each one does not seem like the right way to go about it.
Is there a way I'm able to give each piece of text it's own label or some how even spread the text out so it appears as a list on screen?
Below is data just in case for reference.
Class module that gets imported and processes the text file
# class
class Dictionary:
# Dunder init asigns values to varibles each time code is exacuted.
def __init__(self,title,description):
self.title = title
self.description = description
def formatData(self):
print("Title: {} Description {}".format(self.title,self.description))
def placeholder(self):
return "Title: {} Description {}".format(self.title,self.description)
dict.txt
CPU,CPU_INFORMATION
RAM,RAM_INFORMATION
SOMETHING,SOMETHING_INFORMATION
I think your problem is a simple one. Try changing the line:
self.add_widget(Label(text = flipper, pos=(i*00, 100)))
to something like:
self.add_widget(Label(text = flipper, pos=(00, i*50)))
Or, if you add an id to your BoxLayout:
<Dictionary_Screen>:
BoxLayout:
id: box
Then you can use:
self.ids.box.add_widget(Label(text = flipper))

Kivy ScreenManager - Updating label text

I asked a question regarding updating label text (Kivy change label text with python) - it was answered and was working but I've been trying for hours trying to adapt my running code to ScreenManager so I can have multiple screens. I've cut down the code to the basic stuff I can't get working.
ScreenManager code breaks the solution, I know what the issue is I just can't resolve it. The code is working, text and time updating in the shell but not the labels, I couldn't add return self.first_screen to the Kivy def build so its not binding to the_time: _id_lbl_time - Any help/pointers would be really appreciated.
from kivy.app import App
from kivy.base import runTouchApp
from kivy.lang import Builder
from kivy.properties import ListProperty, StringProperty, ObjectProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen, WipeTransition, FadeTransition
from kivy.uix.anchorlayout import AnchorLayout
from kivy.clock import Clock
import time
from datetime import datetime, timedelta
class FirstScreen(Screen):
def update_time(self, sec):
MyTime = time.strftime("%H:%M:%S")
print MyTime # to test update_time is called etc
self.the_time.text = MyTime #<---- self.the_time isn't working
class SecondScreen(Screen):
def update_text(self, sec):
MyText = 'New Text'
print MyText # to test update_text is called etc
self.the_set.text = MyText #<---- self.the_set isn't working
class MyScreenManager(ScreenManager):
pass
Builder.load_string('''
<FirstScreen>:
name: 'first'
the_time: _id_lbl_time
BoxLayout:
orientation: 'vertical'
Label
id: _id_lbl_time
text: 'Clock'
font_size: 30
BoxLayout:
Button:
text: 'New Here'
font_size: 20
size: 200, 50
size_hint: None, None
on_release: app.root.current = 'second'
<SecondScreen>:
name: 'second'
the_set: _id_lbl_set
BoxLayout:
orientation: 'vertical'
Label:
id: _id_lbl_set
text: 'New Here'
font_size: 30
BoxLayout:
Button:
text: 'Main'
font_size: 20
size: 200, 50
size_hint: None, None
on_release: app.root.current = 'first'
''')
class ScreenManagerApp(App):
def build(self):
sm = ScreenManager()
sm.add_widget(FirstScreen(name='first'))
sm.add_widget(SecondScreen(name='second'))
self.first_screen = FirstScreen()
self.sec_screen = SecondScreen()
return sm #<---- I can't return self.first_screen etc here?
def on_start(self):
Clock.schedule_interval(self.first_screen.update_time, 1) # 1 second
Clock.schedule_interval(self.sec_screen.update_text, 2)
ScreenManagerApp().run()
I can't return self.first_screen etc here?
No. There has to be a ScreenManager on top of the Screen widgets, otherwise it's just a RelativeLayout as is its definition in the source code.
You experienced a really common mistake by beginners. You used one instance FirstScreen() and SecondScreen() for ScreenManager(those are visible) and then you created another instances with:
self.first_screen = FirstScreen()
self.sec_screen = SecondScreen()
which you then used for Clock:
Clock.schedule_interval(self.first_screen.update_time, 1)
Clock.schedule_interval(self.sec_screen.update_text, 2)
and that means text properties in instances that actually aren't added anywhere as widgets were used for updating. The instances exist, so no error to trigger except the visual one → you don't see the values, because you used wrong instance.
Correct build():
def build(self):
sm = ScreenManager()
self.first_screen = FirstScreen(name='first')
self.sec_screen = SecondScreen(name='second')
sm.add_widget(self.first_screen)
sm.add_widget(self.sec_screen)
return sm

Categories

Resources