Issues with adding custom camera widget to kivy kv file - python

Based on arnav's example I am trying to add this custom camera widget into a kv structure. Unfortunately this 'mechanism' is still not clear to me. So I have ended up with the following code. The light of the cam is active after click on the start button. However no 'video stream' is being displayed. When running just arnav's code with cv2.VideoCapture(0), the 'video stream' is displayed.
What am I doing wrong here?
qrtest.py:
from kivy.app import App
from kivy.uix.image import Image
from kivy.clock import Clock
from kivy.graphics.texture import Texture
from kivy.uix.boxlayout import BoxLayout
from kivy.core.window import Window
import cv2
import os
class KivyCamera(Image):
def dostart(self, capture, fps, **kwargs):
self.capture = capture
Clock.schedule_interval(self.update, 1.0 / fps)
def update(self, dt):
ret, frame = self.capture.read()
if ret:
# convert it to texture
buf1 = cv2.flip(frame, 0)
buf = buf1.tostring()
image_texture = Texture.create(
size=(frame.shape[1], frame.shape[0]), colorfmt='bgr')
image_texture.blit_buffer(buf, colorfmt='bgr', bufferfmt='ubyte')
# display image from the texture
self.texture = image_texture
capture = None
class QrtestHome(BoxLayout):
def init_qrtest(self):
pass
def dostart(self, *largs):
global capture
capture = cv2.VideoCapture(0)
my_camera = KivyCamera(capture=capture, fps=10, )
my_camera.dostart(capture,10)
def doexit(self):
global capture
if capture != None:
capture.release()
os._exit(0)
class qrtestApp(App):
def build(self):
Window.clearcolor = (.4,.4,.4,1)
Window.size = (400, 300)
homeWin = QrtestHome()
homeWin.init_qrtest()
return homeWin
qrtestApp().run()
and the qrtest.kv file:
<QrtestHome>:
BoxLayout:
orientation: "vertical"
Label:
height: 20
size_hint_y: None
text: 'Testing the camera'
KivyCamera:
canvas:
Color:
rgb: (0, 0.6, 0.6)
Rectangle:
texture: self.texture
pos: (50, 30)
size: (300, 240)
height: 260
id: qrcam
BoxLayout:
orientation: "horizontal"
height: 20
size_hint_y: None
Button:
id: butt_start
size_hint: 0.5,1
text: "start"
on_press: root.dostart()
Button:
id: butt_exit
text: "quit"
size_hint: 0.5,1
on_press: root.doexit()

Related

Problem: The size or resolution of the kivy camera is small

Why is the screen size of the camera on the screen so small?While I adjusted the full screen size.When I change the resolution, the application does not come up on the phone . With opencv resolution 640, 480 full screen is displayed
Sorry my English is not good
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
# import time
Builder.load_string('''
<CameraClick>:
BoxLayout:
id:boxz
orientation: 'vertical'
Camera:
id: camera
size_hint: None , None
size: boxz.width , boxz.height
pos_hint :{"center_x":.5}
resolution: (640, 480)
play: False
ToggleButton:
text: 'Play'
on_press: camera.play = not camera.play
size_hint_y: None
height: '48dp'
Button:
text: 'Capture'
size_hint_y: None
height: '48dp'
on_press: root.capture()
''')
class CameraClick(BoxLayout):
def capture(self):
'''
Function to capture the images and give them the names
according to their captured time and date.
'''
camera = self.ids['camera']
# timestr = time.strftime("%Y%m%d_%H%M%S")
camera.export_to_png("11.png")
print("Captured")
class TestCamera(App):
def build(self):
return CameraClick()
TestCamera().run()
enter image description here
enter image description here

How to schedule the kivy camera to read the texture continuously?

