目次

tkinter利用

 Tcl/TkのTkは、他のプログラミング言語で
 GUIを実現するときに使う、拡張ライブラリ
 とみなせます。

 Tkを親となる言語から使いたいときには、ライブラリ
 tkinterを利用するのが、開発時間短縮に役立ちます。

 Pythonを親言語として、tkinterによるGUIを実現すると
 次のような画面を生成できます。



 このGUIを生成しているPythonのソースコードは、以下。

import sys
import tkinter as tk

root = tk.Tk()
root.title("Green House")
root.geometry("340x300")

# unit
lblUnit1 = tk.Label(text = "Celcuis")
lblUnit1.grid(row = 0, column = 1)
lblUnit2 = tk.Label(text = "Celcuis")
lblUnit2.grid(row = 0, column = 2)
lblUnit3 = tk.Label(text = "%")
lblUnit3.grid(row = 0, column = 3)
lblUnit4 = tk.Label(text = "Celcuis")
lblUnit4.grid(row = 0, column = 5)
lblUnit5 = tk.Label(text = "%")
lblUnit5.grid(row = 0, column = 6)
lblTop = tk.Label(text = "TOP")
lblTop.grid(row = 1, column = 0)
lblMid = tk.Label(text = "MIDDLE")
lblMid.grid(row = 2, column = 0)
lblBot = tk.Label(text = "BOTTOM")
lblBot.grid(row = 3, column = 0)

# channel 0 parameters
ch0TopVal = 28
ch0MidVal = 29
ch0BotVal = 29
lblCh0Top = tk.Label(text = str(ch0TopVal) )
lblCh0Top.grid(row = 1, column = 1)
lblCh0Mid = tk.Label(text = str(ch0MidVal))
lblCh0Mid.grid(row = 2, column = 1)
lblCh0Bot = tk.Label(text = str(ch0BotVal))
lblCh0Bot.grid(row = 3, column = 1)

# channel 1 parameters
ch1TopVal = 28
ch1MidVal = 27
ch1BotVal = 30
lblCh1Top = tk.Label(text = str(ch1TopVal) )
lblCh1Top.grid(row = 1, column = 2)
lblCh1Mid = tk.Label(text = str(ch1MidVal))
lblCh1Mid.grid(row = 2, column = 2)
lblCh1Bot = tk.Label(text = str(ch1BotVal))
lblCh1Bot.grid(row = 3, column = 2)

# channel 2 parameters
ch2TopVal = 72
ch2MidVal = 80
ch2BotVal = 79
lblCh2Top = tk.Label(text = str(ch2TopVal) )
lblCh2Top.grid(row = 1, column = 3)
lblCh2Mid = tk.Label(text = str(ch2MidVal))
lblCh2Mid.grid(row = 2, column = 3)
lblCh2Bot = tk.Label(text = str(ch2BotVal))
lblCh2Bot.grid(row = 3, column = 3)

# limit parameters
tempUpper = 40
tempLower = 2
humiUpper = 95
humiLower = 20
lblTempUpper = tk.Label(text = "Upper" )
lblTempUpper.grid(row = 1, column = 4)
lblTempLower = tk.Label(text = "Lower" )
lblTempLower.grid(row = 2, column = 4)

entTempUpper = tk.Entry(width=4)
entTempUpper.insert(tk.END,str(tempUpper))
entTempUpper.grid(row = 1, column = 5)

entTempLower = tk.Entry(width=4)
entTempLower.insert(tk.END,str(tempLower))
entTempLower.grid(row = 2, column = 5)

entHumiUpper = tk.Entry(width=4)
entHumiUpper.insert(tk.END,str(humiUpper))
entHumiUpper.grid(row = 1, column = 6)

entHumiLower = tk.Entry(width=4)
entHumiLower.insert(tk.END,str(humiLower))
entHumiLower.grid(row = 2, column = 6)

# procedure
def setTemp():
  utemp = entTempUpper.get()
  ltemp = entTempLower.get()
  #print( str(utemp) + " " + str(ltemp) )
  tempUpper = utemp
  tempLower = ltemp
  entTempUpper.delete(0,tk.END)
  entTempLower.delete(0,tk.END)
  entTempUpper.insert(tk.END,str(tempUpper))
  entTempLower.insert(tk.END,str(tempLower))

# procedure
def setHumi():
  uhumi = entHumiUpper.get()
  lhumi = entHumiLower.get()
  #print( str(uhumi) + " " + str(lhumi) )
  humiUpper = uhumi
  humiLower = lhumi
  entHumiUpper.delete(0,tk.END)
  entHumiLower.delete(0,tk.END)
  entHumiUpper.insert(tk.END,str(humiUpper))
  entHumiLower.insert(tk.END,str(humiLower))

