Passing text from textinput to label in Kivy - python

I am trying to get the textinput widget to pass text into the callback function that makes a label with the text when called by the printbutton, should be fairly simple when you think about it. But I have a habit of not seeing the wood for the trees. Anyhoo, if anyone can figure this out then code it up :P
import kivy
kivy.require('1.5.1')
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
class kivyentrywidget(GridLayout):
def __init__(self, **kwargs):
super(kivyentrywidget, self).__init__(**kwargs)
self.cols = 2
self.add_widget(Label(text='What do you want to print?'))
self.text_input = TextInput(multiline=False)
self.add_widget(self.text_input)
self.printbutton = Button(text='Print')
self.printbutton.bind(on_press=callback)
self.add_widget(self.printbutton)
def callback(self):
return Label(text=self.text_input.text)
class Firstapp(App):
def build(self):
return kivyentrywidget()
if __name__ == '__main__':
Firstapp().run()

def callback(self,evt=None): #not sure if kivy sends event info so added optional arg just in case
return self.add_widget(Label(text=self.text_input.text))
maybe ... not overly familiar with kivy but i think that would do it ..
also
self.printbutton.bind(on_press=self.callback)
should fix your other problem

Related

Kivy(framework): blank window after running code

After running this code python idle gave me a blank window without any kivy widgets and python idle does not show any error.
what is the problem in this code?
screen shot of blank window
code:
import kivy
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
class me(App):
def __init__(self,b,g,l,t):
super(me, self).__init__()
self.b=Button(text='start')
self.g=GridLayout(cols=4)
self.l=Label(text='label')
self.t=TextInput()
self.g.add_widget(self.b)
self.g.add_widget(self.t)
self.g.add_widget(self.l)
m=me('b','g','l','t')
m.run()
Building the App should be done in a build() method of the App, and that method should return the root widget for the App. Like this:
class me(App):
def __init__(self,b,g,l,t):
super(me, self).__init__()
self.b=Button(text='start')
self.g=GridLayout(cols=4)
self.l=Label(text='label')
self.t=TextInput()
self.g.add_widget(self.b)
self.g.add_widget(self.t)
self.g.add_widget(self.l)
def build(self):
return self.g

How to update a Kivy Scrollview Label in real time?

