プログラミング習得への道のり #8 Tkinterを学習する ~PCキーボードで演奏したい~
プログラミング完全初心者の私が、プログラミングを習得するまでの全過程(主に悩み…)を記事にしていきます。
プログラミング学習にあたり、以下の順で進めています。
①アウトプットを決める、②基礎を学習する、③アウトプットを作り始める
アウトプットは PCキーボードで演奏できるアプリケーション に決めました。
前回、ステップ1. キーボード入力で音を鳴らすのうち、”アプリケーション画面(GUI部分)をつくりはじめる“にチャレンジしました。結果、pygameというライブラリを用いてPCのキープレスを検出したのち、キーに応じたsin波を作成、グラフにプロットすることはできました。一方、画面がないためキーを押した瞬間にグラフは出現せず、リアルタイム性がない状況です。
そこで本記事では、画面上に動的に変化するグラフを表示させる第一歩として、 “画面作成ライブラリTkinterの基礎を学ぶ” にチャレンジしました。
PCキーボード演奏アプリの作成ステップ
- キーボード入力で音を鳴らす
☑1−1.1つの音を鳴らす
☑1-2.音階を鳴らす
☑1-3.音の長さを自由に変える
1-4.画面をつくる
1-5.メトロノーム機能をつくる - 音を制御する
2-1.波形を変える
2-2.フィルタリング機能を追加する
2-3.複数の音を同時に鳴らす - 外部から音を取り込む
3-1.単音の音源サンプルから音を取り込む(1楽器)
3-2.音源から楽器を取り出す - 機能を追加する
4-1.録音&再生する(パターンをつくる)
4-2.外部と連携する - 曲を演奏する
- 曲を作る
☑︎本記事の内容
- 【序章】画面作成ライブラリを統一する
- Tkinterの基礎
- 画面の構成要素
- Tkinterにmatplotlibグラフを埋め込む
☑︎著者の経験
この記事を書いている私は、非情報系の大学院を卒業後、通信関係の企業に3年勤めた後、現在までコンサルティング会社に勤めています。
学生時代〜現職までプログラミングとは縁がなく、前職でルーターの設定を少しかじった程度のプログラミング完全初心者です。
こういった私が、解説していきます。
Twitterもはじめました。
【序章】画面作成ライブラリを統一する
これまでpygameを使ってキープレスを検出してきました。このpygameはもともと画面作成用のライブラリで、キープレス検出単体では使えず画面を作っていました。
一方、参考にした画面イメージはTkinterという画面作成ライブラリを使っています。
ここで問題が発生しました。ネットで色々調べてみましたが、pygameとTkinterのは併用できなしようです。。。
どっちに合わせるのがよいか考えた結果、完成イメージに近い参考コードがあることから Tkinterで進めていこうと思います。
なので、キープレス検出はやり直しです。。。まぁ、新しいライブラリの勉強と思って頑張ろうと思います。
プログラミングって思ったより言語によってこのような制約があるのかもしれません。だから色々な言語があり、得意不得意があるのだなぁと思いました。
Tkinterの基礎
最初にTkinterの基本構文について学びました。
○Tkinterとは?
そもそもTkinterとはどんなことができるライブラリでしょうか?
Tkinterは、Python で GUI を扱うための標準的なライブラリです。キーワードとして、「イベント駆動方式」が用いられていることが挙げられます。
イベント駆動というのは、GUIアプリケーション上で何かしらの処理(イベント)が起こると、そのイベントをきっかけにプログラムが実行されることを言います。
今つくろうとしているPCキーボード演奏アプリでいうと、「キーを押す」というイベントをきっかけに、「音が鳴る」というプログラムが実行されるイメージです。
○Tkinterの基本構文
Tkinterの動きは以下のとおりです。
- 初期化
- イベント取得
- イベントに応じた処理の振り分け
- 後続プログラム実行
- 2 に戻る
ここでまた新しいキーワードとして、「メインループ」、「バインディング」、「イベントハンドラ」というものを紹介します。
- メインループ(イベントループ):一連の処理の流れ(上記の2~5に対応)
- バインディング:振り分け時の処理機能(上記の3に対応)
- イベントハンドラ:バインディングによって実行される後続プラグラム(上記の4)
実際にプログラミング手順は以下です。
- Tkinterをインスタンス化することでメインウィンドウを用意する。
※よく用いられるインスタンス名は”root”のようです。 - メインウィンドウ上に、ウィジェットと呼ばれる要素を配置する。
- 必要に応じてbind()メソッド(バインディング)やコールバック関数(イベントハンドラ)を用いてユーザーからのイベントを処理する。(※次回記事)
- メインループで上記の処理をループさせる。
まずは、最も基本的な構文として、何もない画面を作成しメインループで表示させてみたいと思います。
基本構文
# ライブラリのインポート
import tkinter
# メインウィンドウを作成
root = tkinter.Tk()
# メインウィンドウのオプション
root.geometry("400x300") # 画面サイズ
root.title("メインウィンドウ") # 画面のタイトル
# 〜略〜
# メインループ
root.mainloop()
root = tkinter.Tk()でTkinterのWindowを用意し(インスタンス名をrootとし)、root.mainloop()でメインループさせています。あとは、この間に画面のオプションやバインディング、イベントハンドラ要素を足していくのが基本です。
Tipsですが、Tkinterをインポートする際に、from tkinter import *という書き方もあります。そうするとインスタンス化の際にtkinter.部分が必要なくなります。
別の書き方
# ライブラリのインポート
from tkinter import *
# メインウィンドウを作成
root = Tk()
画面の構成要素
画面の構成要素は大きく3つに分けられます。
- メインウィンドウ
- フレーム
- ウィジット
それぞれについて簡単にまとめました。
○メインウィンドウ
これはその名のとおり、アプリを実行したときに立ち上がるメインの画面です。このメインウィンドウに対し、フレームやウィジットを配置していくことになります。画面全体の大きさや立ち上がった際にPC上に配置される位置などは、このメインウィンドウで定義していきます。(メソッドを使います。)
基本構文
# メインウィンドウを作成
root = tkinter.Tk()
主なメソッド
○フレーム
フレームは複数のウィジットをグルーピングする枠です。
フレームは必須要素でなく、ウィジットの一部と捉えることもできますが、フレームを使うことでレイアウトが綺麗になったり、同一グループ内でウィジットを実行するようにできたり、コードとしても見やすくなったりと、良い点がたくさんあります。
フレームのメリット
- レイアウトが綺麗になる
- 機能をグルーピングできる
- コードが見やすくなる
フレームの概念を学ぶのにすごくわかりやすい記事があったので参考までに。
基本構文
# メインウィンドウ上にフレームを作成
frame = tkinter.Frame(“インスタンス名”, “オプション1”, “オプション2”, …)
# フレームを配置(pack,grid,placeの3つのメソッドがある)
frame.pack(“オプション1”, “オプション2”, …) # 親ウィジェット上にウィジェットを詰め込むメソッド
frame.grid(“オプション1”, “オプション2”, …) # 2次元的に複数のセルに分割し、各セルにウィジェットを配置するメソッド
frame.place(“オプション1”, “オプション2”, …) # 座標を指定して、その座標にウィジェットを配置するメソッド
フレームのオプション例
フレームを含めたウィジェットの配置方法には、.pack, .grid, .placeの3種類のメソッドがあります。 どのメソッドを使用すればいいかは、どれも一長一短なので参考リンクの配置イメージを見ながら決めていくのがよいと思います。それぞれのオプションを簡単にまとめました。
.packのオプション例
.gridのオプション例
.placeのオプション例
○ウィジェット
ウィジェットはGUIの様々な部品で、テキストやボタン、グラフの表示など様々な機能をもたせることができます。
たくさん種類があるので、下記を参考に一部を紹介します。
色々なウィジェットのコード
ウィジェットの配置例
Tkinterを使って試しにコードを書いてみました。
メインウィンドウに対し、2つのフレームを用意し、各フレームに様々なウィジットを配置しています。
やってみてわかったことですが、ウィンドウやフレームは大きさを定義してもその中のウィジットの大きさによって自動でサイズ調整れてしまいます。なので、サイズを固定したい場合、固定用のメソッドを記述する必要があります。
# メインウィンドウの作成
root = tk.Tk()
root.title("main window")
root.geometry("700x300")
root.resizable(width=False,height=False) #ウィンドウ幅の固定
# フレームの配置
frame_left = tk.Frame(root, width=350, height=300, bd = 5, relief = tk.GROOVE)
frame_right = tk.Frame(root, width=350, height=300, bg="#000080")
frame_left.grid(column=0, row=0) # 1行1列に配置
frame_right.grid(column=1, row=0) # 1行2列に配置
frame_left.grid_propagate(0) # フレーム幅の固定
frame_right.grid_propagate(0) # フレーム幅の固定
Tkinterにmatplotlibグラフを埋め込む
最後に、今回やりたいことであるTkinterでグラフを表示させる方法も調べてみました。
Tkinterにグラフを埋め込む方法は少し特殊なようです。手順としては以下の4ステップになります。
Tkinterにmatplotlibを埋め込むステップ
- Tkinterのメインウィンドウを用意する
※必要に応じてFrameウィジェットを配置する - Matplotlibライブラリを利用して、グラフを作成する
2-1.Figureインスタンスをつくる
2-2.実際のグラフを描画するAxesインスタンスをつくる
2-3.Figureインスタンス上にグラフをプロットする - FigureCanvasTkAggを宣言し、メインウィンドウ上またはFrameウィジェット上に配置する
- グラフをTkinterのウィジェットとして表示させる
1.は本記事ですでに記載したとおりです。また、2.に関しては前の記事のとおりです。 最も重要なのが3.FigureCanvasTkAggの宣言です。
FigureCanvasTkAggはMatplotlibライブラリを使って作成したグラフを、Tkinter内で表示するために必要なメソッドです。使用するにはインポートする必要があります。
# FigureCanvasTkAggのインポート
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
実際にやってみるのが一番!ということで上記のステップに従ってコードを書いてみました。
○結果
結果は以下のとおりで、Tkinterにグラフを埋め込むことができました。
まとめ&次回予告
○まとめ
Pythonで画面(GUI)をつくるためにTkinterというライブラリの基礎構造を学びました。
Tkinterの基本的な動き
- 初期化
- イベント取得
- イベントに応じた処理の振り分け
- 後続プログラム実行
- 2 に戻る
プログラミング手順
- Tkinterをインスタンス化することでメインウィンドウを用意する。
- メインウィンドウ上に、ウィジェットを配置する。
- 必要に応じてbind()メソッド(バインディング)やコールバック関数(イベントハンドラ)を用いてユーザーからのイベントを処理する。(※次回記事)
- メインループで上記の処理をループさせる。
画面の構成要素
- メインウィンドウ
- フレーム
- ウィジット
ウィジェットの配置方法
- .pack()
- .grid()
- .place()
○次回予告
長くなりましたが基礎編は以上です。
いよいよPCキーボード演奏アプリに画面をつけたいと思います。
- キーボード入力で音を鳴らす
☑1−1.1つの音を鳴らす
☑1-2.音階を鳴らす
☑1-3.音の長さを自由に変える
1-4. 画面をつくる
1-5.メトロノーム機能をつくる
lteru
最新記事 by lteru (全て見る)
- 【ノーコード・ローコード】OutSystemsでアプリづくり#04 ~マッチングアプリをつくる①~ - 2022年8月13日
- 【ノーコード・ローコード】OutSystemsでアプリづくり#03 ~簡単なリスト型アプリをつくる③~ - 2022年7月24日
- 【ノーコード・ローコード】OutSystemsでアプリづくり#02 ~簡単なリスト型アプリをつくる②~ - 2022年7月22日