「日経ソフトウェア2022年9月号 特集2 Python デスクトップアプリを作ろう」をやってみた その4

日経ソフトウェア2022年9月号 特集2 Python デスクトップアプリを作ろう」を実行してみました。

 

サンプルプログラム

サンプルプログラムは日経ソフトウェアのWebからダウンロードできます。

以下URLから「本誌バックナンバーを見る」→「2022年9月号」→「「特集2 Pythonでデスクトップアプリを作ろう 前編」(t22209.zip)

 

nkbp.jp

 

PART4 「4択クイズ」アプリを作ろう

最後は、csvファイルを読み込んで、ラジオボタンで選択する「4択クイズ」アプリです。

csvファイルはt22209\Part4\quiz.csvを読み込みます。

csvファイルは私の環境(windows10)ではそのまま開くと文字化けして読めません。。

 

CSV文字化け

 

 

エクスプローラーからquiz.csvを右クリックし、「プログラムから開く」→「メモ帳」と実行し、ファイルを開くと文字化けが解決しています。

メモ帳

これをquiz2.csvという名前で『文字コード』を「UTF8(BOM付き)」にして保存しました。

(メモ帳の名前を付けて保存を選ぶと一番下に文字コードの選択できる部分があります)

リネームしてもよかったですが、とりあえずquiz2.csvで進めます。

 

というわけで、ラジオボタンの使用法がわかるサンプルプログラムを実行してみます。

ラジオボタンの実装は、以下のように定義し行います。

tk.Radiobutton(ボタンをつけるオブジェクト名、ボタンに表示する文字列、最初にチェックされているボタン、選択されているボタンの値)

 

引数valueには値が存在しないのでStringVarで文字列を変数に変換して代入しています。

StringVar(value='選択肢2'と記述すると、ウインドウ起動時に’選択肢2’のラジオボタンが選択されます。

 

import tkinter as tk
from tkinter import messagebox

# ハンドラ関数
def click_get():
  messagebox.showinfo('メッセージ', var.get())

root = tk.Tk()
root.geometry('250x220')
root.title('Radio Test')

action = ['選択肢1', '選択肢2', '選択肢3', '選択肢4']
# 選択状態を保持する変数(初期値を'選択肢1'にしている)
var = tk.StringVar(value='選択肢1')
for act in action:
  radio = tk.Radiobutton(root,
                         text=act,
                         variable=var,
                         value=act)
  radio.pack(pady=5)

# Buttonウィジェットの生成と配置
button = tk.Button(root, text='表示', command=click_get)
button.pack(pady=5)

root.mainloop()

 

実行結果

実行結果

 

csvファイルの読み込み時に文字コードを指定します。quiz.csvファイルの文字コードutf-8なのでencoding='utf-8'を指定します。Excelで文字化けしないように作成したquia2.csvもencoding='utf-8'で同様に以下のプログラミングで実行できます。

 

import csv

with open('quiz.csv',encoding='utf-8', newline='') as csvfile:
  reader_quiz = csv.reader(csvfile)
  data = [row for row in reader_quiz]

print(data)

 

実行結果

[['「松阪牛」の正しい読み方は?', 'まつざかぎゅう', 'しょうざかぎゅう', 'まつざかうし', 'まつさかうし', '4'], ['「チゲ鍋」の「チ
ゲ」の意味は?', '鍋', '辛い', '赤い', 'おいしい', '1'], ['「地震・雷・火事・おやじ」の「おやじ」の意味は?', '親父', '台風', ' 
爆弾', '大砲', '2']]

 

4択クイズのデスクトップアプリ

change_quiz()という関数を作成します。”次のクイズ”ボタンが押されるとラジオボタンのテキスト内容を更新する関数です。

 

judgement関数は”回答”ボタンが押されたときに行う処理を定義する関数です。

正解なら”正解です。”、不正解なら”残念!不正解です。”をメッセージボックスに表示します。

import tkinter as tk
from tkinter import messagebox
import csv

# 次のクイズを設定
def change_quiz():
  global quiz_count
  var.set(0)
  quiz_count = quiz_count + 1
  if quiz_count < len(data):
    question['text'] = data[quiz_count][0]
    for i in range(len(radio)):
      radio[i]['text'] = data[quiz_count][i+1]
      radio[i]['variable'] = var
      radio[i]['value'] = i + 1
  else:
    quiz_count = quiz_count - 1
    messagebox.showinfo('メッセージ',
                        'クイズはもうありません!')

# 正解、不正解の表示
def judgement():
  if data[quiz_count][5] == str(var.get()):
    messagebox.showinfo('正解', '正解です。')
  else:
    messagebox.showinfo('不正解', '残念!不正解です!')

root = tk.Tk()
root.geometry('300x250')
root.title('4択クイズアプリ')

for i in range(2):
  root.columnconfigure(i, weight=1)
for i in range(6):
  root.rowconfigure(i, weight=1)

quiz_count = 0    # クイズ番号(0始まり)
var = tk.IntVar() # 選択されているラジオボタンを保持する変数
data =         # ファイルから読み込んだクイズデータ

# quiz.csvからクイズデータを読み込む
with open('quiz.csv',encoding='utf-8', newline='') as csvfile:
  reader_quiz = csv.reader(csvfile)
  data = [row for row in reader_quiz]  

question = tk.Label(root, text=data[quiz_count][0])
question.grid(row=0, column=0, columnspan=2)

# Radiobuttonウィジェットの生成と配置
radio =
for i in range(4):
  radio.append(tk.Radiobutton(root,
                              text=data[quiz_count][i+1],
                              variable=var,
                              value=i+1))
  radio[i].grid(row=i+1, column=0, columnspan=2)

answer = tk.Button(root, text='回答', command=judgement)
answer.grid(row=5, column=0, sticky=tk.N)
next_quiz = tk.Button(root, text='次のクイズ', command=change_quiz)
next_quiz.grid(row=5, column=1, sticky=tk.N)

root.mainloop()

 

正解

 

/* -----codeの行番号----- */