def myExit():
  exit()

# Button object
btnTempGet = tk.Button( text = "Set" , command = setTemp )
btnTempGet.grid(row = 3, column = 5)
btnHumiGet = tk.Button( text = "Set" , command = setHumi )
btnHumiGet.grid(row = 3, column = 6)
btnExit = tk.Button( text = "Exit" , command = myExit )
btnExit.grid(row = 0, column = 7)

root.mainloop()

 Tcl/Tkのwidgetを生成するためのコマンドを
 ライブラリでクラスを定義し、メソッドへと
 変換しているのがわかります。

 このPythonスクリプトで使ったコマンドは、以下。

 ラベルLabel、エントリEntry、ボタンButtonは、Tcl/Tkの場合と
 ほぼ同じですが、エントリEntryとボタンButtonは、気をつけない
 と、嵌ってしまうところがあります。

 Entryコマンドに関する注意

  Entryでは、扱う文字列はPythonの文字列の性質を
  受け継ぐので、消去と追加は、Pythonでの操作と
  同等のコードを用意しなければなりません。

  文字列消去は、次のように記述。

    XXX.delete(0,tk.END)

  文字列は、次のような文字の並びとPythonでは考えます。



  上に書いてある数字は、エントリーポイントからの
  オフセットを表します。

  deleteメソッドは、文字列が格納されている領域の中にある
  文字を消去すると同時に、ポインタを先頭に戻す操作をして
  いると考えなければなりません。

  deleteメソッドを実行すると、次のように領域の中が
  空にされると同時にポインタが付け替えられます。



  ポインタを利用したカラクリがわかれば、insertの目的も
  理解できます。

    XXX.insert(tk.END,str(humiUpper))

  tk.ENDでポイントする位置をエントリとして
  文字列を並べていくのが、insertになります。



 Buttonコマンドに関する注意

  Buttonでは、クリックしたときに動くコード(ハンドラ)を
  指定することができます。

  ボタンを定義するときに、commandプロパティに
  関数、手続きを指定できます。
  commandプロパティで指定する関数、手続きは
  defを使って定義しなければなりません。

  関数、手続きは、ボタンを定義する前に記述しておかないと
  エラーになります。位置関係が、重要なのです。

# procedure
def setTemp():
  utemp = entTempUpper.get()
  ltemp = entTempLower.get()
  #print( str(utemp) + " " + str(ltemp) )
  tempUpper = utemp
  tempLower = ltemp
  entTempUpper.delete(0,tk.END)
  entTempLower.delete(0,tk.END)
  entTempUpper.insert(tk.END,str(tempUpper))
  entTempLower.insert(tk.END,str(tempLower))

# Button object
btnTempGet = tk.Button( text = "Set" , command = setTemp )

 画像表示には、Canvasオブジェクトを利用します。

 その前に、画像ファイルを扱うためにライブラリpillowを
 使うので、次のようにimportしておきます。

from PIL import Image

 本来は、pillowを指定するべきなのですが、PILの後継が
 pillowなので、ライブラリ名はそのままで使います。

 同一ディレクトリにPNGファイルがあるとして、メソッド
 を使ってファイル名を指定してから、Canvasオブジェクト
 を生成後、貼り付けます。

imgFile = tk.PhotoImage( file = 'ldrv.png' )
cvImage = tk.Canvas(root)
cvImage.create_image(0,0,image = imgFile, anchor = tk.NW )
cvImage.grid(row=5, column=8)

 領域サイズを調整しながら画像表示まで含めると
 以下(RaspberryPiの画面スクリーンショット)。



 この画面を実現するPythonスクリプトは、次のようになります。

import sys
import tkinter as tk
from PIL import Image

#+++++++++++++++++
# generate window
#+++++++++++++++++
root = tk.Tk()
root.title('Green House')
root.geometry('480x300')

# unit
lblUnit1 = tk.Label(text = 'Celcuis')
lblUnit1.grid(row = 0, column = 1)
lblUnit2 = tk.Label(text = 'Celcuis')
lblUnit2.grid(row = 0, column = 2)
lblUnit3 = tk.Label(text = '%')
lblUnit3.grid(row = 0, column = 3)
lblUnit4 = tk.Label(text = 'Celcuis')
lblUnit4.grid(row = 0, column = 5)
lblUnit5 = tk.Label(text = '%')
lblUnit5.grid(row = 0, column = 6)
lblTop = tk.Label(text = 'TOP')
lblTop.grid(row = 1, column = 0)
lblMid = tk.Label(text = 'MIDDLE')
lblMid.grid(row = 2, column = 0)
lblBot = tk.Label(text = 'BOTTOM')
lblBot.grid(row = 3, column = 0)

