在Kivy中实现按钮圆角

25

在Kivy中创建按钮的圆角,最好的方法是什么?

还有其他同样可行的方法来完成这个任务吗?

4个回答

29

这个有点棘手。我认为,Widgets 总是矩形的。但是我们可以改变背景并使用 background_normalbackground_down 属性分别放置一些图片来表示正常和按下状态。此外,您需要了解 border 属性。

有了这两个名为 normal.pngdown.png 的图片,您就可以开始添加圆角边框了。

enter image description here enter image description here

这是一段非常简单明了的代码(我在下面尝试解释了 border 属性):

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

Builder.load_string("""
<Base>:
    Button:
        background_normal: 'normal.png'
        background_down: 'down.png'
        border: 30,30,30,30
""")


class Base(FloatLayout):
    pass

class ButtonsApp(App):
    def build(self):
        return Base()

if __name__ == "__main__":
    ButtonsApp().run()
我理解的方式是这样的(可能有错):border: 30,30,30,30中的值告诉背景按钮边框将使用顶部、右侧、底部和左侧各多少像素。其余部分将填充中间部分。我不太确定。另外,如果你想看一些酷炫的东西,可以尝试border: 150,150,150,150。需要注意的是:小部件仍然是矩形的。这意味着即使你点击圆角,按钮仍然会接收事件。我认为这是一个公平的代价。如果你想做得更好,也许我可以帮忙,但我们需要使用一些数学方法来碰撞点。在文档中,关于Pong游戏教程的一个技巧是球实际上是一个正方形。我在这里发布了一个相关问题here,但你需要使用Canvas

3
自定义的碰撞检测示例可以在https://github.com/kivy/kivy/blob/master/examples/widgets/customcollide.py中找到。按钮使用边框图像显示其图像,该图像具有边框属性。这种边框图像在功能上与CSS BorderImage非常相似。您可以从http://css-tricks.com/understanding-border-image/了解更多信息。 - qua-non
这种按钮图像方法也在_GeeksforGeeks_文章Python - 在kivy中将按钮角四舍五入中有所解释。 - hc_dev

12

如果你只是想追求外观美观,并且不太在意即使四角是圆的还是有触点的话,你可以简单地完成它,正如此示例程序所示(此示例具有大半径):

from kivy.uix.button import Button
from kivy.lang import Builder
from kivy.base import runTouchApp

kv="""
<RoundedButton@Button>:
    background_color: 0,0,0,0  # the last zero is the critical on, make invisible
    canvas.before:
        Color:
            rgba: (.4,.4,.4,1) if self.state=='normal' else (0,.7,.7,1)  # visual feedback of press
        RoundedRectangle:
            pos: self.pos
            size: self.size
            radius: [50,]
"""
class RoundedButton(Button):
    pass

Builder.load_string(kv)

runTouchApp(RoundedButton(text="Hit Me!"))

这个Button类的扩展在KivyCoders上也有解释: 用Kivy创建圆角按钮-Python Kivy GUI教程#22(包括视频) - hc_dev

3
如何使用canvas项创建自定义类?
您可以为每个布局更改半径。
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.relativelayout import RelativeLayout
from kivy.graphics import *

root=Widget()

class RoundCorner(RelativeLayout):
    def __init__(self,r=50,**kwargs):
        super(RoundCorner, self).__init__(**kwargs)
        self.surf=FloatLayout(); self.add_widget(self.surf)
        with self.canvas:
            Color(.3,0,3,0.3)
            Rectangle(pos=[-r,0],size=[r,self.size[1]])
            Rectangle(pos=[0,-r],size=[self.size[0],self.size[1]+2*r])
            Rectangle(pos=[self.size[0],0],size=[r,self.size[1]])

            Color(0,.3,0,.5)
            Ellipse(pos=[-r,-r],size=[2*r,2*r])
            Ellipse(pos=[self.size[0]-r,-r],size=[2*r,2*r])
            Ellipse(pos=[-r,self.size[1]-r],size=[2*r,2*r])
            Ellipse(pos=[self.size[0]-r,self.size[1]-r],size=[2*r,2*r])

            Color(1,1,1,0.3)
            self.bg=Rectangle(size=self.size)

root.add_widget(RoundCorner(size=[300,400],pos=[320,100]))
root.add_widget(RoundCorner(size=[100,100],pos=[100,200]))

class MyApp(App):
    def __init__(self):
        super(MyApp, self).__init__()
    def build(self):
        return root

if __name__=="__main__":
    MyApp().run()

我选择了相对布局,因为它更容易编写。通过将其全局位置添加到画布项中,可以将其用于小部件,但出于简单起见,我只是这样做了。颜色的选择是为了使逻辑可见。以下是上面代码的示例:

Enter image description here

只需要在代码中调整颜色,就可以开始了。

Enter image description here

这样更好,因为分辨率不是问题(我可能错了 - 我不是OpenGL的专家)。
嗯,这并不是一个完整的按钮。它只是一个布局,有按下或按压时,可以像真正的按钮一样使用。我没有将其包含在代码中。关于事件的许多内容都在官方网站上。

0

使用材料扩展KivyMD,有许多带有圆角的新按钮类:

一个简单的例子

在Python中使用KV语言:

from kivymd.app import MDApp

from kivy.lang import Builder

KV = '''
Screen:

    MDRoundFlatButton:
       text: "MDROUNDFLATBUTTON"
'''


class Example(MDApp):
    def build(self):
        return Builder.load_string(KV)


Example().run()

你也可以导入并扩展抽象类kivymd.uix.button.MDRoundFlatButton


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接