【问题标题】:Moving tkinter window移动 tkinter 窗口
【发布时间】:2020-11-07 02:34:01
【问题描述】:

我正在尝试通过删除其标题栏来创建一个窗口。当用户使用鼠标单击并拖动时,我使窗口移动。现在,如果我在任何小部件内单击并拖动,窗口就会移动。但我想让它只有在用户点击小部件外部时才移动。任何建议都会有所帮助。这是我的代码。

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()

【问题讨论】:

  • 尝试设置一个容器,也许是 Frame,做你为赢得框架所做的事情,比如绑定、列表框、按钮……
  • @JasonYang 我已经尝试过你所说的。它的行为仍然与以前相同。
  • 我觉得你应该搞错了,给你看一个脚本。

标签: python tkinter


【解决方案1】:

如何使用 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)

【讨论】:

  • 我只需要在小部件内限制窗口的移动。如果我们点击所有其他位置,它应该会移动。
【解决方案2】:

在这里,我使用框架作为容器,而不是根窗口。 它将显示一个窗口,顶部区域用于列表框,默认可能有 10 行,底部区域有一个按钮和两个暗绿色区域框。这里在列表框和按钮上单击并拖动不会移动窗口,但是这两个深绿色区域可以工作。

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()

【讨论】:

  • 这就是我想要的。谢谢。
【解决方案3】:

似乎最简单的做法就是在拖动功能中检查哪个窗口接收到事件,并且只有在它是根窗口时才进行拖动:

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))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-10-15
    • 2019-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-21
    • 2020-09-10
    相关资源
    最近更新 更多