在 kivy python 中将按钮的背景更改为不同的形状和样式,如阴影效果等

Posted

技术标签:

【中文标题】在 kivy python 中将按钮的背景更改为不同的形状和样式,如阴影效果等【英文标题】:Changing background of a Button to a different shape and Styles like shadow effect etc in kivy python 【发布时间】:2014-05-14 16:08:45 【问题描述】:

我了解到,在 Qt 中,我们确实有一些方法可以制作 QpushButton:

    阴影效果 通过将 setFlat 属性设置为 True 使其扁平化。 如果有人像 pushButton_18.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) 一样将光标悬停在不同类型的光标上

我希望在 kivy 中也使按钮行为类似。可能吗 ? 我了解到我们可以将背景图像更改为圆形图像 Changing the background color of a Button in Kivy

但这并不令人满意,因为按钮看起来仍然很正常。没有阴影影响。即使我们单击按钮外的角,它也会被视为单击按钮。

我浏览了 Kivy Button 和 Label 的文档,并尝试更改按钮的行为和外观。有人可以建议如何使按钮看起来更好吗?我们可以尝试:

    阴影效果 背景中的动画效果 圆角等。 我们可以将动画 gif 图像作为动画背景吗(我确实尝试过,但它不再是动画了)

下面是我刚刚创建的代码,用于探索更多 Kivy 中的按钮:

__author__ = 'pbatra'
#Good info about background
#https://***.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() 

【问题讨论】:

【参考方案1】:

kivy 中的按钮以 ButtonBehavior 开头,它与 Label 结合添加诸如 background_normal/down 之类的属性...用于处理画布上的纹理。

了解这一点后,您可以简单地将 ButtonBehavior 与您选择的任何其他小部件结合使用。例如。

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))

这里我们只是将 ButtonBehavior 设置为与 AsyncImage 结合,后者会从网络下载图像作为您的背景。

你应该会看到类似这样的

背景中的动画效果

这就像将源更改为动画 gif 或 .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))

看看sequence images example 这是在引入 ButtonBehaviors 之前完成的,所以它甚至有一个使用旧方法的 AnimatedButton 类示例,基本上不再需要了。

阴影效果:

也有很多方法可以做到这一点。

您可以向小部件/布局添加阴影,并让该小部件/布局顶部的按钮占用比阴影更少的空间,以便考虑对阴影的触摸。

或者创建您自己的从 ButtonBehavior 派生的 CustomButtonBehavior 类,该类覆盖 collidepoint 方法,仅针对自定义碰撞返回 True。有一个将custom collision 用于小部件的示例。您甚至可以将 Image 的 keep_data 属性设置为 True,然后检查 pixel 的 alpha 数据以确定是否要为碰撞返回 true。

圆角等

简单地使用圆角的图像 kivy 支持使用 BorderImage 指令,在功能上相当于 css 的borderimage。 Kivy 自己的按钮默认使用这个。 试试BorderImage的边框属性。

【讨论】:

你的回答真的很有帮助。我仍在试图弄清楚,当我尝试对 background_normal 和 background_down 使用 .gif 图像时,它并没有显示动画,而是以你的方式显示动画。我仍在尝试从您的帖子中学习阴影效果。您知道为什么 .gif 不适用于 background_normal 或 background_down 吗? Button 默认只使用一个顶点指令.. BorderImage 用于绘制它的画布,它加载并显示静态(不支持动画,你必须手动处理它)。然而,Image Widget 确实支持仅获得带有动画图像的 gif 或 .zip。【参考方案2】:
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()

我认为这更有效。我正在使用两种图像。

【讨论】:

以上是关于在 kivy python 中将按钮的背景更改为不同的形状和样式,如阴影效果等的主要内容,如果未能解决你的问题,请参考以下文章

在 Kivy 中将图像对象作为按钮背景传递

如何更改 Kivy 中按钮的背景颜色?

更改背景画布 kivy

在 Python/Selenium 中将焦点更改为新窗口

如何在反应离子应用程序中将 ios 键盘返回按钮更改为下一步/完成?

在导航栏中将后退按钮更改为向下箭头