🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Kivy

Kivyは、Pythonを用いたNUI開発のためのオープンソースフレームワーク。マルチタッチなど多くの入力に対応したNUIアプリなどを開発することができます。多くの環境で動作するクロスプラットフォームです。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

Q&A

解決済

1回答

1771閲覧

Kivyによる画面切り替えを行たいが画面が真っ暗になる問題を解決したい

kawataku

総合スコア3

Kivy

Kivyは、Pythonを用いたNUI開発のためのオープンソースフレームワーク。マルチタッチなど多くの入力に対応したNUIアプリなどを開発することができます。多くの環境で動作するクロスプラットフォームです。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

0グッド

0クリップ

投稿2021/02/20 02:26

前提・実現したいこと

pythonとkivyを使って、株価の予測のGUIアプリを作っております。
複数画面を作成して、ActionBarでの切り替えができるようにしたいです。
現在は、実行しても真っ暗になってしまいます。

また、今回は便宜上、会社名はAとBという名前にしております。
データの取得はgraph01〜graph03、予測結果の取得はFile01〜File03で行っております。

また、app.rooot.root.の違いがわからないので、教えていただけるとありがたいです。

該当のソースコード

python

1import japanize_kivy 2import pandas_datareader.data as web 3import numpy as np 4import matplotlib.pyplot as plt 5import datetime 6import talib 7import mplfinance as mpf 8import time 9import pandas as pd 10import tensorflow as tf 11import schedule 12import traceback 13import sys 14from sklearn import preprocessing 15from StockApp import * 16from matplotlib import gridspec 17from kivy.app import App 18from kivy.config import Config 19from kivy.uix.widget import Widget 20from kivy.uix.boxlayout import BoxLayout 21from kivy.properties import * 22from kivy.resources import resource_add_path 23from kivy.core.text import LabelBase, DEFAULT_FONT 24from kivy.uix.screenmanager import ScreenManager, Screen 25from kivy.garden.matplotlib.backend_kivyagg import FigureCanvasKivyAgg 26from kivy.graphics import * 27from kivy.factory import Factory 28 29# マルチタッチを無効化する => 右クリックしても赤い点が残らない 30Config.set('input', 'mouse', 'mouse, disable_multitouch') 31Config.set('modules', 'inspector', '') 32 33Name = ['A', 'B'] 34 35# csvファイルを読み込む 36Hello01 = pd.read_csv('graph01.csv') 37Hello02 = pd.read_csv('graph02.csv') 38Hello03 = pd.read_csv('graph03.csv') 39 40Hello01['Date'] = pd.to_datetime(Hello01['Date']) 41Hello02['Date'] = pd.to_datetime(Hello02['Date']) 42Hello03['Date'] = pd.to_datetime(Hello03['Date']) 43 44# DataFrameの状態では、インデックス番号で指定できないからnp.arrayで配列に変換する 45A_Hello = np.array(Hello01).T 46B_Hello = np.array(Hello02).T 47C_Hello = np.array(Hello03).T 48 49class FirstPage(BoxLayout): 50 text = StringProperty() # プロパティの追加 51 graph = NumericProperty(0) 52 def __init__(self, *args, **kwargs): 53 super().__init__(*args, **kwargs) 54 self.text = ' ' 55 56 # リストに入れる 57 self.d_list = [] 58 self.w_list = [] 59 self.m_list = [] 60 61 self.numbers = 0 62 with open('File01.txt', 'r', encoding='utf-8') as day: 63 self.day = day.readlines() 64 with open('File02.txt', 'r', encoding='utf-8') as week: 65 self.week = week.readlines() 66 with open('File03.txt', 'r', encoding='utf-8') as month: 67 self.month = month.readlines() 68 69 # ActionBarの次へボタンを押したら次の会社に行くようにする処理 70 def Next(self, index_num): 71 if 0 <= index_num < len(Name) - 1: 72 self.numbers = index_num 73 74 self.text = self.day[self.numbers] 75 76 # 月のグラフの表示を更新する処理 77 def update01(self): 78 self.text = self.month[self.numbers] 79 80 # 週のグラフの表示を更新する処理 81 def update02(self): 82 self.text = self.week[self.numbers] 83 84 # 日の表示を更新する処理 85 def update03(self): 86 self.text = self.day[self.numbers] 87 88 89class GraphView(BoxLayout): 90 def __init__(self, *args, **kwargs): 91 super().__init__(*args, **kwargs) 92 # データをrootウィジェットの方に呼び出すようにする => このクラスがインスタンス化された時に1番最初に呼び出される 93 self.A_Hello = A_Hello 94 self.B_Hello = B_Hello 95 self.C_Hello = C_Hello 96 97 self.d_data = Hello01 98 self.w_data = Hello02 99 self.m_data = Hello03 100 101 self.num = 0 102 103 104 # figとaxだけで表す必要あり 105 self.fig, self.ax = plt.subplots(2, 1, 106 gridspec_kw={ 107 'height_ratios':[4,1] 108 }) 109 110 self.Update(self.A_Hello[self.num+1], self.d_data[Name[self.num]], Hello['Date']) 111 112 self.add_widget(FigureCanvasKivyAgg(self.fig)) 113 114 115 def Update(self, data, signal, times): 116 # 前にプロットされたグラフを消去する 117 self.ax[0].clear() 118 self.ax[1].clear() 119 120 period = 30 121 upper, middle, lower = talib.BBANDS(signal, timeperiod=period, nbdevup=1, nbdevdn=1, matype=0) # 引数としてHelloを取得するからselfをつける必要はない 122 123 rsi = talib.RSI(signal, timeperiod=period) 124 125 # 取得したデータを元にプロットする 126 self.ax[0].plot(times, data) 127 self.ax[0].set_ylabel('price', fontsize=15) 128 self.ax[0].plot(times, upper) 129 self.ax[0].plot(times, lower) 130 self.ax[0].legend([Name[self.num]]) 131 self.ax[0].tick_params(labelsize=10) 132 133 self.ax[1].plot(times, rsi) 134 self.ax[1].set_xlabel('time', fontsize=20) 135 self.ax[1].set_ylabel('persentage', fontsize=15) 136 self.ax[1].legend(['RSI']) 137 self.ax[1].tick_params(labelsize=10) 138 139 # 再描画する 140 self.fig.canvas.draw() 141 self.fig.canvas.flush_events() 142 time.sleep(0.1) # 0.1秒だけ開ける 143 144 145 146 # ActionBarの次へボタンを押したら次に行くようにする処理 147 def Next(self, index_num): 148 if 0 <= index_num < len(Name) - 1: 149 self.num = index_num 150 151 A_Hello = self.A_Hello[self.num+1] 152 data = self.d_data[Name[self.num]] 153 154 self.Update(A_Hello, data, Hello['Date']) 155 156 157 # 月のグラフの表示を更新する処理 158 def update01(self): 159 C_Hello = self.C_Hello[self.num+1] 160 m_data = self.m_data[Name[self.num]] 161 162 self.Update(C_Hello, m_data, Hello03['Date']) # 上で変更された変数を元にしてメソッドが実行される 163 164 165 # 週のグラフの表示を更新する処理 166 def update02(self): 167 B_Hello = self.B_Hello[self.num+1] 168 w_data = self.w_data[Name[self.num]] 169 170 self.Update(B_Hello, w_data, Hello02['Date']) 171 172 # 日毎の表示を更新する処理 173 def update03(self): 174 A_Hello = self.A_Hello[self.num+1] 175 d_data = self.d_data[Name[self.num]] 176 177 self.Update(A_Hello, d_data, Hello['Date']) 178 179class TextWidget(Widget): 180 sm = ScreenManager() 181 print(Name[0]) 182 def __init__(self, *args, **kwargs): 183 super().__init__(*args, **kwargs) 184 185 def change_page(self): 186 self.clear_widgets() 187 self.add_widget(FirstPage()) 188 189 def change_page2(self): 190 self.clear_widgets() 191 page2 = Factory.SecondPage() 192 self.add_widget(page2) 193 194class CopyHelloApp(App): 195 def __init__(self, **kwargs): 196 super().__init__(**kwargs) 197 self.title = 'HelloWold' # ウィンドウの名前を変更する 198 199 def build(self): 200 return TextWidget() 201 202if __name__ == '__main__': 203 CopyHelloApp().run()

