如何在kivy recycleview中select只有一个按钮
How to select only one button in kivy recycleview
我正在使用 kivy recycleview 创建一个 mp3 播放器,该应用程序的播放列表屏幕中有很多按钮,每当您单击一个按钮时,该按钮的图标就会从 'play' 变为 'pause' 反之亦然。
我想知道如何使单击另一个按钮将所有其他按钮图标更改为 'play' 只有所选按钮的图标应为 'pause'。
.py 文件:
from kivy.lang import Builder
from kivymd.app import MDApp
from kivy.core.window import Window
from kivy.properties import StringProperty, ObjectProperty
from kivymd.theming import ThemableBehavior
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.screen import MDScreen
from kivymd.uix.behaviors import RectangularRippleBehavior
from kivy.uix.behaviors import ButtonBehavior
from kivy.clock import Clock
Builder.load_file('playlist.kv')
KV = """
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
ScreenManager:
transition: FadeTransition()
Playlist:
name: "playlist screen"
"""
class Playlist(ThemableBehavior, MDScreen):
rv = ObjectProperty()
def __init__(self, **kwargs):
super().__init__(**kwargs)
Clock.schedule_once(self._finish_init)
def music_list(self):
return ['audio '+str(i) for i in range(1, 121)]
def _finish_init(self, dt):
self.set_list_musics()
def set_list_musics(self):
"""Builds a list of audios for the screen Playlist."""
print(self.ids)
def add_music_item(num, sura, secText, icon):
self.ids.rv.data.append(
{
"viewclass": "MusicListItem",
"number": num,
"text": sura,
"secondary_text": secText,
"icon": icon,
"callback": lambda x:x})
for i in range(len(self.music_list())):
music = self.music_list()
add_music_item(str(i+1), music[i], '00:00:00', 'play')
class MusicListItem(ThemableBehavior, RectangularRippleBehavior, ButtonBehavior, MDBoxLayout):
text = StringProperty()
secondary_text = StringProperty()
number = StringProperty()
icon = StringProperty()
def on_release(self, *args):
if self.icon == "play":
self.icon = "pause"
else:
self.icon = "play"
class Mp3Player(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def build(self):
self.theme_cls.primary_palette = "Purple"
self.theme_cls.theme_style = "Dark"
return Builder.load_string(KV)
if '__main__' == __name__:
Mp3Player().run()
.kv 文件:
#: import gch kivy.utils.get_color_from_hex
#: import StiffScrollEffect kivymd.effects.stiffscroll.StiffScrollEffect
<Playlist>
md_bg_color: gch("#5D1049")
MDGridLayout:
cols: 1
MDToolbar:
left_action_items: [["menu", lambda x: x]]
right_action_items: [["magnify", lambda x: x]]
elevation: 10
md_bg_color: 75/255, 6/255, 54/255, 1
title: 'Playlist'
pos_hint: {'top':1}
MDBoxLayout:
orientation: 'vertical'
RecycleView:
id: rv
effect_cls: 'ScrollEffect'
viewclass: 'MusicListItem'
RecycleBoxLayout:
padding: dp(10)
default_size: None, dp(60)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
<MusicListItem>
size_hint_y: None
padding: dp(14)
height: dp(60)
canvas:
Color:
rgba:
self.theme_cls.divider_color
Line:
points: (root.x+dp(10), root.y, root.x+self.width-dp(10)-0, root.y)
MDBoxLayout:
orientation: "horizontal"
pos_hint: {"center_x": .5, "center_y": .5}
MDBoxLayout:
orientation: 'horizontal'
MDBoxLayout:
orientation: 'vertical'
size_hint_x: .2
MDLabel:
text: root.number
font_style: "H6"
adaptive_height: True
MDLabel:
size_hint_y: .3
MDBoxLayout:
orientation: 'vertical'
MDLabel:
text: root.text
font_style: "Subtitle2"
adaptive_height: True
MDLabel:
text: root.secondary_text
font_style: "Caption"
theme_text_color: "Hint"
adaptive_height: True
MDIconButton:
icon: root.icon
谢谢
因此,据我了解,您希望将一个图标设置为 'pause',而将所有其他图标设置为 'play'。这样做的一种方法可能是,每次图标更改时,您都必须重新加载 RecyclView
数据 。
现在为 数据 提供图标参考(即 'play' 或 'pause'),我发现 number
属性合适,所以改成NumericProperty
。因此 number = NumericProperty()
.
另外这需要kv的一些变化,
MDLabel:
text: str(int(root.number))
font_style: "H6"
adaptive_height: True
- 为了让
Playlist
知道 number
引用,
def set_list_musics(self, music_no = 0):
"""Builds a list of audios for the screen Playlist."""
print(self.ids)
self.ids.rv.data = [ ] # Since you are appending data and we need to reload everytime.
- 在数据、
中进行必要的更改
for i in range(len(self.music_list())):
new_icon = 'pause' if i+1 == music_no else 'play'
music = self.music_list()
add_music_item(str(i+1), music[i], '00:00:00', new_icon)
- 现在是最后一部分,通过按钮触发更改,
def on_release(self, *args):
if self.icon == "play":
self.icon = "pause"
pl = self.parent.parent.parent.parent.parent # Accessing the Playlist according to your design pattern.
pl.set_list_musics(self.number)
else:
self.icon = "play"
请注意,我在 'pause' 图标中进行了此更改(即在 if self.icon == "play"
中),因此您也可以自由切换此图标。否则无法实现。
也许这可以用其他设计风格更系统地完成。我发现您的设计模式存在一些问题。这(例如在 for
循环中重复调用函数等)可能会随着 data 的增加而变慢一点。
我正在使用 kivy recycleview 创建一个 mp3 播放器,该应用程序的播放列表屏幕中有很多按钮,每当您单击一个按钮时,该按钮的图标就会从 'play' 变为 'pause' 反之亦然。
我想知道如何使单击另一个按钮将所有其他按钮图标更改为 'play' 只有所选按钮的图标应为 'pause'。
.py 文件:
from kivy.lang import Builder
from kivymd.app import MDApp
from kivy.core.window import Window
from kivy.properties import StringProperty, ObjectProperty
from kivymd.theming import ThemableBehavior
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.screen import MDScreen
from kivymd.uix.behaviors import RectangularRippleBehavior
from kivy.uix.behaviors import ButtonBehavior
from kivy.clock import Clock
Builder.load_file('playlist.kv')
KV = """
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
ScreenManager:
transition: FadeTransition()
Playlist:
name: "playlist screen"
"""
class Playlist(ThemableBehavior, MDScreen):
rv = ObjectProperty()
def __init__(self, **kwargs):
super().__init__(**kwargs)
Clock.schedule_once(self._finish_init)
def music_list(self):
return ['audio '+str(i) for i in range(1, 121)]
def _finish_init(self, dt):
self.set_list_musics()
def set_list_musics(self):
"""Builds a list of audios for the screen Playlist."""
print(self.ids)
def add_music_item(num, sura, secText, icon):
self.ids.rv.data.append(
{
"viewclass": "MusicListItem",
"number": num,
"text": sura,
"secondary_text": secText,
"icon": icon,
"callback": lambda x:x})
for i in range(len(self.music_list())):
music = self.music_list()
add_music_item(str(i+1), music[i], '00:00:00', 'play')
class MusicListItem(ThemableBehavior, RectangularRippleBehavior, ButtonBehavior, MDBoxLayout):
text = StringProperty()
secondary_text = StringProperty()
number = StringProperty()
icon = StringProperty()
def on_release(self, *args):
if self.icon == "play":
self.icon = "pause"
else:
self.icon = "play"
class Mp3Player(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def build(self):
self.theme_cls.primary_palette = "Purple"
self.theme_cls.theme_style = "Dark"
return Builder.load_string(KV)
if '__main__' == __name__:
Mp3Player().run()
.kv 文件:
#: import gch kivy.utils.get_color_from_hex
#: import StiffScrollEffect kivymd.effects.stiffscroll.StiffScrollEffect
<Playlist>
md_bg_color: gch("#5D1049")
MDGridLayout:
cols: 1
MDToolbar:
left_action_items: [["menu", lambda x: x]]
right_action_items: [["magnify", lambda x: x]]
elevation: 10
md_bg_color: 75/255, 6/255, 54/255, 1
title: 'Playlist'
pos_hint: {'top':1}
MDBoxLayout:
orientation: 'vertical'
RecycleView:
id: rv
effect_cls: 'ScrollEffect'
viewclass: 'MusicListItem'
RecycleBoxLayout:
padding: dp(10)
default_size: None, dp(60)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
<MusicListItem>
size_hint_y: None
padding: dp(14)
height: dp(60)
canvas:
Color:
rgba:
self.theme_cls.divider_color
Line:
points: (root.x+dp(10), root.y, root.x+self.width-dp(10)-0, root.y)
MDBoxLayout:
orientation: "horizontal"
pos_hint: {"center_x": .5, "center_y": .5}
MDBoxLayout:
orientation: 'horizontal'
MDBoxLayout:
orientation: 'vertical'
size_hint_x: .2
MDLabel:
text: root.number
font_style: "H6"
adaptive_height: True
MDLabel:
size_hint_y: .3
MDBoxLayout:
orientation: 'vertical'
MDLabel:
text: root.text
font_style: "Subtitle2"
adaptive_height: True
MDLabel:
text: root.secondary_text
font_style: "Caption"
theme_text_color: "Hint"
adaptive_height: True
MDIconButton:
icon: root.icon
谢谢
因此,据我了解,您希望将一个图标设置为 'pause',而将所有其他图标设置为 'play'。这样做的一种方法可能是,每次图标更改时,您都必须重新加载 RecyclView
数据 。
现在为 数据 提供图标参考(即 'play' 或 'pause'),我发现
number
属性合适,所以改成NumericProperty
。因此number = NumericProperty()
.另外这需要kv的一些变化,
MDLabel:
text: str(int(root.number))
font_style: "H6"
adaptive_height: True
- 为了让
Playlist
知道number
引用,
def set_list_musics(self, music_no = 0):
"""Builds a list of audios for the screen Playlist."""
print(self.ids)
self.ids.rv.data = [ ] # Since you are appending data and we need to reload everytime.
- 在数据、 中进行必要的更改
for i in range(len(self.music_list())):
new_icon = 'pause' if i+1 == music_no else 'play'
music = self.music_list()
add_music_item(str(i+1), music[i], '00:00:00', new_icon)
- 现在是最后一部分,通过按钮触发更改,
def on_release(self, *args):
if self.icon == "play":
self.icon = "pause"
pl = self.parent.parent.parent.parent.parent # Accessing the Playlist according to your design pattern.
pl.set_list_musics(self.number)
else:
self.icon = "play"
请注意,我在 'pause' 图标中进行了此更改(即在 if self.icon == "play"
中),因此您也可以自由切换此图标。否则无法实现。
也许这可以用其他设计风格更系统地完成。我发现您的设计模式存在一些问题。这(例如在 for
循环中重复调用函数等)可能会随着 data 的增加而变慢一点。