I have been trying to create a kivy camera scanner from a number of sources (I would use the zbarcam if I could, but the garden.xcamera module will not import, therefore I am trying to create something similar).
Problem
The problem is the camera does not read or update the texture continuously nor is there a way that I can find to capture frame-for-frame from the camera. This means I only get the texture on initialization.
Tried
Firstly, I have tried scheduling an event that will update the texture instance every 0.5 seconds. I could not get the texture instance of the camera because there is some delay in the camera to load, which caused an error.
Secondly, I created an on_texture event in my kv string, but it only reads the texture on initialization.
Thirdly, I tried binding the on_texture event a bit later in the python script, by creating a binding function and calling it as a scheduled event. It did not even get the instance.
Fourthly, I created_triggers and ask_update(callbacks) to the _on_texture() event, but again the script loads to fast before the camera can instantiate crashing the script.
Fifthly, I noticed there is a kivy.core.video module that contains a on_frame attribute. Did re-write my script to use it in conjunction with the kivy.uix.video module, but noticed that the video cannot run without first loading a video file.
Code
import kivy
import gi
kivy.require('1.11.1')
gi.require_version('Gst', '1.0')
from collections import namedtuple
from PIL import Image
from kivy.app import App
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ListProperty, ObjectProperty
from kivy.uix.camera import Camera
import time
from gi.repository import Gst
import pyzbar.pyzbar
from kivy.uix.modalview import ModalView
Builder.load_string('''
#: import Window kivy.core.window.Window
<ScanPreview>:
auto_dismiss: False
size_hint_x: 0.6
size_hint_y: None
height: Window.height / 9
pos_hint: {'top':0.7, 'x': 0.1}
background_normal: ''
background_color: (1, 1, 1, 0)
background: 'white.png'
Label:
id: sc_data
text: 'See me...'
<ScanCamera>:
orientation: 'vertical'
The_Camera:
id: camera
resolution: root.resolution
on_texture: root._on_texture(camera)
ToggleButton:
text: 'Stop'
on_press: camera.play = not camera.play
size_hint_y: None
height: '48dp'
''')
class ScanPreview(ModalView):
pass
class The_Camera(Camera):
pass
class ScanCamera(BoxLayout):
resolution = ListProperty([640, 480])
symbols = ListProperty([])
code_types = ListProperty(set(pyzbar.pyzbar.ZBarSymbol))
cam_cam = ObjectProperty(The_Camera())
the_preview = ObjectProperty(ScanPreview())
Symb = namedtuple('Symb', ['type','data'])
def __init__(self, **kwargs):
super(ScanCamera, self).__init__(**kwargs)
self.cam_cam.play = True
def _on_texture(self, instance):
#source: https://github.com/kivy-garden/garden.zbarcam/blob/develop
#/zbarcam/zbarcam.py
print(instance)
if not instance.texture == None:
print(instance.texture)
self.symbols = self._detect_qrcode_frame(
texture=instance.texture, code_types=self.code_types)
def _detect_qrcode_frame(cls, texture, code_types):
image_data = texture.pixels
size = texture.size
#source: https://github.com/kivy-garden/garden.zbarcam/blob/develop
#/zbarcam/zbarcam.py
# Fix for mode mismatch between texture.colorfmt and data returned
#by
# texture.pixels. texture.pixels always returns RGBA, so that
#should
# be passed to PIL no matter what texture.colorfmt returns. refs:
# https://github.com/AndreMiras/garden.zbarcam/issues/41
pil_image = Image.frombytes(mode='RGBA', size=size,
data=image_data)
symbols = []
print(pil_image)
print(size)
print(texture.tex_coords)
print(texture.target)
codes = pyzbar.pyzbar.decode(pil_image, symbols=code_types)
for code in codes:
symbol = CameraClick.Symb(type=code.type, data=code.data)
symbols.append(symbol)
print(symbols)
return symbols
class TestCamera(App):
title = 'Scan Camera'
def build(self):
return ScanCamera()
def on_stop(self):
cc = The_Camera()
print('Stop')
cc.play = False
def on_pause(self):
return True
def on_resume(self):
pass
TestCamera().run()
Desired result
The camera's texture must continuously update, which will allow the pyzbar and PIL module to decode the texture?
I don't know if this is how its done, but as I answered my own question I am posting the answer and marking it as such.
Answer
So I managed to solve my question by using the example code here: https://kivy-fork.readthedocs.io/en/latest/_modules/kivy/uix/camera.html and mixing in some functions of zbarcam.
By using self.canvas.ask_update() in the on_texture call it updates the texture. I have added to the code and it now updates the texture continuously and prints the barcode to a togglebutton. At the moment I have just tested it on Ubuntu Bionic Beaver. Will test it on android this weekend.
Answer code
import kivy
import gi
kivy.require('1.11.1')
gi.require_version('Gst', '1.0')
from collections import namedtuple
from PIL import Image as Img
from kivy.app import App
from gi.repository import Gst
import pyzbar.pyzbar
from kivy.uix.image import Image
from kivy.core.camera import Camera as CoreCamera
from kivy.properties import NumericProperty, ListProperty, \
BooleanProperty, ObjectProperty
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivy.core.window import Window
Builder.load_string('''
#: import Window kivy.core.window.Window
<ScanCamera>:
<BarcWin>:
ActionBar:
pos_hint: {'top': 1, 'right': 1}
color: (1,1,1,1)
canvas.before:
Color:
rgba: (0,0,0,1)
Rectangle:
pos: self.pos
size: self.size
ActionView:
use_separator: True
ActionPrevious:
title: ''
with_previous: False
app_icon: ''
ActionButton:
color: (0,0,0,1)
background_normal: ''
Image:
source: 'gear_2.png'
center_y: self.parent.center_y
center_x: self.parent.center_x
size: self.parent.width /1.7, self.parent.height/ 1.7
allow_stretch: True
ActionButton:
color: (0,0,0,1)
size_hint_x: 0.09
background_normal: ''
Image:
source: 'dustbin_backgrnd_792521.png'
center_y: self.parent.center_y
center_x: self.parent.center_x
size: self.parent.width /1.7, self.parent.height/ 1.7
allow_stretch: True
ScanCamera:
pos_hint: {'top': 0.9, 'right': 1}
size_hint: [1, 0.8]
canvas.before:
PushMatrix
Rotate:
angle: 0
origin: self.center
canvas.after:
PopMatrix
Line:
width: 2.
rectangle: (self.x + 40, self.y + 40, self.width/1.1, self.height/1.12)
ToggleButton:
id: show_bcode
pos_hint: {'bottom': 1, 'right': 1}
size_hint: [1, 0.1]
color: (1,1,1,1)
background_color: (0,0,0,0)
background_normal: ''
canvas.before:
Color:
rgba: (.18,.36,.61,1) if self.state=='down' else (0,0,0,1)
Rectangle:
pos: self.pos
size: self.size
text: 'Hier kom die barcode...'
''')
class BarcWin(FloatLayout):
cam_cam = ObjectProperty(None)
def __init__(self, **kwargs):
super(BarcWin, self).__init__(**kwargs)
self.cam_cam = ScanCamera()
def accept_in(self):
print('In')
def accept_out(self):
print('Out')
class ScanCamera(Image):
play = BooleanProperty(True)
index = NumericProperty(-1)
resolution = ListProperty([Window.width, Window.height])
symbols = ListProperty([])
code_types = ListProperty(set(pyzbar.pyzbar.ZBarSymbol))
Symb = namedtuple('Symb', ['type','data'])
app_ini_ = ObjectProperty(None)
got_bcode = BooleanProperty(False)
def __init__(self, **kwargs):
self._camera = None
super(ScanCamera, self).__init__(**kwargs)
if self.index == -1:
self.index = 0
on_index = self._on_index
fbind = self.fbind
fbind('index', on_index)
fbind('resolution', on_index)
on_index()
self.app_ini_ = App.get_running_app()
def on_tex(self, *l):
self.canvas.ask_update()
if not self.texture == None:
self.symbols = self._detect_qrcode_frame(texture=self.texture, code_types=self.code_types)
if not self.symbols == []:
for s in self.symbols:
if s.data:
if s.data.decode('utf-8') != "":
self.app_ini_.root.ids.show_bcode.text = s.data.decode('utf-8')
def _on_index(self, *largs):
self._camera = None
if self.index < 0:
return
if self.resolution[0] < 0 or self.resolution[1] < 0:
return
#first init of corecamera object
self._camera = CoreCamera(index=self.index,
resolution=self.resolution, stopped=True)
#when camera loads call _camera_loaded method to bind corecamera method with uix.image texture
self._camera.bind(on_load=self._camera_loaded)
if self.play:
self._camera.start()
self._camera.bind(on_texture=self.on_tex)
def _camera_loaded(self, *largs):
#bind camera texture with uix.image texture that is still equal to None
self.texture = self._camera.texture
def on_play(self, instance, value):
if not self._camera:
return
if value:
self._camera.start()
else:
self._camera.stop()
def _detect_qrcode_frame(self, texture, code_types):
if not self.got_bcode:
image_data = texture.pixels
size = texture.size
# Fix for mode mismatch between texture.colorfmt and data returned by
# texture.pixels. texture.pixels always returns RGBA, so that should
# be passed to PIL no matter what texture.colorfmt returns. refs:
# https://github.com/AndreMiras/garden.zbarcam/issues/41
pil_image = Img.frombytes(mode='RGBA', size=size,
data=image_data)
bcode = []
codes = pyzbar.pyzbar.decode(pil_image, symbols=code_types)
#print(pil_image, type(pil_image), dir(pil_image))
if codes != []:
for code in codes:
symbol = self.Symb(type=code.type, data=code.data)
bcode.append(symbol)
return bcode
else:
self.got_bcode = False
return []
class TestCamera(App):
title = 'Scan Camera'
def build(self):
return BarcWin()
def on_stop(self):
cc = ScanCamera()
print('Stop')
cc._camera.stop()
def on_pause(self):
return True
def on_resume(self):
pass
TestCamera().run()

