FactoryException when trying to create a "IconButton" in Kivy - python

I've tried to create an Icon that can be clicked, which means an Image with a ButtonBehavior.I followed the documentation (http://kivy.org/docs/api-kivy.uix.behaviors.html), and I've got a FactoryException with the following code:
# coding: utf-8
from kivy.uix.behaviors import ButtonBehavior
from kivy.core.image import Image
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.lang import Builder
kv_string = """
BoxLayout:
IconButton
"""
class IconButton(ButtonBehavior, Image):
def on_press(self):
print("on_press")
class DashboardApp(App):
pass
Builder.load_string(kv_string)
if __name__ == "__main__":
DashboardApp().run()
When I change the parent class of IconButton from (ButtonBehavior, Image) to (ButtonBehavior, Widget), the problem disappears.

You want kivy.uix.image, not kivy.core.image.

Related

How to link a string in python code to a label in the kivy file

I'll try to be as curt and straight to the point as possible, as I believe this is probably a simple solution.
How do I get a string that is defined in a python file to show up as a label within a kivy file? Below is a very basic idea on how I tried to achieve this.
kivy-tests.py
import kivy
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.properties import ObjectProperty
from kivy.properties import StringProperty
class Entry(BoxLayout):
x = ObjectProperty('Trees')
class kvfiletests(App):
def build(self):
return Entry()
if __name__ == '__main__':
kvfiletests().run()
kivyfiletests.kv
<Entry>
x: set_name
Label:
id: set_name
text: set_name.text
Any help is greatly appreciated.

How to change screen by swiping in kivy python

I am trying to change to another screen by swiping the screen. I've tried carousel but it seems that it only works with images, so I've tried detecting a swipe motion and changing the screen after it has been detected.
main.py
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen
from kivy.uix.button import ButtonBehavior
from kivy.uix.image import Image
from kivy.uix.label import Label
from kivy.uix.carousel import Carousel
from kivy.uix.widget import Widget
from kivy.uix.popup import Popup
class HomeScreen(Screen):
def on_touch_move(self, touch):
if touch.x < touch.ox: # this line checks if a left swipe has been detected
MainApp().change_screen(screen_name="swipedhikr_screen") # calls the method in the main app that changes the screen
class ImageButton(ButtonBehavior, Image):
pass
class LabelButton(ButtonBehavior, Label):
pass
class SettingsScreen(Screen):
pass
class SwipeDhikrScreen(Screen):
pass
#def quit_verification():
# pop = Popup(title="verification", content=Label(text= "Are you sure?"))
GUI = Builder.load_file("main.kv")
class MainApp(App):
def build(self):
return GUI
def change_screen(self, screen_name):
# get the screen manager from the kv file
screen_manager = self.root.ids["screen_manager"]
screen_manager.transition.direction = "up"
screen_manager.current = screen_name
def quit_app(self):
MainApp().stop()
MainApp().run()
I got an attribute error: "None type object has no attribute 'ids'"
MainApp().change_screen(screen_name="swipedhikr_screen")
This line creates a new instance of MainApp, which doesn't have any widgets and therefore naturally fails when you try to access them.
Use the existing instance of MainApp, i.e. the one that you're actually running, via MainApp.get_running_app().
Also you are not correct that Carousel works only with images.

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 how to use online images in python

I'm trying to make a button which uses an image from URL.
icon= str('https://cdn2.iconfinder.com/data/icons/flat-ui-icons-24-px/24/eye-24-256.png')
self.add_widget(ImageButton(source=(icon), size=(100,100), size_hint=(0.1, 0.1), on_press=callback, pos_hint={"x":0.90, "top":1.0}))
class ImageButton(ButtonBehavior, Image):
pass
It shows as an white image for some reason. Could anyone help me please?
As eyllanesc comments, you must use AsyncImage subclass to load the image asynchronously from the server. Otherwise, the image will not be available when you instantiate the widget.
On the other hand, the code you show in your comment;
icon = AsyncImage(source='https://.../icon.png')
self.add_widget(ImageButton(source=(str(icon)))
is also incorrect, You are trying to pass to source (StringPropery) an instance of AsyncImage. The simple solution to that is to inherit from AsyncImage and not from Image:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import AsyncImage
from kivy.uix.behaviors import ButtonBehavior
from kivy.core.window import Window
Window.clearcolor = (1, 1, 1, 1)
class ImageButton(ButtonBehavior, AsyncImage):
pass
class MainWindow(BoxLayout):
def __init__(self, **kwargs):
super(MainWindow, self).__init__(**kwargs)
icon = 'https://cdn2.iconfinder.com/data/icons/flat-ui-icons-24-px/24/eye-24-256.png'
self.add_widget(ImageButton(source=icon))
class Test(App):
def build(self):
return MainWindow()
if __name__ == "__main__":
Test().run()

Kivy Event on carousel when slide change

I don't have any idea to find a solution of my problem.
I have make an application with Carousel Widget. In this Carousel I have 4 slides.
welcomeSlide -> DVDSlide -> DVDPretSlide --> CategorySlide
I have make a class for each slides.
I use a ListAdpter to display the data extracted from an Sqlite3 Database.
My pblem is about the refresh of the list, when I modify a DVD (add name to pret) in the DVDSlide, when I slide to the DVDPret, the DVD do not appears because the List is not refresh.
Like the doccumentation for the carousel I don't find the event when slide change. It will be the best if an event exist to get the current slide index.
Have you got any Idea ?
Thanks,
You can observe index property:
from kivy.uix.carousel import Carousel
from kivy.uix.boxlayout import BoxLayout
from kivy.app import App
from kivy.lang import Builder
Builder.load_string('''
<Page>:
Label:
text: str(id(root))
<Carousel>
on_index: print("slide #{}".format(args[1]))
''')
class Page(BoxLayout):
pass
class TestApp(App):
def build(self):
root = Carousel()
for x in range(10):
root.add_widget(Page())
return root
if __name__ == '__main__':
TestApp().run()
Or you can observe current_slide property:
from kivy.uix.carousel import Carousel
from kivy.uix.boxlayout import BoxLayout
from kivy.app import App
from kivy.lang import Builder
Builder.load_string('''
<Page>:
label_id: label_id
Label:
id: label_id
text: str(id(root))
<Carousel>
on_current_slide: print(args[1].label_id.text)
''')
class Page(BoxLayout):
pass
class TestApp(App):
def build(self):
root = Carousel()
for x in range(10):
root.add_widget(Page())
return root
if __name__ == '__main__':
TestApp().run()
If you want a pure python solution rather than a Kivy Language solution you can create your own carousel that inherits from the Kivy carousel as follows.
import kivy
from kivy.uix.carousel import Carousel
class MyCarousel(Carousel):
# This class is a carousel that runs script
# when a slide gets focus (except first load).
def on_index(self, *args):
print('the slide is', self.index)
# YOUR CODE GOES HERE
Carousel.on_index(self, *args)

Categories

Resources