【Python GUI tkinterサンプル】マウス用イベントとplaceを使用してttk.Buttonをマウスカーソルに追従させる(指定した位置に再配置)
使用するイベント
<Button1>:右クリック
<B1-Motion>:右クリック中
<ButtonRelease-1>:右クリック終わり
解説
①<Button1>:ボタンの現在地の取得と、マウスカーソルの位置の取得を行う
②<B1-Motion>:押されたときに取得した位置と現在のマウスカーソル位置で移動距離を計算し、再配置を行う
③<ButtonRelease-1>:保持していた座標をクリアする
※対象のwidget.place_info()でplaceの情報が取得でき、widget.place_configureでplaceの情報を渡すと再設定ができる。
クリックしボタンを動かしたときのサンプル画像
初期配置
クリックしながら動かすとボタンWidgetがマウスカーソルを追従する
サンプルコード
from tkinter import *
import tkinter.ttk as ttk
class ButtonSampleMove(ttk.Frame):
def __init__(self, master):
super().__init__(master,width=300,height=300)
self.start_xy = None
self.x_y = None
self.create_widgets()
self.propagate(False)
self.pack()
def create_widgets(self):
button = ttk.Button(self,text = "button")
button.place(x=100,y=100)
button.bind("<Button-1>",self.move_start)
button.bind("<B1-Motion>",self.move_now)
button.bind("<ButtonRelease-1>",self.move_end)
def move_start(self,event):
# マウスカーソルの座標取得
self.start_xy = (event.x_root,event.y_root)
# 位置情報取得
place_info = event.widget.place_info()
x = int(place_info['x'])
y = int(place_info['y'])
self.x_y = (x,y)
def move_now(self,event):
if self.start_xy is None:
return
# 移動距離を調べる
distance = (event.x_root-self.start_xy[0],event.y_root-self.start_xy[1])
# 再度座標を設定する
place_info = event.widget.place_info()
place_info['x'] = self.x_y[0] + distance[0]
place_info['y'] = self.x_y[1] + distance[1]
event.widget.place_configure(place_info)
def move_end(self,event):
# 座標類を初期化
self.start_xy = None
self.x_y = None
if __name__ == '__main__':
master = Tk()
master.title("ButtonSampleMove")
master.geometry("300x300")
ButtonSampleMove(master)
master.mainloop()