Python3 tkinter画布,设置相对宽度和高度

7uzetpgm  于 2023-02-01  发布在  Python
关注(0)|答案(3)|浏览(198)

我尝试将一些画布的宽度设置为master的宽度(全屏),高度设置为master的1/5、3/10和1/2。窗口正确显示,但画布没有出现。我尝试使用place()代替pack(),relwidth = 1,relheight = 0.2,但没有成功。我只希望我的三个画布堆叠起来,水平填充窗口。

master = Tk()
master.attributes('-zoomed', True)

w = master.winfo_width()
h = master.winfo_height()
hu = int(h/10)
h1 = hu*2
h2 = hu*3
h3 = hu*5

c1 = Canvas(master, bg='grey', width = w, height = h1)
c1.pack()
c2 = Canvas(master, bg='blue', width = w, height = h2)
c2.pack()
c3 = Canvas(master, bg='red', width = w, height = h3)
c3.pack()

编辑:我的工作代码现在是:

c1 = Canvas(master)
c1.place(rely = 0, relheight = 0.2, relwidth = 1)
c2 = Canvas(master)
c2.place(rely = 0.2, relheight = 0.3, relwidth = 1)
c3 = Canvas(master)
c3.place(rely = 0.5, relheight = 0.5, relwidth = 1)

但我有一个副作用,我不能在中心对齐文本:

c1.create_text(0, 0, text = 'text', fill = 'red', font = ('olivier', 30, 'bold'))
c1.update()

我用这种不雅的方式解决了

master.update_idletasks()
w = master.winfo_width()
h = master.winfo_height()
ww = int(w/2)
hh = int(h/10)
c1.create_text(ww, hh, text = 'text', fill = 'red')
13z8s7eq

13z8s7eq1#

您需要使用.place()几何管理器。
.place()有两个主要参数,我认为您会需要它们。
第一个是relheight,顾名思义,它设置任何小部件相对于其父小部件的高度。
因此,如果relheight为0.5,那么height将为0.5(高度),或者父小部件高度的50%。
这同样适用于relwidth,它的工作方式相同,但适用于宽度。
了解更多关于.place()here的信息。
此外,如果您希望您的代码:

master = Tk()
master.attributes('-zoomed', True)

c1 = Canvas(master, bg='grey')
c1.place(x = 0, rely = 0, relheight = 0.2, relwidth = 1)
c2 = Canvas(master, bg='blue')
c2.pack(x = 0, rely = 0.25, relheight = 0.3, relwidth = 1)
c3 = Canvas(master, bg='red')
c3.pack(x = 0, rely = 0.5, relheight = 0.5, relwidth = 1)

希望这有帮助!
编辑:.place()不适用于canvas元素,为此,您需要获取canvas的长度和宽度,然后将两者除以2(如果您想要中间值)。
例如:

height = 100
width = 100
c = Canvas(master, bg = "blue", height = height, width = width, highlighthickness = 0)
c.place(x = 0, rely = 0.5, relheight = 0.2, relwidth = 1)
text = c.create_text(height/2, width/2, text = "text")

这会将文本text放置在画布的中心。
希望这有帮助!

jmp7cifd

jmp7cifd2#

第一次使用master.winfo_width()master.winfo_height()时,它将为零(如果使用print(w,h),则会发现它们都为零)。
只需在master.winfo_xxxx之前添加master.update_idletasks()
所有代码都可以是:

from tkinter import *
master = Tk()
master.state('zoomed')

# add here 
master.update_idletasks()
w = master.winfo_width()
h = master.winfo_height()
hu = int(h/10)
h1 = hu*2
h2 = hu*3
h3 = hu*5

c1 = Canvas(master, bg='grey', width = w, height = h1)
c1.pack()
c2 = Canvas(master, bg='blue', width = w, height = h2)
c2.pack()
c3 = Canvas(master, bg='red', width = w, height = h3)
c3.pack()
master.mainloop()
omqzjyyz

omqzjyyz3#

c1.bind("<Configure>", lambda event: TextPositionChange(c1, TextId))
C1(画布)尺寸变更时(c1尺寸将随窗口尺寸变更而变更)
canvas.bbox(TextId)
→ TextId的x1、y1、x2、y2(画布的项目)
画布.创建文本(文本中心x,文本中心y,选项...)
c1.moveto(TextId, c1.winfo_width()/2-xOffSet, c1.winfo_height()/2-yOffSet)
→画布.移动到(项目,左上方x,左上方y)
→项目移动到其新的左侧顶部位置

from tkinter import *
master = Tk()
master.state('zoomed')

def TextPositionChange(canvas, TextId):
    x1, y1, x2, y2 = canvas.bbox(TextId)
    xOffSet, yOffSet = (x2-x1)/2, (y2-y1)/2
    canvas.moveto(TextId, canvas.winfo_width()/2-xOffSet, canvas.winfo_height()/2-yOffSet)

c1 = Canvas(master, bg="#111111")
c1.place(rely = 0, relheight = 0.2, relwidth = 1)
c2 = Canvas(master, bg="#222222")
c2.place(rely = 0.2, relheight = 0.3, relwidth = 1)
c3 = Canvas(master, bg="#333333")
c3.place(rely = 0.5, relheight = 0.5, relwidth = 1)

TextId = c1.create_text(0, 0, text = "text", fill = "red", font = ("olivier", 30, "bold"))
c1.bind("<Configure>", lambda event: TextPositionChange(c1, TextId))

master.mainloop()

您还可以看到:
https://tcl.tk/man/tcl8.6/TkCmd/canvas.htm#M60
希望能帮到你。

相关问题