我有以下使用kivy gui框架创建的简单应用程序。这不是最简单的一种,因为label_1
具有背景色,并且其大小根据标签的文本进行了修改。这是我第一次接触奇异果。不幸的是,kivy文档和大多数可通过Google访问的示例都大量使用kivy语言。我的问题是:如何仅使用python 3在没有奇异语言的情况下如何获得相同的结果?
代码:
from kivy.config import Config
from kivy.core.window import Window
from kivy.app import App
from kivy.lang import Builder
MainScreen = Builder.load_string('''
BoxLayout:
orientation: 'vertical'
Label:
text: 'label_1'
font_size: 18
color: (0, 0, 0, 1)
size_hint: None, None
size: self.texture_size
canvas.before:
Color:
rgba: 1, .5, 0, 1
Rectangle:
pos: self.pos
size: self.size
Label:
text: 'label_2'
color: (0, 0, 0, 1)
''')
class MyApp(App):
def build(self):
return MainScreen
if __name__ == '__main__':
Config.set('input', 'mouse', 'mouse,multitouch_on_demand')
Window.clearcolor = (1, 1, 1, 1)
MyApp().run()
外观:
答案 0 :(得分:1)
您需要的代码的实现是:
from kivy.config import Config
from kivy.core.window import Window
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.graphics import Rectangle, Color
mainscreen = BoxLayout(orientation='vertical')
label1 = Label(text='label_1', font_size=18, color=(0, 0, 0, 1), size_hint=(None, None))
label1.bind(texture_size=label1.setter('size'))
def update_rect(instance, *args):
rect.pos = instance.pos
rect.size = instance.size
with label1.canvas.before:
Color(1, .5, 0, 1)
rect = Rectangle(pos=label1.pos, size=label1.size)
label1.bind(pos=update_rect, size=update_rect)
label2 = Label(text='label_2', color=(0, 0, 0, 1))
mainscreen.add_widget(label1)
mainscreen.add_widget(label2)
class MyApp(App):
def build(self):
return mainscreen
if __name__ == '__main__':
Config.set('input', 'mouse', 'mouse,multitouch_on_demand')
Window.clearcolor = (1, 1, 1, 1)
MyApp().run()
恕我直言,kv中的实现在完成绑定时更具可读性和灵活性,例如适合大小的标签。
from kivy.config import Config
from kivy.core.window import Window
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.graphics import Rectangle, Color
from kivy.properties import ListProperty
class CustomLabel(Label):
bgcolor = ListProperty([0, 0, 0, 1])
def __init__(self, **kwargs):
if kwargs.get('bgcolor'):
self.bgcolor = kwargs['bgcolor']
kwargs.pop('bgcolor')
super(CustomLabel, self).__init__(**kwargs)
self.bind(texture_size=self.setter('size'))
with self.canvas.before:
self.p = Color(*self.bgcolor)
self.rect = Rectangle(pos=self.pos, size=self.size)
self.on_bgcolor()
self.bind(pos=self.geometry_bind, size=self.geometry_bind)
def on_bgcolor(self, *args):
self.p.rgba = self.bgcolor
def geometry_bind(self, *args):
self.rect.pos = self.pos
self.rect.size = self.size
class MyApp(App):
def build(self):
mainscreen = BoxLayout(orientation='vertical')
label1 = CustomLabel(text='label_1', font_size=18, color=(0, 0, 0, 1), size_hint=(None, None), bgcolor=(1, .5, 0, 1))
label2 = Label(text='label_2', color=(0, 0, 0, 1))
mainscreen.add_widget(label1)
mainscreen.add_widget(label2)
return mainscreen
if __name__ == '__main__':
Config.set('input', 'mouse', 'mouse,multitouch_on_demand')
Window.clearcolor = (1, 1, 1, 1)
MyApp().run()
说明:
bind
:当foo_property更改时,bind(foo_property = callback)
函数负责调用回调。
setter
:setter('foo_property')
函数生成一个回调,可让您设置一个值。
如果您同时使用两个功能:
class FooClass(Foo_EventDispatcher):
property_a = FooProperty(initial_value_a)
property_b = FooProperty(initial_value_b)
def __init__(self, **kwargs):
super(FooClass, self).__init__(**kwargs)
self.bind(property_a=self.setter('property_b'))
等同于.kv中的以下指令:
<FooClass>:
property_b: self.property_a
答案 1 :(得分:0)
解决我的问题的另一种方法-基于@eyllanesc的答案和kivy crash course videos的解决方案。我将其发布在这里的原因有两个:(1)使用此版本,您可以清楚地看到正在发生的事情-如何以及何时实际绘制背景-没有其他语法层(海军语言)并且没有bind
和{{1} }对我来说是全新的,(2)eyllanesc提供了一些凌乱的python代码。
代码:
setter
外观: