2016-05-17 129 views
1

我想制作一个Python程序,您可以在其中移动小部件。拖放小部件tkinter

这是我的代码:

import tkinter as tk 
main = tk.Tk() 
notesFrame = tk.Frame(main, bd = 4, bg = "a6a6a6") 
notesFrame.place(x=10,y=10) 
notes = tk.Text(notesFrame) 
notes.pack() 
notesFrame.bind("<B1-Motion>", lambda event: notesFrame.place(x = event.x, y = event.y) 

但是,这得到超级出问题和小部件跳来回。

谢谢!

+2

你真的尝试* *这个代码?因为它有多个错误,并且不会移动任何东西 - 至少在Mac上的Python 3.5下。 –

+0

你有点击边框,而不是文本框 –

回答

5

您正在观察的行为是由事件的坐标相对于拖动的窗口部件引起的。更新小部件的位置(在绝对坐标)与相对坐标显然导致混乱。

为了解决这个问题,我使用了.winfo_x() and .winfo_y()函数(允许将相对坐标转换为绝对坐标)和Button-1事件来确定拖动开始时光标在控件上的位置。 以下是一个混合使得一个小部件可拖动。

class DragDropWidget: 
    def __init__(self, *args, **kwargs): 
     super().__init__(*args, **kwargs) 

     self.drag_start_x = 0 
     self.drag_start_y = 0 
     self.bind("<Button-1>", self.drag_start) 
     self.bind("<B1-Motion>", self.drag_motion) 

    def drag_start(self, event): 
     self.drag_start_x = event.x 
     self.drag_start_y = event.y 

    def drag_motion(self, event): 
     x = self.winfo_x() - self.drag_start_x + event.x 
     y = self.winfo_y() - self.drag_start_y + event.y 
     self.place(x=x, y=y) 

用法:

# As always when it comes to mixins, make sure to 
# inherit from DragDropWidget FIRST! 
class DnDFrame(DragDropWidget, tk.Frame): 
    pass 

# This wouldn't work: 
# class DnDFrame(tk.Frame, DragDropWidget): 
#  pass 

main = tk.Tk() 
notesFrame = DnDFrame(main, bd = 4, bg = "grey") 
notesFrame.place(x=10,y=10) 
notes = tk.Text(notesFrame) 
notes.pack() 
+0

谢谢!有效 –

2

Tkinter有一个模块,在模块docstring中有记录。预计它会被一个tk dnd模块取代,但是这并没有发生。我从来没有尝试过。在SO搜索[tkinter] dnd返回this page。以下是文档字符串的开头。

>>> from tkinter import dnd 
>>> help(dnd) 
Help on module tkinter.dnd in tkinter: 

NAME 
    tkinter.dnd - Drag-and-drop support for Tkinter. 

DESCRIPTION 
    This is very preliminary. I currently only support dnd *within* one 
    application, between different windows (or within the same window). 
[snip]