百人一首学習アプリ ー 完成編

一つの乱数を他の関数ででも使えるようにしましたので、全て欲しい処理が可能になりました。 

・まず最初にPythonに不足しているライブラリー(urllib, pygame, PILなど)の追加installをしました
・global乱数とし全ての関数で使えるようにした
・その為にすべてのメソッドを第一階層に置くようにした
・jpg、mp3追加
・百人一首100歌追加
・歌の出自追加(「古今集」とか)
・不要なcode削除(import sys, canvas表示)

 

最初のすべてのメソッドを第一階層に置くようにしたことにより、何とか上手く処理できるようになりましたが、この辺はよく理解できていません。 ネットで探し回ったり質問したりなんとか動くようになったのが実態です。

Pythonという未知の世界に彷徨っているところですが、参考書・ネット質問ルームなどがあればなんとか行けそうです。

これがtKinterで作ったGUIの完成品です。

 

以下が今回の「百人一首学習アプリ」の全codeです。 自分向けに出来るだけ多くのコメントを付けました。

いや~、すごく疲れたけれど面白かったです。 実力も少しついた感じです。

ではまた。

 

############################################
# 百人一首100a(完成品).py 6/4/2019

import time
import random

import tkinter as tk
import urllib.request as req #URL を開くための関数とクラスを定義
import pygame

“””
pygame は、ビデオゲームを製作するために設計されたクロスプラットフォームのPythonモジュール集であり、
Pythonでコンピュータグラフィクスと音声を扱うためのライブラリを含んでいる
“””

from time import sleep
from PIL import Image, ImageTk #Pythonの画像処理ライブラリPillow(PIL)
from mutagen.mp3 import MP3 as mp3 #mp3などのマルチメディアファイルのタグ(メタデータ)を編集することができる。

root = tk.Tk()

root.geometry(‘500×395’)
root.title(‘クマさんの百人一首’)

# PILでjpgを使用
img1 = Image.open(open(‘./100_jpg/1.jpg’, ‘rb’)) #path設定に注意
img1.thumbnail((190, 285), Image.ANTIALIAS) #写真をキレイに縮小(このjpgでは差は分からず)。無くても動作する。
img1 = ImageTk.PhotoImage(img1)  # 表示するイメージを用意

# Label
lbl1 = tk.Label(text=’上の句:’)
lbl1.place(x=220, y=30)
lbl2 = tk.Label(text=’下の句:’)
lbl2.place(x=220, y=80)
lbl3 = tk.Label(text=’歌人:’)
lbl3.place(x=220, y=140)
lbl4 = tk.Label(text=’現代訳:’)
lbl4.place(x=220, y=200)
lbl7 = tk.Label(text=’出典:’)
lbl7.place(x=350, y=140)

# Text(Entry)
txt1 = tk.Entry(width=40)
txt1.place(x=225, y=50)
txt2 = tk.Entry(width=40)
txt2.place(x=225, y=100)
txt3 = tk.Entry(width=15)
txt3.place(x=225, y=160)
txt4 = tk.Entry(width=40)  #entryでは現代訳を表示出来ないので文字列格納だけをする
#txt4.place(x=225, y=220) #使用はするが即データをmessageboxへ渡す。Entryの表示はしない
txt7 = tk.Entry(width=15)
txt7.place(x=350, y=160)

# Command Button1
btn1 = tk.Button(root, text=’開始/次へ’)
btn1.place(x=50, y=330)

btn2 = tk.Button(root, text=’読上げる’)
btn2.place(x=150, y=330)

btn3 = tk.Button(root, text=’読上停止’)
btn3.place(x=240, y=330)

btn4 = tk.Button(root, text=’終わる’)
btn4.place(x=380, y=330)

#百人一首テキストを読み込む
def read_words():
    file = open(‘./百人一首100/百人一首100a.txt’, ‘r’, encoding=’utf_8′)
    lines = file.readlines()
    file.close()

    kami_words = []  # 上の句list
    shimo_words = []  # 下の句list
    poet_words = []  # 歌人list
    trans_words = []  # 現代訳list
    reference_words= [] # 出典

    line_count = 0  # 句数カウンター
    for line in lines:
        # line = line.rstrip(“\n”) #有ってもなくても変化いみたい
        name = line.rsplit(“\t”)
        if len(name) == 5:  # 要素4個をそれぞれのlistへ追加する
            kami_words.append(name[0])  # 下記の句listへadd
            shimo_words.append(name[1]) # 下の句をlistへadd
            poet_words.append(name[2])  # 歌人をlistへadd
            trans_words.append(name[3]) # 現代訳をlistへadd
            reference_words.append(name[4]) # 出典をlistへadd

            line_count += 1
    # txtがなくなるまで繰り返す
    return line_count, [kami_words, shimo_words, poet_words, trans_words, reference_words]

#歌を表示する関数
def poem_Show(event):
    global global_num #globalにして全関数で使用する
    num = global_num

    kami_word = kami_words[num-1]  # 上の句をh_wordに格納
    shimo_word = shimo_words[num-1]
    poet_word = poet_words[num-1]
    trans_word = trans_words[num-1]
    reference_word = reference_words[num-1]

    txt1.delete(0, tk.END)
    txt2.delete(0, tk.END)
    txt3.delete(0, tk.END)
    txt4.delete(0, tk.END)
    txt7.delete(0, tk.END)

    txt1.insert(0, f’ {kami_word}’)  # txt1.insert(tk.END, kami_word)でもOK
    txt2.insert(0, f’ {shimo_word}’)
    txt3.insert(0, f’ {poet_word}’)
    txt4.insert(0, f’ {trans_word}’)  # 1行で長すぎので、表示はしない(messageで表示させる)
    txt7.insert(0, f’ {reference_word}’)  

    txt5 = txt4.get()

    txt6 = tk.Message(root,
                      width=230,
                      text=txt5, bd=0, relief=”ridge”,  bg=”white”
                      )
    txt6.place(x=225, y=220)

