简体   繁体   中英

Tkinter python 3 - Moving a borderless window



This post is practically with the same question as this , but instead of Python 2 in Python 3 and the fact that it would also be good if you can precisely say which frame dragging actually moves like desired (like "top_Frame" in the example code).

Example code:

from tkinter import *

def main():
    root = Tk()
    root.geometry("200x200")
    root.resizable(0, 0)
    root.overrideredirect(1)

    back = Frame(root, bg="grey")
    back.pack_propagate(0)
    back.pack(fill=BOTH, expand=1)

    top_Frame = Frame(back, bg="#505050")
    top_Frame.place(x=0, y=0, anchor="nw", width=200, height=20)
    '''Would Be great if it could be specified to only be moved
    when dragging with the Frame above.'''

    Ext_but = Button(top_Frame, text="X", bg="#FF6666", fg="white", command=lambda: exit())
    Ext_but.place(x=170, y=0, anchor="nw", width=30, height=20)

    root.mainloop()

main()

a complete example that uses a class to wrap all the functionality:

from tkinter import *

class Grip:
    ''' Makes a window dragable. '''
    def __init__ (self, parent, disable=None, releasecmd=None) :
        self.parent = parent
        self.root = parent.winfo_toplevel()

        self.disable = disable
        if type(disable) == 'str':
            self.disable = disable.lower()

        self.releaseCMD = releasecmd

        self.parent.bind('<Button-1>', self.relative_position)
        self.parent.bind('<ButtonRelease-1>', self.drag_unbind)

    def relative_position (self, event) :
        cx, cy = self.parent.winfo_pointerxy()
        geo = self.root.geometry().split("+")
        self.oriX, self.oriY = int(geo[1]), int(geo[2])
        self.relX = cx - self.oriX
        self.relY = cy - self.oriY

        self.parent.bind('<Motion>', self.drag_wid)

    def drag_wid (self, event) :
        cx, cy = self.parent.winfo_pointerxy()
        d = self.disable
        x = cx - self.relX
        y = cy - self.relY
        if d == 'x' :
            x = self.oriX
        elif d == 'y' :
            y = self.oriY
        self.root.geometry('+%i+%i' % (x, y))

    def drag_unbind (self, event) :
        self.parent.unbind('<Motion>')
        if self.releaseCMD != None :
            self.releaseCMD()

def main():
    root = Tk()
    root.geometry("200x200")
    root.resizable(0, 0)
    root.overrideredirect(1)

    back = Frame(root, bg="grey")
    back.pack_propagate(0)
    back.pack(fill=BOTH, expand=1)

    top_Frame = Frame(back, bg="#505050")
    top_Frame.place(x=0, y=0, anchor="nw", width=200, height=20)
    '''Would Be great if it could be specified to only be moved
    when dragging with the Frame above.'''
    grip = Grip(top_Frame)

    Ext_but = Button(top_Frame, text="X", bg="#FF6666", fg="white", command=lambda: exit())
    Ext_but.place(x=170, y=0, anchor="nw", width=30, height=20)

    root.mainloop()

main()

note there are some extra bits in this class (I copied it from what I'd done before) as it can be used to restrict which direction it can be dragged (the disable flag) and trigger a callback when the drag stops.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM