6

キャンバスにドラッグアンドドロップできるリストボックスを作成しようとしています。以前にドラッグアンドドロップを行ったことがありますが、ここで見つけたこのチェッカープログラムのコードに基づいて大まかにcanvas.create_textの間だけでした。ドラッグ アンド ドロップ リストボックスに関するいくつかの質問を見てきましたが、それらはリストボックス内の要素の順序の変更のみを扱っています。私が扱っているのは、名前のリストを持つリストボックスと、キャンバス上にいくつかの create_text オブジェクトを持つキャンバスであり、リストボックスからキャンバスに名前をドラッグできるようにしたいと考えています。図の場合、リストボックスのサブクラスを作成する必要がありますが、そこからどこに行くべきかわかりません。

だから私はDialogWindow(Toplevelのサブクラス)を持っていて、DialogWindowにキャンバスとリストボックスを持っています。リストボックスから名前を取得する方法を考え出しました。名前をクリックすると、それを canvas.create_text オブジェクトに変換してからドラッグします。私の問題はドロップです。canvas.canvasx を使用してキャンバス座標に変換しようとしましたが、うまくいきませんでした。x と y はまだリストボックス座標にあります。

def onRelease(self, event): 
    x = self.canvas.canvasx(event.x)
    y = self.canvas.canvasx(event.y)
    print(event.x, event.y)
    print(x, y) #Prints the same thing as the previous line
4

1 に答える 1

4

ドラッグ アンド ドロップの要点は、次の 3 つのことを行う必要があるということです。

  • バインドし<ButtonPress-1>て、ドラッグするアイテムを選択します
  • バインドし<B1-Motion>てドラッグする
  • バインドし<ButtonRelease-1>てドロップする

これには、サブクラス化は必要ありません。これらのバインディングはすべてリストボックス ウィジェットにあります。テキスト ラベルを含む のインスタンスを作成しToplevel、ウィンドウの装飾を ( を使用してwm_overrideredirect(True)) 削除して、ドラッグされているアイテムを表すことをお勧めします。

canvasxドロップ時に、キャンバスのおよびcanvasyメソッドを使用して、マウスの座標をキャンバス座標に変換する必要があります。event.xand event.y(リストボックスに相対的) から始める代わりに、winfo_pointerxyメソッドを使用してマウスの画面座標を取得してから、少し計算します。

ドロップを行う方法の例を次に示します。

def _on_drag_drop(self, event):
    i = self.listbox.curselection()[0]
    text = self.listbox.get(i)
    wx, wy = self.canvas.winfo_rootx(), self.canvas.winfo_rooty()
    x,y = self.winfo_pointerxy()
    cx = self.canvas.canvasx(x-wx)
    cy = self.canvas.canvasy(y-wy)
    self.canvas.create_text(cx,cy,text=text, anchor="sw")
    self.canvas.configure(scrollregion=self.canvas.bbox("all"))
于 2013-05-20T11:16:55.570 に答える