【Python】Tkinter リストボックス選択時にイベントを発生させる方法

Python

本記事では、Tkinterの「リストボックス」において、イベントを発生させる方法を解説します。

コピペ用ソースコードは本記事の最後に載せています。

Tkinterについて、概要をおさらいしておきたい!という方は、以下記事をご参照ください。

リストボックスの作成方法

まずはじめに、リストボックスの作成方法について紹介します。

たとえば、上記のようなリストボックスを作成する場合、以下の2ステップで行います。

  1.  部品を定義する
  2.  1で作成した部品を配置する

具体的には以下のようになります。

list_val = ("りんご", "みかん", "バナナ", "ぶどう", "なし")
var = tkinter.StringVar(value=list_val)
input_list = tkinter.Listbox(frame2, selectmode="single", listvariable=var, height=15, width=60)
input_list.grid(row=2, column=4, padx=10, pady=10)

tkinter.Listbox が、部品の定義部分です。この引数に、selectmode(単一選択)とか、listvariable(リストの内容)などを定義していきます。

input_list.gridで、作成した部品を配置しています。引数には、配置する座標やパディング(部品間の間隔)を指定します。

部品の配置方法についての詳しい解説はこちらの記事にて行っています。

csvファイルからリスト項目をインポートしたい場合

csvファイルからリスト項目をインポートしたい場合は、以下のように行います。

csvファイルの作成

リストに表示するためのcsvファイルを作成します。ファイル名は「test.csv」としています。

【test.csv】

honban,yamada@test.com,password
staging,tanaka@test.com,psw
test1,suzuki@test.com,pass0123
test2,suzuki@test.com,pass0123

csvファイル読み込み処理を作成

csvファイルの中身を読み込んで、一行ずつ配列(リスト)に追加していきます。

【read_csv.py】
import csv

def read_csv():
    path = "./test.csv"

    with open(path, encoding='utf8', newline='') as f:
        reader = csv.reader(f)
        csv_arr = []
        for row in reader:
            csv_arr.append(row)
    return csv_arr

リスト生成時にcsvファイル内容をセットする

最後に、前項で作成したリストをlistvariableにセットします。

【login.py】

import read_csv
(略)

var = tkinter.StringVar(frame2, value=read_csv.read_csv())
input_list = tkinter.Listbox(frame2, selectmode="single", listvariable=var, height=15, width=60)
input_list.grid(row=2, column=4, padx=10, pady=10)

read_csv.pyを別ファイルにモジュール化する場合は、import read_csvを忘れずに追加してください。

選択時にイベントを発火させる方法

リストボックスの内容を選択した際に、別の項目にその値を反映させるなど、何かしらの処理を行いたい場合があります。このように、リストボックスの状態が変更された場合に処理を行うことを「イベント処理」といいます。

これをどうやって行うかというと、「ListboxSelect」という仮想イベントを該当のリストボックスにバインド(関連付け)させてあげます。

【login.py】

var = tkinter.StringVar(frame2, value=readCsv.read_csv())
input_list = tkinter.Listbox(frame2, selectmode="single", listvariable=var, height=15, width=60)
input_list.bind('<<ListboxSelect>>', list_selected)
input_list.grid(row=2, column=4, padx=10, pady=10)

こうすることで、リストボックスの項目が選択されたら「list_selected」関数が実行されるようになります。

リストボックスの選択内容を別項目に反映させる方法

前項の内容をもとに、リストボックスで選択した内容を別項目に反映させる処理を作ります。

リストボックスへのイベント紐づけは、

input_list.bind('<<ListboxSelect>>', list_selected)

で行いました。第2引数の「list_selected」関数を定義します。

【login.py】

def list_selected(event):
    selected_index = input_list.curselection()
    if selected_index:
        selected_module = input_list.get(selected_index)
        clear()
        input_combo.insert(0, selected_module[0])
        input_id.insert(0, selected_module[1])
        input_password.insert(0, selected_module[2])

def clear():
    input_combo.delete(0, tkinter.END)
    input_id.delete(0, tkinter.END)
    input_password.delete(0, tkinter.END)
    input_list.select_clear(0, tkinter.END)

引数を「event」にすると、イベント発生時にクリックされたときの情報が渡されます。clear()で各項目の内容をクリアしてからセットします(クリアしないと追記されてしまう)。

コピペ用ソースコード

以下にコピペOKのソースコードを載せておきます。なお、実際に動かすには

  • test.csv
  • read_csv.py
  • login.py

