別の質問にて、チャートをkivyGUI上に表示させるコードについて質問しまして、そのとき一旦はチャートが表示されたのですが、KV言語で編集しようとしても反応せず、コードを書き直しました。ですが、ModuleNotFoundError: No module named 'フォルダ名'というエラーが出てしまい、KV言語での編集はおろか、チャートも表示されなくなってしまいました。
python
1from datetime import datetime 2from logging import root 3from os import kill 4from stock_sns_project.chart_plot import ManiScreen 5from kivy.uix.floatlayout import FloatLayout 6from kivy.uix.layout import Layout 7from kivy_garden.graph import Graph, MeshLinePlot 8##https://kivy-garden.github.io/graph/flower.html ↑ 9from kivy.app import App 10from datetime import datetime 11import sys 12from numpy import right_shift, rint 13from yahoo_finance_api2 import share 14from yahoo_finance_api2.exceptions import YahooFinanceError 15from datetime import datetime 16from kivy.uix.scrollview import ScrollView 17from kivy.app import runTouchApp 18from kivy.uix.screenmanager import ScreenManager, Screen 19from kivy.core.window import Window 20from kivy.base import runTouchApp 21from kivy.uix.label import Label 22from kivy.uix.boxlayout import BoxLayout 23 24class Chart_plot(BoxLayout): 25 def __init__(self, **kwargs): 26 super(FloatLayout, self).__init__(**kwargs) 27 pass 28 29 def chart(self): 30 31 #データを読み込んで分割する 32 my_share = share.Share('MSFT') 33 symbol_data = None 34 try: 35 symbol_data = my_share.get_historical(share.PERIOD_TYPE_DAY, 36 60, 37 share.FREQUENCY_TYPE_MINUTE, 38 5) 39 except YahooFinanceError as e: 40 print(e.message) 41 sys.exit(1) 42 43 #data = symbol_data['timestamp'] 44 #new_data = [datetime.utcfromtimestamp(int(data[i]/1000)) for i in range(len(data))] 45 prices = symbol_data['close'] 46 price = prices[:2000] 47 max_price = max(price) 48 min_price = min(price) 49 #print(min_price) 50 51 #プロットする 52 graph = Graph(xlabel='datetime', ylabel='price', x_ticks_minor=5, 53 x_ticks_major=25, y_ticks_major=10, 54 y_grid_label=False, x_grid_label=False, padding=5, 55 x_grid=True, y_grid=True, xmin=0, xmax= 2000, ymin = min_price - 5, ymax = max_price + 5) 56 57 plot = MeshLinePlot(color=[1, 0, 0, 1]) 58 plot.points = [(i, price[i]) for i in range(0, 2000)] 59 graph.add_plot(plot) 60 graph.width = 2000 61 62 graph.size_hint_x = None 63 return graph 64 65 66 def scroll_chart(self): 67 root = ScrollView(FloatLayout) 68 root.add_widget(Chart_plot.chart.build()) 69 70 runTouchApp(root) 71 72 73class ChartMainScreen(BoxLayout): 74 pass 75 76class ChartMainApp(App): 77 def build(self): 78 return ChartMainScreen() 79 80if __name__ == '__main__': 81 ChartMainApp().run()
kivy
1#:kivy 2.0.0 2 3#:import MeshLinePlot 4<ChartMain>: 5 BoxLayout: 6 orientation: 'vertical' 7 size_hint_y: 0.2 8 text: 'MSFT Chart' 9 10 Chart_plot: 11 id: graph_test 12 plot: MeshLinePlot 13 14 15 BoxLayout: 16 orientation: 'vertical' 17 18<Chart_plot>:
https://chaika.hatenablog.com/entry/2018/08/24/090000
こちらのページでファイルをインポートしてみてりしましたが、同じエラーが出てしまいます。
解決策わかる方、どうかよろしくお願いします。
コード全体が滅茶苦茶だとのこと(;;)質問者からの依頼により、Buttonなどを並べたシンプルなコード載せます
python
1from kivy.config import Config 2Config.set('graphics', 'width', '640') 3Config.set('graphics', 'height', '480') 4 5from kivy.uix.textinput import TextInput 6from kivy.app import App 7from kivy.uix.widget import Widget 8from kivy.uix.label import Label 9from kivy.properties import StringProperty 10 11from kivy.core.text import LabelBase, DEFAULT_FONT 12from kivy.resources import resource_add_path 13 14resource_add_path("font") 15LabelBase.register(DEFAULT_FONT, "NotoSansJP-Regular.otf") 16#LabelBase.register(DEFAULT_FONT, "Exo2-Regular.ttf") 17 18from random import randint 19 20#--------------------------------------- 21 22class ImageWidget(Widget): 23 def __init__(self, **kwargs): 24 super(ImageWidget, self).__init__(**kwargs) 25 pass 26 27 def login_ID(self): 28 pass 29 30 def login_PW(self): 31 pass 32 33 def login_button(self): 34 pass 35 36class login_logonApp(App): 37 def __init__(self, **kawargs): 38 super(login_logonApp, self).__init__(**kawargs) 39 self.title = 'LoginLogon' 40 41if __name__ == '__main__': 42 login_logonApp().run() 43
kivy
1#:kivy 2.0.0 2 3ImageWidget: 4 5<ImageWidget>: 6 7 canvas.before: 8 Color: 9 rgba: 1, 1, 1, 1 10 Rectangle: 11 pos: self.pos 12 size: self.size 13 14 BoxLayout: 15 orientation: 'vertical' 16 size: root.size 17 18 Label: 19 id: title_login 20 font_size: 50 21 text: 'VERBIN' 22 color: .100, .100, .100, .50 23 font_name: "Exo2-Regular.ttf" 24 25 BoxLayout: 26 orientation: 'vertical' 27 padding: 50, 20, 50, 30 28 29 Label: 30 id: user_id_label 31 font_size: 35 32 text: 'ID' 33 color: .3, .3, .3, .85 34 text_size: self.size 35 halign: 'left' 36 font_name: "Exo2-Regular.ttf" 37 38 TextInput: 39 id: user_id_input 40 font_size: 12 41 color: 0.6, 0.6, 0.6, 0.6 42 background_color: .2, .2, .35, .100 43 44 BoxLayout: 45 orientation: 'vertical' 46 padding: 50, 0, 50, 22 47 Label: 48 id: user_PW_label 49 font_size: 35 50 text: 'PassWord' 51 color: .3, .3, .3, .85 52 text_size: self.size 53 halign: 'left' 54 font_name: "Exo2-Regular.ttf" 55 56 TextInput: 57 id: user_PW_input 58 font_size: 12 59 color: .40, .40, .40, .40 60 background_color: .2, .2, .35, .100 61 62 Button: 63 text: '会員登録がまだの方' 64 font_size: 10 65 background_normal: '' 66 color: .1, .3, .30, .40 67 68 Button: 69 text: 'LOGIN' 70 background_normal: '' 71 background_color: 1, .3, .4, .85 72 font_size: 50 73 font_name: "Exo2-Regular.ttf" 74 75
widgetを縦に並べただけのコード
今書いてみましたが、うまく動作しませんでした。
python
1from kivy.app import App 2from kivy.uix.boxlayout import BoxLayout 3from kivy.uix.label import Label 4 5class Screen(BoxLayout): 6 pass 7 8class chart2App(App): 9 pass 10 11chart2App().run()
kivy
1 2 3 4#:kivy 2.0.0 5Screen: 6 7 8<Screen>: 9 orientation: 'vertical' 10 size: root.size 11 Label: 12 text: 'おはよう' 13 14 Button: 15 text: 'konnnitiha' 16 17 Button: 18 text: 'Hello, Python'
別の質問の方でも書きましたが、kivyだけを使ったprogramを書くことから始めてそれができてから徐々に他のlibraryを組み込んでいってください。code全体がもうメチャクチャなので。
例えばLabelとButtonを縦に並べて表示するだけのprogramを作れますか?
作りました。。
これはネットで拾った動きそうなcodeを貼り付けただけですよね?私が言ったことを行うだけの最小限のcodeを自分で書けますか?
違います!自分で書きました。。。
これ書くのにもまる一日かかりましたけど、、、
それじゃあ訊きますけど
質問のcodeでは runTouchApp(root) を呼んでいるのに こっちでは呼んでいないのは何故ですか?
loginのほうはlogin_logonApp(App)を呼び出して走らせるためにlogin_logonApp().run()と記述して、
質問のほうはスクロールさせるためにrunTouchApp()を呼び出しているのではないですか?
スクロールもよくわからなくて、、、このコードとは違うんですけど、グラフのクラスと別にクラスを用意して、関数の中に
root = ScrollView()
root.add_widget(graph_plotApp.build())
#graph_plotApp().run()
runTouchApp(root)
と記述すると動かなくて、クラスの中に直接書くと動くんです。。
決まりがよくわかってません
> 質問のほうはスクロールさせるためにrunTouchApp()を呼び出しているのではないですか?
違います。Kivyというか多分GUI全般なんですが、GUI programにはevent loopという物が要ります。これをGUIを正常に動かすのに必要な心臓のような物だと思ってください。program開始時に心臓を動かし始め、ユーザーが閉じるボタンを押すなどして終了の合図が来たら心臓も止める、みたいな感じです。Kivyにおいてこの心臓を動かす役割を担っているのが runTouchApp() と App().run()です。この心臓なんですが(少なくともKivyにおいては)一度しか動かしてはいけないので、質問のcodeのように一つのprogram内に両方の関数が現れる事は基本無いですし、片方を複数回呼び出すなんてこともあってはいけないです。
ここで「どっちの関数を使えばいいの?」と思ったかもしれないですが、runTouchApp()は内部用のものなのでApp().run()を使うようにしてください。runTouchApp()を使うと幾つかの機能が使えなかったりもするので。
> クラスの中に直接書くと動くんです
これはpython言語自体の話になりますが、class直下に書いた物はそのclassのcodeが読み込まれる際に実行されるので
class MyClass:
print('A')
のprint('A')は実行されるタイミングだけでいうならclassの外に
print('A')
と書くのとなんら変わらないです。関数の中に書いた時にだけ動かないのなら、その関数がそもそも呼ばれていない可能性を疑ってください。そしてclass直下でwidgetの作るのは一般的なやり方じゃないのでやめたほうが良いです。
python文法からKivyの使い方まで分からない事は多いと思いますが、だからといって分からない物を一気にprogram内に組み込むようなことはせず、分からない部分を一つ試すだけの最小限のcodeを別に書いて各個撃破していってください。とりあえずLabelとButtonを縦に並べて表示するだけの"最小限"のprogramを書いてみてくれませんか?widgetが三個あればできると思いますが。
試しに書いてみましたが「Hello,Python」ボタンしか表示されませんでした(;;)
Kivyには元々Screenという名前のwidgetがあってそれと自作のScreenの名前が被っているのが原因なので、名前を別の何か(例えばMyWidget)に変えてみてください。
質問のcodeなんですけど
root = ScrollView(FloatLayout)
root.add_widget(Chart_plot.chart.build())
の部分って何を参考にして書きましたか
class Chart_plot(BoxLayout):
def __init__(self, **kwargs):
super(FloatLayout, self).__init__(**kwargs)
pass
super()の引数は正しくは
class Chart_plot(BoxLayout):
def __init__(self, **kwargs):
super(Chart_plot, self).__init__(**kwargs)
pass
ですね。もしpython3系を使っているなら引数無しでもいけます
class Chart_plot(BoxLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
pass
動きました。壊れたのかと思いました。。
kivyのリファレンスです。
https://kivy.org/doc/stable/api-kivy.uix.scrollview.html
何処にもそういった使い方は見当たらないです。
> 動きました。壊れたのかと思いました。。
良かったです (^_^)
本題の`ModuleNotFoundError: No module named 'フォルダ名'`何ですが、importに関するerrorなのでcode内のimport文を省略せずに載せてください。
root = ScrollView(size_hint=(1, None), size=(Window.width, Window.height))
root.add_widget(layout)
runTouchApp(root)
のところです、、ScrollViewのところFloatLayout書いたらだめですよね。。
更新しました。
> ScrollViewのところFloatLayout書いたらだめですよね。
widgetに別のwidgetを加える時は
widget.add_widget(別のwidget)
としないといけないですし、加えるのはclassじゃなくてinstanceじゃないといけないです。
( FloatLayout じゃなくて FloatLayout() )
ただScrollViewは子widgetを一つしか持てないので二回目のadd_widget()を呼んだ時にerrorが起こるのに変わりはないです。
importのerror何ですけどcodeを見ただけだとちょっと分からないですね。私ならprojectのあるdirectoryやlibraryの置いてあるdirectory内のテキストファイルの中身を'フォルダ名'で検索してみるかもです。
後、「ネットで拾った動きそうなcodeを貼り付けただけ」とか言ってごめんなさい
scroll_chart.add_widget(Chart_plot.chart())のChart_plot.chart()は中身はgraphですよね、分けないでchart()の中で、
scroll_chart = ScrollView(size_hint=(1, None),size=(Window.width, Window.height))
scroll_chart.add_widget(graph)にするということでしょうか。
いやいや!丁寧に教えていただきありがとうございます。。(;;)
> 分けないで...にするということでしょうか
その方が良いですね。あとchart()関数には@classmethod付けたほうが良いのと、kvファイルの名前がchartmain.kvになってるかも確めてみてください。
フォルダ名を使ったimport文を消して、(よくわからないインポートをしていた)レイアウト用に新しくクラスを作ってみたら、チャートはまだ表示されませんが、KVファイルでの編集ができるようになりました。
回答2件
あなたの回答
tips
プレビュー