How to immediately update widget in Kivy? - python

I have this sample program written in Python and Kivy:
#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-
import time
from kivy.app import App
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import AsyncImage
from kivy.uix.label import Label
class Application(App):
def build(self):
keyboard = Window.request_keyboard(None, self)
keyboard.bind(on_key_down=self.__on_key_down)
box_layout = BoxLayout(orientation='vertical')
self.__label = Label(text='Ready')
box_layout.add_widget(self.__label)
self.__img = AsyncImage()
box_layout.add_widget(self.__img)
return box_layout
def __on_key_down(self, keyboard, keycode, text, modifiers):
self.__set_status('Loading, please wait...')
print(self.__label.text)
time.sleep(3) # simulates long image download time
self.__img.source = 'http://pl.python.org/forum/Smileys/default/cheesy.gif'
def __set_status(self, text):
self.__label.text = text
# self.__label.canvas.ask_update()
app = Application()
app.run()
Basically what I want to do is label which displays status of application like: Ready, loading, done, etc. but my widget is not updating text when it should.
What can I do to immediately update text in self.__label widget?
I've tried ask_update() method but it seems to not work for this case.

You're blocking Kivy from doing anything when you call time.sleep. Kivy can't update the screen or process input until your function returns control to the main loop.
When you set the source of the AsyncImage, the image will be downloaded in the background without blocking the main loop. This widget is designed to just work automatically. It will display a loading animation until the image is downloaded, so you don't need to show any text.
If you want to show your own loading text, however, you can do so by using Loader directly. It will return a ProxyImage which you can use to determine when the image has loaded:
def __on_key_down(self, keyboard, keycode, text, modifiers):
self.__set_status('Loading, please wait...')
proxy = Loader.image('http://pl.python.org/forum/Smileys/default/cheesy.gif')
proxy.bind(on_load=self.__image_loaded)
def __image_loaded(self, proxy):
if proxy.image.texture:
self.__img.texture = proxy.image.texture
self.__set_status('Done')

Related

how to bind an exe to a gui button - kivy

Allright, I just wrote a programme specific for my data analysis purposes and convert it to exe and when i double click on it, it works fine now except showing the console and all the other things it is doing. Instead double clicking on the exe file, i developped a very simple kivy gui which is as follows;
from cProfile import label
from email.mime import image
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.image import Image
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
class Data_Col(App):
def build(self):
self.window = GridLayout()
self.window.cols = 1
self.window.size_hint = (0.5, 0.5)
self.window.pos_hint = {"center_x": 0.5, "center_y" : 0.5}
# add widgets to window
# image widget
self.window.add_widget(Image(source="logo.png"))
# label widget
self.greeting = Label(text="Bonjour!!!", font_size = 18, bold = True)
self.window.add_widget(self.greeting)
# button widget
self.button = Button(text="Run Data-Col", size_hint = (0.3, 0.3), bold = True, background_color = '0175E8', background_normal = "")
self.window.add_widget(self.button)
return self.window
if __name__ == "__main__":
Data_Col().run()
what i want is when the user clicks on the button, it runs the exe file which is in a different folder in my pc. So i need to give a path too to the button to go and tricks the execution of exe file. But don't know how to do it, if anyone knows i would appreciate it. thanks
I don't know much about Kivy, but I can help you run an .EXE file.
This is the code I wrote:
import os
def run_exe(file): # This is the function to run
os.system("start "+file)
run_exe("path/to/file.exe") # Replace "path/to/file.exe" with the path to your file (E.G. "C:/Users/Hipposgrumm/Documents/helloworld.exe").
Hopefully, that works. I'm more of a TKinter user so tell me if this isn't usable.

How to enable/disable button to prevent repeated playing of audio in Kivy?