How to set file selected by tkinter filechooser (image) as the source to a Kivy image widget?

I'm currently learning Kivy, I'm using tkinter filechooser to browse for images stored on my computer and want the selected image to be set as the source of the Images widget.
The code below launches the tkinter filechooser on button click, how should I go about to set the obtained file as source for my image widgets. Thank you for your time.
main.py
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.core.window import Window
from kivy.uix.popup import Popup
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from tkinter.filedialog import askopenfilename
from tkinter import Tk
class SampBoxLayout(BoxLayout):
# Defines two FileChoosers.
def get_image_one(self):
# Select image file types, returned image should be used as source of Image widget.
Tk().withdraw() # avoids window accompanying tkinter FileChooser
img1 = askopenfilename(initialdir = "/",title = "Select file",filetypes = (("jpeg files","*.jpg"),("all files","*.*")))
return img1
def get_image_two(self):
Tk().withdraw()
img2 = askopenfilename(initialdir = "/",title = "Select file",filetypes = (("jpeg files","*.jpg"),("all files","*.*")))
return img2
class SampleApp(App):
def build(self):
# Set the background color for the window
Window.clearcolor = (1, 1, 1, 1)
return SampBoxLayout()
sample_app = SampleApp()
sample_app.run()
sample.kv
#: import CheckBox kivy.uix.checkbox
<ColoredBackground#Image>:
font_size: '48sp'
color: (.9, .5, .4, 1)
canvas.before:
Color:
rgb: (.9, .9, .9)
Rectangle:
pos: self.x + sp(2), self.y + sp(2)
size: self.width - sp(5), self.height - sp(4)
<SampBoxLayout>:
orientation: "vertical"
padding: 10
spacing: 10
# ---------- Button FileChooser ----------
BoxLayout:
orientation: "horizontal"
height: 30
Button:
text: "FileChooser-1"
on_press: root.get_image_one()
Button:
text: "FileChooser-2"
on_press: root.get_image_two()
# ---------- Display Images----------
BoxLayout:
orientation: "horizontal"
height: 30
ColoredBackground:
source: " " # <----------- should be the image file selected by FileChooser-1
size: self.parent.width, self.parent.height
allow_stretch: True
keep_ratio: False
ColoredBackground:
source: " " # <----------- should be the image file selected by FileChooser-2
size: self.parent.width, self.parent.height
allow_stretch: True
keep_ratio: False
The solution is that the ColoredBackground are accessible in get_image_one and get_image_two for it we do properties:
*.kv
...
<SampBoxLayout>:
first_image: first_image # <----
second_image: second_image # <----
orientation: "vertical"
padding: 10
spacing: 10
# ---------- Button FileChooser ----------
BoxLayout:
...
# ---------- Display Images----------
BoxLayout:
orientation: "horizontal"
height: 30
ColoredBackground:
id: first_image # <----
size: self.parent.width, self.parent.height
allow_stretch: True
keep_ratio: False
ColoredBackground:
id: second_image # <----
size: self.parent.width, self.parent.height
allow_stretch: True
keep_ratio: False
*.py
def get_image_one(self):
# Select image file types, returned image should be used as source of Image widget.
Tk().withdraw() # avoids window accompanying tkinter FileChooser
img = askopenfilename(initialdir = "/",title = "Select file",filetypes = (("jpeg files","*.jpg"),("all files","*.*")))
self.first_image.source = img
def get_image_two(self):
Tk().withdraw()
img = askopenfilename(initialdir = "/",title = "Select file",filetypes = (("jpeg files","*.jpg"),("all files","*.*")))
self.first_image.source = img

