Stretchable Image Button Keeping Aspect Ratio

398 views
Skip to first unread message

Shoumik Das

unread,
Apr 28, 2020, 8:47:26 AM4/28/20
to Kivy users support
Hi! I am trying to build a simple login screen with two buttons. One is an image button and the other is a plain text button. When I specify the background_normal and background_down attributes, the image button works but the image appears stretched, probably because the size_hint values are not equal for the parent box layout in which they are placed.

I Googled up some tips and came across a suggestion to create a new class with the Image and ButtonBehavior classes. However, now, the image does not even show up. All I get is a blank white box in place of the image button.

Python Code:

from kivy.config import Config
# Config.set should be used before importing any other Kivy module.
Config.set('kivy','window_icon','sivaicon.png')
# Config set for resizing image button
Config.set('graphics', 'resizable', True)
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.button import Button
from kivy.uix.behaviors import ButtonBehavior
from kivy.uix.image import Image
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.lang.builder import Builder


class SivaLoginScreen(Screen):
    pass


class SivaTabbedScreen(Screen):
    pass


class SivaScreenManager(ScreenManager):
    pass


class ImageButton(ButtonBehavior, Image):
    pass


# Tell Kivy to directly load a file. If this file defines a root widget, it will be returned by the method.
root_widget = Builder.load_file('siva.kv')

class SivaApp(App):
    def build(self):
        # Initialize root widget
        return root_widget


if __name__ == '__main__':
    # Run application
    SivaApp().run()

Kivy File:

SivaScreenManager:
    SivaLoginScreen:


<SivaLoginScreen>:
    name: 'login_screen'
    canvas.before:
        Color:
            rgba: 195/255, 60/255, 35/255, 1
        Rectangle:
            pos: self.pos
            size: self.size
    FloatLayout:
        size: root.width, root.height
        Label:
            id: login_label_siva
            pos: self.x*0.5-4, self.y*0.5+15
            markup: True
            font_name: 'roboto/Roboto-Medium.ttf'
            text: '[color=#FDFD98]S.[/color][color=#B29DD9]I[/color][color=#FDFD98].[/color][color=#77DD77]V[/color][color=#FDFD98].[/color][color=#779ECB]A[/color]'
            font_size: '50sp'
        Label:
            id: login_label_slogan1
            pos: self.x*0.5-3, self.y*0.5-6
            markup: True
            font_name: 'roboto/Roboto-Regular.ttf'
            text: '[color=#FDFD98]SLOGAN TEXT[/color]'
            font_size: '15sp'
        Label:
            id: login_label_slogan2
            pos: self.x*0.5-3, self.y*0.5-20
            markup: True
            font_name: 'roboto/Roboto-Regular.ttf'
            text: '[color=#FDFD98]HEADLINE TEXT[/color]'
            font_size: '15sp'
        BoxLayout:
            id:login_button_layout
            orientation: 'horizontal'
            size_hint: 0.30, 0.20
            pos_hint: {'center_x':0.5, 'center_y':0.25}
            ImageButton:
                id: login_button1
                size: 100, 100
                keep_ratio: True
                allow_stretch: False
                background_normal: 'images/button-release.png'
                background_down: 'images/button-press.png'
            Button:
                id: login_button2
                text: 'Login'

Can you please guide me where I might be going wrong? I want to create a image button which maintains its aspect ratio, even when the screen is resized.

Thanks in advance.

Elliot Garbus

unread,
Apr 28, 2020, 12:20:05 PM4/28/20
to kivy-...@googlegroups.com

Here are the issues.

Image gets it’s image from source.

ButtonBehavior does not include image attributes.  It does provide button state.

You can use state to dynamically select the image based on the state.  This works for both ButtonBehavior and ToggleButtonBehavior.

 

I typically would do something like:

ImageButton:
    source: {'normal':
'images/button-release.png', 'down': 'images/button-press.png'} [self.state]
    keep_ratio: True
  

This line make look a little strange at first.

{'normal':'icons8-play-96.png', 'down': 'icons8-pause-96.png'} [self.state]
This is a dictionary.  The state of the button, self.state, will be either 'normal’ or ‘down’.

 

The dictionary will provide one filename for ‘normal’, and another for ‘down’, providing a compact way of dynamically choosing the ‘normal’ and ‘down’ images based on state.

--
You received this message because you are subscribed to the Google Groups "Kivy users support" group.
To unsubscribe from this group and stop receiving emails from it, send an email to kivy-users+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/1e4ea3c1-b3d9-43b9-bd23-cf091b3c9e6a%40googlegroups.com.

 

Shoumik Das

unread,
Apr 28, 2020, 2:13:06 PM4/28/20
to Kivy users support
Thanks for the suggestion, Elliott. I am wondering if it is mandatory for every class defined in Python to have a corresponding rule in Kivy.

For example, is it necessary for the ImageButton class, in this case, to be defined as a rule in the kv file?

Please excuse my ignorance. I am very new to Kivy and still learning.

Thanks in advance.

Elliot Garbus

unread,
Apr 28, 2020, 3:30:15 PM4/28/20
to kivy-...@googlegroups.com

You can define the classes directly in kivy as ‘dynamic classes’ see: https://kivy.org/doc/stable/api-kivy.lang.html?highlight=lang#dynamic-classes

 

You do not need to kivy rule for things defined in Python.  They can make it easier, Ideally you define the layout in kv, and the logic and data in python.

 

From: Shoumik Das
Sent: Tuesday, April 28, 2020 11:13 AM
To: Kivy users support

--

You received this message because you are subscribed to the Google Groups "Kivy users support" group.

To unsubscribe from this group and stop receiving emails from it, send an email to kivy-users+...@googlegroups.com.

Shoumik Das

unread,
Apr 29, 2020, 5:30:49 AM4/29/20
to Kivy users support
Thank you very much for the suggestions.


On Wednesday, April 29, 2020 at 1:00:15 AM UTC+5:30, Elliot Garbus wrote:

You can define the classes directly in kivy as ‘dynamic classes’ see: https://kivy.org/doc/stable/api-kivy.lang.html?highlight=lang#dynamic-classes

 

You do not need to kivy rule for things defined in Python.  They can make it easier, Ideally you define the layout in kv, and the logic and data in python.

 

From: Shoumik Das
Sent: Tuesday, April 28, 2020 11:13 AM
To: Kivy users support
Subject: RE: [kivy-users] Stretchable Image Button Keeping Aspect Ratio

 

Thanks for the suggestion, Elliott. I am wondering if it is mandatory for every class defined in Python to have a corresponding rule in Kivy.

 

For example, is it necessary for the ImageButton class, in this case, to be defined as a rule in the kv file?

 

Please excuse my ignorance. I am very new to Kivy and still learning.

 

Thanks in advance.

 

--

You received this message because you are subscribed to the Google Groups "Kivy users support" group.

To unsubscribe from this group and stop receiving emails from it, send an email to kivy-...@googlegroups.com.

Reply all
Reply to author
Forward
0 new messages