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

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

ただいまの
回答率

91.02%

  • Python

    5519questions

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

  • MacOS(OSX)

    1635questions

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

  • Python 2.7

    1094questions

    Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

[kivy][python]kivyファイルを複数使いたい

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 331

night9071

score 7

前提・実現したいこと

今、kivyファイルを1枚で作ってます。
ScreenManagerで画面切り替えをできるようにしています。
test.kvの中身が増えてきて、ごちゃごちゃしてきたので画面の処理ごとにkvファイルを作りたいと思ってます。
サイトのソースをそのままコピーしてみましたが、エラーが発生しました。

kivyのバージョンが違うのでしょうか?

イメージ説明

サイト名:Qiita 項目:Python Kivy で外部KvファイルをIncludeして使用する

main.py(サイトのソース)
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty

class RootWidget(BoxLayout):
    button_include = ObjectProperty()  

    def print_obj(self, obj):
        print(obj)

    def check_button_include(self):
        print(self.button_include)  

class TestApp(App):
    def build(self):
        return RootWidget()

if __name__ == '__main__':
    TestApp().run()
test.kv(サイトのソース)
#:include gui/tab_test.kv 
<RootWidget>:
    button_include: tab_button_include.button_include

    TabbedPanel:
        do_default_tab: False

        TabbedPanelItem:
            text: 'Tab1'
            BoxLayout:
                Button:
                    text: 'button 1'
                    on_press: root.print_obj(self)
                Button:
                    text: 'button 2'
                    on_press: root.check_button_include()
        TabbedPanelItem:
            text: 'Tab2'
            ButtonInclude:
                id: tab_button_include
gui/tab_test.kv(サイトのソース)
<ButtonInclude@Button>:
    button_include: button_include

    id: button_include
    text: 'button include'
    on_press: app.root.print_obj(self) 
main.py(私のソース)
# -*- coding: utf-8 -*-
import kivy
kivy.require('1.7.3')
from kivy.lang import Builder
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.widget import Widget
from kivy.core.window import Window
from kivy.properties import StringProperty,ListProperty
Window.clearcolor=[0.999,0.89,0.999,1]

import csv
import codecs

import sys
from kivy.core.text import LabelBase, DEFAULT_FONT
from kivy.resources import resource_add_path

# デフォルトに使用するフォントを変更する
resource_add_path('./fonts')
LabelBase.register(DEFAULT_FONT, 'mplus-2c-regular.ttf') #日本語が使用できるように日本語フォントを指定する

class TextWidget(BoxLayout):
    text = StringProperty()
    def __init__(self, **kwargs):
        super(TextWidget, self).__init__(**kwargs)
        self.text = 'Good'
    def buttonClicked(self):
        self.text=self.ids["text_box"].text
        self.text2=self.ids["text_box2"].text
        word=[[self.text,self.text2]]
        f = codecs.open('sample.csv',"a","utf-8")
        writer = csv.writer(f)
        #writer.writerow(self.text)
        writer.writerows(word)

        f.close
    def buttonClicked2(self):
        f = codecs.open('sample.csv',"r","utf-8")
        reader = csv.reader(f)
        for row in reader:
            print(row[0] + " " + row[1])
        f.close()

    def buttonClicked_tops(self):
        pass
    def buttonClicked_bottoms(self):
        bird = Bird()
        self.add_widget(bird)
    def buttonClicked_autor(self):
        pass

class TestApp(App):
    def __init__(self, **kwargs):
        super(TestApp, self).__init__(**kwargs)
        self.title = 'Apomol'
        reload(sys)
        sys.setdefaultencoding('utf-8')
        Builder.load_file('main.kv')
    def build(self):
        return TextWidget()


if __name__ == '__main__':
    TestApp().run()
test.py
TextWidget: # ルートに追加

