tkinter中的turtle.TurtleScreen()中的背景图片无法正确显示

时间:2019-01-23 18:33:23

标签: python turtle-graphics tkinter-canvas

代码1:创建一个Tk()窗口,一个Frame()Canvas(),以托管具有特定背景图片的turtle.TurtleScreen()。这些小部件的尺寸一开始没有定义。相反,它们是在小部件创建后使用tkinter的.configure()方法和turtle .screensize()方法定义的。 这里的问题是,即使乌龟屏幕大小显示正确,背景图片也无法正确显示。

代码2:除了它首先获得图像的大小并在显示图像之前先使用它来定义Canvas小部件的大小之外,它与代码1的作用相同。作为turtle.TurtleScreen()的背景图片。背景图片确实显示正确。

问题:

  1. 为什么该问题在代码1中发生,以及如何解决该问题,即在背景图片大小发生更改的情况下,在turtle.TurtleScreen()中正确显示背景图片?
  2. 即使Frame是用Canvas定义的,为什么代码1的Canvasborderwidth=0小部件的尺寸比代码2大2个像素?这与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 个答案:

答案 0 :(得分:0)

第一季度答案:

经过进一步研究,我发现TurtleScreen()有一个名为.cv的属性,指向指向其中传递的tk.Canvas小部件。与所有tk.Canvas小部件一样,当发生更改时,需要更新(即配置)其scrollregion以显示tk.Canvas的新可见区域。 “ scrollregion”选项说明画布可以滚动到多大的区域。

因此对代码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个像素是由于代码1中使用的+2造成的。

canvas.configure( width=pw+2, height=ph+2 )

相反,我应该使用:

canvas.configure( width=pw, height=ph )

似乎Canvas确实消耗了1行/列的像素来形成边界。