Python 在kivy中嵌套小部件
我正在尝试用kivy制作一个界面,我想关于自定义小部件以及如何对它们进行层次化,我还不了解一些基本的东西,即使在阅读了教程之后。我认为我更倾向于框模型html,因此在本机GUI中嵌套小部件的方式对我来说仍然有些陌生 一些背景:Python 在kivy中嵌套小部件,python,user-interface,widget,kivy,Python,User Interface,Widget,Kivy,我正在尝试用kivy制作一个界面,我想关于自定义小部件以及如何对它们进行层次化,我还不了解一些基本的东西,即使在阅读了教程之后。我认为我更倾向于框模型html,因此在本机GUI中嵌套小部件的方式对我来说仍然有些陌生 一些背景: 我就如何添加背景进行了咨询(它回答了一个问题:“如何将背景图像/颜色/视频/…添加到布局”,我相信我是在用_update _rect方法进行复制) 有一个触地事件 K、 我正试图让我的应用程序看起来像这样 据我所知,以下是我需要的东西: 你有一个应用程序 该应用程序有一
#!/usr/bin/kivy
import kivy
kivy.require('1.7.2')
from random import random
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.floatlayout import FloatLayout
from kivy.graphics import Color, Ellipse, Rectangle
class MyApp(App):
title = 'My App'
def build(self):
root = RootWidget()
root.bind(
size=self._update_rect,
pos=self._update_rect)
def _update_rect(self, instance, value):
self.rect.pos = instance.pos
self.rect.size = instance.size
class RootWidget(FloatLayout):
def __init__(self, **kwargs):
super(RootWidget, self).__init__(**kwargs)
with self.canvas.before:
Color(1, 0, 0, 1) # This RED does not display.
self.rect = Rectangle(
size=self.size,
pos=self.pos,
text="some junk!") # This label does not display.
mybackground = Background()
self.add_widget(mybackground)
def _update_rect(self, instance, value):
self.rect.pos = instance.pos
self.rect.size = instance.size
class Background(Widget):
def __init__(self, **kwargs):
super(Background, self).__init__(**kwargs)
with self.canvas.before:
Color(1, 1, 1, 1) # This WHITE does not display
self.rect = Rectangle(
size=self.size,
pos=self.pos,
text="More stuff!") # This label does not display.
myholder = Holder()
self.add_widget(myholder)
def _update_rect(self, instance, value):
self.rect.pos = instance.pos
self.rect.size = instance.size
class Holder(Widget):
def __init__(self, **kwargs):
super(Holder, self).__init__(**kwargs)
with self.canvas.before:
Color(0.25, 0.25, 0.25, 1) # This GRAY does not display
self.rect = Rectangle(
size=self.size,
pos=self.pos,
text="More stuff!") # This does not display.
c1 = Circley(label="Label 1") # I see I'd need to do some size/pos math here to center
c2 = Circley(label="Label 2") # but since everything isn't working, I've tabled this.
self.add_widget(c1)
self.add_widget(c2)
def _update_rect(self, instance, value):
self.rect.pos = instance.pos
self.rect.size = instance.size
def on_touch_down(self, touch):
rcolor = Color(random(), random(), random(), 1)
with self.canvas:
self.color = rcolor
class Circley(Widget):
def __init__(self, label='label', **kwargs):
super(Circley, self).__init__(**kwargs)
with self.canvas.before:
Color(0, 1, 0, 1) # This GREEN does not display
self.circ = Ellipse(
size=self.size,
pos=self.pos,
text=label
)
def _update_circ(self, instance, value):
self.circ.pos = instance.pos
self.circ.size = instance.size
def on_touch_down(self, touch):
rcolor = Color(random(), random(), random(), 1)
with self.canvas:
self.color = rcolor
if __name__ == '__main__':
MyApp().run()
有没有关于我做错了什么以及如何正确嵌套这些小部件的指针?出现空白屏幕的原因是应用程序的
build()
方法没有返回任何内容。无论它返回什么,都将是根小部件,但即使您制作了一些小部件,您也不会返回一个,因此不会显示任何内容
如果您解决了这个问题,您可以再次运行应用程序,但您会立即得到一个错误,例如MyApp没有属性rect
。这是因为您的根小部件会立即调整大小和位置以填充窗口,这(根据您的root.bind
行)会触发MyApp.\u update\u rect
。但是,此方法尝试修改MyApp.rect.pos…但是应用程序没有self.rect!您可能打算绑定到root.\u update\u rect
,而不是应用程序的方法。(编辑:我绑定到根目录。_update_rect
,现在至少出现了红色背景和绿色圆圈。)
编辑:顺便说一句,使用kv语言会容易得多,它可以自动处理许多小部件的创建、矩形绑定等
我现在没有时间修复它,但是这两个问题可能会帮助您修复整个流程。如果其他人都没有,我会尝试稍后发布一个更完整的答案
根据评论,这里有一个更新的MyApp
class MyApp(App):
title = 'My App'
def build(self):
root = RootWidget()
root.bind(
size=root._update_rect,
pos=root._update_rect)
这很有帮助,但我不明白你所说的
是什么意思。然而,这个方法试图修改MyApp.rect.pos…但是这个应用没有self.rect!您可能打算绑定到root.\u update\u rect,而不是应用程序的方法。(编辑:我绑定到根目录下。_update_rect,现在至少出现了红色背景和绿色圆圈。)
这对MyApp(App)的``def_update_rect(self,instance,value)意味着什么变化:self.rect.pos=instance.pos self.rect.size=instance.size``?我应该将self.rect.pos更改为root,并将root作为输入传递给该函数?我已经在更新的MyApp类中编辑了我想要的更改。它根本没有一个_update_rect方法,因为应用程序没有矩形。
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.widget import Widget
from kivy.graphics import Color, Rectangle, Ellipse
class MyApp(App):
title = 'My App'
def build(self):
root = RootWidget()
root.bind(
size=root._update_rect,
pos=root._update_rect)
return root
class RootWidget(FloatLayout):
def __init__(self, **kwargs):
super(RootWidget, self).__init__(**kwargs)
with self.canvas.before:
Color(1, 0, 0, 1) # This RED does not display.
self.rect = Rectangle(
size=self.size,
pos=self.pos,
text="some junk!") # This label does not display.
mybackground = Background()
self.add_widget(mybackground)
def _update_rect(self, instance, value):
self.rect.pos = instance.pos
self.rect.size = instance.size
class Background(Widget):
def __init__(self, **kwargs):
super(Background, self).__init__(**kwargs)
with self.canvas.before:
Color(1, 1, 1, 1) # This WHITE does not display
self.rect = Rectangle(
size=self.size,
pos=self.pos,
text="More stuff!") # This label does not display.
myholder = Holder()
self.add_widget(myholder)
def _update_rect(self, instance, value):
self.rect.pos = instance.pos
self.rect.size = instance.size
class Holder(Widget):
def __init__(self, **kwargs):
super(Holder, self).__init__(**kwargs)
with self.canvas.before:
Color(0.25, 0.25, 0.25, 1) # This GRAY does not display
self.rect = Rectangle(
size=self.size,
pos=self.pos,
text="More stuff!") # This does not display.
c1 = Circley(label="Label 1") # I see I'd need to do some size/pos math here to center
c2 = Circley(label="Label 2") # but since everything isn't working, I've tabled this.
self.add_widget(c1)
self.add_widget(c2)
def _update_rect(self, instance, value):
self.rect.pos = instance.pos
self.rect.size = instance.size
def on_touch_down(self, touch):
rcolor = Color(random(), random(), random(), 1)
with self.canvas:
self.color = rcolor
class Circley(Widget):
def __init__(self, label='label', **kwargs):
super(Circley, self).__init__(**kwargs)
with self.canvas.before:
Color(0, 1, 0, 1) # This GREEN does not display
self.circ = Ellipse(
size=self.size,
pos=self.pos,
text=label
)
def _update_circ(self, instance, value):
self.circ.pos = instance.pos
self.circ.size = instance.size
def on_touch_down(self, touch):
rcolor = Color(random(), random(), random(), 1)
with self.canvas:
self.color = rcolor
if __name__ == '__main__':
MyApp().run()