kivy

1#:kivy 2.0.0 2 3# TextWidget rootウィジェットに指定されている 4TextWidget: 5 6<TextWidget>: 7 FirstPage: 8 id: page1 9 10<page1>: 11 orientation: 'vertical' 12 size: root.size # BoxLayoutのサイズ rootウィジェット(TextWidget)の大きさに合わせる 13 14 # メニューバー 15 ActionBar: 16 17 ActionView: 18 ActionPrevious: 19 title: 'ページタイトル1' 20 with_previous: False # 戻るボタンを表示する 21 22 ActionButton: 23 text: '次のページ' 24 on_release: app.root.change_page2() 25 26 ActionGroup: 27 text: 'グループ名' 28 mode: 'spinner' 29 ActionButton: 30 text: 'A' 31 on_release: app.root.ids['graph_view'].Next(0) 32 on_release: app.root.ids['page1'].Next(0) 33 on_release: name.text = 'A' 34 ActionButton: 35 text: "B" 36 on_release: app.root.ids['graph_view'].Next(1) 37 on_release: app.root.ids['page1'].Next(1) 38 on_release: name.text = 'B' 39 40 41 BoxLayout: 42 orientation: 'horizontal' 43 size_hint_y: 0.1 44 45 Label: 46 id: name 47 text: 'A' 48 49 Label: 50 id: show 51 text: app.root.ids['page1'].text 52 53 54 # グラフをここで表示する 55 GraphView: 56 size_hint_y: 0.9 57 id: graph_view 58 59 GridLayout: 60 cols: 3 61 rows: 1 62 size_hint_y: 0.1 63 Button: 64 id: button11 65 text: '月' 66 font_size: 48 67 on_release: app.root.ids['graph_view'].update01() 68 on_release: app.root.ids['page1'].update01() 69 70 Button: 71 id: button12 72 text: '週' 73 font_size: 48 74 on_release: app.root.ids['graph_view'].update02() 75 on_release: app.root.ids['page1'].update02() 76 77 Button: 78 id: button13 79 text: '日' 80 font_size: 48 81 on_release: app.root.ids['graph_view'].update03() 82 on_release: app.root.ids['page1'].update03() 83 84<GraphView>: 85 86 87<SecondPage@BoxLayout>: 88 id: page2 89 size: root.size 90 orientation: 'horizontal' 91 92 # 画面の切り替えを行う 93 ActionBar: 94 95 ActionView: 96 ActionPrevious: 97 title: 'ページタイトル2' 98 with_previous: False # 戻るボタンを表示する 99 100 ActionButton: 101 text: '前のページ' 102 on_release: app.root.change_page() 103 104 MyLabel: 105 id: first_button 106 text: 'Hello' 107 108 MyLabel: 109 id: second_button 110 text: 'World' 111 112<MyLabel@Label>: 113 font_size: 60 114 size_hint_y: 1 115''' 116 117