I am making an app in Kivy, and I have managed to bind audio to a button. I have had a problem earlier regarding overlapping audio (i.e. when the button is pressed for the second or more times while the audio is still playing), for which I have found a solution.
I've added instance.disabled = True to the code, and as a result there's no more overlapping audio since the button is disabled after pressing once. But, after the audio is finished playing, and if I press the button again to play the audio for the second time, it will not play. Kindly help . Thanks.
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.button import Button
from kivy.core.audio import SoundLoader
class MySound(FloatLayout):
def __init__(self,*kwargs):
super().__init__(*kwargs)
self.btn1 = Button(text = "Press Me",size_hint = (0.3,0.3),
pos_hint={"center_x":0.5,"center_y":0.5})
self.btn1.bind(on_press = self.SoundPlayer)
self.add_widget(self.btn1)
def SoundPlayer(self,instance):
sound = SoundLoader.load("clip.mp3")
sound.play()
instance.disabled = True
class MyApp(App):
def build(self):
return MySound()
MyApp().run()

How to create button with kivy

I'm trying to use kivy for my project but I can't deal with it well..
I made a button, but I want that when I press him it will create another (new) button. Thanks a lot!
from kivy.app import App
from kivy.lang import builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.widget import Widget
from kivy.uix.button import Button
def createButton():
b = Button(pos=(0, 90), size_hint=(.2, .2), on_press=lambda a:ad())
return b
def ad():
"crate new button here!"
class NoobApp(App):
def build(self):
return createButton()
if __name__ == '__main__':
NoobApp().run()
In your ad() method add a line to create a Button and add it to the root of the app:
def ad():
print("crate new button here!")
App.get_running_app().root.add_widget(Button(text='hi'))
Note that this is adding a Button to a Button, (the root of the app is the original Button). Not a recommended approach. You should probably return some kind of Layout from your build() method instead.

Kivy: drag n drop, get file path

In Kivy, I am trying to build an interface where the user can drag and drop a file into a widget (text input) and then my code would retrieve the file system path of that file (/path/to/users.file). That seems like a simpler approach than using the FileChooser widget, but how would I do it?
Thanks!
Use on_dropfile event handler. Here is an working example:
from kivy.app import App
from kivy.core.window import Window
class WindowFileDropExampleApp(App):
def build(self):
Window.bind(on_dropfile=self._on_file_drop)
return
def _on_file_drop(self, window, file_path):
print(file_path)
return
if __name__ == '__main__':
WindowFileDropExampleApp().run()

Issues with changing color of basic Kivy app

I created a simple text-to-speech app with Kivy, using the FloatLayout option but am having trouble changing the color of the GUI without actually creating a .kv file (which I do not wish to do). The code of my app is here:
import kivy
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.image import Image
import requests
from threading import Thread
import os
class ButtonApp(App):
def talk(self):
self.info.text = self.text.text
command = "say %s" % (self.text.text)
os.system(command)
def say(self,instance):
t = Thread(target=self.talk)
t.start()
def build(self):
self.b = FloatLayout()
self.info = Label(text="Hello!", pos=(20,400) ,size_hint=(1,0.5), font_size="40sp")
self.text = TextInput(text='Hello!', pos=(20,200), size_hint=(1,0.5))
self.submit = Button(on_press=self.say,text='Submit',pos=(20,100), size_hint=(1,0.5))
self.b.add_widget(self.info)
self.b.add_widget(self.text)
self.b.add_widget(self.submit)
self.b.bind()
return self.b
if __name__ == "__main__":
ButtonApp().run()
Like I mentioned beforehand, all the suggestions I found doing prior research involved either Canvas (which I am not using), or creating a .kv file. Is there a pure python-kivy method of changing the color of a GUI?
You can do anything in pure python, though the reason you see so many kv examples is because it's easier and more concise due to being a more domain specific language, so I don't recommend avoiding it.
What kind of change do you actually want to make? For instance, you can change the background image of the Button with the background_normal or background_down properties (which take a filepath to an image), or tint its colour by setting its background_color to e.g. (1, 0, 0, 1) for red.

Categories

Resources