# 乱数に応じた要素を表示する関数
def show_data(kami_words, shimo_words, poset_words, trans_words, reference_words):  
    global global_num
    num = global_num

    kami_word = kami_words[num-1]  # 俳句をh_wordに格納
    shimo_word = shimo_words[num-1]
    poet_word = poet_words[num-1]
    trans_word = trans_words[num-1]
    reference_word = reference_words[num-1]

    # ボタン1「次へ」が押されたときの画像処理
    kami_word = kami_words[num-1]  # 上の句をh_wordに格納
    shimo_word = shimo_words[num-1]
    poet_word = poet_words[num-1]
    trans_word = trans_words[num-1]
    reference_word = reference_words[num-1]

    #表示前に以前のデータを消しておく
    txt1.delete(0, tk.END)
    txt2.delete(0, tk.END)
    txt3.delete(0, tk.END)
    txt4.delete(0, tk.END)
    txt7.delete(0, tk.END)

    #格納されている要素をテキストボックスへ書き込む(insert)
    txt1.insert(0, f’ {kami_word}’)  # txt1.insert(tk.END, kami_word)でもOK
    txt2.insert(0, f’ {shimo_word}’)
    txt3.insert(0, f’ {poet_word}’)
    txt4.insert(0, f’ {trans_word}’)  # 1行で長すぎので、表示はしない(messageで表示させる)
    txt7.insert(0, f’ {reference_word}’)
    
    txt5 = txt4.get() #txt4のデータをtxt5へcopyする(get)

    #現代訳の表示用にメッセージボックスを設定する
    txt6 = tk.Message(root,
                      width=230,
                      text=txt5, bd=0, relief=”ridge”,  bg=”white”
                      )
    txt6.place(x=225, y=220)

########## ここまでが準備のプログラム #####################

########## これから各ボタンに応じたプログラム #############

#乱数に応じたjpgのpathを選ぶ(returnが大事)
def select_img_file():
    global global_num
    num = global_num

    photo_file = ‘./100_jpg/’ + str(num)+’.jpg’
    #print(‘photo_path =’, photo_file)

    return photo_file

#上で選んだjpgを表示しなおす
def change_img(event):
    img_next = ImageTk.PhotoImage(Image.open(select_img_file()))
    panel.configure(image=img_next)
    panel.photo = img_next

#ボタン2「読上げ開始」が押されたときの処理
def select_mp3_file(event):
    global global_num
    num = global_num
    mp3_file = ‘./100_mp3/’ + str(num)+’.mp3′
    #print(‘mp3_file= ‘, mp3_file)

    pygame.mixer.init()
    pygame.mixer.music.load(mp3_file)  # 音源を読み込み
    mp3_length = mp3(mp3_file).info.length  # 音源の長さ取得
    pygame.mixer.music.play(1)  # 再生開始。1の部分を変えるとn回再生(その場合は次の行の秒数も×nすること)    

#ボタン3「音声止める」が押されたときの処理
def stop_sound(event):
    pygame.mixer.init()
    pygame.mixer.fadeout(100)#100mS     
    pygame.mixer.music.stop()

#ボタン4「終わる」が押されたときの処理。
def destroy(event):
    stop_sound(event)
    global root
    root.destroy()

#ボタン1「次へ」を押したときの処理
def push_btn1(event):
    global global_num
    global global_count
    global_num = random.randrange(1, global_count+1) #歌・jpg・mp3で同じ乱数を使う(+1で同期させている)
    print(‘global_num= ‘, global_num)
    change_img(event)
    poem_Show(event)
    stop_sound(event)
    
#ボタン1「次へ」を押したときの処理。歌・jpg・mp3と同期とれている    
btn1.bind(“<1>”, push_btn1)

# ボタン2「読上げ開始」が押されたときの処理   
btn2.bind(“<1>”, select_mp3_file)

# ボタン3「音声止める」が押されたときの処理
btn3.bind(“<1>”, stop_sound)

#ボタン4「終わる」が押されたときの処理。 読上げを中止しプログラムを終了する
btn4.bind(“<1>”, destroy)

#boot時の乱数がglobalとして、歌・jpg・mp3で使用される
global_count, words = read_words()
global_num = random.randrange(1, global_count+1)
#print(‘global_num= ‘, global_num)

kami_words = words[0]
shimo_words = words[1]
poet_words = words[2]
trans_words = words[3]
reference_words=words[4]
show_data(kami_words, shimo_words, poet_words, trans_words, reference_words)

img = ImageTk.PhotoImage(Image.open(select_img_file()))
panel = tk.Label(root, image=img)
panel.pack(side=”bottom”, fill=”both”, expand=”yes”)
panel.place(x=5, y=5)

root.mainloop()

Python別館
Python 1年間のまとめ widget編 ⑮

Pythonの学習を初めてから約1年が過ぎました。 何もないところから始めたので、遅々として進歩しま …

Python別館
高齢者運転免許認知症テスト

最近は高齢者は3年に一度の認知症テストが有ります。 先日受けてきたのですが、確か次のようなテストが有 …

Python別館
Pythonファイルをexe化する ⑤

Pythonンプログラムを作っても、他人に渡す時はexeファイルにしないといけません。コマンドプロン …