試したこと

pythonファイル側でclass SecondPage(BoxLayout):として2ページ目のクラス定義を行い、kivyファイル側で、<TextWidget>内の記述を消し、<page1>から<FirstPage>に変更してみましたが、真っ暗なままでした。
ページ数が1枚だけの場合は、上手くいきましたが、2枚に増やした途端にエラーになりました。

補足情報(FW/ツールのバージョンなど)

Python v3.7.7
kivy v2.0.0
Visual Studio Code v1.53.2
MacOS Darwin x64 20.3.0

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

[変更点]
・rootウィジェットである、TextWidgetの親クラスをBoxLayoutに変更。
・カスタムウィジェットである<page1>の部分を<FirstPage>に変更。
・Labelのtextをapp.root.ids['page1'].textからroot.textに変更
・TextWidgetクラス内で、__init__メソッドを追加し、self.page1=Factory.FirstPage()self.page2=Factory.SecondPage()を記述。
・rootウィジェット内にidを置いたウィジェット(今回ではFirstPage)のメソッドにアクセスする際に、app.root.ids['ID名'].メソッド名を使用する
・rootウィジェットのメソッドにアクセスする際に、root.メソッド名を使用する。
・rootウィジェットの下のウィジェットのメソッドにアクセスする際に、root.ids.ID名.メソッド名を使用する。

[わかった点]
・textやsizeなどイベントでは無い部分に対して、app.rootは使わない。root.sizeroot.textという記述をする。
・TextWidgetクラスの初期化部分で、self.ページ名を記述しておくと、別のページに移動しても元の画面の情報が失われない。

これで解決しました。

投稿2021/02/20 06:59

kawataku

総合スコア3

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問