【Python GUI tkinterサンプル】マウス用イベントとplaceを使用してttk.Buttonをマウスカーソルに追従させる(指定した位置に再配置)

<tkinterトップページに戻る>

使用するイベント

<Button1>:右クリック

<B1-Motion>:右クリック中

<ButtonRelease-1>:右クリック終わり

解説

①<Button1>:ボタンの現在地の取得と、マウスカーソルの位置の取得を行う

②<B1-Motion>:押されたときに取得した位置と現在のマウスカーソル位置で移動距離を計算し、再配置を行う

③<ButtonRelease-1>:保持していた座標をクリアする

※対象のwidget.place_info()でplaceの情報が取得でき、widget.place_configureでplaceの情報を渡すと再設定ができる。

クリックしボタンを動かしたときのサンプル画像

初期配置

button_button1

クリックしながら動かすとボタンWidgetがマウスカーソルを追従する

button_b1motion

 

 

サンプルコード

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()

 

 

 

あわせて読みたい