Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
329 views
in Technique[技术] by (71.8m points)

python - tkinter maximum canvas size?

It seems I'm hitting some kind of preset maximum scrollable canvas size, that I didnt know about...

I've written a simple bare-bones iTunes replacement in Tkinter.

Since I like the album cover view, an album needs at least 200x200 px size, and I have A LOT of albums (~1600), it follows that I need a lot of space.

But I discovered that above a height ~ 35000px the window is unable to show them.

Here I written a sample code of it - it needs ImageMagick's convert, and around 15sec to run on my machine. You can see that the window only shows 163 of the 170 squares...

from Tkinter import *

import subprocess

def main():

    root = Tk()
    root.geometry("%dx%d+0+0" % (1800,1000))
    cv = Canvas(root)
    vscrollbar = Scrollbar(root, orient=VERTICAL)
    vscrollbar.pack(fill=Y, side=RIGHT)
    vscrollbar.config(command=cv.yview)
    cv.config(yscrollcommand=vscrollbar.set)
    cv.configure(scrollregion=(0,0, 4000, 50000))      
    cv.pack(side=LEFT, fill=BOTH, expand=TRUE)    
    fcv=Frame(root)
    cv.create_window(0, 0, anchor = "nw", window=fcv)    


    memimages=[]    
    for row_index in range(170):
        a=subprocess.Popen("convert -size 200x200 -pointsize 22  -gravity center label:%d test.gif" % row_index, shell=True,
                           stdout=subprocess.PIPE,stderr=subprocess.PIPE) 
        output, errors = a.communicate()
        iconimage = PhotoImage(file="test.gif")
        b=Button(fcv,image=iconimage)
        memimages.append(iconimage)             
        b.grid(row=row_index, column=0, sticky=N+S+E+W)  

    mainloop()

main()
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I modified your code to show an image at specific pixel height locations, e.g. one at y=0, one at y=32000 and one at y=50000. The canvas is able to traverse from 0 all the way to 50,000 pixel height, and we can see the images as expected.

This means the canvas is able to scroll all the way to y=50000 pixels and the problem lies not with pixel height limitation of canvas but I am guessing it could be with the manner the button is placed into the frame of the canvas window or the placement of frame in the canvas window or the placement of the canvas window itself into the canvas.

You can run this revised code to see what I mean. Scroll all the way to the bottom. Hope this gives you more insight to troubleshoot your code.

from Tkinter import *

def main():

    root = Tk()
    root.geometry("%dx%d+0+0" % (1800,1000))
    cv = Canvas(root)
    vscrollbar = Scrollbar(root, orient=VERTICAL)
    vscrollbar.pack(fill=Y, side=RIGHT)
    vscrollbar.config(command=cv.yview)
    cv.configure(yscrollcommand=vscrollbar.set)
    cv.configure(scrollregion=(0,0, 4000, 50000))      
    cv.pack(side=LEFT, fill=BOTH, expand=TRUE)
    iconimage = PhotoImage(file="monkey.gif")
    testimage = cv.create_image(300, 0, image=iconimage)
    testimage1 = cv.create_image(300, 32000, image=iconimage)
    testimage2 = cv.create_image(300, 50000, image=iconimage)
    mainloop()

main()

Update: After further testing, it does seems there is a limitation on the display height of the window formed by the Canvas.create_window() method. I added the code below, just before mainloop(), which attempts to create buttons and labels with image of 100x100 pixels. The max. no. of rows of buttons that could be displayed was 316+ while max. no. of rows of labels that could be displayed was 322+. If buttons and labels were created together, the max. no. of row that could be displayed was 316+. My conclusion appears to be identical to yours.

Sorry to not have been able to answer your question. However, I hope to support you with my answer, and recommend someone more knowledgeable explains why this behaviour is the case.

fcv=Frame(cv)
cv.create_window(0, 0, anchor = "nw", window=fcv)    
iconimage = PhotoImage(file="monkey100.gif") # Image dimension is 100x100 pixels
for row_index in range(340):
    b=Button(fcv,image=iconimage)
    b.grid(row=row_index, column=0, sticky=N+S+E+W)
    lb=Label(fcv,text=str(row_index), image=iconimage, compound=LEFT)
    lb.grid(row=row_index, column=1, sticky=N+S+E+W)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...