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

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

今回は、問題文のレイアウトとボタンの親クラスを作成します。問題文のレイアウトはただ単に文字を表示させるだけのレイアウトであるため、簡単です。親クラスも子ボタンに共通する部分を指定するだけであるため簡単です。

 

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

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

 

 

 

スポンサードサーチ


問題文を表示するレイアウト

まず、実際にプレイする画面のレイアウトを以下に示します。このレイアウトには、問題文やマッチ棒を動かす範囲、回答ボタンなどを配置します。

 

今回作成する問題文を表示するレイアウトは、上記の画像におけるQuestionLabelと書かれた薄い赤色の範囲です。

Labelクラスを継承して、文や色、サイズ、背景色などを設定していきます。

 

 

コードの提示

問題文を表示するレイアウトのソースコードを以下に示します。

import kivy
kivy.require("2.0.0")

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.graphics import Color, Rectangle, Ellipse
from kivy.graphics import Rotate
from kivy.graphics.context_instructions import PushMatrix, PopMatrix
from kivy.storage.jsonstore import JsonStore

import numpy as np
import random
import copy

class MatchStickWidget(Widget):
    # 省略

class MatchStickFrameWidget(Widget):
    # 省略

class PlayFieldWidget(FloatLayout):
    # 省略

class QuestionLabel(Label):
    def __init__(self, **kwargs):
        super(QuestionLabel, self).__init__(**kwargs)
        self.background_color = [1, 1, 1, 1]
        self.bold = True
        self.color = [0, 0, 0, 1]
        self.font_name = "C://ipaexg00401//ipaexg.ttf"
        self.font_size = 36
        self.text = "Q.マッチ棒を1本動かして以下の式を正しく直しなさい。\n"\
                    "ただし「=(イコール)」は変化しないものとする。"
        with self.canvas.before:
            Color(rgb=[1, 1, 1])
            self.bg_rect = Rectangle(pos=self.pos, size=self.size)
    def on_pos(self, *args):
        self.bg_rect.pos = self.pos
    def on_size(self, *args):
        self.bg_rect.size = self.size

class RootWidget(FloatLayout):
    def __init__(self, **kwargs):
        super(RootWidget, self).__init__(**kwargs)
        with self.canvas.before:
            Color(rgb=[1, 1, 1])
            self.bg_rect = Rectangle(pos=self.pos, size=self.size)
    def on_size(self, *args):
        self.bg_rect.size = self.size

class MatchStickQuizApp(App):
    def build(self):
        root = RootWidget()
        qlb = QuestionLabel()
        root.add_widget(qlb)
        return root

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

 

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

  

 

コードの解説

7行目の「import文」は、Labelをインポートしています。

  

 

26行目から42行目の「QuestionLabel」は、問題文を表示するレイアウトです。

 

27行目から38行目の「init関数」は、QuestionLabelの初期化を行っています。

 

28行目の「super関数」は、親クラスであるLabelクラスのinit関数を実行しています。

 

29行目の「self.background_color」は、背景色を設定しています。[1, 1, 1, 1]は白色を表しています。

 

30行目の「self.bold」は、Trueを代入することで太字にしています。

 

31行目の「self.color」は、文字の色を設定しています。[0, 0, 0, 1]は黒色を表しています。

 

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

 

33行目の「self.font_size」は、文字の大きさを設定しています。

 

34行目と35行目の「self.text」は、QuestionLabelの文字列を設定しています。テキストの途中に「\n」を入れることで、表示する際に改行するようにしています。

 

36行目の「with文」は、self.canvas.beforeオブジェクトを扱うための文です。

 

37行目の「Color」は、後述するRectangleの色を設定しています。

 

38行目の「self.bg_rect」は、Rectangleクラスが代入される変数です。Rectangleを文字の背面に画面いっぱいに表示することで背景色を設定しています。

posはQuestionLabelのposをsizeはQuestionLabelのsizeを設定しています。

 

39行目と40行目の「on_pos関数」は、posが変化したときに実行される関数です。

40行目では、背面に表示しているRectangleのposにQuestionLabelのposを代入しています。

 

41行目と42行目の「on_size関数」は、sizeが変化したときに実行される関数です。

42行目では、背面に表示しているRectangleのsizeにQuestionLabelのsizeを代入しています。

  

 

動作確認

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

python matchstickquiz.py

 

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

  

 

スポンサードサーチ


ボタンの親クラス

実際にプレイする画面のレイアウトを以下に示します。このレイアウトには、問題文やマッチ棒を動かす範囲、回答ボタンなどを配置します。

 

今回作成するボタンの親クラスは、上記の画像における薄い赤色の範囲で使用するボタンの親クラスです。

Buttonクラスを継承して共通している要素を設定していきます。

 

 

コードの提示

ボタンの親クラスのソースコードを以下に示します。

import kivy
kivy.require("2.0.0")

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.graphics import Color, Rectangle, Ellipse
from kivy.graphics import Rotate
from kivy.graphics import Line
from kivy.graphics.context_instructions import PushMatrix, PopMatrix
from kivy.storage.jsonstore import JsonStore