が必要となります。

import tkinter
from tkinter import messagebox
import tkinter.ttk as ttk

#import read_csv
#from login import loginMypage


def list_selected(event):
    selected_index = input_list.curselection()
    if selected_index:
        selected_module = input_list.get(selected_index)
        clear()
        input_combo.insert(0, selected_module[0])
        input_id.insert(0, selected_module[1])
        input_password.insert(0, selected_module[2])


def login():
    input_id_value = input_id.get()
    input_combo_value = input_combo.get()
    input_password_value = input_password.get()
    input_list_value = input_list.curselection()

    if not input_combo_value and not input_list_value:
        messagebox.showinfo("入力内容", "URLが未選択です")
    else:
        #loginMypage(input_combo_value, input_id_value, input_password_value)


def clear():
    input_combo.delete(0, tkinter.END)
    input_id.delete(0, tkinter.END)
    input_password.delete(0, tkinter.END)
    input_list.select_clear(0, tkinter.END)


# ウインドウの作成
root = tkinter.Tk()
root.title("〇〇システム テスト用")
root.geometry("840x400")

frame1 = tkinter.Frame(root, relief=tkinter.FLAT, bd=1, height=100, width=500, pady=10, padx=30)
frame1.grid(column=1, row=0)

# URL
input_combo = tkinter.Label(frame1, text="URL")
input_combo.grid(row=1, column=1, pady=10, padx=10)
variable = tkinter.StringVar()
test_target = ("honban", "staging", "test1", "test2")
input_combo = ttk.Combobox(frame1, values=test_target, textvariable=variable, width=32)
input_combo.grid(row=1, column=2, padx=10, pady=10)

# ID
input_id_label = tkinter.Label(frame1, text="ユーザーID/mail")
input_id_label.grid(row=2, column=1, padx=10, pady=10)
input_id = tkinter.Entry(frame1, width=35)
input_id.grid(row=2, column=2)

# パスワード
input_password_label = tkinter.Label(frame1, text="パスワード")
input_password_label.grid(row=3, column=1, padx=10, pady=10)
input_password = tkinter.Entry(frame1, width=35)
input_password.grid(row=3, column=2)

frame2 = tkinter.Frame(root, bd=2, height=100, width=500, pady=10, padx=10)
frame2.grid(column=4, row=0)

# コンボボックス(csv読み込み)
input_list_label = tkinter.Label(frame2, text="test.csvの内容")
input_list_label.grid(row=1, column=4, padx=10, )
var = tkinter.StringVar(frame2, value=read_csv.read_csv())
input_list = tkinter.Listbox(frame2, selectmode="single", listvariable=var, height=15, width=60)
input_list.bind('<<ListboxSelect>>', list_selected)
input_list.grid(row=2, column=4, padx=10, pady=10)

# ログインボタン
button = tkinter.Button(text="ログイン", command=login, width=20, height=1, padx=10, pady=10, bg='#dae3ea')
button.place(x=300, y=320)


# 閉じるが押されたときの後処理
def click_close():
    root.destroy()


root.protocol("WM_DELETE_WINDOW", click_close)
root.mainloop()

「ログイン」ボタンを押したあとの処理はまた別ファイルとなるため、コメントアウトしています。もし、ログイン後の処理も共有してほしいという方がいらっしゃいましたらお気軽にコメントorお問い合わせください。

パスワードを伏字にしたい場合は、引数にshow='*'を追加してください。

まとめ

今回は、Tkinterの「リストボックス」において、イベントを発生させる方法について解説しました。

日々の業務で、複数の環境に入って操作する機会があるのですが、アカウント情報を忘れてログインから手こずってしまうことがあります。さらには、検証で同じような操作を繰り返しすることもけっこうあるので、簡単にできるようにツールを作ることにしました。実際使っているものはログインだけでなく一連の操作ができるようにしていますが、なかなか便利です。

ちょっとしたツールを作るのに、Tkinterは手軽でいいなと感じているので、今後またなにか作成したらブログにて共有したいと思います。

chaso

文系出身、数字が苦手な平凡主婦。塾講師、大手企業SE、不動産事務、Webライター、QAエンジニアを経て現在RPAエンジニアとして働いています。機械音痴だけど効率化や自動化をこよなく愛しています!お仕事の依頼・ご相談は問い合わせよりお願いいたします♪

chasoをフォローする

コメント

タイトルとURLをコピーしました