【Python】マッチ棒クイズ開発 Part22

こんにちは、にわこまです。

今回は、プレイ画面を作成します。問題文を表示したり、マッチ棒を動かす画面を設置したり、ボタンを設置したりを行います。

 

誤字脱字や分からない点がございましたらご連絡お願いいたします!

メールまたはTwitterのDMまで!!

 

 

 

スポンサードサーチ


プレイ画面 問題文とマッチ棒を動かす画面

ここでは、プレイ画面の内問題文の表示とマッチ棒を動かす画面のみを追加してプレイ画面を作成します。

 

以下に作成するプレイ画面の範囲を示します。薄い赤色の範囲をここでは作成します。

 

 

コードの提示

kvファイルでプレイ画面を表現するソースコードを以下に示します。

# -*- coding: utf-8 -*-
#:import np numpy

<MatchStickWidget>:
    # 省略

<MatchStickFrameWidget>:
    # 省略

<PlayFieldWidget>:
    # 省略

<ButtonBaseWidget>:
    # 省略

<ResultPopup>:
    # 省略

<PlayWidget>:
    orientation: "horizontal"
    BoxLayout:
        orientation: "vertical"
        size_hint: [0.75, 1]
        Label:
            background_color: [1, 1, 1, 1]
            bold: True
            color: [0, 0, 0, 1]
            font_name: "C://ipaexg00401//ipaexg.ttf"
            font_size: 36
            size_hint: [1, 0.3]
            text: "Q.マッチ棒を1本動かして以下の式を正しく直しなさい。\nただし「=(イコール)」は変化しないものとする。"
            canvas.before:
                Color:
                    rgb: [1, 1, 1]
                Rectangle:
                    pos: self.pos
                    size: self.size
        PlayFieldWidget:
            id: pfw
            size_hint: [1, 0.7]


<RootWidget>:
    canvas:
        Color:
            rgb: [1, 1, 1]
        Rectangle:
            pos: self.pos
            size: self.size

 

pythonファイルでプレイ画面を表現するソースコードを以下に示します。

import kivy
kivy.require('2.0.0')

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.popup import Popup
from kivy.storage.jsonstore import JsonStore

from kivy.core.window import Window

from kivy.lang import Builder
Builder.load_file('matchstickquiz.kv')

import numpy as np
import random
import copy

class MatchStickWidget(Widget):
    # 省略

class MatchStickFrameWidget(Widget):
    # 省略

class PlayFieldWidget(FloatLayout):
    # 省略

class ButtonBaseWidget(Button):
    # 省略

class ResultPopup(Popup):
    # 省略

class PlayWidget(BoxLayout):
    def __init__(self, **kwargs):
        super(PlayWidget, self).__init__(**kwargs)
        self.rp = ResultPopup()

class RootWidget(FloatLayout):
    pass


class MatchStickQuizApp(App):
    def build(self):
        root = RootWidget()
        pw = PlayWidget()
        root.add_widget(pw)
        return root


if __name__ == '__main__':
    MatchStickQuizApp().run()
    pass

  

上記のコードは以下からダウンロードできます。

  

 

コードの解説 kvファイル

19行目から40行目の「PlayWidget」は、BoxLayoutを継承したプレイ画面を表現するクラスです。

 

20行目の「orientation」は、子ウィジェットをどの方向に追加していくかを設定する変数です。horizontalを代入することで水平方向に追加していくように設定しています。

 

 

21行目の「BoxLayout」は、問題文とマッチ棒を動かす画面を追加するクラスです。

 

22行目の「orientation」は、子ウィジェットをどの方向に追加していくかを設定する変数です。verticalを代入することで垂直方向に追加していくように設定しています。

 

23行目の「size_hint」は、比率によってサイズを設定する変数です。横幅75%、縦幅100%で設定しています。

 

 

24行目の「Label」は、問題文を表示するクラスです。

 

25行目の「background_color」は、Labelの背景色を設定する変数です。[1, 1, 1, 1]は白色を表しています。

 

26行目の「bold」は、文字の太さを設定する変数です。Trueを代入することで太字に設定しています。

 

27行目の「color」は、文字の色を設定する変数です。[0, 0, 0, 1]は黒色を表しています。

 

28行目の「font_name」は、フォントを設定しています。デフォルトのまま日本語を表示させると文字化けして読めないため設定しています。フォントファイルのパスに気を付けて設定してください。

  

29行目の「font_size」は、文字の大きさを設定する変数です。36を設定しています。

 

30行目の「size_hint」は、比率によってLabelのサイズを設定する変数です。横幅100%、縦幅30%で設定しています。

 

