質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
Kivy

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

2146閲覧

kvファイル上の2クラス間におけるScreenManagerを使っての画面遷移

penpal

総合スコア13

Kivy

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2018/11/26 15:27

編集2018/11/26 16:06

前提・実現したいこと

ScreenManagerを使って画面遷移のサンプルを作成する。

◆ここに質問の内容を詳しく書いてください。

kvファイル上の2クラス間の画面遷移方法を教えて頂けますでしょうか。
正直ほぼAPIのサンプル通りに書いているのに、なぜ動かないのかわかりません。。。
こんな初歩的な所で躓いており、お恥ずかしい限りですが、宜しくお願い致します。

該当のソースコード

python

1【ScreenManager.py】 2 3from kivy.app import App 4from kivy.uix.screenmanager import ScreenManager, Screen 5 6class MenuScreen(Screen): 7 pass 8 9class SettingsScreen(Screen): 10 pass 11 12sm = ScreenManager() 13sm.add_widget(MenuScreen(name='menu')) 14sm.add_widget(SettingsScreen(name='settings')) 15 16class ScreenApp(App): 17 def build(self): 18 return sm 19 20if __name__ == "__main__": 21 ScreenApp().run() 22 23 24【screen.kv】 25 26<MenuScreen>: 27 BoxLayout: 28 Button: 29 text: 'Goto settings' 30 on_press: root.manager.current = 'settings' 31 Button: 32 text: 'Quit' 33 34<SettingsScreen>: 35 BoxLayout: 36 Button: 37 text: 'My settings button' 38 Button: 39 text: 'Back to menu' 40 on_press: root.manager.current = 'menu' 41

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

Python 3.7
Kivy 1.10.1

追記

事象に対する対処法は見つかりましたが、
原因は分かっておりません。。。

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

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

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

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

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

guest

回答2

0

ベストアンサー

widgetにKv言語で書かれた物を反映させるには、widgetのinstanceを作る前にKv言語のコードを読み込ませないといけないです。TestAppクラスが自身の名前を元にtest.kvを読みに行くのはTestApp().run()の中(この部分)なので、TestApp().run()を呼ぶ前に作ったMenuScreenSettingsScreenのinstanceはKv言語で書かれた定義が無い状態になりますね。

なので最初の失敗例を正しく動作させるにはMenuScreenSettingsScreenのinstanceを作る前に以下のように明示的にKv言語のコードを読み込めばいいです。

python

1from kivy.lang import Builder 2 3Builder.load_file('test.kv') 4sm = ScreenManager() 5sm.add_widget(MenuScreen(name='menu')) 6sm.add_widget(SettingsScreen(name='settings'))

(このやり方の場合、test.kvは別の名前に変えたほうがいいかもしれないです。)

投稿2018/11/30 09:51

編集2018/11/30 10:00
gottadiveintopy

総合スコア736

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

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

penpal

2018/12/01 05:03 編集

丁寧にご教示頂きありがとうございます。大変勉強になりました。 おっしゃる通りScreenManagerクラスのinstanceを作成する前にBuilder.load_fileでkvファイルを読み込むと正常に動作しました。 事前に読み込みを行ってから、ScreenManagerクラスのinstanceにScreenを追加してないと、app.run()の中でWindow.add_widget(self.root)を呼ぶ際に、 引数のrootのchildrenにいるname = "menu"に紐づくScreenに、kvファイルで定義したBoxLayoutクラスのinsutanceが入ってない状態になるんですね。
gottadiveintopy

2018/12/02 13:46

"Window.add_widget(self.root)を呼ぶ際" ではなくて widgetのinstanceを作る時 ですね。
guest

0

自己解決しました。

ScreenManagerのインスタンス化をScreenAppのbuild内で行う必要があったみたいです。

python

1◆誤り 2sm = ScreenManager() 3sm.add_widget(MenuScreen(name='menu')) 4sm.add_widget(SettingsScreen(name='settings')) 5 6class ScreenApp(App): 7 def build(self): 8 return sm 9

python

1◆正しい 2class ScreenApp(App): 3 def build(self): 4 sm = ScreenManager() 5 sm.add_widget(MenuScreen(name='menu')) 6 sm.add_widget(SettingsScreen(name='settings')) 7 return sm

ちなみに、API Referenceの公式サンプルは以下のようになっております。
pyファイルとkvファイルに分割すると、ScreenManagerをbuild内で
インスタンス化する必要が出てくる原因はよくわかりません。。。

どなたか、原因が分かる方はいらっしゃいますでしょうか。

python

1from kivy.app import App 2from kivy.lang import Builder 3from kivy.uix.screenmanager import ScreenManager, Screen 4 5# Create both screens. Please note the root.manager.current: this is how 6# you can control the ScreenManager from kv. Each screen has by default a 7# property manager that gives you the instance of the ScreenManager used. 8Builder.load_string(""" 9<MenuScreen>: 10 BoxLayout: 11 Button: 12 text: 'Goto settings' 13 on_press: root.manager.current = 'settings' 14 Button: 15 text: 'Quit' 16 17<SettingsScreen>: 18 BoxLayout: 19 Button: 20 text: 'My settings button' 21 Button: 22 text: 'Back to menu' 23 on_press: root.manager.current = 'menu' 24""") 25 26# Declare both screens 27class MenuScreen(Screen): 28 pass 29 30class SettingsScreen(Screen): 31 pass 32 33# Create the screen manager 34sm = ScreenManager() 35sm.add_widget(MenuScreen(name='menu')) 36sm.add_widget(SettingsScreen(name='settings')) 37 38class TestApp(App): 39 40 def build(self): 41 return sm 42 43if __name__ == '__main__': 44 TestApp().run()

投稿2018/11/26 16:04

penpal

総合スコア13

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問