Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
536
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

@CyberRex

Pythonで簡単なGUIを作れる「Tkinter」を使おう

今IoTで注目されている、手のひらサイズのコンピューター「Raspberry Pi(通称RPi、ラズパイ)」が人気を浴びています。
ラズパイでプログラムを動かしたりするとき、そのほとんどはPythonでやっていることが多いようです。
そのとき、プログラムを作っていて「GUIが使いたい」と思うときはありませんか?
過去にも紹介されてきている、簡単なGUIをわずかなコードで作れるライブラリをご紹介します。

軽量ライブラリ「Tkinter」

簡単に扱えるものの中に「Tkinter」というライブラリがあります。
現在はQtなどが主流ですが、Tkinterはコードを難しくすることなくできるので、日経Linuxなどでも取り上げられています。
tkinter-window.png

Tkinterが動作している様子。

さっそく導入してみましょう。

導入においては、以下の環境が必要です。

Name Value
OS Windows, macOS, Linux
Pythonバージョン 3.8以降

Tkinterの導入

まず、TkinterはPythonで動くので、まだインストールしていない場合はインストールします。

Windows の場合

WSLを使う手もありますが、TkinterはGUIを扱うものですのでネイティブ環境で実行します。
ここでは安定版の3.8.5をインストールします。

64ビット版: https://www.python.org/ftp/python/3.8.5/python-3.8.5-amd64.exe
32ビット版: https://www.python.org/ftp/python/3.8.5/python-3.8.5.exe

起動して最初の画面には「Add Python 3.8 to PATH」のチェックボックスがありますのでチェックを入れます。
これを設定すると、どこでもPythonが使えます。
まあ、本当はチェックボックス設けないで自動的にパス通してほしいのですが...

途中インストールを進めているとオプション機能をインストールするか尋ねられます。
image.png
Tkinterを使いますので、td/tk and IDLE にチェックを入れて進んでください。

image.png
最後にこの画面が出ますが、「Disable path length limit」というものがあります。
これは、環境変数に登録できるパスの長さを無制限にするものです。設定したからと言ってWindowsが起動しなくなったり不安定になることはありません。
特に事情がなければクリックして制限を外しておきます。

macOS の場合

こちらも公式サイトよりダウンロードできます。
前者同様、3.8.5をインストールします。

64ビット版: https://www.python.org/ftp/python/3.8.5/python-3.8.5-macosx10.9.pkg
Mac OS Xでは32ビット版はありません。

macOSのインストーラでは自動的にTkinterがインストールされますので特段操作は必要ありません。
画面の表示に従ってください。

Linux の場合

Ubuntu系ディストリビューションや、一部のLinuxOSでは、はじめからPythonがインストールされているものがあります。
事前に $ python3 --version を実行して存在を確かめ、ないようであれば必要に応じてインストールしてください。

$ sudo apt-get install python3.8 python3-pip

※2020年7月30日追記 Python2.7のサポートが終了しましたので、インストールするパッケージを修正しました。

これでPythonは用意できました。次にTkinterをインストールします。

$ sudo apt-get install python3-tk

完了すればTkinterの準備は完了です。

Pythonで使えるようにするには

Pythonでは、ライブラリのインポートにimportというのを使います。
例えば、timeというライブラリをインポートするにはimport timeとします。
カンマ区切りで一括で指定することもできます。

import os, sys, time

ここではTkinterをインポートするので、import tkinterと入力します。
でも、毎回 tkinter.・・・とするのは面倒なので、tkという名前で使えるようにしたいなら

import tkinter as tk

と記述します。ここからは、tkというエイリアス名でプログラムを作成していきます。

では、GUIを作成していきます。

GUIを試しに作ってみよう

Tkinterでは、ボタンなどをウィジェットと呼んでいます。
でもいまいちピンと来ない方もいるでしょうから、ここでは部品と呼ぶことにします。

rootウィンドウを作る

Tkinterでは、まずrootウィンドウを作らないと、ウィンドウが表示されません。
また、色々な部品を表示するときにも、すべてrootウィンドウにぶら下がります。
そのため、Tk()メソッドで新しくウィンドウを作ります。

tk.py
# メインウィンドウ作成
root = tk.Tk()

とりあえずこれを書いた状態で実行してみましょう。これはtk.pyとして保存した場合です。

$ python3 tk.py

すると、プログラムが正しければ、何もないウィンドウが表示されるはずです。
キャプチャ.PNG

ちなみに、ウィンドウのタイトルを変えることもできます。

#メインウィンドウのタイトルを変更
root.title("Tkinter test")

キャプチャ.PNG

root変数で、Tkメソッドで作ったウィンドウが操作できるようになります。
root変数に対して、titleメソッドを呼び出すと、タイトルが変えられるというわけです。
日本語も入れられます。(※場合によっては文字化けするかもしれません)

