turtle.TurtleScreen() 中的背景图片在 tkinter 中无法正确显示
Background picture in turtle.TurtleScreen() does not show correctly in tkinter
代码 1: 创建一个 Tk()
window、一个 Frame()
、Canvas()
来承载一个 [=16= 】 配上一定的背景图。这些小部件的尺寸在一开始就没有定义。相反,它们是在使用 tkinter 的 .configure()
方法和 turtle 的 .screensize()
方法创建小部件之后定义的。 这里的问题是背景图片没有正确显示,即使 turtle 屏幕尺寸显示正确。
代码2: 和代码1做的一样,只是先获取图片的大小,然后用它来定义Canvas
在将其显示为 turtle.TurtleScreen()
的背景图像之前,首先显示小部件。背景图片显示正确。
问题:
- 为什么问题出现在代码 1 中以及如何解决这个问题,即在背景图像大小发生变化时正确显示
turtle.TurtleScreen()
中的背景图像?
- 为什么
Frame
和 Canvas
小部件的大小对于代码 1 比代码 2 大 2 个像素,即使 Canvas
是用 borderwidth=0
定义的?这与 Canvas 的默认 borderwidth=2 有关吗?
代码 1:
import tkinter as tk
import turtle as tt
root = tk.Tk()
def getsize( widget ):
widget.update_idletasks()
w = widget.winfo_width()
h = widget.winfo_height()
print( 'w={}, h={}\n'.format(w,h) )
return w,h
app = tk.Frame( root, )
canvas = tk.Canvas( app, bg='yellow', borderwidth=0, )
app.grid( row=0, column=0, sticky='nsew' )
canvas.grid( row=0, column=0, sticky='nsew' )
print('\nFrame'); aw, ah = getsize( app )
print('canvas'); cw, ch = getsize( canvas )
pic = 'test.gif'
screen = tt.TurtleScreen( canvas )
screen.bgpic( pic )
screen.bgcolor( 'pink' )
screen.update()
print( 'Turtle :' )
print( 'screen size = ', screen.screensize() )
print( 'screen attributes = ', screen.__dict__ )
print( 'screen.bgpic() = ', screen.bgpic() )
photoimage = screen._bgpics[pic]
pw = photoimage.width()
ph = photoimage.height()
print( '\nphotoimage width={} height={}'.format( pw, ph) )
canvas.configure( width=pw+2, height=ph+2 )
screen.screensize( pw+2, ph+2 )
screen.bgpic( pic )
print('\nFrame'); aw, ah = getsize( app )
print('canvas'); cw, ch = getsize( canvas )
代码 2:
import tkinter as tk
import turtle as tt
root = tk.Tk()
pic ='test.gif'
image = tk.PhotoImage( file=pic )
iw = image.width()
ih = image.height()
print( 'image width={} height={}\n'.format( iw, ih) )
def getsize( widget ):
widget.update_idletasks()
w = widget.winfo_width()
h = widget.winfo_height()
print( 'w={}, h={}\n'.format(w,h) )
return w,h
app = tk.Frame( root, )
canvas = tk.Canvas( app, width=iw, height=ih, bg='yellow', borderwidth=0 )
app.grid( row=0, column=0, sticky='nsew' )
canvas.grid( row=0, column=0, sticky='nsew' )
print('Frame'); aw, ah = getsize( app )
print('canvas'); cw, ch = getsize( canvas )
screen = tt.TurtleScreen( canvas )
screen.bgpic( pic )
screen.bgcolor( 'pink' )
screen.update()
print( 'Turtle :' )
print( 'screen size = ', screen.screensize() )
print( 'screen attributes = ', screen.__dict__ )
print( 'screen.bgpic() = ', screen.bgpic() )
photoimage = screen._bgpics[pic]
pw = photoimage.width()
ph = photoimage.height()
print( '\nphotoimage width={} height={}'.format( pw, ph) )
问题 1 的答案:
经过进一步研究,我发现 TurtleScreen()
有一个名为 .cv
的属性指向传递给它的 tk.Canvas
小部件。与所有 tk.Canvas
小部件一样,需要更新(即配置)其 scrollregion
以在发生更改时显示 tk.Canvas
的新可见区域。 "scrollregion" 选项说明 canvas 可以滚动的区域有多大。
所以代码 1 的更改,我需要替换:
canvas.configure( width=pw+2, height=ph+2 )
screen.screensize( pw+2, ph+2 )
screen.bgpic( pic )
和
canvas.configure( width=pw, height=ph, borderwidth=0 )
w = int(screen.cv.cget("width"))
h = int(screen.cv.cget("height"))
screen.cv.configure(scrollregion = (-w//2, -h//2, w//2+1, h//2 ))
print( '\nscreen.cv width={} height={}'.format( w, h) )
问题 2 的答案:
报告框架和 Canvas 大小相差 2 个像素是由于代码 1 中使用的 +2:
canvas.configure( width=pw+2, height=ph+2 )
相反,我应该使用:
canvas.configure( width=pw, height=ph )
似乎 Canvas 确实消耗了 1 row/column 像素来形成它的边界。
代码 1: 创建一个 Tk()
window、一个 Frame()
、Canvas()
来承载一个 [=16= 】 配上一定的背景图。这些小部件的尺寸在一开始就没有定义。相反,它们是在使用 tkinter 的 .configure()
方法和 turtle 的 .screensize()
方法创建小部件之后定义的。 这里的问题是背景图片没有正确显示,即使 turtle 屏幕尺寸显示正确。
代码2: 和代码1做的一样,只是先获取图片的大小,然后用它来定义Canvas
在将其显示为 turtle.TurtleScreen()
的背景图像之前,首先显示小部件。背景图片显示正确。
问题:
- 为什么问题出现在代码 1 中以及如何解决这个问题,即在背景图像大小发生变化时正确显示
turtle.TurtleScreen()
中的背景图像? - 为什么
Frame
和Canvas
小部件的大小对于代码 1 比代码 2 大 2 个像素,即使Canvas
是用borderwidth=0
定义的?这与 Canvas 的默认 borderwidth=2 有关吗?
代码 1:
import tkinter as tk
import turtle as tt
root = tk.Tk()
def getsize( widget ):
widget.update_idletasks()
w = widget.winfo_width()
h = widget.winfo_height()
print( 'w={}, h={}\n'.format(w,h) )
return w,h
app = tk.Frame( root, )
canvas = tk.Canvas( app, bg='yellow', borderwidth=0, )
app.grid( row=0, column=0, sticky='nsew' )
canvas.grid( row=0, column=0, sticky='nsew' )
print('\nFrame'); aw, ah = getsize( app )
print('canvas'); cw, ch = getsize( canvas )
pic = 'test.gif'
screen = tt.TurtleScreen( canvas )
screen.bgpic( pic )
screen.bgcolor( 'pink' )
screen.update()
print( 'Turtle :' )
print( 'screen size = ', screen.screensize() )
print( 'screen attributes = ', screen.__dict__ )
print( 'screen.bgpic() = ', screen.bgpic() )
photoimage = screen._bgpics[pic]
pw = photoimage.width()
ph = photoimage.height()
print( '\nphotoimage width={} height={}'.format( pw, ph) )
canvas.configure( width=pw+2, height=ph+2 )
screen.screensize( pw+2, ph+2 )
screen.bgpic( pic )
print('\nFrame'); aw, ah = getsize( app )
print('canvas'); cw, ch = getsize( canvas )
代码 2:
import tkinter as tk
import turtle as tt
root = tk.Tk()
pic ='test.gif'
image = tk.PhotoImage( file=pic )
iw = image.width()
ih = image.height()
print( 'image width={} height={}\n'.format( iw, ih) )
def getsize( widget ):
widget.update_idletasks()
w = widget.winfo_width()
h = widget.winfo_height()
print( 'w={}, h={}\n'.format(w,h) )
return w,h
app = tk.Frame( root, )
canvas = tk.Canvas( app, width=iw, height=ih, bg='yellow', borderwidth=0 )
app.grid( row=0, column=0, sticky='nsew' )
canvas.grid( row=0, column=0, sticky='nsew' )
print('Frame'); aw, ah = getsize( app )
print('canvas'); cw, ch = getsize( canvas )
screen = tt.TurtleScreen( canvas )
screen.bgpic( pic )
screen.bgcolor( 'pink' )
screen.update()
print( 'Turtle :' )
print( 'screen size = ', screen.screensize() )
print( 'screen attributes = ', screen.__dict__ )
print( 'screen.bgpic() = ', screen.bgpic() )
photoimage = screen._bgpics[pic]
pw = photoimage.width()
ph = photoimage.height()
print( '\nphotoimage width={} height={}'.format( pw, ph) )
问题 1 的答案:
经过进一步研究,我发现 TurtleScreen()
有一个名为 .cv
的属性指向传递给它的 tk.Canvas
小部件。与所有 tk.Canvas
小部件一样,需要更新(即配置)其 scrollregion
以在发生更改时显示 tk.Canvas
的新可见区域。 "scrollregion" 选项说明 canvas 可以滚动的区域有多大。
所以代码 1 的更改,我需要替换:
canvas.configure( width=pw+2, height=ph+2 )
screen.screensize( pw+2, ph+2 )
screen.bgpic( pic )
和
canvas.configure( width=pw, height=ph, borderwidth=0 )
w = int(screen.cv.cget("width"))
h = int(screen.cv.cget("height"))
screen.cv.configure(scrollregion = (-w//2, -h//2, w//2+1, h//2 ))
print( '\nscreen.cv width={} height={}'.format( w, h) )
问题 2 的答案:
报告框架和 Canvas 大小相差 2 个像素是由于代码 1 中使用的 +2:
canvas.configure( width=pw+2, height=ph+2 )
相反,我应该使用:
canvas.configure( width=pw, height=ph )
似乎 Canvas 确实消耗了 1 row/column 像素来形成它的边界。