31行目の「text」は、Labelの文字列を設定する変数です。「Q.マッチ棒を1本動かして以下の式を正しく直しなさい。\nただし「=(イコール)」は変化しないものとする。」という文字列を設定しています。

文字列中の「\n」は、改行を意味します。

  

32行目の「canvas.before」は、canvas.beforeオブジェクトを宣言しています。

 

33行目の「Color」は、後述するRectangleの色を設定するオブジェクトです。

34行目では、色を白色に設定しています。

 

35行目の「Rectangle」は、Labelの背景を表現するオブジェクトです。

36行目の「pos」は、背景の座標を保持する変数です。Labelと同じ座標を設定しています。

37行目の「size」は、背景のサイズを保持する変数です。Labelと同じサイズを設定しています。

 

 

38行目の「PlayFieldWidget」は、マッチ棒を動かす画面を表現するクラスです。

 

39行目の「id」は、そのオブジェクトを識別するための変数です。つまり、クラス名を定義するようなものです。pfwを代入することでPlayFieldWidgetオブジェクトをpfwとして呼び出すことができます。

 

40行目の「size_hint」は、比率によってPlayFieldWidgetのサイズを設定する変数です。横幅100%、縦幅70%で設定しています。

 

  

コードの解説 pythonファイル

pythonに書かれているコードは、ほとんどこれまでのPartで解説しているため、新しく記述したコードや気を付けて欲しいコードについて解説します。

 

以前はinit関数に色んな変数を定義していましたが、今回は39行目の「self.rp = ResultPopup()」でポップアップを定義するだけになりました。

 

 

動作確認

コードを保存したら、コマンドプロンプトを開きファイルを保存したフォルダまで移動します。移動したら、以下のコマンドを入力し実行します。

python matchstickquiz.py

 

以下のように表示されれば動作確認完了です。

 

 

スポンサードサーチ


プレイ画面 ボタン

ここでは、先ほど作成した問題とマッチ棒を動かす画面の横にボタン群を追加してプレイ画面を作成します。

 

以下に作成するプレイ画面の範囲を示します。薄い赤色の範囲をここでは作成します。

 

 

コードの提示

kvファイルでボタン群を追加したプレイ画面のソースコードを以下に示します。

# -*- coding: utf-8 -*-
#:import np numpy

<MatchStickWidget>:
    # 省略

<MatchStickFrameWidget>:
    # 省略

<PlayFieldWidget>:
    # 省略

<ButtonBaseWidget>:
    # 省略

<ResultPopup>:
    # 省略

<PlayWidget>:
    orientation: "horizontal"
    BoxLayout:
        orientation: "vertical"
        size_hint: [0.75, 1]
        Label:
            background_color: [1, 1, 1, 1]
            bold: True
            color: [0, 0, 0, 1]
            font_name: "C://ipaexg00401//ipaexg.ttf"
            font_size: 36
            size_hint: [1, 0.3]
            text: "Q.マッチ棒を1本動かして以下の式を正しく直しなさい。\nただし「=(イコール)」は変化しないものとする。"
            canvas.before:
                Color:
                    rgb: [1, 1, 1]
                Rectangle:
                    pos: self.pos
                    size: self.size
        PlayFieldWidget:
            id: pfw
            size_hint: [1, 0.7]
    BoxLayout:
        orientation: "vertical"
        width_10Per: int(self.width * 0.1)
        height_05Per: int(self.height * 0.05)
        padding: [self.width_10Per, self.width_10Per]
        spacing: self.height_05Per
        size_hint: [0.25, 1]
        canvas.before:
            Color:
                rgb: [1, 1, 1]
            Rectangle:
                pos: self.pos
                size: self.size
        ButtonBaseWidget:
            text: "Answer"
            on_press: root.rp.tof = root.ids["pfw"].checkAnswerFML(); root.rp.open()
        ButtonBaseWidget:
            text: "Reset"
            on_press: root.ids["pfw"].drawQuestion()
        ButtonBaseWidget:
            text: "See"
            on_press: root.ids["pfw"].drawAnswer()
        ButtonBaseWidget:
            text: "Next"
            on_press: root.ids["pfw"].setQA()
        ButtonBaseWidget:
            text: "Return"
            on_press: app.root.gotoTitleWidget()


<RootWidget>:
    canvas:
        Color:
            rgb: [1, 1, 1]
        Rectangle:
            pos: self.pos
            size: self.size

 

pythonファイルは変化がないため、提示を省略します。

 

上記のコードは以下からダウンロードできます。

 

  

コードの解説 kvファイル

41行目から68行目の「BoxLayout」は、ボタンを縦に5つ配置するためのレイアウトです。

 

42行目の「orientation」は、子ウィジェットをどの方向に追加するか設定する変数です。verticalを代入することで垂直方向に追加するように設定しています。

 

