Python 標準 GUI ライブラリ Tkinter で Listbox
を使うと、項目数が増えた瞬間にスクロールがなくて詰まる──そんな経験ありませんか?
実は たった 3 行 追加するだけで縦横スクロール対応のリストボックスが完成します。本記事では 「まず動く最小コード」→「pack/grid/ttk 別の応用レシピ」→「スクロールが動かない原因チェック」 の順で、初心者でも迷わないよう体系的に解説します。
Listbox と Scrollbar が連携する仕組み
Tk の Listbox
には
・yscrollcommand … スクロールバーの位置を通知
・xscrollcommand … 水平バー用
があらかじめ用意され、逆に Scrollbar
側は command で Listbox.yview()
/xview()
を呼び出します。この双方向コールバックが噛み合うと、つまみ移動で表示範囲が同期するわけです。citeturn0search10
環境と前提条件
項目 | 推奨バージョン | 理由 |
---|---|---|
Python | 3.8 – 3.12 | 3.12 でも API 変更なし |
Tk | 8.6 以上 | ttk テーマ対応 |
OS | Windows / macOS / Linux 共通 | バンドル Tcl/Tk で動作 |
超高速!3 行サンプルコード
from tkinter import Tk, Listbox, Scrollbar, RIGHT, Y
lb = Listbox(Tk()); Scrollbar(lb.master, command=lb.yview).pack(side=RIGHT, fill=Y)
lb.pack(); lb.config(yscrollcommand=lb.master.children['!scrollbar'].set)
Tk().mainloop()
① インポートを除く 3 行 で実行可
②Scrollbar
はListbox
と同じ親ウィジェットで OK
③yscrollcommand
とcommand
を相互設定すれば完了
コード解説
行 | 処理 | 補足 |
---|---|---|
1 | Listbox と親ウィンドウ生成 | 省メモリなら Tk() を変数に入れる |
2 | Scrollbar → yview をコールバック | fill=Y で縦方向に伸長 |
3 | Listbox に yscrollcommand を設定 | Scrollbar.set が自動でつまみ位置を更新 |
実用パターン別レシピ
pack で縦スクロール(基本形)
root = Tk()
frame = Frame(root)
frame.pack()
sb = Scrollbar(frame)
sb.pack(side=RIGHT, fill=Y)
lb = Listbox(frame, yscrollcommand=sb.set)
lb.pack(side=LEFT, fill=BOTH, expand=True)
sb.config(command=lb.yview)
パック順が「スクロールバー → リストボックス」でも動きますが、可読性重視でフレームを挟むと UI が崩れません。
grid で縦+横を同時に付ける
root = Tk()
lb = Listbox(root, width=40, height=10)
vbar = Scrollbar(root, command=lb.yview)
hbar = Scrollbar(root, orient='horizontal', command=lb.xview)
lb.grid(row=0, column=0, sticky='nsew')
vbar.grid(row=0, column=1, sticky='ns')
hbar.grid(row=1, column=0, sticky='ew')
lb.config(yscrollcommand=vbar.set, xscrollcommand=hbar.set)
root.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(0, weight=1)
grid
はセルサイズを動的に伸縮できるので、レスポンシブなツール系 GUI に最適です。
ttk + themed scrollbar でモダン UI
from tkinter import Tk, ttk
root = Tk()
style = ttk.Style(root); style.theme_use('clam') # Dark mode 対応
lb = tk.Listbox(root)
vbar = ttk.Scrollbar(root, command=lb.yview)
lb.config(yscrollcommand=vbar.set)
vbar.pack(side=tk.RIGHT, fill=tk.Y)
lb.pack(fill=tk.BOTH, expand=True)
ttk.Scrollbar
を使うだけでネイティブライクな外観に。Python Assets の記事でも ttk + Listbox 組み合わせが推奨されています。
スクロールが動かないときのチェックリスト
症状 | 原因 | 解決策 |
---|---|---|
つまみが動いてもリストが動かない | command 未設定 | Scrollbar(command=lb.yview) を確認 |
リストは動くがバー位置が更新されない | yscrollcommand 未設定 | lb.config(yscrollcommand=sb.set) |
横方向だけ効かない | orient='horizontal' 不足 | Scrollbar(..., orient='horizontal') |
バーが横に並ぶ | pack 順序ミス | フレームで左右を明示 |
バーが消えた | アイテム数不足 | height を小さくして動作確認 |
よくある質問
Q. Listbox を 2 列にしたい場合は?
A. ttk.Treeview
や ttk.ListboxExtension
が便利。複数列・ソート付きで、スクロールバー連携も同じ要領です。
Q. macOS でスクロールバーが細すぎる
A. style.configure("Vertical.TScrollbar", troughcolor="#ddd", width=14)
で太さを調整可能。
Q. MouseWheel を連動させたい
A. <MouseWheel>
イベントを lb.yview_scroll(int(-1*(event.delta/120)), "units")
にバインドすると自然な動きになります。
まとめ
- やることは 3 行 ―
Scrollbar(command=…)
,yscrollcommand
,pack/grid
のみ grid
なら縦横バーも楽々レイアウト、ttk
を使えばモダンに- 動かないときは コールバック設定漏れ と orient を最優先で疑う
- GUI ツール自作・ログビューア・チャットアプリなど、スクロール可能リストは Tkinter の鉄板部品。ぜひ本記事のサンプルをコピペして即活用してください。
コメント