Breaking Main loop in kivy (Freezing Screen) - android

I got and issue that when i bind a function with an button that works good but when i bind a function which has a infinite loop in it so screen freezes and other button do not works as example below....please give me solution to break that loop using another button..
from kivy.uix.popup import Popup
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.uix.boxlayout import BoxLayout
from kivy.uix.stacklayout import StackLayout
class APPLICATION_START(FloatLayout):
def __init__(self, **kwargs):
super(MyApp, self).__init__(**kwargs)
self.buone = Button(text="Start Loop",pos=(0,180),size=(470,90),size_hint=(None,None))
self.logi.bind(on_release=self.loooop)
self.exitbtn = Button(text="exit",pos=(0,90),size=(235,70),size_hint=(None,None))
self.exitbtn.bind(on_press=exit)
def loooop(self,instance):
while True:
# do any Activity
#I want to break this loop when someone press on exit button
class MyApp(App):
def build(self):
return APPLICATION_START()
if __name__ == '__main__':
MyApp().run()

The gui can't update until your function returns, which it doesn't.
Either use a thread for your task, or if it is composed of many repetitions of a short task you can do Clock.schedule_interval(your_function, some_timestep) to run it repeatedly.

Related

Kivy ScrollView Doesn't work with on_touch_down method

I am trying to use ScrollView in Widget class but it doesn't work when i put a on_touch_down method. What's a problem? How to solve this?
Here is a code:
from kivy.app import App
from kivy.core.window import Window
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.widget import Widget
Window.size = (520, 960)
class GameManager(Widget):
def __init__(self, **kwargs):
super(GameManager, self).__init__(**kwargs)
layout = GridLayout(cols=1, spacing=10, size_hint_y=None)
layout.bind(minimum_height=layout.setter('height'))
for i in range(100):
btn = Button(text=str(i), size_hint_y=None, height=40)
layout.add_widget(btn)
root = ScrollView(size_hint=(1, None), size=(Window.width/2, Window.height*3/4))
root.add_widget(layout)
self.add_widget(root)
#When I delete this method everything is fine
def on_touch_down(self, touch):
if self.collide_point(*touch.pos):
pass
class ScrollViewApp(App):
game = GameManager()
touch_down event propagate down the widget tree, first being passed to the root widget and then having each widget pass the touch to its children. The problem is that, you overwrote on_touch_down method and the event isn't propagate, consecuencely your ScrollView not respont to this event.
You should only call the on_touch_downd method of the parent to allow event propagation:
def on_touch_down(self, touch):
if self.collide_point(*touch.pos):
pass
super(GameManager, self).on_touch_down(touch)

I turn the application on android and this application crashes. Why?(Kivy)

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

Kivy App Error- Invalid instance in App.root

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.

usage of speech to text in kivy

How to use pyttsx module in kivy app?
import kivy
import sys
kivy.require('1.9.0')
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
class My(App):
def build(self):
return Myapp()
class Myapp(FloatLayout):
def callback(self,instance):
import pyttsx
self.engine=pyttsx.init()
if self.t1.text:
self.engine.say("you wrote something")
self.engine.runAndWait()
def __init__(self, **kwargs):
super(Myapp, self).__init__(**kwargs)
self.t1=TextInput(multiline=True,size_hint_x=0.5, size_hint_y=0.5)
btn1=Button(text='read',size_hint=(.1,.1),pos_hint= {'x': .5,'top': .2})
self.add_widget(self.t1)
self.add_widget(btn1)
self.bind(on_press=self.callback)
if __name__=='__main__':
My().run()
On clicking the button the callback function is called and it has to speak the text entered in text field.But it doesn't work.Is there any other way to do it?
Use the text to speech functions in plyer. These will call the Android api for the task.

Set a numeric keyboard to my kivy app python

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)

Categories

Resources