<TextWidget>:
    orientation: 'vertical'
    ScreenManager:
        size_hint_y: 0.7
        id: scrmgr
        Screen:
            name: 'top'
        Screen: #ここの中身を別kvにしたい
            name: 'main1'
            BoxLayout:
                orientation:'vertical'
                size:root.size
                Label:
                    id:label2
                    font_size:20
                    text:'Select the type'
                    color:[0.2,0.2,0.2,1]
                BoxLayout:
                    Label:
                        size: 50,50
                        size_hint: None, None
                    Button:
                        text:"トップス"
                        size: 150,150
                        size_hint: None, None
                        Image:
                            source: "bird.png"
                            center_x: self.parent.center_x
                            center_y: self.parent.center_y
                    Button:
                        size: 150,150
                        size_hint: None, None
                        Image:
                            source: "bird.png"
                            center_x: self.parent.center_x
                            center_y: self.parent.center_y

                Button:
                    id:button_bottoms
                    text:"bottoms"
                    size_hint_y:0.3
                    on_press:scrmgr.current = 'bottoms'
                Button:
                    id:button_autor
                    text:"autor"
                    size_hint_y:0.3
                    on_press:scrmgr.current = 'autor'
        Screen: #ここの中身を別kvにしたい
            name: 'main2'
            BoxLayout:
                orientation:'vertical'
                size:root.size
                Label:
                    id:label1
                    font_size:20
                    text:"洋服の登録をします"
                    color:[0.2,0.2,0.2,1]
                BoxLayout:
                    TextInput:
                        id:text_box
                        focus:True
                        text:"名前"
                        on_text_validate:root.buttonClicked()
                    TextInput:
                        id:text_box2
                        focus:True
                        text:"色"
                        on_text_validate:root.buttonClicked()
                Label:
                    id:label_pass1
                Label:
                    id:label_pass11
                BoxLayout:
                    Label:
                        id:label_pass1
                    Button:
                        id:button1
                        text:"登録"
                        size_hint_x:1
                        size_hint_y:1
                        on_press:root.buttonClicked()
                    Label:
                        id:label_pass2
                    Button:
                        id:button2
                        text:"表示"
                        size_hint_x:1
                        size_hint_y:1
                        on_press:root.buttonClicked2()
                    Label:
                        id:label_pass3
        Screen:  #main1から派生するScreen
            name: 'tops'
            BoxLayout:
                orientation:'vertical'
                BoxLayout:
                    Button:
                        id:back_tops
                        Image:
                            source: "bird.png"

                BoxLayout:
                    Button:
                        id:back_tops
                        text:'back'
                        size_hint_x:1
                        on_press:scrmgr.current = 'main1'
        Screen: #main1から派生するScreen
            name: 'bottoms'
        Screen: #main1から派生するScreen
            name: 'autor'

    BoxLayout:
        size_hint_y: 0.1
        padding: 10,10,20, 10
        Button:
            text: "top"
            font_size: 20
            on_press: scrmgr.current = 'top'
        Button:
            text: "main1"
            font_size: 20
            on_press: scrmgr.current = 'main1'
        Button:
            text: "main2"
            font_size: 20
            on_press: scrmgr.current = 'main2'

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

python2.7
kivy

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

コメントだとMarkdownが使えないのでこちらに書きますね

スクリーンが重なっている、ということでしょうか?

screen1.kvには"class rule"しか無いため、Builder.load_file()がNoneを返しています。
"class rule"と"root rule"の違いに関しては記事を書いたことがあるので良かったら参考にしてください。

私が上で挙げたやり方はScreenの派生classを作らない場合のお薦めです。もしMain1Screenという派生classを新たに作るのなら、Builder.load_string()を使ってMain1Screenに関するpythonコードとkvコードを一つのファイルにまとめるのをお薦めします。

 方法1 (Screenの派生classが要らない場合のお薦め)

main.kv

<TextWidget>:
    ScreenManager:
        id: scrmgr
        Screen:
            name: 'top'
    BoxLayout: 

main1screen.kv

Screen:
    name: 'main1'

main2screen.kv

Screen:
    name: 'main2'

main.py

class TestApp(App):
    def build(self):
        root = TextWidget()
        scrmgr = root.ids.scrmgr
        scrmgr.add_widget(Builder.load_file('main1screen.kv'))
        scrmgr.add_widget(Builder.load_file('main2screen.kv'))
        return root

 方法2 (Screenの派生classを作る場合のお薦め)

main.kvは方法1と同じ

main1screen.py

class Main1Screen(Screen):
    pass

Builder.load_string(r'''
<Main1Screen>:
    name: 'main1'
''')

main2screen.py

class Main2Screen(Screen):
    pass

Builder.load_string(r'''
<Main2Screen>:
    name: 'main2'
''')

main.py

from main1screen import Main1Screen
from main2screen import Main2Screen

class TestApp(App):
    def build(self):
        root = TextWidget()
        scrmgr = root.ids.scrmgr
        scrmgr.add_widget(Main1Screen())
        scrmgr.add_widget(Main2Screen())
        return root

 ややこしいですが

"class rule"と"root rule"の違いはややこしいので気をつけて。例えばオリジナルのmain.kvにはTextWidgetの"root rule"があるにも関わらずBuilder.load_file('main.kv')の戻り値を誰も受け取っていない為、TextWidgetのインスタンスを作ってすぐに捨てている事になります。またそもそもTestApp.build()内でTextWidgetのインスタンスを作っているのでmain.kv内の"root rule"は要りません。

