Like, can an output-only TextEntry(readonly=True) be changed with TextEntry.insert_text()? Does the readonly refers ONLY to the user part of the GUI?
I assume you actually mean TextInput. If so, the answer is: no, you cannot change the text in code using insert_text, but you can change it using a simple text=.
John Anderson has already given an answer.
You can download the Kivy Launcher or QPython from google playstore so that you can test your kivy codes without using a desktop.
Here is a simple code with TextInput using QPython2:
#-*-coding:utf8;-*-
#qpy:2
#qpy:kivy
#qpy:fullscreen
from kivy.app import App
from kivy.uix.textinput import TextInput
from kivy.uix.widget import Widget
from kivy.core.window import Window
from kivy.uix.button import Button
class TestingText(Widget):
def __init__(self):
super(TestingText, self).__init__()
self.size = Window.size
self.t = TextInput(readonly=True)
self.b1 = Button(text="Insert")
self.b2 = Button(text="Set")
self.t.center = self.center
self.b2.right = self.right
self.b1.on_press = self.inserttext
self.b2.on_press = self.settext
self.add_widget(self.t)
self.add_widget(self.b1)
self.add_widget(self.b2)
def inserttext(self):
self.t.insert_text("insertme")
def settext(self):
self.t.text = "setme"
class Test(App):
def build(self):
return TestingText()
Test().run()
Related
I'm using kivymd version 1.1.0dev0, and I just want the stack button to be able to call a distinct function for each of them, I've tried the correct way that supposed to work but not for me. I tried on version 1.0.2 and it worked, but unfortunately style theme M3 is unusable.
from kivy.lang import Builder
from kivymd.app import MDApp
screen = '''
Screen:
MDFloatingActionButtonSpeedDial:
data:app.data
callback: app.callback
'''
class testApp(MDApp):
data = {
'register': 'key',
}
def callback(self, instance):
if instance.icon == 'key':
print('Callback self.key()')
def build(self):
return Builder.load_string(screen)
testApp().run()
Did I write correctly? After the application is turned on, the android device must vibrate, but after the application turns on, it crashes. Why my apps on kivy crashed? Code:
from plyer import vibrator
from kivy.app import App
from kivy.properties import StringProperty
from kivy.clock import Clock, mainthread
from kivy.uix.floatlayout import FloatLayout #the UI layout
from kivy.uix.label import Label #a label to show information
class UI(FloatLayout):
"""docstring for UI"""
def __init__(self):
super(UI, self).__init__()
self.lblAcce = Label(text="Vibrate: ") #create a label at the center
self.add_widget(self.lblAcce) #add the label at the screen
time = 2
try:
vibrator.vibrate(time=time)
#if you want do disable it, just run: accelerometer.disable()
Clock.schedule_interval(self.update, 1.0/24) #24 calls per second
except:
self.lblAcce.text = "Failed to start vibrate" #error
class Vibrate(App): #our app
def build(self):
ui = UI()# create the UI
return ui #show it
if __name__ == '__main__':
Vibrate().run() #start our app
I am working on building a kivy app. The below code is a simple Hello World of sorts. Press a button. The label changes from 'Hello' to 'World'
import kivy
kivy.require('1.9.1') # replace with your current kivy version !
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.label import Label
#from tasks import assign_task
class GetTask():
def __init__(self, **kwargs):
super(GetTask,self).__init__(**kwargs)
self.main_label = Label(text = "Hello")
button = Button(text="Press")
button.bind(on_press= self.update)
def update(self):
self.main_label.text = "World"
class MyApp(App):
def build(self):
return GetTask()
if __name__ == '__main__':
MyApp().run()
The error I get when I run it is:
raise Exception('Invalid instance in App.root')
Exception: Invalid instance in App.root
I looked at this- Kivy: Invalid instance in App.root
I still cannot figure what I am doing wrong. Please help. Thank you.
What does your GetTask inherit from? It seems to me that it doesn't inherit from anything at all. Try changing it to
class GetTask(Widget):
# The rest is like it's in your code.
Also have a look at my comment under the question. Not sure if it's still the issue in 1.9.1, though.
I have a kivy app with some textinput and I want to show in my smartphone a numeric keyboard. I've been reading about it and I think that with the property input_type=number I could get the right result but I realised that with the kivy updates doesn't work nowadays. How could I get the numeric keyboard when my textinput is focused? With the app in landscape mode it could be useful or the keyboard still will take half screen? Here do you have the code:
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.screenmanager import ScreenManager, Screen
from kivy.core.window import Window
class LoginScreen(GridLayout):
def __init__(self,**kwargs):
super(LoginScreen, self).__init__(**kwargs)
self.cols=2
self.add_widget(Label(text='Subject'))
self.add_widget(Label(text=''))
self.add_widget(Label(text='1'))
self.add_widget(TextInput(multiline=False))
self.add_widget(Label(text='2'))
self.add_widget(TextInput(multiline=False))
self.add_widget(Label(text='3'))
self.add_widget(TextInput(multiline=False))
self.add_widget(Label(text='4'))
self.add_widget(TextInput(multiline=False))
b1=Button(text='Exit',background_color=[0,1,0,1],height=int(Window.height)/9.0) #doesn't work properly
self.add_widget(b1)
b2=Button(text='Run',background_color=[0,1,0,1],height=int(Window.height)/9.0) #doesn't work properly
self.add_widget(b2)
b1.bind(on_press=exit)
class SimpleKivy(App):
def build(self):
return LoginScreen()
if __name__=='__main__':
SimpleKivy().run()
I think is a bit late, bu maybe someone looks for it tomorrow.
Is true you should change the input_type propery of your TextInput, in your case for example:
self.add_widget(TextInput(multiline=False, input_type = 'number'))
I suggest you create a new custom widget for that in order works in android and desktop, like this that implement a maxdigits property:
class IntegerInput(TextInput):
def __init__(self, **kwargs):
super(IntegerInput, self).__init__(**kwargs)
self.input_type = 'number'
def insert_text(self, substring, from_undo=False):
if substring.isnumeric():
if hasattr(self, "maxdigits"):
if len(self.text) < self.maxdigits:
return super(IntegerInput,self).insert_text(substring, from_undo=from_undo)
else:
return super(IntegerInput, self).insert_text(substring, from_undo=from_undo)
Background: I have been learning Python - and through it - Kivy, by making an app. I have been using the .kv file and Builder.load_string methods to create my graphics, but have decided to try using solely python, and moving all of my layouts over into python.
The Problem: When I began using screens, I was unable to bind the correct code to the buttons to make the screens transition. When I am writing the line, 'self.manager.etc...' auto-complete shows me a list of valid properties to use.
So after 'self.' it shows that I can use 'manager', and after 'manager.' it does not think that the screen's manager has a 'current' or 'transition' property. I must have messed up in how I connected the screen to the manager, but I cannot fathom how.
class HomePage(Screen):
def __init__(self, **kwargs):
super(HomePage, self).__init__(**kwargs)
layout = FloatLayout()
notification = Label(text='upcoming: ....', font_size='16sp', size_hint=(0,0), pos_hint={'center_x':.5, 'top':0.9})
layout.add_widget(notification)
button_row=BoxLayout(size_hint_y=.1, spacing=20)
profile_button=Label(text='Profile')
button_row.add_widget(profile_button)
layout.add_widget(button_row)
self.add_widget(layout)
def transit():
self.manager.current = profile_button # <- this should work, right?
profile_button.bind(on_press=transit)
class ScreenApp(App):
def build(self):
sm = ScreenManager()
sm.add_widget(HomePage(name='home'))
return sm
if __name__ == "__main__":
ScreenApp().run()
You should add in your imports the transition
from kivy.uix.screenmanager import Screen, ScreenManager, FadeTransition
And pass it in the builder
class ScreenApp(App):
def build(self):
sm = ScreenManager(transition=FadeTransition())
as for the current you should add a second screen, give it a name and and use that name to change to that screen.from the https://github.com/kivy/kivy/blob/master/kivy/uix/screenmanager.py
by default, the first added screen will be shown. If you want to
show another one, just set the 'current' property. sm.current = 'second'
Also current is a string property, you can not set it to a label
:attr:current is a :class:~kivy.properties.StringProperty and
defaults to None.
So your full code should be something like
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.label import Label
from kivy.uix.screenmanager import Screen, ScreenManager, FadeTransition
class HomePage(Screen):
def __init__(self, **kwargs):
super(HomePage, self).__init__(**kwargs)
layout = FloatLayout()
notification = Label(text='upcoming: ....', font_size='16sp', size_hint=(0,0), pos_hint={'center_x':.5, 'top':0.9})
layout.add_widget(notification)
button_row=BoxLayout(size_hint_y=.1, spacing=20)
profile_button=Button(text='Profile') # changed to a button
button_row.add_widget(profile_button)
profile_button.bind(on_press=self.transit) # moved here the bind action
layout.add_widget(button_row)
self.add_widget(layout)
def transit(self, *args):
# unintended to become a class method and reference to it with self
print "ok"
self.manager.current = "screen2"
class ProfilePage(Screen):
def __init__(self, **kwargs):
super(ProfilePage, self).__init__(**kwargs)
layout = FloatLayout()
labelP = Label(text="Profile Page")
layout.add_widget(labelP)
self.add_widget(layout)
class ScreenApp(App):
def build(self):
sm = ScreenManager(transition=FadeTransition())
# create the first screen
screen1 = HomePage(name='Home') #your home page
screen2 = ProfilePage(name='screen2') # the second screen
sm.add_widget(screen1)
sm.add_widget(screen2)
return sm
if __name__ == "__main__":
ScreenApp().run()