首页 > 解决方案 > 移动覆盖重定向的顶级窗口以及允许最小化

问题描述

下午好,

我一直在尝试从这个页面实现脚本: Tkinter:鼠标拖动一个没有边框的窗口,例如。覆盖直接(1)

使用我的 tkinter 顶级窗口。这就是我的 tkinter 窗口的初始化方式:

    def __init__(self, master=None):
        tkinter.Tk.__init__(self, master)

然后我隐藏根窗口并启动一个顶级窗口。我正在这样做,以便我目前可以最小化并重新打开顶级窗口。

    #Hide Root
    self.attributes("-alpha",0.0)
    self.attributes("-topmost", True)

    #Top Level Window
    top_level = tkinter.Toplevel(self)
    top_level.geometry("600x300")
    top_level.overrideredirect(True)
    top_level.config(bg="#1e1e1e")

现在我尝试使用上面列出的页面中的这段代码来移动窗口。(我已经更改了一些变量以匹配我的窗口)

    top_level.bind("<ButtonPress-1>", top_level.StartMove)
    top_level.bind("<ButtonRelease-1>", top_level.StopMove)
    top_level.bind("<B1-Motion>", top_level.OnMotion)

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

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

def OnMotion(top_level, event):
    deltax = event.x - top_level.x
    deltay = event.y - top_level.y
    x = top_level.winfo_x() + deltax
    y = top_level.winfo_y() + deltay
    top_level.geometry("+%s+%s" % (x, y))

这是我收到的错误:

Traceback (most recent call last):
  File "E:/Programs/TestGUI/script_gui.py", line 2, in <module>
    import authenticator
  File "E:\Programs\TestGUI\authenticator.py", line 148, in <module>
    root = Win()
  File "E:\Programs\TestGUI\authenticator.py", line 127, in __init__
    top_level.bind("<ButtonPress-1>", top_level.StartMove)
AttributeError: 'Toplevel' object has no attribute 'StartMove'

任何帮助将不胜感激,因为这是我完成这个项目需要做的最后一件事。

谢谢

标签: python-3.xtkinter

解决方案


根据错误消息,您有一个Win派生自tkinter.Tk. 因此,发布的代码中的所有函数都在该类中。

然后是三行:

top_level.bind("<ButtonPress-1>", top_level.StartMove)
top_level.bind("<ButtonRelease-1>", top_level.StopMove)
top_level.bind("<B1-Motion>", top_level.OnMotion)

应改为:

self.top_level.bind("<ButtonPress-1>", self.StartMove)
self.top_level.bind("<ButtonRelease-1>", self.StopMove)
self.top_level.bind("<B1-Motion>", self.OnMotion)

top_level最好是类的实例变量,以便其他类方法可以访问它:

self.top_level = tkinter.Toplevel(self)
self.top_level.geometry('600x300')
self.top_level.overrideredirect(1)
self.top_level.config(bg='#1e1e1e')

也通常是类方法的第一个参数的名称StartMove()StopMove()并且OnMotion()self。并且应该修改这些函数以适应top_level从局部变量到实例变量的变化:

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

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

def OnMotion(self, event):
    deltax = event.x - self.top_level.x
    deltay = event.y - self.top_level.y
    x = self.top_level.winfo_x() + deltax
    y = self.top_level.winfo_y() + deltay
    self.top_level.geometry('+%s+%s' % (x, y))

下面是类的定义Win

class Win(tkinter.Tk):
    def __init__(self):
        tkinter.Tk.__init__(self)
        #Hide Root
        self.attributes('-alpha', 0.0)
        self.attributes('-topmost', 1)

        #Top Level Window
        self.top_level = tkinter.Toplevel(self)
        self.top_level.geometry('600x300')
        self.top_level.overrideredirect(1)
        self.top_level.config(bg='#1e1e1e')
        self.top_level.bind('<ButtonPress-1>', self.StartMove)
        self.top_level.bind('<ButtonRelease-1>', self.StopMove)
        self.top_level.bind('<B1-Motion>', self.OnMotion)

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

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

    def OnMotion(self, event):
        deltax = event.x - self.top_level.x
        deltay = event.y - self.top_level.y
        x = self.top_level.winfo_x() + deltax
        y = self.top_level.winfo_y() + deltay
        self.top_level.geometry('+%s+%s' % (x, y))

推荐阅读