Python 如何引用一个似乎超出范围的小部件-适应kivy/examples/demo/images
我编辑了kivy/examples/demo/images文件,尝试执行以下操作: -对于每个添加的图像,它还将在不同的boxlayout侧栏中添加一个按钮 -单击按钮时,会同时删除图像和按钮 为了做到这一点,我创建了这是简短的摘要代码,让您有一个想法Python 如何引用一个似乎超出范围的小部件-适应kivy/examples/demo/images,python,class,reference,kivy,Python,Class,Reference,Kivy,我编辑了kivy/examples/demo/images文件,尝试执行以下操作: -对于每个添加的图像,它还将在不同的boxlayout侧栏中添加一个按钮 -单击按钮时,会同时删除图像和按钮 为了做到这一点,我创建了这是简短的摘要代码,让您有一个想法 boxlayout: floatlayout: #this is where the images, in their own class called "Picture" just like in the demo get ad
boxlayout:
floatlayout:
#this is where the images, in their own class called "Picture" just like in the demo get added
boxlayout:
#this is where the buttons get added. I created a class for them called "PictureBtn"
创建图片时,我会为它们添加一个唯一的id。
然后我创建PictureBtn并添加相同的id。
然后我将图片和按钮填充到它们各自的位置。到目前为止一切顺利
现在的问题是,无论是Pictures还是PictureBtn实例,我都可以引用该应用程序,但我不知道如何引用其他实例。身份证好像不在任何地方
我的理解是,这是因为它们超出了范围。id只在本地保留,因为PictureBtn和Pictures都有自己的根,所以我无法访问它们
我的完整代码如下:
import kivy
kivy.require('1.0.6')
from glob import glob
from random import randint
from os.path import join, dirname
from kivy.app import App
from kivy.logger import Logger
from kivy.uix.scatter import Scatter
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty
# FIXME this shouldn't be necessary
from kivy.core.window import Window
#declare global var for keeping track of unique ids
number_of_pics=0
class Picture(Scatter):
'''Picture is the class that will show the image with a white border and a
shadow. They are nothing here because almost everything is inside the
picture.kv. Check the rule named <Picture> inside the file, and you'll see
how the Picture() is really constructed and used.
The source property will be the filename to show.
'''
source = StringProperty(None)
class PictureBtn(BoxLayout):
pass
class PicturesApp(App):
def build(self):
global number_of_pics
# the root is created in pictures.kv
root = self.root
# get any files into images directory
curdir = dirname(__file__)
for filename in glob(join(curdir, 'images', '*')):
try:
# load the image
picture = Picture(source=filename, rotation=randint(-30,30))
picture.id='pic'+str(number_of_pics)
button = PictureBtn()
button.id = 'pic'+str(number_of_pics)
button.ids.lbl.text= button.id
# add to the main field
self.root.ids.picspace.add_widget(picture)
self.root.ids.sidebar.add_widget(button)
number_of_pics+=1
except Exception as e:
Logger.exception('Pictures: Unable to load <%s>' % filename)
def on_pause(self):
return True
def RemovePicture(self,byid):
#my attempt (obviously failing) at removing the Picture instance and the
#PictureBtn instance with the id "byid"
self.root.ids.sidebar.remove_widget(self.root.ids.sidebar.ids.byid)
self.root.ids.picspace.remove_widget(self.root.ids.picspace.ids.byid)
if __name__ == '__main__':
PicturesApp().run()
然后,我的kv文件包含以下内容:
#:kivy 1.0
#:import kivy kivy
#:import win kivy.core.window
BoxLayout:
orientation: 'horizontal'
FloatLayout:
id: picspace
size_hint: 0.8,1
canvas:
Color:
rgb: 1, 1, 1
Rectangle:
source: 'data/images/background.jpg'
size: self.size
BoxLayout:
padding: 10
spacing: 10
size_hint: 1, None
pos_hint: {'top': 1}
height: 44
Image:
size_hint: None, None
size: 24, 24
source: 'data/logo/kivy-icon-24.png'
Label:
height: 24
text_size: self.width, None
color: (1, 1, 1, .8)
text: 'Kivy %s - Pictures' % kivy.__version__
BoxLayout:
id: sidebar
orientation: 'vertical'
<Picture>:
# each time a picture is created, the image can delay the loading
# as soon as the image is loaded, ensure that the center is changed
# to the center of the screen.
on_size: self.center = win.Window.center
size: image.size
size_hint: None, None
Image:
id: image
source: root.source
# create initial image to be 400 pixels width
size: 400, 400 / self.image_ratio
# add shadow background
canvas.before:
Color:
rgba: 1,1,1,1
BorderImage:
source: 'shadow32.png'
border: (36,36,36,36)
size:(self.width+72, self.height+72)
pos: (-36,-36)
<PictureBtn>:
orientation: 'horizontal'
Label:
id: lbl
text: ''
Button:
text: 'X'
on_release: app.RemovePicture(self.parent.id)
我的原始代码也是类似的情况,但我在一个kivy/示例中创建了相同的问题,以使其更容易解决
谢谢好的,我终于找到了一种方法,但我确信一定有更好的方法:
def RemovePicture(self,idee):
for child in self.ids.picspace.children:
if child.id==idee:
self.ids.picspace.remove_widget(child)
for child in self.ids.sidebar.children:
if child.id==idee:
self.ids.sidebar.remove_widget(child)
所以这似乎奏效了。它们不会出现在ID列表中,但会出现在子项列表中。我仍然不知道这是为什么。如果有人知道更好/更合适的方法,请告诉我。ID仅在kv中有效,并且与根规则相关。它们不是引用小部件的应用程序范围的全局标识符。下面是一个简单的例子,说明为什么会这样:
<MyWidget@BoxLayout>:
Label:
id: mylabel
Button:
id: mybutton
BoxLayout:
MyWidget:
id: widget1
MyWidget:
id: widget2
您的删除代码如下:
def remove_picture(self, idee):
picture, button = self._pictures.pop(idee)
picture.parent.remove_widget(picture)
button.parent.remove_widget(button)
昨天我在Kivy也遇到了scope的问题,并解决了它。你可以看到我的问题和答案。它涉及屏幕,所以它与您的情况并不完全相同,但它仍然可能对您有所帮助。
def remove_picture(self, idee):
picture, button = self._pictures.pop(idee)
picture.parent.remove_widget(picture)
button.parent.remove_widget(button)