Combining image and text within a button in kivy

后端 未结 3 1840
庸人自扰
庸人自扰 2021-02-04 10:05

What\'s the preferred way to combine an image/icon and text within a button? For example, how would you create a button with text = \'my button\', and a graphical i

相关标签:
3条回答
  • 2021-02-04 10:10

    Define a new Button class or modify the one in Kivy.uix.button

    class MyButton(Button):
        #add these three properties in the class
        icon = ObjectProperty(None)
        icon_size = (0,0)
        icon_padding = NumericProperty(0)    #Enter any default value like 50 if you will
                                             #always use an icon, or specify this field
                                             #while creating the button
        def __init__(self, **kwargs):
            #no changes here, just for reference
            return super(MyButton, self).__init__(**kwargs)
    

    KV file:

    <MyButton>:
    state_image: self.background_normal if self.state == 'normal' else self.background_down
    disabled_image: self.background_disabled_normal if self.state == 'normal' else self.background_disabled_down
    canvas:
        Color:
            rgba: self.background_color
        BorderImage:
            border: self.border
            pos: self.pos
            size: self.size
            source: self.disabled_image if self.disabled else self.state_image
    
        Color:
            rgba: (1, 1, 1, 1) if root.icon != None else (1,1,1,0)
    
        Rectangle:
            source: root.icon
            size: (self.texture_size[1],self.texture_size[1]) if self.icon_size == (0,0) else self.icon_size
            pos: int(self.center_x - self.texture_size[0] / 2.)-dp(root.icon_padding), int(self.center_y - self.texture_size[1] / 2.)
    
        Color:
            rgba: 1, 1, 1, 1
    
        Rectangle:
            texture: self.texture
            size: self.texture_size
            pos: int(self.center_x - self.texture_size[0] / 2.)+dp(root.icon_padding), int(self.center_y - self.texture_size[1] / 2.)
    

    Now just create a button widget

    MyButton(text = 'Hello',icon = 'icon.png', icon_padding = 50)
    
    0 讨论(0)
  • 2021-02-04 10:29

    Meanwhile, there is another way. You can use icon fonts such as Font Awesome and combine them with text.

    Either import the font directly and wrap the text in their font tag, or simply use some of the libraries that take care of that.

    #: import icon ...
    Button:
        markup: True
        text: "%s Comment" % icon('comment', 32)
        size_hint_x: None
        width: 100
    

    Kivy-iconfonts converts css/tff combinations that are distributed for web sites into a json format that it loads during runtime using the import statement as shown in the example above. I extended this in my fork to fetch Font Awesome icons during runtime and put them into the working directory of your application. That gives you the advantage of not having to distribute the fonts with the application.

    0 讨论(0)
  • 2021-02-04 10:33

    Regarding to question #2.

    The way Kivy works is embedding Widget instances. Since Image and Button are subclasses of Widget, then all you have to do is embed an Image inside a the Button. Notice that the positioning inside a widget is fixed. You have to give explicit coordinates.

    That said, you can always embed a Layout to organize the stuff you are putting inside the Button.

    Here is the simple ex

    from kivy.app import App
    from kivy.uix.boxlayout import BoxLayout
    from kivy.lang import Builder
    
    Builder.load_string("""
    <ButtonsApp>:
        orientation: "vertical"
        Button:
            text: "B1"
            Image:
                source: 'kivy.png'
                y: self.parent.y + self.parent.height - 200
                x: self.parent.x
        Label:
            text: "A label"
    """)
    
    class ButtonsApp(App, BoxLayout):
        def build(self):
            return self
    
    if __name__ == "__main__":
        ButtonsApp().run()
    

    EDIT: An example of how a relative layout can be embedded inside a button

    In this case I am using a StackLayout to organize an Image and a Label inside. As I said, Button is a Widget and Kivy works embedding widgets inside widgets. It doesn't matter if they are labels, buttons or layouts.

    from kivy.app import App
    from kivy.uix.boxlayout import BoxLayout
    from kivy.lang import Builder
    
    Builder.load_string("""
    <ButtonsApp>:
        orientation: "vertical"
        Button:
            StackLayout:
                pos: self.parent.pos
                size: self.parent.size
                orientation: 'lr-tb'
                Image:
                    source: 'kivy.png'
                    size_hint_x: None
                    width: 74
                Label:
                    size_hint_x: None
                    width: 100
                    text: "The text"
        Label:
            text: "A label"
    """)
    
    class ButtonsApp(App, BoxLayout):
        def build(self):
            return self
    
    if __name__ == "__main__":
        ButtonsApp().run()
    
    0 讨论(0)
提交回复
热议问题