I could really really need some help with my actually quite simple Python Kivy Problem! I wrote a program that first announces counting to 5 and then should start counting from 1 to 5. The info should be shown in a scrollview-Label. The code roughly does its job but does not update the scrollview step-by-step but all at once after time is elapsed...can anybody please help? Thank you in advance!
import kivy
from kivy.config import Config
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.core.window import Window
from kivy.uix.scrollview import ScrollView
import time
kivy.require("2.0.0")
Config.set('kivy', 'keyboard_mode', 'systemandmulti')
class MainMenu(GridLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.cols = 1
self.rows = 2
self.infowindow = ScrollableInfo(height=Window.size[1]*0.8, size_hint_y=None)
self.add_widget(self.infowindow)
self.ButtonCheckConnection = Button(text="Start Counting to 5")
self.ButtonCheckConnection.bind(on_press=self.countingtofive)
self.add_widget(self.ButtonCheckConnection)
def countingtofive(self, *_):
self.infowindow.update_scrollview(f"Counting to 5 is going to start in 3 seconds")
time.sleep(3)
countingmaximum = 5
for i in range(countingmaximum):
currentnumber = i+1
self.infowindow.update_scrollview(str(currentnumber))
time.sleep(1)
class ScrollableInfo(ScrollView):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.layout = GridLayout(cols=1, size_hint_y=None)
self.add_widget(self.layout)
self.connectioninfo_history = Label(size_hint_y=None, markup=True)
self.layout.add_widget(self.connectioninfo_history)
def update_scrollview(self, newinfo):
self.connectioninfo_history.text += '\n' + newinfo
self.layout.height = self.connectioninfo_history.texture_size[1]+15
self.connectioninfo_history.height = self.connectioninfo_history.texture_size[1]
self.connectioninfo_history.text_size = (self.connectioninfo_history.width*0.98, None)
class Counting(App):
def build(self):
self.screen_manager = ScreenManager()
self.mainmenu_page = MainMenu()
screen = Screen(name="MainMenu")
screen.add_widget(self.mainmenu_page)
self.screen_manager.add_widget(screen)
return self.screen_manager
if __name__ == "__main__":
counting_app = Counting()
counting_app.run()
The problem is that you are running your countingtofive() method on the main thread. Since Kivy uses the main thread to update the GUI, it cannot do that until you release the main thread (by returning from the countingtofive() method). That is why you never see anything until that method completes.
To fix that, run the countingtofive() method in another thread, like this:
def start_counting_thread(self, *args):
Thread(target=self.countingtofive, daemon=True).start()
And change the Button to bind to the start_counting_thread() method:
self.ButtonCheckConnection.bind(on_press=self.start_counting_thread)
And one minor change to the update_scrollview() method (add the #mainthread decorator):
#mainthread
def update_scrollview(self, newinfo):
The #mainthread decorator forces the decorated method to be run on the main thread. The same can be accomplished by using Clock.schedule_once(), but the decorator is easier. Just the piece of the code that actually updates the GUI must be run on the main thread. Generally, you should try to avoid long running methods on the main thread.

Kivy Text Editor Input Not Showing Up

I have unfortuanlly have encourtered an error in kivy and Python 3. I have not found a soultion via Google. I wanted to get text input at the very least but it does not show up. Just the text itself. Thank you for your time!
import kivy
kivy.require('1.10.1') # replace with your current kivy version !
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.textinput import TextInput
from kivy.uix.label import Label
class ColdKivyApp(App):
def build(self):
f = FloatLayout()
label = Label(text="Cold") #I acutally orginally called it Zone unitil I changed it into Cold cause it's really cold now
f.add_widget(label)
txt = TextInput(text='', focus=True, multiline=True, cursor_blink=True, background_color=(1,1,1,1))
f.add_widget(txt)
return f
if __name__ == '__main__':
ColdKivyApp().run()
It seems that there is a bug in TextInput when setting the focus in the constructor, a workaround is to set the focus an instant after the window is shown through Clock:
import kivy
kivy.require('1.10.1') # replace with your current kivy version !
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.textinput import TextInput
from kivy.uix.label import Label
from kivy.clock import Clock
class ColdKivyApp(App):
def build(self):
f = FloatLayout()
label = Label(text="Cold")
f.add_widget(label)
txt = TextInput(multiline=True, cursor_blink=True, background_color=(1,1,1,1))
f.add_widget(txt)
Clock.schedule_once(lambda *args: setattr(txt, "focus", True))
return f
if __name__ == '__main__':
ColdKivyApp().run()

kivy python widget instance or all widgets

Please help me with understanding classes/instances in python. I want to make a few buttons, and change color of the button, when it's clicked. I don't understand why on_touch_down changes the color of all the instances of the class, not the one that is touched. It's difficult for me to find answer because I don't know how to name it, I don't have much experience with objects. Please explain this. Thank you a million.
import kivy
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.textinput import TextInput
from kivy.graphics import Color, Ellipse
class MemoWidget(Button):
def on_touch_down(self, touch):
self.background_color=[100,100,1,1]
class MyApp(App):
def build(self):
root = BoxLayout(orientation='vertical',spacing=4)
m1 = MemoWidget()
m2 = MemoWidget()
m3 = MemoWidget()
root.add_widget(m1)
root.add_widget(m2)
root.add_widget(m3)
return root
if __name__ == '__main__':
MyApp().run()
You might think that on_touch_down only affects the widget you touch. But it affects all widgets of that class.
So what you might want, is on_press or on_release, to only affect the widget itself.
class MemoWidget(Button):
def on_release(self):
self.background_color=[100,100,1,1]

Python kivy text input

I'm a newbie at python, and now doing a dictionary with kivy. Issue is when I type text, it's not working. Below there I just want to check if it's working or not, so I put some popup, and if input text is 'a' then print true. It's just checking it's working or not, hope you guys help me, thank you.
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.lang import Builder
from kivy.uix.popup import Popup
from kivy.uix.bubble import Bubble
class CustomPopup(Popup):
pass
class Diction(GridLayout):
def __init__(self, **kwargs):
super(Diction, self).__init__(**kwargs)
self.cols=2
self.add_widget(Label(text="Search"))
self.search=TextInput(multiline=False)
self.add_widget(self.search)
if self.search=='A':
print 'True'
else:
print 'False'
self.add_widget(Button(text="click",on_press=self.show_popup))
def show_popup(self, b):
p = CustomPopup()
p.open()
class MyApp(App):
def build(self):
return LoginScreen()
if __name__=="__main__":
MyApp().run()
There are two reasons why is not working:
The if should be in the method that handles the events, i.e. show_popup
You should compare the text in the Label, not the Label itself. Instead of self.search=='A', you should use self.search.text=='A'
Here is the corrected __init__ and show_popup code:
class Diction(GridLayout):
def __init__(self, **kwargs):
super(Diction, self).__init__(**kwargs)
self.cols=2
self.add_widget(Label(text="Search"))
self.search=TextInput(multiline=False)
self.add_widget(self.search)
self.add_widget(Button(text="click",on_press=self.show_popup))
def show_popup(self, b):
if self.search.text=='A':
print 'True'
else:
print 'False'
p = CustomPopup()
p.open()
An alternative approach using the Kivy Language
The Kivy Language could help you to have a cleaner code. Your code could look like this:
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
# DON'T forget to import Label!!!
from kivy.uix.label import Label
from kivy.uix.popup import Popup
from kivy.lang import Builder
Builder.load_string("""
<CustomPopup#Popup>:
title: "My Custom Poput"
<Diction#GridLayout>:
cols: 2
search: id_search
Label:
text: "Search"
TextInput:
id: id_search
Button:
text: "click"
on_press: root.show_popup(self)
""")
class CustomPopup(Popup):
pass
class Diction(GridLayout):
def show_popup(self, b):
if self.search.text=='A':
print 'True'
else:
print 'False'
# You can send any content to the popup with the content attribute
CustomPopup(content=Label(text=self.search.text)).open()
class MyApp(App):
def build(self):
return Diction()
It helps to keep the logic separated from the interface. You can even keep in separate files if you use the load_file function instead of the load_string.

Categories

Resources