从Kivy语言到python的Kivy标签代码
我使用KivyGUI框架创建了以下简单的应用程序。它不是最简单的一个,因为从Kivy语言到python的Kivy标签代码,python,python-3.x,kivy,kivy-language,Python,Python 3.x,Kivy,Kivy Language,我使用KivyGUI框架创建了以下简单的应用程序。它不是最简单的一个,因为label_1具有背景色,并且其大小根据标签的文本进行修改。这是我第一次体验kivy。不幸的是,kivy文档和通过google访问的大多数示例都大量使用kivy语言。我的问题是:如果没有只使用Python3的kivy语言,如何获得相同的结果 代码: 外观: 您需要的代码的实现是: from kivy.config import Config from kivy.core.window import Window from
label_1
具有背景色,并且其大小根据标签的文本进行修改。这是我第一次体验kivy。不幸的是,kivy文档和通过google访问的大多数示例都大量使用kivy语言。我的问题是:如果没有只使用Python3的kivy语言,如何获得相同的结果
代码:
外观:
您需要的代码的实现是:
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()
IMHO当完成绑定时,以kv为单位的实现更具可读性和灵活性,就像适合大小的标签一样
说明:
- :bind(foo\u property=callback)函数负责在foo\u属性更改时调用回调
- :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'))
相当于以下说明(单位:千伏):
<FooClass>:
property_b: self.property_a
:
property_b:self.property_a
解决我问题的另一种方法-基于@eyllanesc的答案和答案的解决方案。我把它贴在这里有两个原因:(1)有了这个版本,人们可以清楚地看到正在发生的事情——如何以及何时实际绘制背景——没有另一个语法层(kivy语言),没有对我来说是全新的bind
和setter
,(2)eyllanesc提供了一点混乱的python代码
代码:
外观:
谢谢你的回答。你能解释一下
bind
和setter
吗?@Poolka我的第一个代码只按顺序实现逻辑,这样你就可以看到元素之间的关联,在这个更新的代码中,我比你的代码做得更有效,在你的例子中,你清理指令并创建其他指令,在我的例子中,只有重用。此外,还添加了一个简短的解释,但如果您想要更精确的解释,请阅读文档。感谢添加的解释。老实说,我决定尝试kivy,因为它是用python编写的,与另一个python gui框架相比,它是python的。现在看来kivy并不真正适合复杂/动态GUI。@Poolka什么是pythonic?IMHO声明性语言有利于轻松创建sight,但在业务逻辑部分,支持OOP的语言是最好的。kivy有双方,因此只使用python编写代码将是乏味和难以忍受的,一开始kv语言似乎很奇怪,但当您使用真相时,这是非常简单的。相对于其他库,我推荐kivy用于移动设备,而不是桌面。@Poolka用于桌面,我更喜欢使用Qt(PyQt4/PyQt5/PySide/PySide2),因为它是一个成熟且多功能的库,有时我将它与QML结合使用,因为它允许快速实现视图(类似于Qt的kv语言)。其他库,比如tkinter,我用来做极简主义的事情,pygame,我几乎不用它,等等。
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'))
<FooClass>:
property_b: self.property_a
from kivy.config import Config
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.graphics import Color, Rectangle
from kivy.app import App
class LabelWithBackground(Label):
def __init__(self, bgcolor, **kwargs):
super().__init__(**kwargs)
self.bgcolor = bgcolor
self.draw_background()
def draw_background(self):
if self.canvas is not None:
self.canvas.before.clear()
with self.canvas.before:
Color(*self.bgcolor)
Rectangle(pos=self.pos, size=self.size)
def on_size(self, *args):
self.draw_background()
def on_pos(self, *args):
self.size = self.texture_size
self.draw_background()
class MyApp2(App):
def __init__(self):
super().__init__()
self.layout = BoxLayout()
self.layout.orientation = 'vertical'
self.labels = [
Label(text='label_0', color=(0, 0, 0, 1)),
LabelWithBackground(text='label_1', color=(0, 0, 0, 1), size_hint=(.5, None), bgcolor=(1, .5, 0, 1)),
Label(text='label_2', color=(0, 0, 0, 1)),
LabelWithBackground(text='label_3', color=(0, 0, 0, 1), size_hint=(None, .25), bgcolor=(1, .5, 0, 1)),
Label(text='label_4', color=(0, 0, 0, 1)),
LabelWithBackground(text='label_5', color=(0, 0, 0, 1), size_hint=(None, None), bgcolor=(1, .5, 0, 1))]
for lbl in self.labels:
self.layout.add_widget(lbl)
def build(self):
return self.layout
if __name__ == '__main__':
Config.set('input', 'mouse', 'mouse,multitouch_on_demand')
Window.clearcolor = (1, 1, 1, 1)
MyApp2().run()