Help us understand the problem. What is going on with this article?

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

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

軽量ライブラリ「Tkinter」

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

Tkinterが動作している様子。

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

Tkinterの導入

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

$ sudo apt-get install python python3 python-pip python3-pip

※python-pip、python3-pipは導入されていない場合があるので、Python導入済みでもインストールしてください。
※2019/01/29追記:Ubuntuなどの有名ディストリビューションでは標準でインストールされていますので作業は不要です。

これで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メソッドを呼び出すようにする

CyberRex
PHP,HTML5,Python,JavaScriptをメインに色々やってます。 GitHubもぜひ。https://github.com/CyberRex
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
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  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
ユーザーは見つかりませんでした