PythonでDBを使用してみる その4 Tkinter(GUIライブラリ)を使ってみる2

こんにちは。そらです。
前回の続きでtkinterのウィジェットを触っていこうと思います。ボタンを押したときに処理をしていくことをしていきたいと思います。
その後、ボタンを押されたときに新しいウィンドウを作るということをやっていきます。ライブラリの詳しい使い方は参考文献を参照していただければと思います。それぞれの説明のところでは記載しませんが、コンストラクタに作成した関数を呼び出す必要があります。




ボタンを押したときにテキストボックス(Entry)のデータを取得する

ボタンを画面に追加してみる

ボタンをウィジェットの表面に配置してみたいと思います。前回作成したクラスのメソッドの一つとして実装しましょう。

def addButton(self):
  self.button = ttk.Button(self, text="click here").grid(column=0, row=3, sticky=(ttk.N, ttk.S, ttk.E, ttk.W))

ボタンを押されたときに関数を実行する

ウィジェットにボタンを配置してみましたが、このままではボタンが押されたときに何か処理をするということができません。引数について調べてみるとcommandの引数に関数を与えてあげることでボタンを押したときの処理を実行できるそうです。前回のプログラムも含め、以下のように改造しました。改造をしたところだけ以下に記載します。

def addTextBox(self):
  self.text_box = ttk.Entry(self)
  self.text_box.grid(column=0, row=2, sticky=(ttk.N, ttk.S, ttk.E, ttk.W))

def addButton(self):
  self.button = ttk.Button(self, text="click here", command=self.showEntry).grid(column=0, row=3, sticky=(ttk.N, ttk.S, ttk.E, ttk.W))

def showEntry(self):
  entry_str = self.text_box.get()
  print(entry_str)

テキストを入力してからボタンを押すと、標準入出力にテキストボックスの内容を出力します。

Tkinter Toplevelを使用してみる

複数ウィンドウを表示してみる

Tkinterで複数のウィジェットを扱う場合は、Toplevelメソッドを使用することでできるそうです。物は試しということで別途クラスを製作して使ってみたいと思います。

def addSubWindowButton(self):
  self.button = ttk.Button(self, text="make subwindow", command=self.makeSubWindow).grid(column=0, row=4, sticky=(ttk.N, ttk.S, ttk.E, ttk.W))
def makeSubWindow(self):
  sub = SubWindow(ttk.Toplevel())

class SubWindow(ttk.Toplevel):
  def __init__(self, master = None):
    self.master = master

実行をして、make subwindowボタンをクリックするとウィンドウが生成されると思います。また、ここで生成されるウィンドウの上限はないことがわかります。一つしかウィンドウが作られないように以下のように改造をしていきたいと思います。

ひとつだけウィンドウを表示するようにしてみる

サブウィンドウを表示したいが、ボタンを押すと無限に増えていくのは嫌だということがあると思います。コンストラクタにオブジェクトを定義しておいて、オブジェクトに情報があるかどうかでサブウィンドウを表示するかどうかを決定するプログラムを書いていきたいと思います。

def makeSubWindow(self):
  self.sub_window.makeNewWindow()

class SubWindow():
  def __init__(self):
    self.window = None

  def makeNewWindow(self):
    if not self.window:
      self.window = ttk.Toplevel()
      self.window.protocol("WM_DELETE_WINDOW", self.close)

  def close(self):
    self.window.destroy()
    self.window = None 

コンストラクタにSubWindowクラスのオブジェクトを作成して、SubWindowクラスの中にwindowオブジェクトを作っておいてmakeNewWindowsが呼ばれたときにウィンドウがなければ表示、あれば何もしないという処理に置き換えました。
また、このウィンドウが削除されるときにcloseメソッドが呼ばれるようにして、その中でウィンドウの破壊、windowオブジェクトを再び何も持っていない状況にするというようにプログラムを改造しました。

ここまでのプログラムの全文

import tkinter as ttk
from tkinter import font

class Application(ttk.Frame):
  def __init__(self, master = None):
    super().__init__(master)
    self.master = master
    self.pack()
    self.addLabel()
    self.addChangeFonrLabel()
    self.addTextBox()
    self.addButton()
    self.addSubWindowButton()
    self.sub_window = SubWindow()

  def addLabel(self):
    ttk.Label(self,text="hello world").grid(column=0, row=0, sticky=(ttk.N, ttk.S, ttk.E, ttk.W))

  def addChangeFonrLabel(self):
    font_label = ttk.font.Font(family='Times', size=20)
    ttk.Label(self,text="hello world", font=font_label).grid(column=0, row=1, sticky=(ttk.N, ttk.S, ttk.E, ttk.W))

  def addTextBox(self):
    self.text_box = ttk.Entry(self)
    self.text_box.grid(column=0, row=2, sticky=(ttk.N, ttk.S, ttk.E, ttk.W))

  def addButton(self):
    self.button = ttk.Button(self, text="click here", command=self.showEntry).grid(column=0, row=3, sticky=(ttk.N, ttk.S, ttk.E, ttk.W))

  def showEntry(self):
    entry_str = self.text_box.get()
    print(entry_str)

  def addSubWindowButton(self):
    self.button = ttk.Button(self, text="make subwindow", command=self.makeSubWindow).grid(column=0, row=4, sticky=(ttk.N, ttk.S, ttk.E, ttk.W))

  def makeSubWindow(self):
    self.sub_window.makeNewWindow()

class SubWindow():
  def __init__(self):
    self.window = None

  def makeNewWindow(self):
    if not self.window:
      self.window = ttk.Toplevel()
      self.window.protocol("WM_DELETE_WINDOW", self.close)

  def close(self):
    self.window.destroy()
    self.window = None

root = ttk.Tk()
app = Application(root)
app.mainloop() 

さいごに

今回は、前回と同様にTkitnerの各種機能の使い方の例を紹介しました。次回は、DBの操作をするウィンドウの製作に取り掛かりたいと思います。次回からは新しいプログラムを使用していく予定です。

次回予告

DBを使用していくプログラムの製作に入っていく予定です。

参考文献

Tk を用いたグラフィカルユーザインターフェイス

An Introduction to Tkinter (Work in Progress)