今の状態では、ちょっとウィンドウサイズが小さいですね。大きくしてみましょう。
ウィンドウサイズを変えるには、geometryメソッドで変更できます。
例えば、640x480のウィンドウにするには

#メインウィンドウを640x480にする
root.geometry("640x480")

とします。実行してみると、大きくなっているのがわかると思います。
キャプチャ.PNG

最後は必ず、mainloop()

ウィンドウの表示ができるようになりましたが、最後にもう1つ。
Tkinterでは、各部品を表示した後は、最後に追加した部品でmainloopメソッドを実行することが定められています。
これがないと、ボタンなどが正しく表示されない、描画されない、イベントが処理されないといったバグの原因になります。
例えば、今rootウィンドウを作りましたが、とりあえずrootウィンドウだけなので、そちらでmainloopメソッドを呼び出します。

#rootを表示し無限ループ
root.mainloop()

このmainloopメソッドはどの部品でも必須です。覚えておきましょう。

テキストを表示する

TkinterではLabelという部品を使うと、文字を表示できます。
試しに「Hello,World」と表示してみましょう。

#ラベルを追加
label = tk.Label(root, text="Hello,World")
#表示
label.grid()

root.mainloop()

最後にroot.mainloop()と書いてある場合は消してから追加してください。
実行すると、左上に「Hello,World」と表示されるはずです。
キャプチャ.PNG

Labelメソッドの書式はこんな感じです。

label = tk.Label(window, param1=value, param2=value...)

windowにはラベルを表示させたいウィンドウの変数を、param1=valueの部分には色々なパラメーターを指定します。
「abc」と表示させたいなら

label = tk.Label(window, text="abc")

となります。他のパラメーターを指定することもできます。

部品を表示するにはgrid()

label.grid()ってなんだろうと思ったと思いますが、gridメソッドはすべての部品に備わっているものです。
pack、gridメソッドを呼び出さないと部品は表示されません。
※Buttonはgridメソッドで表示するのが主流です

ボタンを表示する

ボタンを表示するには、Buttonという部品を使えば表示できます。

button = tk.Button(root, text="ボタン", command=pushed)
button.grid()

キャプチャ.PNG

tk.Buttonでは、commandに関数を指定すると、クリックした時に関数を呼び出すことができます。
例えば、pushedという関数を作り、クリックするとprint関数で「clicked」と表示するものとしましょう。

def pushed():
 print("clicked")

defというのは、自作関数を作るものです。

それで、ボタン作成時は

button = tk.Button(root, text="クリックしてね", command=pushed)
button.grid()

とします。実行して、ボタンをクリックしてみてください。

端末に「clicked」が出力されるはずです。
キャプチャ.PNG

さらに、ボタン作成後に表示するテキストを変更することもできます。

button["text"] = "変更したぜ"

キャプチャ.PNG

では、クリックしたときにメッセージを変えてみます。これをpushed関数に取り込んでみましょう。
pushed関数の定義の部分を

def pushed(b):

に変えます。
その下に

tk.py
[空白]b["text"] = "押されたよ"
[改行]

を入力します。
Pythonでは、インデント(空白やタブ)でまとまりを認識しているので、空白を開けないと

IndentationError: expected an indented block

というエラーになります。そのため、defifなどの複数行記述するものは、必ずインデントをつけるようにしましょう。
また、まとまりの終わりは改行を1回余計に加えることが重要です。

さて、ボタンを生成する側は

button = tk.Button(root, text="ボタン", command=lambda: pushed(button))
button.grid()

にします。
ここで、lambdaというのが出ますが、これはPythonでコールバックなどを指定するときに役立つ無名関数というものです。
詳しくは「python lambda」「python 無名関数」で調べてみてください。

それで、pushed(button)の部分ですが、button変数をpushed関数から操作できるように、pushed関数に渡しています。
pushed関数ではそれをbという変数として受け取っています。

これまでの部品を生成するプログラム

tk.py
#!/usr/bin/python3
# -*- coding: utf8 -*-
import tkinter as tk

def pushed(b):
 b["text"] = "押されたよ"

#rootウィンドウを作成
root = tk.Tk()
#rootウィンドウのタイトルを変える
root.title("Tkinterテスト")
#rootウィンドウの大きさを320x240に
root.geometry("320x240")

#Label部品を作る
label = tk.Label(root, text="Tkinterのテストです")
#表示する
label.grid()

#ボタンを作る
button = tk.Button(root, text="ボタン", command= lambda : pushed(button))
#表示
button.grid()

#メインループ
root.mainloop()

大体、PythonとTkinterに慣れたでしょうか?
Tkinterは他にも使えることがたくさんあるので、調べてみてください。

まとめ

まずはじめに、tk.Tk()でメインウィンドウをつくる
部品を生成したら、grid、packメソッドを呼び出す
プログラムの最後には、最後に作った部品に対してmainloopメソッドを呼び出すようにする

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
536
Help us understand the problem. What are the problem?