アプリの教科書

アプリ・ウィンドウズで困ったことを調べたブログ

ウィンドウズ10やアプリで困ったことを調べたブログです。

スポンサーリンク


【ラズパイでPython】ウィンドウを表示する ボタンの表示は?図形を描くには?アニメは?

PythonでウィンドウなどのGUIを表示させたい場合の便利なライブラリがTkinterです。

Tkinterを使うと、ウィンドウにボタンやテキストボックスを簡単に装備できます。キャンバスを追加して図形を表示させることも比較的簡単です。

掲載コードはラズパイ上で作っているので、ラズパイで実行したコードとなります。

Pythonでウィンドウを作る

Una mirada al otro lado

Visual Studioなどでウィンドウインタフェースを作るのに慣れていると、ラズパイPythonでもウィンドウを作りたいかもしれません。

 

PythonではTkinterというライブライを使うとウィンドウの管理がしやすいです。

 

ウィンドウを作る

最初にライブラリをインストールします。

「$ sudo apt-get install python3-tk」で入れます。

 

インストール後は

import tkinter

root = tkinter.Tk()

 だけでウィンドウを確認できます。

f:id:apicode:20191117111820p:plain

 

ウィンドウに要素を追加する

ラベル

ラベルは文字だけのパーツです。

 

guiLabel = tkinter.Label(text=u'python sample')

guiLabel.pack()

のように文字を指定して作ります。

 

文字入力

文字入力用フィールドは
guiEditbox = tkinter.Entry()
guiEditbox.pack()

のように作ります。

 

ボタン

ボタンは

guiButton = tkinter.Button(text=u'OK')
guiButton.pack()

のように作ります。

 

ボタンの命令を書くには

guiButton.bind("<Button-1>",btnFunc)

のようにします。

<Button-1>は左クリックの意味です。

btnFuncは実行する関数を定義してその名前となります。

def btnFunc(event):

  messagebox.showinfo('message','Bingo!');

などと定義しておきます。

 

以上の要素を組み込むと

import tkinter

from tkinter import messagebox

def btnFunc(event):
messagebox.showinfo('message','Bingo!')

root = tkinter.Tk()


guiLabel = tkinter.Label(text=u'python sample')
guiLabel.pack()

guiEditbox = tkinter.Entry()
guiEditbox.pack()

guiButton = tkinter.Button(text=u'OK')
guiButton.bind("<Button-1>",btnFunc)
guiButton.pack()
root.mainloop()

 

実行するとウィンドウが作られます。

f:id:apicode:20191117152657p:plain

 

ボタンを押すとダイアログがでます。

f:id:apicode:20191117152659p:plain



図形を描く

図形をウィンドウ上に描くには、まずキャンバスという部品を設置します。

以下のように背景色とサイズを指定してキャンバスをつくり、XY座標を指定して配置すればOK。

canvas = tkinter.Canvas(bg='black',width=400,height=300)

canvas.place(x=0,y=0)

 

実行すると、黒い部分がキャンバスとなります。

f:id:apicode:20191117154728p:plain

 

canvasの大きさをいちいちウィンドウに合わせるのが面倒なら以下のような書き方で自動的に広がります。

canvas = tkinter.Canvas(bg='black')
canvas.place(x=0, y=0, relwidth=1.0, relheight=1.0)

 

キャンバスができれば、あとはそこに文字や図形を描画します。

文字を書くには「create_text」を、

直線は「create_line」を、

矩形は「create_rectangle」を使います。

座標や色などのパラメータを指定して以下のように書いてみます。

canvas = tkinter.Canvas(bg='black',width=400,height=300)

canvas.place(x=0,y=0)

canvas.create_text(100,20,text = 'This is a test.')

canvas.create_line(100,120,150,120)

canvas.create_line(200,120,250,120,width='10')

canvas.create_rectangle(100,220,150,250)

canvas.create_rectangle(200,220,250,250,fill='red')

 

