はじめに
今回は、pythonのtkinterというライブラリを使って、ピアノの鍵盤を作ってみました。chatgptに聞きながら、制作したら簡単にできたので紹介したいと思います。
使用したもの
- python3.8.10
- tkinter
- pygame
- 音声ファイル(GitHub – parisjava/wav-piano-sound: Single-octave chromatic C scale, in wave (.wav) audio format. These piano sound files are public domain.からダウンロード)
- VSCode
とりあえず実行してみる
import tkinter as tk
import pygame
# pygame初期化
pygame.init()
# 音ファイル読み込み
sounds = {
"C": pygame.mixer.Sound("wave/c1.wav"),
"C#": pygame.mixer.Sound("wave/c1s.wav"),
"D": pygame.mixer.Sound("wave/d1.wav"),
"D#": pygame.mixer.Sound("wave/d1s.wav"),
"E": pygame.mixer.Sound("wave/e1.wav"),
"F": pygame.mixer.Sound("wave/f1.wav"),
"F#": pygame.mixer.Sound("wave/f1s.wav"),
"G": pygame.mixer.Sound("wave/g1.wav"),
"G#": pygame.mixer.Sound("wave/g1s.wav"),
"A": pygame.mixer.Sound("wave/a1.wav"),
"A#": pygame.mixer.Sound("wave/a1s.wav"),
"B": pygame.mixer.Sound("wave/b1.wav"),
"C2": pygame.mixer.Sound("wave/c2.wav"),
}
# 音を再生する関数
def play_sound(note):
sounds[note].play()
# キーボードからの演奏
# キーに対応する音名(ここでは簡易的に表示だけ)
KEY_TO_NOTE = {
"a": "C",
"w": "C#",
"s": "D",
"e": "D#",
"d": "E",
"f": "F",
"t": "F#",
"g": "G",
"y": "G#",
"h": "A",
"u": "A#",
"j": "B",
"k": "C2"
}
def on_key_press(event):
note = KEY_TO_NOTE.get(event.char)
if note:
play_sound(note)
# tkinterのウィンドウ作成
root = tk.Tk()
root.title("ピアノ鍵盤")
# 白鍵の配置
white_keys = ["C", "D", "E", "F", "G", "A", "B", "C2"]
white_buttons = []
for i, note in enumerate(white_keys):
button = tk.Button(root, text=note, anchor="s", bg="white", fg="black", command=lambda n=note: play_sound(n))
button.place(x=60 * i, y=0, width=59, height=300)
white_buttons.append(button)
# 黒鍵の配置(EとBには黒鍵なし)
black_keys = {
"C#": 1,
"D#": 2,
"F#": 4,
"G#": 5,
"A#": 6
}
for note, position in black_keys.items():
button = tk.Button(root, text=note, anchor="s", bg="black", fg="white", command=lambda n=note: play_sound(n))
button.place(x=60*position - 20, y=0, width=40, height=180)
# ウィンドウサイズを固定
root.geometry("479x300")
root.bind("<Key>", on_key_press)
root.mainloop()
まず、pythonファイルを作り、そこに上記のコードを貼り付けます。
次に、GitHub – parisjava/wav-piano-sound: Single-octave chromatic C scale, in wave (.wav) audio format. These piano sound files are public domain.から音声ファイルをダウンロードし、pythonファイルと同じ改装に作ったwaveファイルに入れます。
それができたら、実行します。実行すると、鍵盤が書かれたウィンドウが表示されます。
試しに、Cのボタンを押してみると、ドの音が出ますね。また、キーボードのaキーを押すと、同様に、ドの音が出ます。
コードの説明
1.ライブラリのインポートと初期化
import tkinter as tk
import pygame
-
tkinter
はPython標準のGUIライブラリです。tk
という短い名前で使えるようにしています。 -
pygame
はゲーム開発用ライブラリですが、今回は音声再生にだけ使います。
# pygame初期化
pygame.init()
pygame.init()
を呼ぶことで、pygame内の各機能(ここではミキサー)が使えるようになります。
2.音声ファイルの読み込み
sounds = {
"C": pygame.mixer.Sound("wave/c1.wav"),
"C#": pygame.mixer.Sound("wave/c1s.wav"),
...
}
-
ピアノの各音階に対応する
.wav
ファイルを読み込み、辞書(sounds
)に格納しています。 -
pygame.mixer.Sound()
は、音声ファイルをロードして、再生可能なオブジェクトを作成します。 -
すべての音声ファイルは「
wave
フォルダ」に保存されている必要があります。
3.音を再生する関数
def play_sound(note):
sounds[note].play()
-
引数
note
には「”C”」や「”F#”」などの音名が渡されます。 -
辞書
sounds
から該当する音声を取得し、.play()
メソッドで音を鳴らします。
4.キーボードに対応させる
KEY_TO_NOTE = {
"a": "C",
"w": "C#",
"s": "D",
"e": "D#",
...
}
-
キーボードの各キー(例:
a
,s
,d
,f
…)をピアノの音に対応づけます。 -
黒鍵(#付きの音)は
w
,e
,t
,y
,u
に割り当てています。
def on_key_press(event):
note = KEY_TO_NOTE.get(event.char)
if note:
play_sound(note)
-
event.char
には押されたキーの文字(例:"a"
)が入ります。 -
対応する音があれば
play_sound(note)
を呼び出して音を鳴らします。
5.Tkinter ウィンドウの作成
root = tk.Tk()
root.title("ピアノ鍵盤")
-
Tk()
でウィンドウを作成します。 -
title()
でウィンドウタイトルを「ピアノ鍵盤」に設定。
6.白鍵のボタン配置
white_keys = ["C", "D", "E", "F", "G", "A", "B", "C2"]
white_buttons = []
-
ピアノの白鍵はこの8つです。
-
各キーに対応するボタンを順番に作成し、画面に並べていきます。
for i, note in enumerate(white_keys):
button = tk.Button(root, text=note, anchor="s", bg="white", fg="black", command=lambda n=note: play_sound(n))
button.place(x=60 * i, y=0, width=59, height=300)
white_buttons.append(button)
-
tk.Button()
でボタン(鍵盤)を作成。-
text=note
→ ボタンに「C」「D」などのラベルを表示。 -
anchor="s"
→ テキストを下寄せに配置。 -
bg="white"
→ 白鍵の背景色。 -
command=lambda n=note: play_sound(n)
→ ボタンがクリックされたら音を再生。
-
-
place()
を使って、ピクセル単位での正確な位置にボタンを配置。 -
width=59
とheight=300
で見た目の大きさを調整。
7.黒鍵のボタン配置
black_keys = {
"C#": 1,
"D#": 2,
"F#": 4,
"G#": 5,
"A#": 6
}
-
黒鍵は白鍵の上に位置し、間隔も異なります。
-
position
の数値は、白鍵のインデックスに基づく位置です。
for note, position in black_keys.items():
button = tk.Button(root, text=note, anchor="s", bg="black", fg="white", command=lambda n=note: play_sound(n))
button.place(x=60*position - 20, y=0, width=40, height=180)
-
x=60*position - 20
にすることで、白鍵の中央より少し左にずらし、重なるように配置。 -
黒鍵は幅が狭く、高さも短い(
height=180
)ので、見た目のリアリティがあります。
8.ウィンドウのサイズ固定と起動
root.geometry("479x300")
- ウィンドウサイズを固定。白鍵8個 × 幅59ピクセル + 微調整 = 約479ピクセル。
root.bind("<Key>", on_key_press)
- キーボードのキーが押されたとき、
on_key_press()
を呼び出すようにバインドします。
root.mainloop()
これでウィンドウを表示し、GUIイベントのループ(待機状態)に入ります。
感想
意外と簡単に作れた。