要旨
Listboxをマウスクリックで選択してアクティブ化する際に、ダブルクリックを行わないとアクティブ化できなかった。
シングルクリックでも選択状態にはなるが、アクティブ化されない。
ボタン選択後の処理でアクティブ状態の行に記載されている内容を参照するため、シングルクリックでもアクティブ化する必要があった。
シングルクリックでアクティブ化するためには次の手順を実行する。
- 現在のアクティブ化状態を消去する
- シングルクリック時にマウスカーソルが存在しているy座標(縦軸)を取得する
- y座標に最も近いListboxを選択する
- y座標に最も近いListboxをアクティブ化する
実際のソースコード
class Listbox(tk.Listbox):
def __init__(self, master=None):
tk.Listbox.__init__(self, master)
self.bind("<Button-1>", self.activate_line_clicked)
def hogehoge(self):
# アクティブ状態の行を参照する何らかの処理
def activate_line_clicked(self, event=None):
self.selection_clear(0, tk.END) # 要旨に記載した手順1
self.selection_set(self.nearest(event.y)) # 要旨に記載した手順2, 3
self.activate(self.nearest(event.y)) # 要旨に記載した手順2, 4
# ボタン選択時の処理実行
self.hogehoge()
各メソッドの説明
self.selection_clear()
指定した行(ここでは0行目からtk.ENDつまり最後の行まで)の選択を解除する。
self.nearest(y)
与えられたy座標に近い行を返す。
ここではevent.yを引数として渡している。
****というシングルクリックした際に生成されるeventを使用して、シングルクリックされた位置のy座標をevent.yで取得している。
self.selection_set()
指定した行を選択する。
行を選択しない場合でもActive状態にはできる。ただ、シングルクリックしてActive状態にする場合は必ず行を選択するため、選択した行=Active状態の行
となる。
そのため、プログラム中でも明示的にActive状態にする行を選択している。
self.activate()
指定した行をActive状態にする。
参考
stackoverflowの質問:Is there any way to select an item in a Tkinter Listbox the right click?
参考にした回答:Okay, I figured it out.First, use the bind command:...
質問者:Jadon Erwin
回答者:Jadon Erwin
14. The Listbox widget
Listboxオブジェクトについての説明
54.6. Writing your handler: The Event class
Eventオブジェクトについての説明