【问题标题】:tkinter listbox drag and droptkinter 列表框拖放
【发布时间】:2013-05-14 11:50:18
【问题描述】:

我正在尝试制作一个能够拖放到画布上的列表框。我以前做过拖放,但它只是在canvas.create_text之间松散地基于我发现here.的这个检查程序的代码我已经看到了一些关于拖放列表框的问题,但他们只处理更改列表框中元素的顺序。我正在处理的是一个列表框,它有一个名称列表,以及一个在画布上带有一些 create_text 对象的画布,我希望能够将一个名称从列表框中拖到画布上。如果图我需要创建一个 Listbox 子类,但我不确定从那里去哪里。

所以我有一个 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

【问题讨论】:

  • 我已经更新了我的答案以解决获取正确坐标的问题。

标签: drag-and-drop tkinter


【解决方案1】:

拖放的关键归结为需要做三件事:

  • 绑定<ButtonPress-1>以选择要拖动的项目
  • 绑定<B1-Motion>进行拖动
  • 绑定<ButtonRelease-1> 进行投放

这些都不需要任何子类化。所有这些绑定都在列表框小部件上。您可能想要创建一个 Toplevel 的实例,其中包含一个文本标签,并删除了窗口装饰(使用 wm_overrideredirect(True))来表示被拖动的项目。

在放置时,您需要使用画布的canvasxcanvasy 方法将鼠标的坐标转换为画布坐标。不要以event.xevent.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-01-05
    • 2012-07-18
    • 1970-01-01
    • 2016-11-03
    • 2012-07-27
    • 2013-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多