#++++++++++++++++++++++++++++++++++
# channel 0 parameters
#++++++++++++++++++++++++++++++++++
ch0TopVal = 28
ch0MidVal = 29
ch0BotVal = 29
lblCh0Top = tk.Label(text = str(ch0TopVal) )
lblCh0Top.grid(row = 1, column = 1)
lblCh0Mid = tk.Label(text = str(ch0MidVal))
lblCh0Mid.grid(row = 2, column = 1)
lblCh0Bot = tk.Label(text = str(ch0BotVal))
lblCh0Bot.grid(row = 3, column = 1)

#++++++++++++++++++++++++++++++++++
# channel 1 parameters
#++++++++++++++++++++++++++++++++++
ch1TopVal = 28
ch1MidVal = 27
ch1BotVal = 30
lblCh1Top = tk.Label(text = str(ch1TopVal) )
lblCh1Top.grid(row = 1, column = 2)
lblCh1Mid = tk.Label(text = str(ch1MidVal))
lblCh1Mid.grid(row = 2, column = 2)
lblCh1Bot = tk.Label(text = str(ch1BotVal))
lblCh1Bot.grid(row = 3, column = 2)

#++++++++++++++++++++++++++++++++++
# channel 2 parameters
#++++++++++++++++++++++++++++++++++
ch2TopVal = 72
ch2MidVal = 80
ch2BotVal = 79
lblCh2Top = tk.Label(text = str(ch2TopVal) )
lblCh2Top.grid(row = 1, column = 3)
lblCh2Mid = tk.Label(text = str(ch2MidVal))
lblCh2Mid.grid(row = 2, column = 3)
lblCh2Bot = tk.Label(text = str(ch2BotVal))
lblCh2Bot.grid(row = 3, column = 3)

#+++++++++++++++++
# limit parameters
#+++++++++++++++++
tempUpper = 40
tempLower = 2
humiUpper = 95
humiLower = 20
lblTempUpper = tk.Label(text = 'Upper' )
lblTempUpper.grid(row = 1, column = 4)
lblTempLower = tk.Label(text = 'Lower' )
lblTempLower.grid(row = 2, column = 4)

entTempUpper = tk.Entry(width=4)
entTempUpper.insert(tk.END,str(tempUpper))
entTempUpper.grid(row = 1, column = 5)

entTempLower = tk.Entry(width=4)
entTempLower.insert(tk.END,str(tempLower))
entTempLower.grid(row = 2, column = 5)

entHumiUpper = tk.Entry(width=4)
entHumiUpper.insert(tk.END,str(humiUpper))
entHumiUpper.grid(row = 1, column = 6)

entHumiLower = tk.Entry(width=4)
entHumiLower.insert(tk.END,str(humiLower))
entHumiLower.grid(row = 2, column = 6)

#+++++++++++++++++
# functions
#+++++++++++++++++
def setTemp() :
  utemp = entTempUpper.get()
  ltemp = entTempLower.get()
  print( str(utemp) + ' ' + str(ltemp) )
  tempUpper = utemp
  tempLower = ltemp
  entTempUpper.delete(0,tk.END)
  entTempLower.delete(0,tk.END)
  entTempUpper.insert(tk.END,str(tempUpper))
  entTempLower.insert(tk.END,str(tempLower))

def setHumi():
  uhumi = entHumiUpper.get()
  lhumi = entHumiLower.get()
  print( str(uhumi) + ' ' + str(lhumi) )
  humiUpper = uhumi
  humiLower = lhumi
  entHumiUpper.delete(0,tk.END)
  entHumiLower.delete(0,tk.END)
  entHumiUpper.insert(tk.END,str(humiUpper))
  entHumiLower.insert(tk.END,str(humiLower))

def myExit():
  exit()

#+++++++++++++++++
# Button object
#+++++++++++++++++
btnTempGet = tk.Button( text = 'Set' , command = setTemp )
btnTempGet.grid(row = 3, column = 5)
btnHumiGet = tk.Button( text = 'Set' , command = setHumi )
btnHumiGet.grid(row = 3, column = 6)
btnExit = tk.Button( text = 'Exit' , command = myExit )
btnExit.grid(row = 0, column = 8)

#+++++++++++++++++
# show image
#+++++++++++++++++
imgFile = tk.PhotoImage( file = 'ldrv.png' )
cvImage = tk.Canvas(root)
cvImage.create_image(0,0,image = imgFile, anchor = tk.NW )
cvImage.grid(row = 5, column = 8)

root.mainloop()


目次

inserted by FC2 system