使用 python 和 .kv 文件将静态小部件树转换为动态小部件树
converting static widget tree to dynamic using python and .kv file
我正在开发一个应用程序,我想在垂直 BoxLayout 中添加 n 个图像帧。 n 帧的数量取决于桌面屏幕尺寸。接下来,框架将动态填充图像。我能够以固定数量的帧以静态方式开发它。
现在我正在尝试将其转换为动态解决方案,其中将根据屏幕的高度创建 n 个框架小部件(在下面的示例中为 7 个小部件)。我迷路了..... :(
框架应该 'sit' 在顶栏和底栏之间。在 .kv 文件中,这由 # Ilist: 行指示。
我有以下问题:
1) 如何使用 .kv 文件动态添加这些小部件?
2) 我如何引用这些单独的框架小部件来动态分配图像?例如:frame[idx] = swid?
非常感谢您抽出时间提前分享知识。
Python 文件 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()
和 Kivy 文件 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
你们其实很接近。
这是略有改动的 kv
文件,添加了用于说明尺寸的彩色矩形:
# 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
在 pplay.py
中,关键部分是使用 self.ids['ilist']
检索 IList
小部件。它还显示了如何通过区分 属性.
检索其子项(IListItems
)
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()
我正在开发一个应用程序,我想在垂直 BoxLayout 中添加 n 个图像帧。 n 帧的数量取决于桌面屏幕尺寸。接下来,框架将动态填充图像。我能够以固定数量的帧以静态方式开发它。 现在我正在尝试将其转换为动态解决方案,其中将根据屏幕的高度创建 n 个框架小部件(在下面的示例中为 7 个小部件)。我迷路了..... :(
框架应该 'sit' 在顶栏和底栏之间。在 .kv 文件中,这由 # Ilist: 行指示。
我有以下问题:
1) 如何使用 .kv 文件动态添加这些小部件?
2) 我如何引用这些单独的框架小部件来动态分配图像?例如:frame[idx] = swid?
非常感谢您抽出时间提前分享知识。
Python 文件 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()
和 Kivy 文件 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
你们其实很接近。
这是略有改动的 kv
文件,添加了用于说明尺寸的彩色矩形:
# 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
在 pplay.py
中,关键部分是使用 self.ids['ilist']
检索 IList
小部件。它还显示了如何通过区分 属性.
IListItems
)
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()