为什么 Anchors 的位置不好并且看起来是倒置的?

Why Anchors have bad position and seem to be inverted?

最近我开始使用 Tkinter 作为 Raspberry Pi 显示的一种方式。我仍然习惯于放置和试验网格和绝对定位。但是我遇到了一个问题。

每当我使用锚点时。唯一正常工作的是 NW。其余的似乎是倒置的,并以屏幕的左角为中心,我不知道为什么。

from tkinter import Tk, Canvas, NW, NE, SW, CENTER
from tkinter.ttk import Frame, Label, Style
from PIL import ImageTk, Image

gui = Tk()
gui.attributes('-fullscreen', True)
gui.configure(background = 'black',cursor ='none')

gui.geometry("1920x1080")
canvas = Canvas(gui, width = 1920, height = 1080, bg ='black',highlightthickness=0)


img5 = ImageTk.PhotoImage(Image.open('../icons/Asset7.png'))
im5 = canvas.create_image(100,100, image = img5, anchor = NW)

img9 = ImageTk.PhotoImage(Image.open('../icons/Asset14.png')
im9 = canvas.create_image(100,100, image = img9, anchor = NE)

这是一个例子。由于某种原因,资产 7 在屏幕的正确部分,资产 14 从屏幕左边框后面开始。根据这张图片,正确的定位应该有所不同 Tkinker Anchors 我很困惑是什么原因造成的。

谁能告诉我这是怎么回事?

已编辑以回复评论。

对于canvas,假设canvas = tk.Canvas(...)

The Top Left     is (0,0), 
the Bottom Right is (canvas.winfo_width(), canvas.winfo_height())

其他相关点可以根据宽高计算。如果 canvas 在使用时调整大小,则需要重新计算点(0,0 除外)。

我找不到任何内置到 'snap' 对象的角落、中点等。 下面的代码要么使罗盘点包装函数将项目捕捉到预定义的位置。或根据比例捕捉到 Canvas 中任意位置的函数。需要 on_resize 回调,即使 Canvas 不改变大小,因为通常在绘制 canvas 之前指定 id 对象。

import tkinter as tk

root = tk.Tk()
root.geometry('400x200')

canvas = tk.Canvas(root)
# canvas changes size with the root.
canvas.grid(sticky=tk.N+tk.S+tk.E+tk.W)

root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)

def snap(parent, id, x_fact, y_fact, anchor = tk.CENTER ):
    """ parent - tk.Canvas widget
        id canvas object id
        x_fact & y_fact: floats 0. to 1. 0 is N/W,  1. is S/E
        anchor is the anchor point on the object.
     """
    def on_resize( ev ):
        """ Callback for Configure event """
        x = int( ev.width * x_fact )
        y = int( ev.height * y_fact )
        parent.coords( id, x, y )

    parent.itemconfigure( id, anchor = anchor )
    x = int( parent.winfo_width() * x_fact )
    y = int( parent.winfo_height() * y_fact )
    parent.coords( id, x, y )
    parent.bind( '<Configure>', on_resize, add='+' )
    return id

def snap_to( x_fact, y_fact, anchor = tk.CENTER ):
    """ Returns a function which snaps to a named location. """

    def func( parent, id ):
        return snap( parent, id, x_fact, y_fact, anchor )

    return func

snap_NW = snap_to( 0,   0,   tk.NW )
snap_N  = snap_to( 0.5, 0 ,  tk.N )
snap_NE = snap_to( 1,   0,   tk.NE )
snap_W  = snap_to( 0,   0.5, tk.W )
snap_C  = snap_to( 0.5, 0.5, tk.CENTER )
snap_E  = snap_to( 1,   0.5, tk.E )
snap_SW = snap_to( 0,   1,   tk.SW )
snap_S  = snap_to( 0.5, 1,   tk.S )
snap_SE = snap_to( 1,   1,   tk.SE )

test0 = canvas.create_text( 0, 0, text=' SE ')
snap_SE(canvas, test0)

test1 = snap_E(canvas, canvas.create_text( 0, 0, text=' East '))

snap_N(canvas, canvas.create_text( 0, 0, text=' North '))
snap_NW(canvas, canvas.create_text( 0, 0, text=' NW '))
snap_NE(canvas, canvas.create_text( 0, 0, text=' NE '))
snap_W(canvas, canvas.create_text( 0, 0, text=' West '))
snap_C(canvas, canvas.create_text( 0, 0, text=' Centre '))
snap_SW(canvas, canvas.create_text( 0, 0, text=' SW '))
snap_S(canvas, canvas.create_text( 0, 0, text=' South '))

snap( canvas, 
       canvas.create_text( 0, 0, text=' Quarters '), 
       0.25, 0.25)

root.mainloop()

这是你想要的那种东西吗?

下面是使用 snap 而不是 snap_to 的替代用法。

#  Named constants for tuples of function parameters.
CEN = ( 0.5, 0.5, tk.CENTER ) # tk.CENTER is the default and could be omitted
SE = ( 1., 1., tk.SE )

# Call snap with the constants setting the three last parameters.
snap( canvas, canvas.create_text( 0, 0, text=' Centre '), *CEN )
snap( canvas, canvas.create_text( 0, 0, text=' SE '), *SE )