在Kivy Python中改变按钮的背景形状和样式,比如阴影效果等
我了解到在Qt中,我们可以通过以下几种方式来制作QpushButton:
- 添加阴影效果
- 通过将setFlat属性设置为True来让按钮看起来更平坦
- 当鼠标悬停在按钮上时,改变鼠标指针的样式,比如使用pushButton_18.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
我也想在Kivy中让按钮的行为类似。这样做可以吗?我发现我们可以把按钮的背景图像换成圆角形状的图像,在Kivy中改变按钮的背景颜色。
但这样做效果并不理想,因为按钮看起来还是很普通。没有阴影效果。即使我们在按钮的边角点击,系统也会把它当作按钮被点击了。
我查看了Kivy按钮和标签的文档,尝试改变按钮的外观和行为。有没有人能给我一些建议,让按钮看起来更好?我们可以尝试添加:
- 阴影效果
- 背景动画效果
- 圆角边缘等等
- 我们能不能把动画GIF图像作为背景来做动画(我试过,但它不再动了)
下面是我刚创建的代码,用来进一步探索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()
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中的按钮是从一个叫做 ButtonBehavior 开始的,这个按钮行为和一个 Label 结合在一起,增加了一些属性,比如背景的正常状态和按下状态,用来处理画布上的纹理。
知道了这些,你可以简单地把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 结合在一起,这个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))
看看这个 序列图像示例。这个示例是在ButtonBehaviors出现之前做的,所以它甚至有一个使用旧方法的 AnimatedButton 类的例子,这种方法现在基本上不再需要了。
阴影效果:
实现阴影效果的方法有很多。
你可以给一个小部件或布局添加阴影,然后让按钮放在这个小部件或布局的上面,按钮的空间要比阴影小,这样就能响应阴影上的触摸。
或者,你可以创建一个自定义的CustomButtonBehavior类,继承自ButtonBehavior,重写 collidepoint
方法,只在自定义碰撞时返回True。这里有一个关于 自定义碰撞 的示例。你甚至可以把图片的 keep_data
属性设置为True,然后检查 像素 数据的透明度,以决定是否要返回True进行碰撞检测。
圆角等效果。
只需使用一张带有圆角的图片,Kivy支持使用BorderImage指令,这在功能上相当于CSS的border-image。Kivy自带的按钮默认就使用这个效果。尝试并实验一下 BorderImage 的边框属性。