11tadpole 发表于 2022-5-23 16:19:29

Canvas中create_window和pack的区别

以下代码中如果用create_window,之前创建的canvas对象可以正常显示(如附件1)
如果屏蔽掉create_window那一行,选择用pack,canvas对象竟然就不可见了(如附件2),我不明白为什么会不见了
from tkinter import *

root = Tk()
root.geometry('400x400')

canvas = Canvas(root, width=200, height=200, bg='green')
canvas.pack(expand=True, anchor='center')

frame = Frame(canvas, bg='yellow', borderwidth=5)
canvas.create_window((0,0), window=frame, anchor='nw')
#frame.pack()

todo1 = Label(frame, text='new', bg='lightgrey', fg='black')
todo1.pack()

豆嘉木 发表于 2022-5-23 17:13:05

pack,canvas这两个对象没有不见,你不create_window就没法显示出来,也就是说你这两个对象就一点用都没用,只是占用内存罢了
觉得有帮助的话给个最佳答案谢了{:10_254:}

11tadpole 发表于 2022-5-23 20:46:47

本帖最后由 11tadpole 于 2022-5-23 20:47 编辑

豆嘉木 发表于 2022-5-23 17:13
pack,canvas这两个对象没有不见,你不create_window就没法显示出来,也就是说你这两个对象就一点用都没用 ...

只有下面代码的话,canvas对象是能正常显示的
为什么在canvas中创建frame, 再选择pack的方式,它就不可见了呢?
from tkinter import *

root = Tk()
root.geometry('400x400')

canvas = Canvas(root, width=200, height=200, bg='green')

canvas.pack(expand=True, anchor='center')

11tadpole 发表于 2022-5-23 20:49:06

大佬,我需要帮助@Twilight6

豆嘉木 发表于 2022-5-23 21:14:27

11tadpole 发表于 2022-5-23 20:49
大佬,我需要帮助@Twilight6

帮你 @Twilight6

Twilight6 发表于 2022-5-23 22:39:44

11tadpole 发表于 2022-5-23 20:46
只有下面代码的话,canvas对象是能正常显示的
为什么在canvas中创建frame, 再选择pack的方式,它就不 ...


对这些只了解一些基础了,这里为什么我也不太清楚,抱歉,帮不了你

另外 tkinter 最后一般不是需要调用 mainloop() 开启事件循环么,建议带上~

11tadpole 发表于 2022-5-24 08:36:57

大佬看过来啊~@zltzlt @小甲鱼

阿奇_o 发表于 2022-5-24 16:30:26

本帖最后由 阿奇_o 于 2022-5-24 16:35 编辑

原因:不是canvas对象不见了,而是它 被frame给占满了—— 被完全挡住了!
          其次是,原来的 canvas.pack(expand=True, )也受到了 frame.pack() 的影响。

解决:要看见,就要自己设置一个合适的"边距"( padx 或 pady ),如

from tkinter import *

root = Tk()
root.geometry('400x400')

canvas = Canvas(root, width=200, height=200, bg='green')
canvas.pack(expand=True, anchor='center')

frame = Frame(canvas, bg='yellow', borderwidth=5)
# canvas.create_window((0,0), window=frame, anchor='nw')
# frame.pack()   # 默认没有padx=0, pady=0, frame会占满整个canvas, 从而"看不见"
frame.pack(padx=50, pady=20)   # 设置边距后,即可看见

todo1 = Label(frame, text='new', bg='lightgrey', fg='black')
todo1.pack()

root.mainloop()

11tadpole 发表于 2022-5-25 23:03:06

阿奇_o 发表于 2022-5-24 16:30
原因:不是canvas对象不见了,而是它 被frame给占满了—— 被完全挡住了!
          其次是,原来的 can ...

还是有一点点不理解
为了确认是不是frame覆盖导致的,我专门设置了frame的背景色为黄色
实际跑出来的图像,明明黄色区域占的面积很小啊,怎么就覆盖了canvas呢?

阿奇_o 发表于 2022-5-26 17:28:27

本帖最后由 阿奇_o 于 2022-5-26 17:35 编辑

11tadpole 发表于 2022-5-25 23:03
还是有一点点不理解
为了确认是不是frame覆盖导致的,我专门设置了frame的背景色为黄色
实际跑出来的图 ...

不是 单纯的覆盖,而是相互影响。并且 frame是位于canvas里面(frame的master是canvas),而frame的四个外边距(ipadx、ipady)如果不设置,即用默认的frame.pack() ,
那么 它就会导致边距为0,也就是canvas原本定义的长和宽都会"被压缩到"和这个frame一样的大小,于是就相当于是"被覆盖了"(而实际是canvas自己改变了大小)。
注:如果有其他frame或组件也位于canvas里(master=canvas),且这些组件都只用 zj.pack(),那么canvas的大小也会"被压缩到"这些组件的"总大小"(也就是这些组件会挤满canvas——canvas同样会被这些组件给"遮挡住了"。)

补充:其实,从 pack 这单词来说,就有"紧凑、塞满"等意思,所以要是得不到你想要的效果,你就可以考虑设置ipadx, ipady 或 其他布局方法的pading或padx, pady等参数,又或 配置布局网格的 "行列最小值"等参数。

页: [1]
查看完整版本: Canvas中create_window和pack的区别