Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing background of a Button to a different shape and Styles like shadow effect etc in kivy python

I learnt that in Qt we do have some ways to make a QpushButton with :

  1. Shadow effect
  2. making it Flat by making setFlat properties to True .
  3. chaning the cursor of a different type if someone hovers over it like pushButton_18.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))

I am looking to make Buttons behavior similar in kivy as well . Is it possible ? I learnt that we can change background Image changed to a Image with rounded shape Changing the background color of a Button in Kivy

but this is not that satisfying as the button still looks very normal . There s no shadow affect . Even when we click on the corners outside the button it is treated s if button is clicked .

I have gone through documentation of Kivy Button as well as Label and tried to change the behavior and look of a button . Can someone advice on how to make a button look better We can try to have :

  1. Shadowing affect
  2. Animation affect in background
  3. Rounded edges etc .
  4. Can we put animated gif Images as background for animation (I did try that but it wasnt animated anymore )

Below is a code which i just created for exploring more into buttons in Kivy :

__author__ = 'pbatra'
#Good info about background
#https://stackoverflow.com/questions/20181250/changing-the-background-color-of-a-button-    in-kivy/20181407#20181407

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty
from kivy.uix.image import Image
from kivy.graphics import Color


gui = '''
<MenuScreen>:
    canvas.before:
        BorderImage:
            # BorderImage behaves like the CSS BorderImage
            border: 10, 10, 10, 10
            texture: self.background_image.texture
            pos: self.pos
            size: self.size
    GridLayout:
        size_hint: .1, .1
        pos_hint: {'center_x': .5, 'center_y': .5}
        rows: 1
        Button:
            text: 'Play'
            font_size: 20
            font_name: 'DroidSans'
            bold: True
            italic: True
            height: 10
            background_color: (0.5, 0.7, 0.5, 0.9)
            #Read more about them from documentation
            background_normal: './images/orange.png'
            background_down: './images/green.png'
            border: 30,30,30,30
            color: (1, .3, .8, .5)

        on_press: self.text = 'Oh yeah'

'''


class MenuScreen(Screen):
    background_image = ObjectProperty(
                                Image(
                                    source='../Examples/examples/widgets/sequenced_images/data/images/button_white_animated.zip',
                                    anim_delay=.5))
    Builder.load_string(gui)
    pass

# Create the screen manager
sm = ScreenManager()
sm.add_widget(MenuScreen(name='menu'))


class MyJB(App):
    def build(self):
        return sm

if __name__ == '__main__':
    MyJB().run() 
like image 878
paarth batra Avatar asked Apr 03 '14 03:04

paarth batra


People also ask

Why does background_normal = '' not work with Kivy buttons?

The problem with using background_normal = '' is that it blows away the kivy button image with raised edges/shadowing and setback. One way to get a raised button of a specific color would be to make your own atlas using gimp or other editors.

How to change the background color of the button using CSS?

To change the background color of the button, use the CSS background-color property and give it a value of a color of your taste. In the .button selector, you use background-color:#0a0a23; to change the background color of the button.

What is the default RGB value for Kivy button color?

In other words, it can have 'RGB' values > 1. So to get an exact button color with the kivy button defaulttheme for raised edges, use:

How do I add shadow or transparency to a button?

Use the box-shadow property to add shadows to a button: Use the opacity property to add transparency to a button (creates a "disabled" look). Tip: You can also add the cursor property with a value of "not-allowed", which will display a "no parking sign" when you mouse over the button:


2 Answers

Button in kivy starts with a ButtonBehavior which is combined with a Label adding properties like background_normal/down...for handling textures on the canvas.

Knowing this you can simply combine ButtonBehavior with any other widget you choose. Eg.

from kivy.base import runTouchApp
from kivy.lang import Builder

kv = '''
<ButImage@ButtonBehavior+AsyncImage>

FloatLayout:
    # we don't specify anything here so float layout takes the entire size of the window.
    ButImage:
        id: but
        # take 50% size of the FloatLayout
        size_hint: .5, .5
        # Make Button change it's opacity when pressed for visual indication
        opacity: 1 if self.state == 'normal' else .5
        source: 'http://www.victoriamorrow.com/sitebuildercontent/sitebuilderpictures/enter_button.gif'
        # Introduce Label incase you want text on top of the image
        Label:
            center: but.center
            # change text acc to but state
            text: "Normal" if but.state == 'normal' else 'down'
'''

if __name__ == '__main__':
    runTouchApp(Builder.load_string(kv))

Here we just set the ButtonBehavior to be combined with a AsyncImage which downloads the image from web for your background.

you should see something like thisscreenshot asyncimage button

Animation affect in background

This would be as simple as changing the source to animated gif or list of images inside a .zip.

from kivy.base import runTouchApp
from kivy.lang import Builder


kv = '''
<ButImage@ButtonBehavior+AsyncImage>

FloatLayout:
    ButImage:
        id: but
        size_hint: .5, .5
        opacity: 1 if self.state == 'normal' else .5
        allow_stretch: True
        keep_ratio: False
        source: 'http://media1.policymic.com/site/article-items/2095/1_gif.gif'
        Label:
            center: but.center
            text: "Normal" if but.state == 'normal' else 'down'


'''

if __name__ == '__main__':
    runTouchApp(Builder.load_string(kv))

Look at the sequence images example This was done before ButtonBehaviors were introduced so it even has a example of a AnimatedButton class using the older method which is essentially not needed any more.

Shadow Effect:

There are many ways to do this too.

You could either add a shadow to a widget/layout and have the button on top of this widget/layout take up less space than the shadow so as to account for touch on the shadows.

Or Create your own CustomButtonBehavior class derived from ButtonBehavior that overrides collidepoint method to only return True for custom collision. There is a example of using custom collision for widgets. You could even set the Image's keep_data property to True and later check pixel data for alpha to determine if you want to return true for collision.

Rounded edges etc.

Simply use a image with rounded edges kivy supports use of BorderImage Instruction which is equivalent to css borderimage in terms of functionality. Kivy's own button by default uses this. Try and experiment with border attribute of BorderImage.

like image 149
qua-non Avatar answered Sep 24 '22 18:09

qua-non


from kivy.app import App from  
kivy.uix.floatlayout import FloatLayout
from kivy.uix.button import Button


class lay(FloatLayout):
    def __init__(self, **kwargs):
       super(lay,self).__init__(**kwargs)
       self.btn = Button(background_normal='image_state_on.png',
       background_down='image_state_off', size_hint_x = .50, size_hint_y = .50)
       self.add_widget(self.btn)

class ImageButton_APP(App):
    def build(self):
           return lay()


ImageButton_APP().run()

I think this is more effective. I am using two kind of image.

like image 45
Amiran Kalandia Avatar answered Sep 23 '22 18:09

Amiran Kalandia