鱼C论坛

 找回密码
 立即注册
查看: 1958|回复: 9

[已解决]Canvas中create_window和pack的区别

[复制链接]
发表于 2022-5-23 16:19:29 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

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

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

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

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

  9. todo1 = Label(frame, text='new', bg='lightgrey', fg='black')
  10. todo1.pack()
复制代码
最佳答案
2022-5-24 16:30:26
本帖最后由 阿奇_o 于 2022-5-24 16:35 编辑

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

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

  1. from tkinter import *

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

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

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

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

  12. root.mainloop()
复制代码
1.PNG
2.PNG
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-5-23 17:13:05 | 显示全部楼层
pack,canvas这两个对象没有不见,你不create_window就没法显示出来,也就是说你这两个对象就一点用都没用,只是占用内存罢了
觉得有帮助的话给个最佳答案谢了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 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的方式,它就不可见了呢?
  1. from tkinter import *

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

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

  5. canvas.pack(expand=True, anchor='center')
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-23 20:49:06 | 显示全部楼层
大佬,我需要帮助@Twilight6
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-5-23 21:14:27 | 显示全部楼层
11tadpole 发表于 2022-5-23 20:49
大佬,我需要帮助@Twilight6

帮你 @Twilight6
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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


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

另外 tkinter 最后一般不是需要调用 mainloop() 开启事件循环么,建议带上~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-24 08:36:57 | 显示全部楼层
大佬看过来啊~@zltzlt @小甲鱼
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-5-24 16:30:26 | 显示全部楼层    本楼为最佳答案   
本帖最后由 阿奇_o 于 2022-5-24 16:35 编辑

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

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

  1. from tkinter import *

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

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

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

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

  12. root.mainloop()
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-25 23:03:06 | 显示全部楼层
阿奇_o 发表于 2022-5-24 16:30
原因:不是canvas对象不见了,而是它 被frame给占满了—— 被完全挡住了!
          其次是,原来的 can ...

还是有一点点不理解
为了确认是不是frame覆盖导致的,我专门设置了frame的背景色为黄色
实际跑出来的图像,明明黄色区域占的面积很小啊,怎么就覆盖了canvas呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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等参数,又或 配置布局网格的 "行列最小值"等参数。

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-20 06:28

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表