KivyMD + kivy + python を使って次のプログラムのsecond_screenに遷った際にのとくていIDのMDBoxLayout内に条件に応じてボタンを追加したり削除したいのですが、うまくいきません。
簡単なプログラムの流れは次です。
1.main_screen から go_second_screen ボタンを押す
2.second_screenに移行する際、on_enter()が実行されてsystem_statusでボタンを追加するかが決められる
3.必要であればsecond_screenの特定IDのMDBoxLayoutにボタンが追加表示される
まず最初に単純に .add_widgetだけをadd_button()メソッドで使います。そうすると、一応ボタンは表示されますが width=と pos=のパラメータが無視され、ボタンが画面最下位に左に最小サイズで表示され意図したデザインで表示されません。下に余分なコードを抜いて単純化したコードをこの話をベース書きました。
2番めの問題としては、add_widgetだけですと、second_screenにアクセスするたびに条件が合えば同じボタンが増えていってしまうので、画面がmain_screenに移るときに追加したボタンを削除します。 remove_widgetを使います。widget関数をクラス内関数に場所をかえて、widgetはすべてself.widgetに書き換えます。ここではテストとしてon_cancel()に削除機能を書きました。すると次のエラーでプログラム起動時に即クラッシュします。
何が悪いのかわからず、行き詰まっています。よろしくお願いします。
remove_widgetを加えたときにでるエラーが下です
remove_widget widget.funbind('pos_hint', self._trigger_layout) AttributeError: 'NoneType' object has no attribute 'funbind'
該当のソースコード
Python
1############ MainScreen class ################ 2 3# go_second_screen button exist 4 5########### SecondScreen class ############### 6 7class SecondScreen(Screen): 8 def __init__(self, **kwargs): 9 super(SecondScreen, self).__init__(**kwargs) 10 Clock.schedule_once(self.on_start,1) 11 12 # this is for 2nd problem 13 #widget = None 14 15 def on_start(self, *args): 16 #do some stuff 17 18 def on_enter(self): 19 Clock.schedule_once(self.system_status_check) 20 self.system_status() 21 22 def system_status(self): 23 #get condition from other class 24 if SystemControl.system_flag() == True: 25 self.add_button() 26 27 def add_button(self): 28 #this kind of works but not intended way (2nd issue rewrited everything with self.widget) 29 widget = MDRaisedButton( 30 text="Extra function button", 31 md_bg_color=(0.3, 1, 1, 0.5), 32 font_size = "20sp", 33 width = self.ids.dialog.width, 34 pos = (self.ids.dialog.x, self.ids.dialog.top + self.height) 35 ) 36 self.ids.add_button_box.add_widget(widget) 37 38 def on_cancel(self): 39 #これが2番めの問題 40 #widgetをクラスの変数にして 全部のwidgetをself.widgetに書き換えた前提です 41 self.ids.add_button_box.remove_widget(self.widget) 42 43 def on_save(self): 44 #ここでなんかする 45 46################ second_screen.kv##################### 47 48<SecondScreen>: 49 id:second_screen 50 name:'second_screen' 51. 52#some sliders and informations 53. 54 #New button should be added just below in the box layout 55 MDBoxLayout: 56 id: add_button_box 57 orientation: "vertical" 58 59 MDBoxLayout: 60 id:dialog 61 orientation: "horizontal" 62 63 MDRaisedButton: 64 id:save_button 65 text:"Save and Exit" 66 width:dialog.width/2 67 md_bg_color: 1, 0, 1, 1 68 on_release: 69 root.on_save() 70 app.root.current = 'main_screen' 71 72 MDRaisedButton: 73 text:"Cancel" 74 width:dialog.width/2 75 on_release: 76 root.on_cancel() 77 app.root.current = 'main_screen' 78 79######### MainSM class ############## 80 81Builder.load_file("./kv/main_screen.kv") 82Builder.load_file("./kv/second_screen.kv") 83. 84. 85#multiple screens 86 87class MainSM(ScreenManager): 88 pass 89 90############## main.kv ############### 91 92<MainSM>: 93 id: screen_manager 94 transition: NoTransition() 95 Main_Screen: 96 Second_Screen: 97 . 98 . 99 100########## MainApp class ############# 101 102class MainApp(MDApp): 103 104 def build(self): 105 106 return MainSM() 107 108MainApp().run() 109 110######################################
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。