Tkinter - 使用画布上的相对偏移对齐图像

时间:2017-04-13 19:52:16

标签: python-3.x tkinter tkinter-canvas

我正在创建自己的Crazy Eights版本。应用程序背后的所有逻辑都很好,但我在将卡片放入画布时遇到了麻烦。实际上,当我为主窗口/画布(800x800)设置特定大小时,我的应用程序运行良好。但是,我希望我的应用程序获取正在运行的设备的屏幕大小并调整主窗口的大小。我通过添加以下几行来实现这一目标:

w, h = root.winfo_screenwidth(), root.winfo_screenheight()
root.geometry("%dx%d+0+0" % (w, h))

到目前为止,一切都很好但是我有一些麻烦试图水平和垂直地重新对齐(对齐)我的卡片。例如:一方面,所有卡都使用绝对偏移(x,700)放置;其中x将增加以便在卡之间给出距离,而700是y坐标中的位置。但是使用绝对偏移仅在窗口大小固定时起作用。因此,我想使用相对偏移,如依赖和relx(放置几何),但我不知道该怎么做。在这里,我发布了一张图片,让您了解发生了什么以及我想要什么。

enter image description here

这是我的剧本:

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

另外,我想创建一个功能,在点击事件后重新居中(对齐)我的卡片。我发布了另一张图片给你一个想法。 enter image description here

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

有人可以帮我吗?提前谢谢。

1 个答案:

答案 0 :(得分:0)

关于使窗口大小与设备屏幕大小相同,我建议使用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

(对不起,最后一行!)

这只是一个简短的代码,用于演示一种可以使用宽度创建以中间为中心的卡片的方法,无论有多少张卡片。您可能需要稍微修补它以获得您想要的效果。

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