後質問とは関係無いところですが
Buttonに画像を表示させたいなら以下のプロパティに
background_normal
background_down
background_disabled_normal
background_disabled_normal
画像ファイル名を入れるという手もありますよ

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/02 15:59

    回答ありがとうございます
    プログラム内容を省略した状態で「Screenの派生classが要らない場合」をテストしてみたところ、今のところエラーなく動いています。
    これから中身を付け加えていきたいと思います
    ありがとうございます。

    キャンセル

  • 2017/11/20 16:19

    この間はありがとうございました。
    Button操作が多いため、.pyを分けてBuilder.load_stringを使うことにしました。
    現在、画面を行き来したいのですが、戻る際のimportがうまく作動しません。
    別質問を作成したので、お時間がありましたら回答していただけると嬉しいです。
    よろしくお願いします。
    URL:https://teratail.com/questions/101254?modal=q-comp

    キャンセル

+1

test.py(おそらくmain.kvの間違いだと思いますが)には参考サイトに書かれていた

#:include gui/tab_test.kv

が書かれていないのが原因かと。

Kvファイルの分割ですが、分割は良いことだと思いますがincludeによる取り込みはする必要がないのではと思います。例えば

screenmanager = ScreenManager()
screenmanager.add_widget(Builder.load_file('screen1.kv'))
screenmanager.add_widget(Builder.load_file('screen2.kv'))
screenmanager.add_widget(Builder.load_file('screen3.kv'))

とするとか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/02 12:48

    回答ありがとうございます。
    早速、「ButtonClicked_bottoms」の部分に
    ***main.py***
    def buttonClicked_bottoms(self):
    screenmanager = ScreenManager()
    screenmanager.add_widget(Builder.load_file('screen1.kv'))
    ******
    ***screen1.kv***
    <Main1Screen>:
    BoxLayout:
    Button:
    text: 'My settings button'
    Button:
    text: 'Goto Main2'
    on_press: root.manager.current = 'main2'
    ******
    と入力し、GUI上のBottomsボタンを押すと
    ***ターミナル***
    screenmanager.add_widget(Builder.load_file('screen1.kv'))
    File "/Library/Python/2.7/site-packages/kivy/uix/screenmanager.py", line 978, in add_widget
    'ScreenManager accepts only Screen widget.')
    kivy.uix.screenmanager.ScreenManagerException: ScreenManager accepts only Screen widget.
    ******
    とエラーが発生しました。
    スクリーンが重なっている、ということでしょうか?

    キャンセル

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

  • ただいまの回答率 91.02%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    kivyのテキスト1行入力ボックスを作るコード

    kivyを勉強中なのですが、tkinterのEntryのようにテキスト1行入力ボックスを作りたくて、公式サイトをみると一応作れるようにはなっているみたいなのですが、よくわかりません

  • 解決済

    Python Kivy | Screen内のidが取得できない

    Kivyについてですが、タイトル通りの状態が続いています。 単純にkivyファイルにてidを設定後、クラスのルート位置にid名を設定し pythonファイルで受け取れるようにしたの

  • 解決済

    Python Kivy | kvファイルのButton.textをPyファイル側で受け取る方法

    KivyのButtonクラスにtextを入れ、Buttonをクリックしたときにクリックしたボタンのtextをpython側で取得するためにはどのように書くのがよいのでしょうか?

  • 解決済

    Kivyを終了させる方法を教えてください

    前提・実現したいこと PythonにKV languageを直書きしています。なので、プログラム自体の終了(Ctrl+Cなど)ではなく、Kivyで作成したアプリのみを終了させる(窓

  • 解決済

    KivyのFBOを使う事でのフレームバッファー

    こんにちは、KivyのFBO(Framebuffer)についてです。 このFBOを利用する事で、フレームバッファ機能を作れるとのことですが、 実際どのように作成するのかわかりません

  • 解決済

    Kivy 複数のScrollViewのスクロール量を同期させたい。

    KivyのScrollViewが複数あったとして、それらのスクロール量を同期させるためのコードを書いているのですが、リアルタイムで同期するにはどのようなコードを書けば良いですか?

  • 解決済

    Python Kivy の起動が遅い

    タイトル通りなのですが、kivyの起動が遅いと感じています。 改善する方法はないものでしょうか? どんなに短いコードであったとしても、平均4秒はかかります。 遅いときは10秒かかる

  • 解決済

    Kivyのボタン入力と表示に関して。

    Kivy入門サイトを参考に、ボタンで入力された数字キーを表示するディスプレイを作ろうとしています。 0ボタンが押されたときにフレーム上段のディスプレイに0と表示させたいのですが、何

同じタグがついた質問を見る

  • Python

    5519questions

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

  • MacOS(OSX)

    1635questions

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

  • Python 2.7

    1094questions

    Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。