Python 3.x Tkinter-使用画布上的相对偏移对齐图像

Python 3.x Tkinter-使用画布上的相对偏移对齐图像,python-3.x,tkinter,tkinter-canvas,Python 3.x,Tkinter,Tkinter Canvas,我正在创作我自己版本的疯狂八人组。应用程序背后的所有逻辑都很好,但我在将卡片放入画布时遇到了麻烦。实际上,当我为主窗口/画布(800x800)设置特定大小时,我的应用程序运行良好。但是,我想让我的应用程序获得它正在运行的设备的屏幕大小,并调整主窗口的大小。我通过添加以下行实现了这一点: w, h = root.winfo_screenwidth(), root.winfo_screenheight() root.geometry("%dx%d+0+0" % (w, h)) 在这一点之前一切都很

我正在创作我自己版本的疯狂八人组。应用程序背后的所有逻辑都很好,但我在将卡片放入画布时遇到了麻烦。实际上,当我为主窗口/画布(800x800)设置特定大小时,我的应用程序运行良好。但是,我想让我的应用程序获得它正在运行的设备的屏幕大小,并调整主窗口的大小。我通过添加以下行实现了这一点:

w, h = root.winfo_screenwidth(), root.winfo_screenheight()
root.geometry("%dx%d+0+0" % (w, h))
在这一点之前一切都很好,但在尝试水平和垂直重新居中(对齐)我的卡时遇到了一些麻烦。例如:对于一只手,所有卡片都使用绝对偏移量(x700)放置;其中x将增加,以给出卡之间的距离,700是y坐标中的位置。但使用绝对偏移仅在窗口大小固定时有效。因此,我想使用相对偏移,比如rely和relx(place geometry),但我不知道怎么做。在这里,我发布了一张图片,让你知道发生了什么,我想要什么

这是我的剧本:

import tkinter as tk

class start_gui(tk.Frame):
def __init__(self, parent, *args, **kwargs):
    tk.Frame.__init__(self,parent, *args, **kwargs)
    self.hand = dict()
    # create canvas
    self.w, self.h = parent.winfo_screenwidth(), parent.winfo_screenheight()
    self.canvas = tk.Canvas(parent, width=self.w, height=self.h, background="red")

    self.x = 280
    self.playerHand = self.gethand()
    # display for south
    for Card in playerHand:
        self.hand[(self.canvas.create_image(self.x, 700, image=self.getImage(Card[0], Card[1]), tags='p1'))] = [
            Card[0], Card[1], sel.x, 700]
        self.x += 20
        # print(str(Card.suit))

def gethand(self):
    # here goes some script to get player card hand
    # return a list of lists

def getImage(self, num, suit):
    # return image item

if __name__ == "__main__":
root = tk.Tk()
w, h = root.winfo_screenwidth(), root.winfo_screenheight()
root.geometry("%dx%d+0+0" % (w, h))
start_gui(root)
root.mainloop()
此外,我想创建一个函数,在单击事件后重新居中(对齐)我的卡。我发布另一张图片给你一个想法。

从上图中,如果我们点击一个正方形。所选择的正方形将放置在画布的中间,其他卡片将水平对齐,保持卡之间的初始空间。如果我们再次单击,则会发生上一个事件,依此类推


有人能帮我吗?提前感谢。

关于将窗口设置为设备屏幕大小,我建议使用root的属性功能使其全屏显示,并扩展画布以填充窗口大小

这看起来像:

root = Tk()
root.attributes("-fullscreen", True) #Makes the window fullscreen.

...

self.canvas = Canvas(self.root, bg="red", highlightthickness=0)
    #Highlight thickness makes the canvas have no border in fullscreen mode.
self.canvas.pack(fill=BOTH, expand=True) #Use pack to make canvas take up full window.
这将使画布占据整个屏幕。 调用mainloop或使用root.update()后,您可以通过使用
self.canvas.winfo_width()
self.canvas.winfo_height()
获得画布/窗口的完整大小(现在相同)

现在,使用您想要的全屏画布,您可以按照前面定义的屏幕宽度在正确的位置生成卡片。使用一个变量表示具有的卡,第二个变量作为每个卡之间的缓冲区大小,您可以按照

start_pos = screen_width/2 - (buffer_width*card_width)*num_of_cards/2 #Gets first x coord
y_pos = [screen_height-card_height*2, screen_height-card_height]      #makes 2 y coords
for i in range(num_of_cards):
    self.canvas.create_rectangle(start_pos+(i*(card_width+buffer_width)), y_pos[0], start_pos+card_width+buffer_width+(i*(card_width+buffer_width)), y_pos[1], fill = card_colours[i]) #Make list of card colours in order
(对不起,最后一行太长了!)

这只是一段简短的代码,演示了一种可以使用宽度创建以中间为中心的卡片的方法,而不管有多少张卡片。你可能需要对它稍加修改,才能得到你想要的结果

我希望这有帮助,祝你好运