Kivy Camera as KV language widget

I am using Kivy with a webcam. I have followed this example by #Arnav of using opencv to form and display the camera as a widget. I have "extended" the layout within python it to add two buttons as a test, in preparation for a more complicated layout.
class CamApp(App):
def build(self):
self.capture = cv2.VideoCapture(0)
self.my_camera = KivyCamera(capture=self.capture, fps=30,resolution=(1920,1080))
root = BoxLayout(orientation = 'vertical')
root.add_widget(self.my_camera,1)
box2 = BoxLayout(orientation = 'vertical')
btn1 = Button(text='Hello world 1')
btn2 = Button(text='Hello world 2')
box2.add_widget(btn1)
box2.add_widget(btn2)
root.add_widget(box2, 0)
return root
#return Builder.load_string(kv)
While this works I would prefer to move the UI components out of python and into a kv language file.
The problem is knowing how to "describe" the self.my_camera in the kv file?
I am not sure whether to inherit the KivyCamera class as a widget within the kv file i.e.
kv = '''
<Cam1#KivyCamera>:
texture: self.my_camera
resolution: (1920, 1080)
pos: self.pos
size: self.size
Or whether to use the canvas widget
<MyWidget>:
canvas:
Rectangle:
source: self.my_camera
pos: self.pos
size: self.size
I have tried other "hacked" implementations, but in all cases the problem is linking through the self.my_camera into the kv file.
Any suggestions?
Perhaps this example may help you.
# Import 'kivy.core.text' must be called in entry point script
# before import of cv2 to initialize Kivy's text provider.
# This fixes crash on app exit.
import kivy.core.text
import cv2
from kivy.app import App
from kivy.base import EventLoop
from kivy.uix.image import Image
from kivy.clock import Clock
from kivy.graphics.texture import Texture
from kivy.uix.boxlayout import BoxLayout
from kivy.core.window import Window
class KivyCamera(Image):
def __init__(self, **kwargs):
super(KivyCamera, self).__init__(**kwargs)
self.capture = None
def start(self, capture, fps=30):
self.capture = capture
Clock.schedule_interval(self.update, 1.0 / fps)
def stop(self):
Clock.unschedule_interval(self.update)
self.capture = None
def update(self, dt):
return_value, frame = self.capture.read()
if return_value:
texture = self.texture
w, h = frame.shape[1], frame.shape[0]
if not texture or texture.width != w or texture.height != h:
self.texture = texture = Texture.create(size=(w, h))
texture.flip_vertical()
texture.blit_buffer(frame.tobytes(), colorfmt='bgr')
self.canvas.ask_update()
capture = None
class QrtestHome(BoxLayout):
def init_qrtest(self):
pass
def dostart(self, *largs):
global capture
capture = cv2.VideoCapture(0)
self.ids.qrcam.start(capture)
def doexit(self):
global capture
if capture != None:
capture.release()
capture = None
EventLoop.close()
class qrtestApp(App):
def build(self):
Window.clearcolor = (.4,.4,.4,1)
Window.size = (400, 300)
homeWin = QrtestHome()
homeWin.init_qrtest()
return homeWin
def on_stop(self):
global capture
if capture:
capture.release()
capture = None
qrtestApp().run()
and the kv file:
<QrtestHome>:
BoxLayout:
orientation: "vertical"
Label:
height: 20
size_hint_y: None
text: 'Testing the camera'
KivyCamera:
id: qrcam
BoxLayout:
orientation: "horizontal"
height: 20
size_hint_y: None
Button:
id: butt_start
size_hint: 0.5,1
text: "start"
on_press: root.dostart()
Button:
id: butt_exit
text: "quit"
size_hint: 0.5,1
on_press: root.doexit()

converting static widget tree to dynamic using python and .kv file

I am working on an application where I want to add n image frames in a vertical BoxLayout. The number of n frames depend on the desktop screen size. Next to this the frames will be filled dynamically with images. I was able to develop this in a static manner with a fixed number of frames.
Now I am trying to convert this to a dynamic solution where n frame widgets will be created depending on the height of the screen (in the example below 7 widgets). And I am lost..... :(
The frames should 'sit' between a top bar and a bottom bar. In the .kv file this is indicated by the # Ilist: line.
I have the following questions:
1) How could I add these widgets dynamically using a .kv file?
2) How could I reference to these individual frame widgets for assigning images dynamically? For example: frame[idx] = swid?
Thanks very much for your time and shared knowledge in advance.
The Python file pplay.py:
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.core.window import Window
from kivy.properties import StringProperty
class IListItem(Widget):
sid = StringProperty('')
image = StringProperty('')
label = StringProperty('')
pass
class IList(Widget):
pass
class pplayHome(BoxLayout):
def init_player(self):
global swid
self.Ilayout = IList()
for idx in range (1, 7):
swid = IListItem(
sid = "s" + str(idx),
image = 'empty_image.png',
label = 'Image' + str(idx)
)
self.Ilayout.add_widget(swid)
class pplayApp(App):
def build(self):
Window.clearcolor = (1,1,1,1)
Window.borderless = True
Window.size = 275, 1080
homeWin = pplayHome()
homeWin.init_player()
return homeWin
if __name__ == "__main__":
pplayApp().run()
and the Kivy file pplay.kv
# File: pplay.kv
<IList#BoxLayout>
pid: self.pid
source: self.source
label: self.label
size_hint_y: None
height: "120dp"
BoxLayout:
orientation: "vertical"
Label:
size_hint: None, 1
text: root.label
Image:
size_hint: None, 1
source: root.source
<pplayHome>:
orientation: "vertical"
ActionBar:
font_size: 8
size: (275,25)
# background color in Kivy acts as a tint and not just a solid color.
# set a pure white background image first.
background_image: 'white-bg.png'
background_color: 0,.19,.34,1
ActionView:
ActionPrevious:
with_previous: False
app_icon: 'trButton.png'
ActionOverflow:
ActionButton:
icon: 'butt_exit.png'
on_press: root.exit_player()
# Ilist:
BoxLayout:
height: "10dp"
size_hint_y: None
pos_x: 0
canvas.before:
Color:
rgb: 0.55,0.77,0.25 # groen
Rectangle:
pos: self.pos
size: self.size
You were actually pretty close.
Here is the slightly changed kv file, with added colored rectangles for illustration of sizes:
# File: pplay.kv
<IListItem#Widget>
source: ''
label: ''
size_hint_y: None
height: "120dp"
canvas.before:
Color:
rgb: 0.55,0.77*self.idx/7,0.25 # groen
Rectangle:
pos: self.pos
size: self.size
BoxLayout:
orientation: "vertical"
size: root.size
pos: root.pos
Label:
size_hint: None, 1
text: root.label
canvas.before:
Color:
rgb: 0.77*root.idx/7,0.55,0.25 # groen
Rectangle:
pos: self.pos
size: self.size
Image:
size_hint: None, 1
source: root.source
<pplayHome>:
orientation: "vertical"
ActionBar:
font_size: 8
size: (275,25)
# background color in Kivy acts as a tint and not just a solid color.
# set a pure white background image first.
background_image: 'white-bg.png'
background_color: 0,.19,.34,1
ActionView:
ActionPrevious:
with_previous: False
app_icon: 'trButton.png'
ActionOverflow:
ActionButton:
icon: 'butt_exit.png'
on_press: root.exit_player()
IList:
id: ilist
orientation: 'vertical'
BoxLayout:
height: "10dp"
size_hint_y: None
pos_x: 0
canvas.before:
Color:
rgb: 0.55,0.77,0.25 # groen
Rectangle:
pos: self.pos
size: self.size
In pplay.py, the essential part is to retrieve the IList widget using self.ids['ilist']. It also shows how its children (the IListItems) can be retrieved via a differentiating property.
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.core.window import Window
from kivy.properties import StringProperty, NumericProperty
class IListItem(Widget):
idx = NumericProperty(1)
sid = StringProperty('')
image = StringProperty('')
label = StringProperty('')
pass
class IList(BoxLayout):
pass
class pplayHome(BoxLayout):
def init_player(self):
#global swid
print self.ids
ilayout = self.ids['ilist']
for idx in range (0, 7):
swid = IListItem(
sid = "s" + str(idx),
image = 'empty_image.png',
label = 'Image' + str(idx),
idx=idx
)
ilayout.add_widget(swid)
children_ids = [il.sid for il in ilayout.children]
print children_ids
print ilayout.children[children_ids.index('s3')]
class pplayApp(App):
def build(self):
# Window.clearcolor = (1,1,1,1)
Window.borderless = True
Window.size = 275, 1080
homeWin = pplayHome()
homeWin.init_player()
return homeWin
if __name__ == "__main__":
pplayApp().run()

Categories

Resources