如何拖动Tkinter窗口手柄?

1 投票
1 回答
2612 浏览
提问于 2025-04-17 02:29

首先,这是我现在的代码,重要的部分如下:

class WindowDraggable():        
    x = 1
    y = 1
    def __init__(self,label):
        label.bind('<ButtonPress-1>',self.StartMove);
        label.bind('<ButtonRelease-1>',self.StopMove);
        label.bind('<B1-Motion>',self.OnMotion);

    def StartMove(self,event):
        self.x = event.x
        self.y = event.y

    def StopMove(self,event):
        self.x = None
        self.y = None

    def OnMotion(self,event):
        deltaX = event.x - self.x
        deltaY = event.y - self.y
        self.x = root.winfo_x() + deltaX
        self.y = root.winfo_y() + deltaY
        root.geometry("+%sx+%s" % (self.x,self.y))

#root is my window:
root = Tk()

#This is how I assign the class to label
WindowDraggable(label)

#All imports
from Tkinter import *
from PIL import Image, ImageTk
import sys
import re

我想实现的功能是:通过一个把手来拖动窗口,在这个例子中就是 label。我现在无法准确描述它的行为,但它确实可以移动窗口,只是没有跟着鼠标移动。

请多多包涵,因为我对Python完全是个新手。任何帮助都非常感谢 :) 如果需要重写这个类也没问题,我知道它写得很糟糕。

1 个回答

2

这里有一个小例子:

from Tkinter import *
root = Tk()

class WindowDraggable():

    def __init__(self, label):
        self.label = label
        label.bind('<ButtonPress-1>', self.StartMove)
        label.bind('<ButtonRelease-1>', self.StopMove)
        label.bind('<B1-Motion>', self.OnMotion)

    def StartMove(self, event):
        self.x = event.x
        self.y = event.y

    def StopMove(self, event):
        self.x = None
        self.y = None

    def OnMotion(self,event):
        x = (event.x_root - self.x - self.label.winfo_rootx() + self.label.winfo_rootx())
        y = (event.y_root - self.y - self.label.winfo_rooty() + self.label.winfo_rooty())
        root.geometry("+%s+%s" % (x, y))

label = Label(root, text='drag me')
WindowDraggable(label)
label.pack()
root.mainloop()

你几乎做对了,但你需要在标签内部进行偏移补偿。注意,我的例子没有考虑窗口边框。你需要使用一些特定的工具来弄清楚这一点(所以这个例子在使用 overrideredirect(1) 时效果很好)。

我猜你可能是从其他编程语言过来的,所以我在这里给你一些小建议:

  • 在Python中,语句后面不需要加 ;(虽然这样写是合法的,但没有必要)。
  • 方法名称应该保持一致,要么用 look_like_this 这种格式,要么用 lookLikeThis 这种格式。
  • 变量不需要提前声明。如果你想创建一个实例变量,可以在 __init__ 方法里创建(绝对不要在方法外创建,除非你想要一个类变量)。

撰写回答