tkinter:为什么我不动时可移动标签会移动?

时间:2019-07-22 21:10:45

标签: python-3.x

我有一个可移动的标签。它的位置是从txt文件读取的,并通过拖动更改了它的位置。 但是当我不拖动标签时,标签的位置就会改变,只需运行代码段即可。

我尝试了多个标签,发现每次运行摘要时,每个可移动标签增量的x和y都具有相同的数字。

import tkinter as tk

def make_draggable(widget):
    widget.bind("<Button-1>", on_drag_start)
    widget.bind("<B1-Motion>", on_drag_motion)

def on_drag_start(event):
    widget = event.widget
    widget._drag_start_x = event.x
    widget._drag_start_y = event.y

def on_drag_motion(event):
    widget = event.widget
    x = widget.winfo_x() - widget._drag_start_x + event.x
    y = widget.winfo_y() - widget._drag_start_y + event.y
    widget.place(x=x, y=y)

def get_new_positions():
    x, y = label1.winfo_rootx(), label1.winfo_rooty()
    positions["moveable_label"] = (x, y)


    dictfile = open("labelposition.txt", "w")   # save new positions
    dictfile.write(str(positions))
    dictfile.close()

def close_window():
    main.destroy()

root = tk.Tk()
root.geometry('1200x900')

tk.Label(root, text="test").pack()


root.withdraw()

# start window
aWindow = tk.Toplevel(root)
aWindow.geometry('1200x900')

def change_window():
    # call function which reads the y coordinates
    aWindow.update()
    get_new_positions()
    #remove the other window entirely
    aWindow.destroy()

    #make root visible again
    root.iconify()
    root.deiconify()

tk.Button(aWindow, text="OK", command=change_window).pack()

# load dict with label positions

dictfile = open("labelposition.txt", "r")
positions = eval(dictfile.read())  # load label positions
dictfile.close()

# position label

label1 = tk.Label(aWindow, text="moveable")
label1.place(x=positions["moveable_label"][0], y=positions["moveable_label"][1])
make_draggable(label1)

root.mainloop()

我的代码段的目标应该是:

  1. 显示一个可移动的标签,并根据保存在txt文件中的y数据将其定位。
  2. 如果用鼠标将标签移到另一个位置,并且单击“确定”按钮,则新的y位置将保存到txt文件中。
  3. 一个新的空白页面打开

但是:当我多次运行代码段而不用鼠标触摸标签时,标签位置无论如何每次都会改变其位置(x和y变高)

您能看到x y变化的来源吗?

1 个答案:

答案 0 :(得分:0)

位置在整个运行过程中不断变化的原因是,用于捕获窗口小部件的x和y坐标的方法返回相对于屏幕左上角的坐标,而不是父级。

  

winfo_rootx():

     

获取窗口小部件左边缘相对于屏幕左上角的像素坐标。      返回:根坐标。

使用winfo_root*代替使用winfo_*,它返回相对于父窗口的位置。

  

winfo_x():

     

返回小部件左角相对于其父级左角的像素坐标。

因此,在您的get_new_positions函数中,x和y坐标应为:

def get_new_positions():
    x, y = label1.winfo_x(), label1.winfo_y()
    positions["moveable_label"] = (x, y)
    dictfile = open("labelposition.txt", "w")   # save new positions
    dictfile.write(str(positions))
    dictfile.close()