Reputation: 61
I'm trying to create a window by removing its title bar. I made the window move when the user click and drag using a mouse. Now if I click inside any widget and drag, the window is moving. But I want to the make it move only if the user clicks outside the widgets. Any suggestions will be helpful. Here is my code.
from tkinter import *
win = Tk()
win.geometry('200x200')
win.overrideredirect(True)
offsetx = 0
offsety = 0
lst = ['Sample 1', 'Sample 2', 'Sample 3', 'Sample 4']
def drag(event):
x = win.winfo_pointerx() - win.offsetx
y = win.winfo_pointery() - win.offsety
win.geometry('+{x}+{y}'.format(x=x,y=y))
def click(event):
win.offsetx = event.x
win.offsety = event.y
win.bind('<Button-1>', click)
win.bind('<B1-Motion>', drag)
lb1 = Listbox(win)
lb1.pack()
b1 = Button(win, text='Close', command=win.destroy).pack()
for i in range(len(lst)):
lb1.insert(i, lst[i])
win.mainloop()
Upvotes: 1
Views: 1638
Reputation: 385970
It seems like the simplest thing to do is just check which window received the event in the drag function, and only do the drag if it's the root window:
def drag(event):
if event.widget == win:
x = win.winfo_pointerx() - win.offsetx
y = win.winfo_pointery() - win.offsety
win.geometry('+{x}+{y}'.format(x=x,y=y))
Or, if you want to be able to drag while clicking in intermediate windows you could check the class of the widget:
def drag(event):
window_class = event.widget.winfo_class()
if window_class in ("Tk", "Toplevel", "Frame"):
x = win.winfo_pointerx() - win.offsetx
y = win.winfo_pointery() - win.offsety
win.geometry('+{x}+{y}'.format(x=x,y=y))
Upvotes: 2
Reputation: 13061
Here, I use a Frame as container, not root window. It will show a window, top area is for list box and maybe 10 lines default, bottom area with one button and two box of drak green area. Here click-and-drag on list box and button won't move the window, but those two dark green area work.
from tkinter import *
def mouse_down(event):
global x, y
x, y = event.x, event.y
def mouse_up(event):
global x, y
x, y = None, None
def mouse_drag(event):
global x, y
try:
deltax = event.x - x
deltay = event.y - y
x0 = win.winfo_x() + deltax
y0 = win.winfo_y() + deltay
win.geometry("+%s+%s" % (x0, y0))
except:
pass
win = Tk()
# win.geometry('200x400')
win.overrideredirect(True)
x, y = None, None
frame = Frame(win, background='#004000')
frame.bind('<ButtonPress-1>', mouse_down)
frame.bind('<B1-Motion>', mouse_drag)
frame.bind('<ButtonRelease-1>', mouse_up)
frame.pack()
list_box = Listbox(frame)
list_box.pack()
button = Button(frame, text='Close', command=win.destroy)
button.pack()
lst = ['Sample 1', 'Sample 2', 'Sample 3', 'Sample 4']
for i, item in enumerate(lst):
list_box.insert(i, item)
win.mainloop()
Upvotes: 2
Reputation: 196
how about creating a title bar canvas with tkinter and keybind to the title bar, instead of the whole application?
titlebar_canvas = tk.Canvas(win, height=20, width=200)
titlebar_canvas.pack(side='top')
titlebar_canvas.bind('<Button-1>', click)
titlebar_canvas.bind('<B1-Motion>', drag)
Upvotes: 0