【Python tkinter】複数のデータをリスト表示:Listbox(リストボックス)ウィジェット

時計 2021.05.19 / 時計

【Python tkinter】複数のデータをリスト表示:Listbox(リストボックス)ウィジェット

本記事ではPythonのTkinterにおける、Listbox(リストボックス)ウィジェットを使用した、複数の選択肢(データ)をリスト表示する方法について解説していきます。

Tkinterに用意されているウィジェットは豊富にあります。
Tkinterには19種類のウィジェットがあり、これらを組み合わせてGUIアプリケーションを作成していきます。

ウィジェット名 説明
Frame ウィジェットをまとめるためのコンテナとして使用
Label 文字列やイメージを表示
Entry 1行の文字列入力ボックスを表示
Button 押下できるボタンを表示
Checkbutton チェックボックスとして複数の選択肢を表示
Radiobutton ラジオボタンとして複数の選択肢を表示
Listbox 選択肢のリストを表示
Canvas 線、楕円、多角形などを描画
Menubutton メニュー項目を表示
Menu Menubutton内に含まれるコマンドを提供
Message ユーザーへのメッセージボックスを表示
Scale スケールから値を選択できるグラフィカルスライダーを表示
Scrollbar リストボックスなどのウィジェットにスクロールバーを追加
Text 複数行を入力できるテキストを表示
Toplevel 別のWindowを表示
Spinbox 固定の値を選択できるEntryウィジェットを表示
PanedWindow 複数のペインを含んだコンテナを表示
LabelFrame ラベルを表示するフレーム
MessageBox 様々なメッセージボックスを表示

データをリスト表示するウィジェットはいくつか存在します。

本記事ではListbox(リストボックス)に焦点をあてて、使い方やオプションについて詳しく説明していきます。

Listbox(リストボックス)ウィジェット

Listboxウィジェットとは

Listboxウィジェットは、一行のテキストデータをリスト表示できるウィジェットです。

tkinter:listboxウィジェット

ユーザーはリスト内のデータを、1つまたは複数を選択できます。
複数のデータを選択できるようにするには、後ほど解説するオプションselectmodeを使用する必要があります。

tkinter:listboxウィジェットのデータを選択

またリストボックス内のデータは、すべて同じフォントタイプ・フォントサイズ・文字色となります。

Listboxウィジェットの生成

Listboxウィジェットを作成するために、次のようにtk.Listboxを使用します。

listbox = tk.Listbox(parent, options)

parentには表示させたい親ウィジェット(frameウィジェット)を指定します。

optionsにはListboxウィジェットに用意されているオプションを指定します。

オプション一覧

Listboxウィジェットに用意されているオプションの一覧を以下に記します。

オプション名 説明
bg or background リストボックスの背景色
bd or borderwidth 枠線のサイズ
cursor マウスホバー時のカーソルの種類
width 横幅:1行の文字数(デフォルト20)
font テキストのフォントタイプ・文字サイズの設定
fg or foreground リストボックス内のデータ文字色
height 高さ:表示するデータ数(デフォルト10)
relief リストボックスのデザイン
selectmode モードの選択:BROWSE(デフォルト)、SINGLE、MULTIPLE、EXTENDED
takefocus TABキーによる移動の許可
activestyle データの選択時のスタイル:DOT、NONE、UNDERLINE(デフォルト)
state リストボックスの状態:NORMAL(デフォルト)、DISABLED
justify テキストの配置位置:LEFT、CENTER、RIGHT

各オプションの使用方法

背景色:bg or background

オプションbgまたはbackgroundによって、リストボックス内の背景色を指定することができます。

listbox = tk.Listbox(frame, bg="red")

tkinter:Listboxオプションのbackground

