#python #tkinter
Вопрос:
Я пытаюсь создать окно, удалив строку заголовка. Я заставил окно перемещаться, когда пользователь щелкает и перетаскивает его с помощью мыши. Теперь, если я нажму внутри любого виджета и перетащу его, окно переместится. Но я хочу, чтобы он двигался только в том случае, если пользователь нажимает за пределами виджетов. Любые предложения будут полезны. Вот мой код.
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()
Комментарии:
1. Попробуйте установить контейнер, может быть, рамку, сделайте то, что вы сделали, чтобы выиграть в рамке, например, привязки, список, кнопку …
2. @JasonYang Я попробовал то, что ты сказал. Тем не менее, он ведет себя так же, как и раньше.
3. Я думаю, что вы должны что-то понять неправильно, покажите один сценарий для вас.
Ответ №1:
Здесь я использую рамку в качестве контейнера, а не корневое окно. Он покажет окно, верхняя область предназначена для списка и, возможно, 10 строк по умолчанию, нижняя область с одной кнопкой и двумя полями зеленой области drak. Здесь щелчок и перетаскивание по списку и кнопке не переместят окно, но эти две темно-зеленые области работают.
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()
Комментарии:
1. Это то, чего я хочу. Спасибо.
Ответ №2:
Кажется, что самое простое, что нужно сделать, — это просто проверить, какое окно получило событие в функции перетаскивания, и выполнять перетаскивание только в том случае, если это корневое окно:
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))
Или, если вы хотите иметь возможность перетаскивать при нажатии в промежуточных окнах, вы можете проверить класс виджета:
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))
Ответ №3:
как насчет создания холста строки заголовка с помощью tkinter и привязки клавиш к строке заголовка вместо всего приложения?
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)
Комментарии:
1. Мне нужно ограничить перемещение окна только внутри виджетов. Он должен переместиться, если мы нажмем на все остальные места.