###やりたいこと(修正後)
複数のエクセルファイルがあり、どれもA列に番号、B列にリストがあります。
Spinnerでエクセルを読み込んだ後、もう1つのSpinnerでリストを選択したいのですが、リストを更新しても、2つめのSpinnerに反映されません。
refresh()やその他いろいろ調べましたが、分かりませんでした。
以下がpyファイルのコードです。
python
1from kivy.app import App 2from kivy.uix.screenmanager import ScreenManager, Screen 3from kivy.uix.boxlayout import BoxLayout 4from kivy.uix.gridlayout import GridLayout 5from kivy.uix.button import Button 6from kivy.uix.label import Label 7from kivy.uix.spinner import Spinner 8from kivy.properties import StringProperty 9import japanize_kivy 10 11#エクセルファイル名 12file = ["a","b","c"] 13report = [] 14#reportの内容 15a = ["営業","経営","人事","福利"] 16b = ["社会","公民","歴史"] 17c = ["政治","経済","司法"] 18 19###################################################################### 20class CustomSpinner(Spinner): 21 text = StringProperty() 22 values = file 23 pass 24 25class CustomSpinner2(Spinner): 26 text = StringProperty() 27 values = report 28 pass 29 30class MainScreen(Screen): 31 text = StringProperty() 32 pass 33 34 #####エクセルファイル選択時の動作##### 35 def on_spinner_change(self , text ): 36 global report 37 self.report = text 38 report = eval(self.report) 39 return report 40 41 42class Manager(ScreenManager): 43 def __init__(self): 44 super(Manager, self).__init__() 45 screen = Screen(name = 'Screen 1') 46 screen.add_widget(MainScreen(name='Screen 1')) 47 self.add_widget(screen) 48 base=Base('main') 49 self.add_widget(base) 50 51class Nav(GridLayout): 52 def __init__(self,sm=None): 53 super(Nav, self).__init__() 54 self.sm = sm 55 self.cols =4 56 self.size_hint = (1,0.05) 57 58class Base(Screen): 59 def __init__(self,name): 60 super(Base, self).__init__() 61 62class Root(BoxLayout): 63 def __init__(self): 64 super(Root, self).__init__() 65 66 self.orientation = "vertical" 67 sm = Manager() 68 self.sm = sm # keep a reference for later use 69 self.add_widget(Nav(sm=sm)) 70 self.add_widget(sm) 71 72 73class ScreenteiApp(App): 74 def build(App): 75 return Root() 76 77if __name__ == '__main__': 78 ScreenteiApp().run()
kvファイルです
kv
1#Filename = screentei.kv 2<MainScreen>: 3 BoxLayout: 4 orientation: 'vertical' 5 size: root.size 6 7 BoxLayout: 8 size_hint_y: 0.05 9 BoxLayout: 10 size_hint_y: 0.08 11 CustomSpinner: 12 id:csp1 13 size_hint: 0.3 , 1 14 pos_hint: {'center_x': .5, 'center_y': .5} 15 on_text: root.on_spinner_change(self.text) 16 17 Label: 18 id: label1 19 text: 'ファイルを選択' 20 size_hint: 0.3 , 0.8 21 pos_hint: {'center_x': .3, 'center_y': .5} 22 font_size: 12 23 text: "←エクセルファイルを選択" 24 Widget: 25 size_hint_x: 0.5 26 27 BoxLayout: 28 size_hint_y: 0.05 29 30 BoxLayout: 31 size_hint_y: 0.08 32 Widget: 33 size_hint: 0.05 , 1 34 35 CustomSpinner2: 36 id:csp2 37 text: '選択' 38 size_hint: 0.5 , 1 39 on_text: root.on_spinner_change2(self.text) 40 41 Widget: 42 43 BoxLayout: 44 size_hint_y: 0.7 45 46 Label: 47 id: label3 48 font_size: 14 49 text: "使い方\n こちらを参照 \n ①エクセルファイルを選びます。" 50 text_size: self.size 51 halign: 'left' 52 valign: 'middle' 53
コードは以上です。
すいませんが、よろしくお願いします。
起こっている不具合を再現するための最小限のコードを載せてください。
再現するのにこれだけのwidgetは要らないはずですし、excelファイルの読み込みもkivyとは関係無いので要らないはずです。
なるほど、いろいろ削ったのですが、そうした方がやはりよいですよね。
ありがとうございます。直しますので、しばしお待ちください。
修正しました。ボタンの画像については、解決しましたので、削除しました。
よろしくお願いします。
まずCustomSpinnerで text = StringProperty() としてますが、SpinnerはButtonを継承しているので既に text = StringProperty() を持っています。結果としてそのコードが無意味なものになっているので消して下さい。
次に values = file や values = report の部分で、Spinnerを壊してしまっています。Kivyのpropertyに値を入れる時は必ずinstance経由で行わないといけないです。
それで直らなければ以下のようにWidgetの中にSpinnerを一つだけ置いた単純な構成でSpinnerの仕組みを確かめる事から始めてみてください。
Widget:
CustomSpinner:
> refresh()やその他いろいろ調べましたが、分かりませんでした。
Spinnerにそんなmethodは見当たらないですよ、公式docを読んでますか?
https://kivy.org/doc/master/api-kivy.uix.spinner.html
gottadiveintopyさん、ご返信ありがとうございます。
プログラミング自体、初めてまだ一月ほどなので、書き方や調べ方が分からず、困っていました。
このようなコメントをいただけると、勉強の筋道が持てます。
まず、instanceの勉強をして、チャレンジしてみます。ありがとうございます。
gottadiveintopyさんの思惑通りなのかは分かりませんが、一応、形として機能しました。
コメントを見て、公式docの読み方も少しわかりました。
大変助かりました。ありがとうございました!
> プログラミング自体、初めてまだ一月ほどなので、書き方や調べ方が分からず、困っていました。
よく分からない時は公式docや参考書のやり方に沿うようにしてください。例えば今回の
class CustomSpinner(Spinner):
values = file
ですけど誰もそんなやり方でvaluesに値を入れている人は居ないでしょう?もし何らかの理由があってその書き方を選んだのならその理由も共に載せて欲しいです。じゃないと何がしたいのか分からないので。
> instance経由で行わないといけないです。
この意味なんですけど
Spinner.values = ...
がclass経由の書き込みで、Kivyのpropertyに対してこのような事をしてはいけません。対して
spinner = Spinner(...)
spinner.values = ...
がinstance経由の書き込みです。Kivyのpropertyへの書き込みは必ずこのやり方か上の公式docに載ってるやり方で行うようにしてください。
再度のアドバイスありがとうございます。
公式docに載っていることと、その他のことを合わせる書き方が、いつも分からず止まってしまいます。
instance経由の意味も、上の書き方で分かったのですが、自分のコードを書き直すときに、kvファイルの修正方法が分からず、止まってしまいます。(いろいろやったけど、失敗に…)
組み合わせの方法を、どのように学ぶか、考えてみます。ありがとうございました。
回答1件
あなたの回答
tips
プレビュー