43行目の「width_10Per」は、後述するpaddingで使用する値を設定する変数です。BoxLayoutの横幅10%を設定しています。

 

44行目の「height_05Per」は、後述するspacingで使用する値を設定する変数です。BoxLayoutの縦幅5%を設定しています。

 

45行目の「padding」は、BoxLayoutの外側の余白を設定しています。縦横それぞれself.width_10Per分の余白が設定されています。

余白は以下の画像における薄い青色の範囲です。縦と横で若干範囲が異なりますが、イメージとして読み取ってください。

 

46行目の「spacing」は、子ウィジェット同士の間に余白を設定しています。子ウィジェットと子ウィジェットの間にはself.height_05Per分の余白が設定されています。

余白は以下の画像における薄い青色の範囲です。

 

47行目の「size_hint」は、比率によってBoxLayoutのサイズを設定する変数です。横幅25%、縦幅100%で設定しています。

 

48行目の「canvas.before」は、canvas.beforeオブジェクトを宣言しています。

 

49行目の「Color」は、後述するRectangleの色を設定するオブジェクトです。

50行目では、色を白色に設定しています。

 

51行目の「Rectangle」は、Labelの背景を表現するオブジェクトです。

52行目の「pos」は、背景の座標を保持する変数です。Labelと同じ座標を設定しています。

53行目の「size」は、背景のサイズを保持する変数です。Labelと同じサイズを設定しています。

 

 

54行目の「ButtonBaseWidget」は、「答える」を表すボタンです。

55行目の「text」は、ボタンに表示する文字列を設定する変数です。「Answer」を設定しています。

56行目の「on_press」は、このボタンが押されたときに実行する関数です。「root.rp.tof = root.ids[“pfw”].checkAnswerFML()」と「root.rp.open()」を実行します。

root.rp.tof = root.ids[“pfw”].checkAnswerFML()」は、PlayFieldWidgetのcheckAnswerFMLを実行して、値をResultPopupのtofに代入しています。「root.rp.open()」は、ResultPopupを表示しています。

 

 

57行目の「ButtonBaseWidget」は、「リセット」を表すボタンです。

58行目の「text」は、ボタンに表示する文字列を設定する変数です。「Reset」を設定しています。

59行目の「on_press」は、このボタンが押されたときに実行する関数です。「root.ids[“pfw”].drawQuestion()」を実行しています。

root.ids[“pfw”].drawQuestion()」は、PlayFieldWidgetのdrawQuestionを実行しています。

 

 

60行目の「ButtonBaseWidget」は、「答えを見る」を表すボタンです。

61行目の「text」は、ボタンに表示する文字列を設定する変数です。「See」を設定しています。

62行目の「on_press」は、このボタンが押されたときに実行する関数です。「root.ids[“pfw”].drawAnswer()」を実行しています。

root.ids[“pfw”].drawAnswer()」は、PlayFieldWidgetのdrawAnswerを実行しています。

  

 

63行目の「ButtonBaseWidget」は、「次の問題へ」を表すボタンです。

64行目の「text」は、ボタンに表示する文字列を設定する変数です。「Next」を設定しています。

65行目の「on_press」は、このボタンが押されたときに実行する関数です。「root.ids[“pfw”].setQA()」を実行しています。

root.ids[“pfw”].setQA()」は、PlayFieldWidgetのsetQAを実行しています。

  

 

66行目の「ButtonBaseWidget」は、「タイトル画面に戻る」を表すボタンです。

67行目の「text」は、ボタンに表示する文字列を設定する変数です。「Return」を設定しています。

68行目の「on_press」は、このボタンが押されたときに実行する関数です。「app.root.gotoTitleWidget()」を実行しています。

app.root.gotoTitleWidget()」は、次回PartでRootWidgetに追加するgotoTitleWidgetを実行しています。

  

 

動作確認

コードを保存したら、コマンドプロンプトを開きファイルを保存したフォルダまで移動します。移動したら、以下のコマンドを入力し実行します。

python matchstickquiz.py

 

以下のように表示されれば動作確認完了です。

  

  

スポンサードサーチ


まとめ

今回は、プレイ画面を作成しました。問題文を表示したり、マッチ棒を動かす画面を設置したり、ボタンを設置したりしました。

ボタンが押された時に実行する関数の設定方法が少し難しかったのでは無いかと思います。

 

次回Part23では、タイトル画面の作成と元のレイアウトとなるRootWidgetの作成を行います。

次回でkvファイルを使ったマッチ棒クイズ開発は終了となります!!!

 

 

 

最後までお読みいただきありがとうございます。


スポンサードサーチ