[英]Displaying a background image in Kivy
我刚开始学习 Kivy 所以我仍然熟悉它的功能。 我正在尝试将图像作为我的应用程序主页的背景。 这就是我所做的:
class Prin(BoxLayout):
def __init__(self,**kwargs):
super(Prin,self).__init__(**kwargs)
layout = BoxLayout(orientation='vertical')
with self.canvas:
self.rect = Rectangle(source='test.png', pos=layout.center, size=(self.width, self.height))
self.text = Label(text='Press start')
fb = Button(text='Start!', size_hint =(0.5, 0.1), pos_hint ={'center_x':.5, 'y':.5}, padding=(10, 0), on_press=self.start)
layout.add_widget(self.text)
layout.add_widget(fb)
self.add_widget(layout)
def start(self,event):
self.text.text = self.text.text+ "\nNew line"
class MainApp(App):
def build(self):
return Prin()
if __name__ == "__main__":
app = MainApp()
app.run()
所需的行为是覆盖整个屏幕的图像,这就是为什么我把pos=self.center, size=(self.width, self.height)
这是 output:
所以我有两个问题:
1/ 为什么图像出现在左下角? 实际上有什么小部件? 我应该只有一个带有 2 个垂直方向小部件的 BoxLayout。 我不明白那里有什么。
2/ 为什么要输入尺寸和位置以获得所需的 output?
我建议将所有图形元素放在一个.kv
文件中,这样可以减少导入并且看起来更好。
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
KV = ("""
<Prin>
BoxLayout:
orientation: 'vertical'
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: 'test.png'
Label:
id: label
text: 'TEXT'
Button:
text: 'Start!'
size_hint: None, None
size_hint: 0.5, 0.1
pos_hint: {'center_x': .5, 'center_y': .5}
padding: 10, 0
on_press: root.start()
""")
class Prin(BoxLayout):
Builder.load_string(KV)
def __init__(self, **kwargs):
super(Prin, self).__init__(**kwargs)
def start(self):
self.ids.label.text += "\nNew line"
class MainApp(App):
def build(self):
return Prin()
if __name__ == "__main__":
app = MainApp()
app.run()
如果您仍然想不在kv
文件中执行此操作,那么问题出在self.size
中,默认情况下,此值为[100, 100]
,只有在调用 class 并将其添加到主 window 后才会更改。
from kivy.core.window import Window
class Prin(BoxLayout):
def __init__(self, **kwargs):
super(Prin, self).__init__(**kwargs)
with self.canvas.before:
Rectangle(source='test.png', pos=self.pos, size=Window.size)
print(self.size) # [100, 100]
...
class MainApp(App):
def build(self):
self.screen = Prin()
return self.screen
def on_start(self):
print(self.screen.size) # [800, 600]
当你提出问题时不要忘记导入,代码应该在没有任何操作的情况下运行
针对您的问题:
该图像出现在 position 中,因为pos=layout.center
不是有效的 position ,因此将其设置为默认值(我相信[100, 100]
)。 要解决此问题, pos=layout.center
更改为pos=layout.pos
您的尺寸也是默认值! 这有点技术性,但是当您初始化Prin
class 时,您将Rectangle
的大小指定为BoxLayout
的当前大小。 然而,由于它还没有被初始化,所以 BoxLayout 还没有大小。 Kivy 通过给它一个默认大小来处理这个问题。
为什么我的按钮和标签正确?
Kivy 自动将 BoxLayout 的子级绑定到 BoxLayout 的 size 和 position 上。 此绑定确保当 BoxLayout 的 position 和大小发生变化时,其中的小部件也会发生变化( https://kivy.org/doc/stable/api-kivy.event.ZFC35FDC70D5FC69D269883A2E )。
为什么 Kivy 不绑定矩形?
这与canvas
。 canvas 是小部件共享的绘图指令,而不是任何单个小部件的属性。 因此,您将以编程方式将矩形绑定到 BoxLayout。 (https://kivy.org/doc/stable/api-kivy.graphics.instructions.html )
我如何实现您所说的这种绑定?
两种方式。 首先(首选),您可以使用 KV 语言定义小部件,因为这将自动处理您希望的任何绑定。 其次,您可以创建一个“on_size”回调。 就像是:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.graphics import Rectangle
class Prin(BoxLayout):
def __init__(self, **kwargs):
super(Prin, self).__init__(**kwargs)
layout = BoxLayout(orientation='vertical')
with self.canvas:
self.rect = Rectangle(source='test.png', pos=layout.pos, size=self.size)
self.text = Label(text='Press start')
fb = Button(text='Start!', size_hint=(0.5, 0.1), pos_hint={'center_x': .5, 'y': .5}, padding=(10, 0),
on_press=self.start)
layout.add_widget(self.text)
layout.add_widget(fb)
self.add_widget(layout)
def start(self, *_):
self.text.text = self.text.text + "\nNew line"
def resize(self, *_):
widgets = self.children[:]
self.canvas.clear()
self.clear_widgets()
with self.canvas:
self.rect = Rectangle(source='test.png', pos=self.pos, size=self.size)
for widget in widgets:
self.add_widget(widget)
on_size = resize
class TestApp(App):
def build(self):
return Prin()
if __name__ == "__main__":
app = TestApp()
app.run()
我只是想添加一个大 PS虽然上面的代码解决了你的问题,但它可能是以可以想象的效率最低的方式来解决的。 在 kv 文件中定义小部件要好得多。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.