実行するとこんな感じです。

f:id:apicode:20191118100624p:plain

 

画像を表示する

Canvasを使えば画像ファイルを読み込んで表示することもできます。

まず画像用モジュールを使うために「from PIL import Image, ImageTk」を宣言します。

ない場合「sudo apt-get install python3-pil python3-pil.imagetk」のようにPython3用のimagetkをインストールしておく必要があります。

 

いくつかサイトを参考に試したら動かなかったのですが、以下サイトを参考にしたら動作しました。

Python - pythonでtkinterを使ってcanvasにimg3ファイル内にある画像を表示させたいです。|teratail

import tkinter
from PIL import Image, ImageTk

root = tkinter.Tk()
root.geometry('640x480')


canvas = tkinter.Canvas(bg="white",width=800,height=600)
canvas.place(x=0,y=0)


im = ImageTk.PhotoImage(file='test.jpg')
canvas.create_image(200,200,image=im)

 

実行するとウィンドウ内に画像を表示。ちなみに画像「test.jpg」は「puthonproj」ディレクトリ内においています。

表示されない場合は画像ファイルの位置についても確認してみてください。

f:id:apicode:20191118102701p:plain

 

画像を切り替えてアニメーション

アニメーションでは一定時間ごとに画像を切り替えて表示したり、図形を書き直していく必要があります。

 

時間管理ではスレッドを利用することで定期的に処理を実行できます。

スレッドについては以下のサイトのスクリプトでうちでも動作を確認できました。

Python スレッドによる並行処理と終了の待ち合わせ、スレッド初期値の設定 - Symfoware

 

ここではスレッドを使って複数画像を切り替えてみます。

まだプログラムが冗長な気もしますが、以下のスクリプトで定期的に画像を切り替えて表示することができました。

 

import tkinter

from PIL import Image, ImageTk

import threading

import time


def funcLoop():

    global var

    global canvas

    var = var +1

    if(var>2):

        var =1

    if(var == 1):

        canvas.create_image(400,200,image=im1)

    else:

        canvas.create_image(400,200,image=im2)

    t = threading.Timer(0.5, funcLoop)

    t.start()


var = 1

root = tkinter.Tk()

root.geometry('640x480')

canvas = tkinter.Canvas(bg="white")

canvas.place(x=0,y=0,relwidth=1.0,relheight=1.0)

im1 = ImageTk.PhotoImage(file='1.png')

im2 = ImageTk.PhotoImage(file='2.jpg')

funcLoop()

root.mainloop()

 

 

Tkinterの不具合

「AttributeError: module 'tkinter' has no attribute 'Tk'」?

実は最初、このエラーで全然ウィンドウが表示できませんでした。

ファイル名が「tinker.py」だと実行できないという書き込みがありました。確かにファイル名を「tinker.py」としていたので、ファイルを別名にして保存してみましたがまだだめです。

 

なんでだろー、なんでだろー、こわいなー、こわいなーと思っていたら、同ディレクトリに「tinker.py」は残っていたのを思い出し、「tinker.py」ファイルを削除したら無事動作しました。

 

「tinker.py」というファイルがあると、そちらを参照してしまってライブラリのほうへたどり着かないということだと思います。注意しましょう。

 

「_tkinter.tclerror couldn't recognize data in image file」?

ネットサイトで見つかるような「img = tkinter.PhotoImage(file="test.jpg")」という書き方を、「img = ImageTk.PhotoImage(file="test.jpg")」のようにしたらうちでは動作しました。

上述のスクリプトを参考ください。

このブログは、ネットや書籍上の情報、個人の体験や感想を中心にまとめたものです。 正確性を期していはいますが、間違い・誤訳等あるかもしれません。 当サイトの情報によって生じたいかなる損失について一切の責任を負わないものとします. あらかじめご了承ください。

利用規約・プライバシーポリシー |〇問い合わせ