Tkinter:用鼠标拖动没有边框的窗口,例如overridedirect(1)

2024-05-10 18:04:41 发布

您现在位置:Python中文网/ 问答频道 /正文

关于如何创建允许用户鼠标拖动无边框窗口(例如使用overridedirect(1)创建的窗口)的事件绑定的任何建议?

用例:我们希望创建一个浮动的工具栏/调色板窗口(无边框),用户可以在桌面上拖动它。

下面是我的想法(伪代码):

  1. window.bind( '<Button-1>', onMouseDown )捕获鼠标的初始位置。

  2. window.bind( '<Motion-1>', onMouseMove )跟踪鼠标开始移动时的位置。

  3. 计算鼠标移动了多少并计算newXnewY位置。

  4. 使用window.geometry( '+%d+%d' % ( newX, newY ) )移动窗口。

Tkinter是否公开了足够的功能来允许我实现手头的任务?或者有更简单/更高级的方法来实现我想要做的事情吗?


Tags: 代码用户bind事件鼠标window用例建议
3条回答

是的,Tkinter公开了足够的功能来实现这一点,不,没有更简单/更高级的方法来实现您想要的。你的想法很对。

下面是一个例子:

import Tkinter as tk
import tkFileDialog 

class App(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.floater = FloatingWindow(self)

class FloatingWindow(tk.Toplevel):
    def __init__(self, *args, **kwargs):
        tk.Toplevel.__init__(self, *args, **kwargs)
        self.overrideredirect(True)

        self.label = tk.Label(self, text="Click on the grip to move")
        self.grip = tk.Label(self, bitmap="gray25")
        self.grip.pack(side="left", fill="y")
        self.label.pack(side="right", fill="both", expand=True)

        self.grip.bind("<ButtonPress-1>", self.StartMove)
        self.grip.bind("<ButtonRelease-1>", self.StopMove)
        self.grip.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
        x = self.winfo_x() + deltax
        y = self.winfo_y() + deltay
        self.geometry("+%s+%s" % (x, y))



app=App()
app.mainloop()

试试这个,肯定管用

  1. 创建用于移动窗口的事件函数:

    def movewindow(事件): root.geometry('+{0}+{1}'。格式(event.x_root,event.y_root))

  2. 绑定窗口:

    根。绑定('',移动窗口)

现在你可以触摸窗口并拖动

此代码与Bryan的解决方案相同,但它不使用overridedirect。

它是用python 3.7、Debian GNU/Linux 10(buster)、gnome3.30进行测试的

import tkinter as tk


class App(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.floater = FloatingWindow(self)


class FloatingWindow(tk.Toplevel):
    def __init__(self, *args, **kwargs):
        tk.Toplevel.__init__(self, *args, **kwargs)

        #self.overrideredirect(True)
        self.resizable(0, 0)  # Window not resizable
        self.wm_attributes('-type', 'splash')  # Hide title bar (Linux)

        self.label = tk.Label(self, text="Click on the grip to move")
        self.grip = tk.Label(self, bitmap="gray25")
        self.grip.pack(side="left", fill="y")
        self.label.pack(side="right", fill="both", expand=True)

        self.grip.bind("<ButtonPress-1>", self.StartMove)
        self.grip.bind("<ButtonRelease-1>", self.StopMove)
        self.grip.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
        x = self.winfo_x() + deltax
        y = self.winfo_y() + deltay
        self.geometry("+%s+%s" % (x, y))


app = App()
app.mainloop()

相关问题 更多 >