色の指定には、blackやredなどの英語表記、または16進数(#FFFFFF)で指定をします。

ボーダーサイズ:bd or borderwidth

オプションbdまたはborderwidthによって、枠線のサイズを指定することができます。
bdのデフォルト値は2ピクセルです。

listbox = tk.Listbox(frame, bd=10)

tkinter:Listboxオプションのborderwidth

カーソル:cursor

オプションcursorによって、リストボックスにマウスがホバーしたときのカーソルの種類を指定することができます。

listbox = tk.Listbox(frame, cursor="dot")

カーソルの種類については、以下サイトを参考にしてください。

Python – Tkinter Cursors

横幅:width

オプションwidthによって、リストボックスの横幅を指定できます。
指定する数値は、表示するデータの文字数です。

widthのデフォルトは20です。

listbox = tk.Listbox(frame, width=10)

tkinter:Listboxオプションのwidth

フォンタイプ・文字サイズ:font

オプションfontによって、テキストの大きさやフォントタイプを指定することができます。
第一引数にフォントタイプ、第二引数に文字サイズを指定します。

listbox = tk.Listbox(frame, font=("Lucida Console",15))

tkinter:Listboxオプションのfont

文字色:fg or foreground

オプションbgまたはforegroundによって、リストボックス内のデータ文字色を指定することができます。

listbox = tk.Listbox(frame, fg="blue")

tkinter:Listboxオプションのforeground

色の指定には、blackやredなどの英語表記、または16進数(#FFFFFF)で指定をします。

データテキストの位置:justify

オプションjustifyによって、リストボックスに表示するデータテキストの文字位置を指定することができます。

指定できる値は、left、center、rightです。

listbox = tk.Listbox(frame, justify="center")

tkinter:Listboxオプションのjustify

ボーダーデザイン:relief

オプションreliefによって、リストボックスのボーダースタイル(デザイン)を変更することができます。

ポイント

reliefを指定する場合は、bdを1以上に指定しましょう

listbox = tk.Listbox(frame, bd=5, relief="groove")

tkinter:Listboxオプションのrelief
ボーダースタイル 説明
FLAT 平面
RAISED ボタンが隆起
SUNKEN ボタンが凹む
GROOVE 枠が凹む
RIDGE 枠が隆起
SOLID 枠が実線

モードの選択:selectmode

オプションselectmodeによって、リストボックス内のデータの選択モードを変更できます。

複数のデータを選択できるようにするには、multipleまたはextendedを指定します。

  • browse:1つのみ選択可能。ドラッグで別データを選択できる。デフォルト値
  • single:1つのみ選択可能
  • multiple:複数を選択可能。
  • extended:複数を選択可能。Ctrl+クリックなどで複数選択ができる

listbox = tk.Listbox(frame, selectmode="multiple")

状態の変更:state

オプションstateによって、リストボックスの状態をしていできます。
tk.DISABLEDを指定すると、データ選択が不可になります。

stateのデフォルト値はNORMALです。

listbox = tk.Listbox(frame, state=tk.DISABLED)

Listbox(リストボックス)ウィジェットのメソッド一覧

以下にListboxウィジェットに関連するメソッドを記します。

メソッド名 説明
.activate(index) indexで指定した行を選択
.curselection() 選択されたデータのインデックスを返す
.delete(first, last) firstとlastで指定した範囲の行を削除
.get(first, last) firstとlastで指定した範囲のデータを取得
.index(i) 指定したインデックスの位置を取得
.insert(index, data) 指定したインデックスの前にdataを挿入
.size() リストボックスの行数(データ数)を返す
.yview() 縦方向のスクロールのためにScrollbarのcommandに設定
.xview() 横方向のスクロールのためにScrollbarのcommandに設定

リストボックスの選択肢(データ初期値)を作成:listvariable

リストボックスに入れる初期値はlistvariableやtk.StringVarを使うことで指定できます。

まず最初にリストボックスに入れたい初期値(データ群)を作成します。

module = ('tkinter', 'os', 'datetime', 'math')

次にtk.StringVarを次のように使用します。

var = tk.StringVar(value=module)

最後にリストボックスを生成する際、listvariableでStringVarオブジェクトを指定します。

listbox = tk.Listbox(frame, listvariable=var)

上記流れにより、リストボックスに表示する初期値を作成することができます。

module = ('tkinter', 'os', 'datetime', 'math')
var = tk.StringVar(value=module)
listbox = tk.Listbox(frame, listvariable=var)

リストに選択肢(データ)を追加:insert()メソッド

listvariableで初期値を設定したあとに、データ(選択肢)を追加した場合はinsert()メソッドを使用します。

listbox.insert(インデックス, データ)

インデックスでは、指定したデータを挿入する位置を指定します。
ENDを指定することで、リストボックスの末尾にデータを追加します。

Scrollbarを追加する:tk.Scrollbar、yscrollcommandオプション

リストボックスでは縦方向または横方向にスクロールバーを付けることができます。

リストボックスの高さ(表示できる行数)以上にデータ数がある場合、スクロールしなければすべてのデータを閲覧することはできません。

スクロールバーは自動的に付かないため、Scrollbarウィジェットを作成し、それをlistboxウィジェットに紐づけてあげる必要があります。

Scrollbarウィジェットは次のように作成します。

scrollbar = ttk.Scrollbar(frame, orient='vertical', command=listbox.yview)

orientにはverticalまたはhorizon、commandにはリストボックスオブジェクトにyviewメソッドを設定したものを指定します。

次に作成したScrollbarとリストボックスを以下のようにして関連付けます。

listbox['yscrollcommand'] = scrollbar.set

上記のように、listboxオブジェクトのyscrollcommandオプション(横の場合はxscrollcommand)にScrollbarのsetメソッドを設定します。

あとはlistboxとscrollbarを設置すれば、スクロールバーが設置されたリストボックスが表示されます。

以下にリストボックスに縦スクロールバーを設置したプログラムを記します。

import tkinter as tk
from tkinter import ttk

root = tk.Tk()
root.geometry('220x200')
root.title('Listbox')

module = ('tkinter', 'os', 'datetime', 'math', 'sys', 'time', 'glob', 'ttk','numpy')
var = tk.StringVar(value=module)

frame = tk.Frame(root)
listbox = tk.Listbox(frame,listvariable=var, selectmode="multiple", height=6)

scrollbar = ttk.Scrollbar(frame, orient='vertical', command=listbox.yview)
listbox['yscrollcommand'] = scrollbar.set

frame.pack(padx=10, pady=20)
listbox.pack(side='left')
scrollbar.pack(side='right', fill='both')

root.mainloop()

選択時のイベント(関数)をバインドする:bind()メソッド

あるオブジェクトに特定のイベントが発生した場合に実行する処理(関数)を設定(バインド)するにはbind()メソッドを使用します。

オブジェクト.bind(イベント, 関数)

第一引数のイベントには、イベントの種類を指定します。
例えば、キーが押された時のイベントであれば”<KeyPress>”、マウスがスクロールされた時のイベントであれば"<MouseWheel>"となります。

リストボックス内のデータ選択時に実行されるイベント(実行する関数)をバインドするには、イベント<<ListboxSelect>>を指定します。

listbox.bind('<<ListboxSelect>>', 実行する関数)

ListboxSelectは仮想イベントなので、<>を2つ必要なことに注意してください。

Listboxで選択された値(データ)を取得:curselection()、get()

リストボックス内のデータが選択された際に、メッセージボックスで選択されているデータを表示するプログラムを作成してみます。

関数の定義

まずはデータが選択された際に実行する関数を定義します。
関数の定義は次のようにします。

def selected():

選択されたデータのインデックス取得

選択されたデータのインデックスを取得にはcurselection()メソッドを使用します。

selected = listbox.curselection()

上記で選択されたデータのインデックスが変数selectedに代入されます。

インデックスからデータを取得

このインデックスから選択されたデータ(値)をget()メソッドを使って取得します。

listbox.get(インデックス)

get()メソッドの引数には、curselection()で取得したインデックス番号を指定します。

ソースコード

実際に作成したプログラムのソースコードを下記に記します。

tkinter:Listboxで選択された値を取得するプログラム
import tkinter as tk
from tkinter import ttk
from tkinter.messagebox import showinfo

def selected(event):
    selected_indices = listbox.curselection()
    selected_module = ",".join([listbox.get(i) for i in selected_indices])
    msg = f'選択したモジュール: {selected_module}'

    showinfo(title='Information', message=msg)

root = tk.Tk()
root.geometry('220x200')
root.title('Listbox')

module = ('tkinter', 'os', 'datetime', 'math', 'sys', 'time', 'glob', 'ttk','numpy')
var = tk.StringVar(value=module)

frame = tk.Frame(root)
listbox = tk.Listbox(frame,listvariable=var, selectmode="multiple", height=6)

scrollbar = ttk.Scrollbar(frame, orient='vertical', command=listbox.yview)
listbox['yscrollcommand'] = scrollbar.set

frame.pack(padx=10, pady=20)
listbox.pack(side='left')
scrollbar.pack(side='right', fill='both')

listbox.bind('<>', selected)
root.mainloop()

Listboxで選択された値(データ)を削除:delete()

リストボックス内のデータが選択された際に、選択されたデータを削除するプログラムを作成してみます。

データを削除するためのdelete()メソッドを使用します。

Listbox.delete(インデックス)

delete()メソッドのインデックスには、curselection()で取得したインデックスを指定します。

Listboxで選択されたデータを削除するプログラムは次のようになります。

import tkinter as tk
from tkinter import ttk

def selected(event):
    selected_indice = listbox.curselection()
    listbox.delete(selected_indice)

root = tk.Tk()
root.geometry('220x200')
root.title('Listbox')

module = ('tkinter', 'os', 'datetime', 'math', 'sys', 'time', 'glob', 'ttk','numpy')
var = tk.StringVar(value=module)

frame = tk.Frame(root)
listbox = tk.Listbox(frame,listvariable=var, selectmode="multiple", height=6)

scrollbar = ttk.Scrollbar(frame, orient='vertical', command=listbox.yview)
listbox['yscrollcommand'] = scrollbar.set

frame.pack(padx=10, pady=20)
listbox.pack(side='left')
scrollbar.pack(side='right', fill='both')

listbox.bind('<>', selected)
root.mainloop()

まとめ

本記事「【Python tkinter】複数のデータをリスト表示:Listbox(リストボックス)ウィジェット」はいかがでしたか。

Listboxの使い方から、オプション一覧、メソッド、スクロールバーの追加方法などを解説してきました。

Listboxは様々な用途で使うことができるウィジェットです。

ぜひListboxを今後作成するGUIアプリケーションに使ってみてください。