Python3.8.1においてkivyを用いて簡単なアプリを作っています。kivyのRecycleViewを用いる際に、viewclassにCheckBoxを持たせて要素を選択、選択した要素をRecycleViewのリストから削除しようとしています。
main.py
main
1from kivy.app import App 2from kivy.uix.boxlayout import BoxLayout 3from kivy.uix.recycleview import RecycleView 4from kivy.properties import ObjectProperty,BooleanProperty 5from kivy.uix.popup import Popup 6import copy 7class TestCheck(App): 8 def __init__(self, **kwargs): 9 super(TestCheck, self).__init__(**kwargs) 10 self.title = "Test" 11class Start(BoxLayout): 12 def start(self): 13 content=Check() 14 self.popup=Popup(title="start",content=content) 15 self.popup.open() 16class Check(BoxLayout): 17 tmplist=ObjectProperty() 18 def __init__(self,**kwargs): 19 super(Check, self).__init__(**kwargs) 20 self.tmplist.data=[{"name":"1","check":False},{"name":"2","check":False},{"name":"3","check":False},{"name":"4","check":False}] 21 Check.data = self.tmplist.data 22 def delete(self): 23 print(self.tmplist.data) 24 booklist = copy.copy(Check.data) 25 print(booklist) 26 27 for book in booklist: 28 id_num = Check.data.index(book) 29 print(book["name"],book["check"]) 30 if book["check"] == True: 31 Check.data.pop(id_num) 32 print("book{} delete!".format(book["name"])) 33 self.tmplist.data=Check.data 34 print(Check.data) 35 print(self.tmplist.data) 36 def restart(self): 37 Start.start(self) 38class FileButton(BoxLayout): 39 name = ObjectProperty() 40 is_checked = BooleanProperty(False) 41 def checkpush(self,checkbox): 42 print(checkbox.active) 43 for book in Check.data: 44 if book["name"] == self.name: 45 book["check"]=checkbox.active 46 47 48if __name__ == "__main__": 49 TestCheck().run()
testcheck.kv
testcheck
1Start 2<Start> 3 BoxLayout: 4 Button: 5 on_press: root.start() 6<Check> 7 tmplist: tmp_list 8 BoxLayout: 9 Label: 10 text: "test" 11 RecycleView: 12 id: tmp_list 13 viewclass: "FileButton" 14 RecycleBoxLayout: 15 orientation: "vertical" 16 default_size_hint: 1,None 17 default_size: None,dp(45) 18 size_hint_y: None 19 scaping: 5 20 height: self.minimum_height 21 padding: 10 22 Button: 23 text: "delete" 24 on_press: root.delete() 25 Button: 26 text: "start" 27 on_press: root.restart() 28<FileButton> 29 name: "" 30 CheckBox: 31 active: root.is_checked 32 on_press: root.checkpush(self) 33 Label: 34 text: root.name 35
簡略化してありますが、起動後ボタンを押すとポップアップを表示、ポップアップ内にRecycleViewを表示しています。さらにRecycleViewの各要素にCheckBoxがついており、Checkしてある要素をdeleteから削除しています。delete時にもポップアップによって削除の確認をしており、削除時のClassとRecycleViewのClassが異なることで上手にRecycleViewのリストを更新できずに困っています。
###起こったエラー
一度削除を行い、残ったリストを再度選択し、再度削除を行う
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/kivy/uix/recycleview/__init__.py", line 225, in refresh_views lm.compute_sizes_from_data(data, f) File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/kivy/uix/recyclelayout.py", line 116, in compute_sizes_from_data del opts[v] IndexError: list assignment index out of range
一度削除を行い、何も選択せずに再度削除を行う
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/kivy/uix/recycleview/__init__.py", line 225, in refresh_views lm.compute_sizes_from_data(data, f) File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/kivy/uix/recyclelayout.py", line 133, in compute_sizes_from_data assert len(data) == len(opts) AssertionError
RecycleViewの削除処理を複数回にわたって行っても安定する方法を教えていただけるとありがたいです。
また、削除後に残った要素や、一度削除をした後にstartボタンでリセットを行うとチェックボックスにチェックが入ったままになることがあります。こちらの解決方法も教えていただけると助かります。
よろしくお願いします。
回答1件
あなたの回答
tips
プレビュー