如何在 Kivy (Python) 中叠加 2 个布局?
How to overlay 2 layouts in Kivy (Python)?
我正在尝试制作一个带有背景网格和交互元素顶层的应用程序,但我无法通过 python 覆盖第二层,所以正如标题所说,有没有办法覆盖Kivy 中的 2 个或更多布局?
这是我要找的东西
解决方案
设置第一层/布局的opacity
为0.5
opacity
Opacity of the widget and all its children.
The opacity attribute controls the opacity of the widget and its
children. Be careful, it’s a cumulative attribute: the value is
multiplied by the current global opacity and the result is applied to
the current context color.
...
opacity is a NumericProperty and defaults to 1.0.
points: list
List of points in the format (x1, y1, x2, y2…)
Property for getting/settings points of the line
Warning
This will always reconstruct the whole graphics from the new points
list. It can be very CPU expensive.
circle
Use this property to build a circle, without calculating the points.
You can only set this property, not get it.
The argument must be a tuple of (center_x, center_y, radius,
angle_start, angle_end, segments):
- center_x and center_y represent the center of the circle
- radius represent the radius of the circle
- (optional) angle_start and angle_end are in degree. The default value is 0 and 360.
- (optional) segments is the precision of the ellipse. The default value is calculated from the range between angle.
Note that it’s up to you to close the circle or not.
例子
main.py - 没有 kv
from kivy.base import runTouchApp
from kivy.core.window import Window
from kivy.uix.screenmanager import Screen
from kivy.uix.boxlayout import BoxLayout
from kivy.graphics import Color, Line
from kivy.metrics import dp
Window.clearcolor = (1, 1, 1, 1)
class Overlay2Layouts(Screen):
def __init__(self, **kwargs):
super(Overlay2Layouts, self).__init__(**kwargs)
self.size = Window.size
layout1 = BoxLayout(opacity=0.5)
with layout1.canvas:
Color(1, 0, 0, 1) # red colour
Line(points=[self.center_x, self.height / 4, self.center_x, self.height * 3/4], width=dp(2))
Line(points=[self.width * 3/ 4, self.center_y, self.width /4, self.center_y], width=dp(2))
layout2 = BoxLayout()
with layout2.canvas:
Color(0, 0, 0, 1) # black colour
Line(circle=[self.center_x, self.center_y, 190], width=dp(2))
self.add_widget(layout1)
self.add_widget(layout2)
if __name__ == "__main__":
runTouchApp(Overlay2Layouts())
main.py - 使用 kv 和 Python
from kivy.lang import Builder
from kivy.base import runTouchApp
from kivy.core.window import Window
Window.clearcolor = (1, 1, 1, 1)
runTouchApp(Builder.load_string('''
#:kivy 1.11.0
Screen:
BoxLayout:
opacity: 0.5
canvas.before:
Color:
rgba: 1, 0, 0, 1
Line:
width: dp(2.)
points: [self.center_x, self.height / 4, self.center_x, self.height * 3/4]
Line:
width: dp(2.)
points: [root.width * 3/ 4, self.center_y, root.width /4, self.center_y]
BoxLayout:
canvas.before:
Color:
rgba: 1, 0, 0, 1
Line:
width: dp(2.)
circle: (root.center_x, root.center_y, 190)
'''))
输出
为了补充 python 中的答案,当 window 改变大小时叠加层没有调整大小,所以这是我的解决方案:
import kivy
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.graphics import Color, Line, Ellipse, Rectangle
from kivy.metrics import dp
class RootWidget(BoxLayout):
def __init__(self, *args, **kwargs):
BoxLayout.__init__(self, *args, **kwargs)
self.bind(pos=self.draw)
self.bind(size=self.draw)
self.layout1 = BoxLayout(opacity=0.3)
self.layout2 = BoxLayout()
self.add_widget(self.layout1)
self.add_widget(self.layout2)
def draw(self, *args):
with self.canvas.before:
Color(1,1,.5,1)
self.bg = Rectangle(pos=self.pos, size=self.size)
self.layout1.canvas.clear()
with self.layout1.canvas:
Color(1, 0, 0, 1) # red colour
Line(points=[self.center_x, self.height / 4, self.center_x, self.height * 3/4], width=dp(2))
Line(points=[self.width * 3/ 4, self.center_y, self.width /4, self.center_y], width=dp(2))
self.layout2.canvas.clear()
with self.layout2.canvas:
Color(0, 0, 0, 1) # black colour
Line(circle=[self.center_x, self.center_y, 190], width=dp(2))
class Overlays_3(App):
title = "Overlays_3"
def build(self):
return RootWidget()
if __name__ == "__main__":
Overlays_3().run()
我正在尝试制作一个带有背景网格和交互元素顶层的应用程序,但我无法通过 python 覆盖第二层,所以正如标题所说,有没有办法覆盖Kivy 中的 2 个或更多布局?
这是我要找的东西
解决方案
设置第一层/布局的opacity
为0.5
opacity
Opacity of the widget and all its children.
The opacity attribute controls the opacity of the widget and its children. Be careful, it’s a cumulative attribute: the value is multiplied by the current global opacity and the result is applied to the current context color.
...
opacity is a NumericProperty and defaults to 1.0.
points: list
List of points in the format (x1, y1, x2, y2…)
Property for getting/settings points of the line
Warning
This will always reconstruct the whole graphics from the new points list. It can be very CPU expensive.
circle
Use this property to build a circle, without calculating the points. You can only set this property, not get it.
The argument must be a tuple of (center_x, center_y, radius, angle_start, angle_end, segments):
- center_x and center_y represent the center of the circle
- radius represent the radius of the circle
- (optional) angle_start and angle_end are in degree. The default value is 0 and 360.
- (optional) segments is the precision of the ellipse. The default value is calculated from the range between angle.
Note that it’s up to you to close the circle or not.
例子
main.py - 没有 kv
from kivy.base import runTouchApp
from kivy.core.window import Window
from kivy.uix.screenmanager import Screen
from kivy.uix.boxlayout import BoxLayout
from kivy.graphics import Color, Line
from kivy.metrics import dp
Window.clearcolor = (1, 1, 1, 1)
class Overlay2Layouts(Screen):
def __init__(self, **kwargs):
super(Overlay2Layouts, self).__init__(**kwargs)
self.size = Window.size
layout1 = BoxLayout(opacity=0.5)
with layout1.canvas:
Color(1, 0, 0, 1) # red colour
Line(points=[self.center_x, self.height / 4, self.center_x, self.height * 3/4], width=dp(2))
Line(points=[self.width * 3/ 4, self.center_y, self.width /4, self.center_y], width=dp(2))
layout2 = BoxLayout()
with layout2.canvas:
Color(0, 0, 0, 1) # black colour
Line(circle=[self.center_x, self.center_y, 190], width=dp(2))
self.add_widget(layout1)
self.add_widget(layout2)
if __name__ == "__main__":
runTouchApp(Overlay2Layouts())
main.py - 使用 kv 和 Python
from kivy.lang import Builder
from kivy.base import runTouchApp
from kivy.core.window import Window
Window.clearcolor = (1, 1, 1, 1)
runTouchApp(Builder.load_string('''
#:kivy 1.11.0
Screen:
BoxLayout:
opacity: 0.5
canvas.before:
Color:
rgba: 1, 0, 0, 1
Line:
width: dp(2.)
points: [self.center_x, self.height / 4, self.center_x, self.height * 3/4]
Line:
width: dp(2.)
points: [root.width * 3/ 4, self.center_y, root.width /4, self.center_y]
BoxLayout:
canvas.before:
Color:
rgba: 1, 0, 0, 1
Line:
width: dp(2.)
circle: (root.center_x, root.center_y, 190)
'''))
输出
为了补充 python 中的答案,当 window 改变大小时叠加层没有调整大小,所以这是我的解决方案:
import kivy
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.graphics import Color, Line, Ellipse, Rectangle
from kivy.metrics import dp
class RootWidget(BoxLayout):
def __init__(self, *args, **kwargs):
BoxLayout.__init__(self, *args, **kwargs)
self.bind(pos=self.draw)
self.bind(size=self.draw)
self.layout1 = BoxLayout(opacity=0.3)
self.layout2 = BoxLayout()
self.add_widget(self.layout1)
self.add_widget(self.layout2)
def draw(self, *args):
with self.canvas.before:
Color(1,1,.5,1)
self.bg = Rectangle(pos=self.pos, size=self.size)
self.layout1.canvas.clear()
with self.layout1.canvas:
Color(1, 0, 0, 1) # red colour
Line(points=[self.center_x, self.height / 4, self.center_x, self.height * 3/4], width=dp(2))
Line(points=[self.width * 3/ 4, self.center_y, self.width /4, self.center_y], width=dp(2))
self.layout2.canvas.clear()
with self.layout2.canvas:
Color(0, 0, 0, 1) # black colour
Line(circle=[self.center_x, self.center_y, 190], width=dp(2))
class Overlays_3(App):
title = "Overlays_3"
def build(self):
return RootWidget()
if __name__ == "__main__":
Overlays_3().run()