from kivy.core.window import Window

import numpy as np
import random
import copy

class MatchStickWidget(Widget):
    # 省略

class MatchStickFrameWidget(Widget):
    # 省略

class PlayFieldWidget(FloatLayout):
    # 省略

class QuestionLabel(Label):
    # 省略

class ButtonBaseWidget(Button):
    def __init__(self, **kwargs):
        super(ButtonBaseWidget, self).__init__(**kwargs)
        self.background_color = [1, 1, 1, 1]
        self.background_normal = ""
        self.bold = True
        self.color = [0, 0, 0, 1]
        self.font_size = 36
        self.size_hint = [1, 0.25]
        with self.canvas.before:
            Color(rgb=[0, 0, 0])
            self.line_rect = Line(width=5, rectangle=[self.x, self.y, self.width, self.height])
        Window.bind(mouse_pos=self.on_mouse_pos)
    def on_pos(self, *args):
        self.line_rect.rectangle = [self.x, self.y, self.width, self.height]
    def on_size(self, *args):
        self.line_rect.rectangle = [self.x, self.y, self.width, self.height]
    def on_mouse_pos(self, *args):
        if(self.x <= args[1][0] and args[1][0] <=self.x+self.width
            and self.y <= args[1][1] and args[1][1] <= self.y+self.height):
            self.background_color = [0, 0, 0, 1]
            self.color = [1, 1, 1, 1]
        else:
            self.background_color = [1, 1, 1, 1]
            self.color = [0, 0, 0, 1]

class RootWidget(FloatLayout):
    def __init__(self, **kwargs):
        super(RootWidget, self).__init__(**kwargs)
        with self.canvas.before:
            Color(rgb=[1, 1, 1])
            self.bg_rect = Rectangle(pos=self.pos, size=self.size)
    def on_size(self, *args):
        self.bg_rect.size = self.size

class MatchStickQuizApp(App):
    def build(self):
        root = RootWidget()
        bbw = ButtonBaseWidget(text="Test Button", pos_hint={"center_y":0.5})
        root.add_widget(bbw)
        return root

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

 

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

 

 

コードの解説

7行目の「import文」は、kivyライブラリのButtonクラスをインポートしています。

 

11行目の「import文」は、kivyライブラリのLineクラスをインポートしています。

 

15行目の「import文」は、kivyライブラリのWindowクラスをインポートしています。

 

 

33行目から57行目の「ButtonBaseWidgetクラス」は、ボタンの親クラスです。

 

34行目から45行目の「init関数」は、ButtonBaseWidgetの初期化を行っています。

 

35行目の「super関数」は、Buttonクラスのinit関数を実行しています。

 

36行目の「self.background_color」は、背景色を設定しています。[1, 1, 1, 1]は白色を表しています。

 

37行目の「self.background_normal」は、背面に表示する画像を設定しています。今回は使用しないため、空の文字列を代入しています。

 

38行目の「self.bold」は、Trueを代入することでボタンの文字を太字に設定しています。

 

39行目の「self.color」は、文字の色を設定しています。

 

40行目の「self.font_size」は、文字のサイズを設定しています。

 

41行目の「self.size_hint」は、ボタンのサイズを比率によって設定しています。[1, 0.25]は、横幅100%、縦幅25%ということです。

 

42行目の「with文」は、self.canvas.beforeオブジェクトを扱うための文です。

 

43行目の「Color」は、後述するLineの色を設定しています。

 

44行目の「self.line_rect」は、Lineクラスが代入される変数です。Lineの横幅は5、表示する位置はボタンを囲むように設定してあります。

 

45行目では、マウスの位置に変化があったとき後述するon_mousu_posを実行するように紐づけています。

  

46行目と47行目の「on_pos関数」は、posが変化したときに実行する関数です。

47行目では、ボタンの縁に表示している線の位置と大きさを更新しています。

 

48行目と49行目の「on_size関数」は、sizeが変化したときに実行する関数です。

49行目では、ボタンの縁に表示している線の位置と大きさを更新しています。

 

50行目から57行目の「on_mouse_pos関数」は、マウスの位置に変化があったとき実行する関数です。

 

51行目と52行目の「if文」は、「マウスがボタン上にある」ということを判別する条件式です。

マウスがボタン上にあるときは、53行目と54行目を実行します。

マウスがボタン上にないときは、56行目と57行目を実行します。

 

53行目では、背景色を黒色に設定しています。

54行目では、文字の色を白色に設定しています。

 

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

57行目では、文字の色を黒色に設定しています。

 

 

動作確認

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

python matchstickquiz.py

 

マウスがボタン上にないとき以下のように表示されていることを確認します。

 

マウスがボタン上にあるとき以下のように表示されいることを確認します。

 

 

スポンサードサーチ


まとめ

今回は、問題文を表示するレイアウトとボタンの親クラスを作成したました。

基本的に、様々なプロパティを設定しただけであったため直ぐ理解できたと思います。

 

次回Part16では、縦に5つボタンを表示する正解不正解を表すポップアップで使用する図形を描画するクラスを作成します。

 

 

 

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


スポンサードサーチ