Tkinter Canvas create_window定位问题

时间:2018-11-14 08:13:51

标签: python canvas tkinter

我试图在tkinter上做一个可调整大小的可滚动画布框架。 问题出在第一次迭代中。我构建了一个窗口和一个画布,并将事件绑定到"<Configure>",以将其大小扩展到窗口的大小。 我创建了一个Frame,然后使用create_window将其放入画布,但是由于某种原因,该方法的参数无法正常工作,或者我不知道它是如何工作的。

我给它的尺寸为200 x 200,并带有height和width参数,框架显示为100x100。 这是因为未在x = 0,y = 0处显示该框架,而是在此下方显示。我已将其位置指定为0,0。

我现在不知道为什么会遇到这个问题,但是它使我发疯,如果有人可以帮助我,我就把代码留在这里。

import sys
from tkinter import *
import tkinter as tk

#Function that initialise the main window
mainwindow = tk.Tk()
mainwindow.resizable(1,1)
mainwindow.title('Resizable Icons')
mainwindoww = 800
mainwindowh = 900
mainwindowws = mainwindow.winfo_screenwidth()
mainwindowhs = mainwindow.winfo_screenheight()
x = (mainwindowws/2) - (mainwindoww/2)
y = (mainwindowhs/2) - (mainwindowh/2)
mainwindow.geometry('%dx%d+%d+%d' % (mainwindoww, mainwindowh, x, y))
mainwindow.minsize(320,600)
frame = Frame(mainwindow,bg='white',width=mainwindoww,height=mainwindowh)
frame.pack()

label1 = Label(frame,text='Resize Proof')
label1.place(x=0,y=20,width=mainwindow.winfo_width())

label2 = Label(frame,text='This is a proof of a resizable elements inside a canvas.') 
label2.place(x=0,y=50,width=mainwindow.winfo_width())

iconframe = Canvas(mainwindow,bg='red', bd=0, highlightthickness=0, relief=FLAT)
iconframe.place(x=0,y=100,width=mainwindoww,height=mainwindowh-140)

iconframe.config(scrollregion=(0,0,320,1000))

'''

sbar = tk.Scrollbar(iconframe,orient='vertical')
sbar.config(command=iconframe.yview)
iconframe.config(yscrollcommand=sbar.set)
sbar.pack(side=RIGHT, fill=Y)

'''


element1 = Frame(iconframe,bg='green')
e1 = iconframe.create_window(0,0,window=(element1))

iconframe.itemconfig(e1,width=200,height=200)


def resizeevent(event):
    width=mainwindow.winfo_width()
    height=mainwindow.winfo_height()
    frame.configure(width=width,height=height)
    iconframe.place_configure(width=width)
    label1.place_configure(width=width)
    label2.place_configure(width=width)

mainwindow.bind("<Configure>",resizeevent)

mainwindow.mainloop()

1 个答案:

答案 0 :(得分:0)

我找到了一种使用画布制作我的响应式可滚动框架而没有定位问题的方法。

我从垂直滚动框架的git页面中获取了代码。因此,感谢Eugene Bakin做到了这一点。 https://gist.github.com/EugeneBakin/76c8f9bcec5b390e45df

因此,请对该代码段进行一些修改以适应我的必需品。

这是我的Scrollable Resizable Tkinter Frame的代码。

class VerticalScrolledFrame(Frame):
    """A pure Tkinter scrollable frame that actually works!
    * Use the 'interior' attribute to place widgets inside the scrollable frame
    * Construct and pack/place/grid normally
    * This frame only allows vertical scrolling

    """
    def __init__(self, parent, bg, *args, **kw):
        Frame.__init__(self, parent, *args, **kw)            

        # create a canvas object and a vertical scrollbar for scrolling it
        vscrollbar = Scrollbar(self, orient=VERTICAL)
        vscrollbar.pack(fill=Y, side=RIGHT, expand=FALSE)
        canvas = Canvas(self, bd=0, highlightthickness=0,
                    yscrollcommand=vscrollbar.set,bg=bg)
        canvas.pack(side=LEFT, fill=BOTH, expand=TRUE)
        vscrollbar.config(command=canvas.yview)

        # reset the view
        canvas.xview_moveto(0)
        canvas.yview_moveto(0)

        # create a frame inside the canvas which will be scrolled with it
        self.interior = interior = Frame(canvas,bg=bg)
        interior_id = canvas.create_window(0, 0, window=interior,
                                       anchor=NW)


        #This would create a frame that had actually the size of the whole window height
        #I have tested so much with options and haven't found a way to make it work correctly without this
        a = Frame(self.interior,height=10,bg='white')
        a.pack()

        # track changes to the canvas and frame width and sync them,
        # also updating the scrollbar
        def _configure_interior(event):
            # update the scrollbars to match the size of the inner frame
            size = (interior.winfo_reqwidth(), interior.winfo_reqheight())
            canvas.config(scrollregion="0 0 %s %s" % size)
            if interior.winfo_reqwidth() != canvas.winfo_width():
                # update the canvas's width to fit the inner frame
                canvas.config(width=interior.winfo_reqwidth())
        interior.bind('<Configure>', _configure_interior)

        def _configure_canvas(event):
            #With this piece of code, the "a" frame adapts its height to the elements inside. 
            a.configure(height=10)
            a.update()
            mylist = interior.winfo_children()
            for i in mylist:
                lasty=i.winfo_height()+i.winfo_y()
            a.configure(height=lasty)
            if interior.winfo_reqwidth() != canvas.winfo_width():
                # update the inner frame's width to fill the canvas
                canvas.itemconfigure(interior_id, width=canvas.winfo_width())
        canvas.bind('<Configure>', _configure_canvas)

#Function that initialise the main window
mainwindow = tk.Tk()
mainwindow.resizable(1,1)
mainwindow.title('Resizable Icons')
mainwindoww = 800
mainwindowh = 900
mainwindowws = mainwindow.winfo_screenwidth()
mainwindowhs = mainwindow.winfo_screenheight()
x = (mainwindowws/2) - (mainwindoww/2)
y = (mainwindowhs/2) - (mainwindowh/2)
mainwindow.geometry('%dx%d+%d+%d' % (mainwindoww, mainwindowh, x, y))
mainwindow.minsize(320,600)
style = ThemedStyle(mainwindow)
style.set_theme("radiance")
if getDarkModeState() == 0:
    mainwindow.configure(background='#000000')
else:
    mainwindow.configure(background='#ffffff')

frame = Frame(mainwindow,bg='white',width=mainwindoww,height=mainwindowh)
frame.pack()

label1 = Label(frame,text='Main Title',font=titlelightfont)
label1.place(x=0,y=20,width=mainwindow.winfo_width())

label2 = Label(frame,text='Title description',font=mainfont) 
label2.place(x=0,y=50,width=mainwindow.winfo_width())

iconframe = VerticalScrolledFrame(mainwindow,bg='white')
iconframe.place(x=0,y=100,width=mainwindoww,height=660)



#I made every single element different from another, with an icon, title and description
#The icon should be 60x60 to fit correctly into the frame
element1 = Frame(iconframe.interior,bg='white')
element1.place(relx=0.025,y=10,height=100,relwidth=0.30)
icon1image = PhotoImage(file='mainicons/user60.png')
icon1 = Label(element1,bg='white',image=icon1image)
icon1.place(x=10,width=60,height=60,y=10)
eltitle1 = Label(element1,bg='white',font=mainfont,text='First option')
eltitle1.place(x=75,y=10)
eldesc1 = Label(element1,bg='white',font=subdescfont,text='This is the first description of the element.',wraplength=155,justify=LEFT)
eldesc1.place(x=75,y=40)

element2 = Frame(iconframe.interior,bg='white')
element2.place(relx=0.350,y=10,height=100,relwidth=0.30)
icon2image = PhotoImage(file='mainicons/testglobal60.png')
icon2 = Label(element2,bg='white',image=icon2image)
icon2.place(x=10,width=60,height=60,y=10)
eltitle2 = Label(element2,bg='white',font=mainfont,text='Second option')
eltitle2.place(x=75,y=10)
eldesc2 = Label(element2,bg='white',font=subdescfont,text='This is the second description of the element.',wraplength=155,justify=LEFT)
eldesc2.place(x=75,y=40)

element3 = Frame(iconframe.interior,bg='white')
element3.place(relx=0.675,y=10,height=100,relwidth=0.30)
icon3image = PhotoImage(file='mainicons/label60.png')
icon3 = Label(element3,bg='white',image=icon3image)
icon3.place(x=10,width=60,height=60,y=10)
eltitle3 = Label(element3,bg='white',font=mainfont,text='Third option')
eltitle3.place(x=75,y=10)
eldesc3 = Label(element3,bg='white',font=subdescfont,text='This is the third description of the element.',wraplength=155,justify=LEFT)
eldesc3.place(x=75,y=40)

element4 = Frame(iconframe.interior,bg='white')
element4.place(relx=0.025,y=120,height=100,relwidth=0.30) 
icon4image = PhotoImage(file='mainicons/testind60.png')
icon4 = Label(element4,bg='white',image=icon4image)
icon4.place(x=10,width=60,height=60,y=10)
eltitle4 = Label(element4,bg='white',font=mainfont,text='Fourth option')
eltitle4.place(x=75,y=10)
eldesc4 = Label(element4,bg='white',font=subdescfont,text='This is the fourth description of the element.',wraplength=155,justify=LEFT)
eldesc4.place(x=75,y=40)

element5 = Frame(iconframe.interior,bg='white')
element5.place(relx=0.350,y=120,height=100,relwidth=0.30)
icon5image = PhotoImage(file='mainicons/philipsdriver60.png')
icon5 = Label(element5,bg='white',image=icon5image)
icon5.place(x=10,width=60,height=60,y=10)
eltitle5 = Label(element5,bg='white',font=mainfont,text='Fifth option')
eltitle5.place(x=75,y=10)
eldesc5 = Label(element5,bg='white',font=subdescfont,text='This is the fifth description of the element.',wraplength=155,justify=LEFT)
eldesc5.place(x=75,y=40)

element6 = Frame(iconframe.interior,bg='#dfdfdf')
element6.place(relx=0.675,y=120,height=100,relwidth=0.30)
icon6image = PhotoImage(file='mainicons/results60.png')
icon6 = Label(element6,bg='#dfdfdf',image=icon6image)
icon6.place(x=10,width=60,height=60,y=10)
eltitle6 = Label(element6,bg='#dfdfdf',font=mainfont,text='Sixth option')
eltitle6.place(x=75,y=10)
eldesc6 = Label(element6,bg='#dfdfdf',font=subdescfont,text='This is the sixth description of the element.',wraplength=155,justify=LEFT)
eldesc6.place(x=75,y=40)

element7 = Frame(iconframe.interior,bg='white')
element7.place(relx=0.025,y=230,height=100,relwidth=0.30)
icon7image = PhotoImage(file='mainicons/luminary60.png')
icon7 = Label(element7,bg='white',image=icon7image)
icon7.place(x=10,width=60,height=60,y=10)
eltitle7 = Label(element7,bg='white',font=mainfont,text='Seventh option')
eltitle7.place(x=75,y=10)
eldesc7 = Label(element7,bg='white',font=subdescfont,text='This is the seventh description of the element.',wraplength=155,justify=LEFT)
eldesc7.place(x=75,y=40)

element8 = Frame(iconframe.interior,bg='white')
element8.place(relx=0.350,y=230,height=100,relwidth=0.30)
icon8image = PhotoImage(file='mainicons/settings60.png')
icon8 = Label(element8,bg='white',image=icon8image)
icon8.place(x=10,width=60,height=60,y=10)
eltitle8 = Label(element8,bg='white',font=mainfont,text='Eighth option')
eltitle8.place(x=75,y=10)
eldesc8 = Label(element8,bg='white',font=subdescfont,text='This is the eighth description of the element.',wraplength=155,justify=LEFT)
eldesc8.place(x=75,y=40)

element9 = Frame(iconframe.interior,bg='white')
element9.place(relx=0.675,y=230,height=100,relwidth=0.30)
icon9image = PhotoImage(file='mainicons/misc60.png')
icon9 = Label(element9,bg='white',image=icon9image)
icon9.place(x=10,width=60,height=60,y=10)
eltitle9 = Label(element9,bg='white',font=mainfont,text='Ninth')
eltitle9.place(x=75,y=10)
eldesc9 = Label(element9,bg='white',font=subdescfont,text='This is the ninth description of the element.',wraplength=155,justify=LEFT)
eldesc9.place(x=75,y=40)

element10 = Frame(iconframe.interior,bg='white')
element10.place(relx=0.025,y=340,height=100,relwidth=0.30)
icon10image = PhotoImage(file='mainicons/help60.png')
icon10 = Label(element10,bg='white',image=icon10image)
icon10.place(x=10,width=60,height=60,y=10)
eltitle10 = Label(element10,bg='white',font=mainfont,text='Tenth option')
eltitle10.place(x=75,y=10)
eldesc10 = Label(element10,bg='white',font=subdescfont,text='This is the tenth description of the element.',wraplength=155,justify=LEFT)
eldesc10.place(x=75,y=40)


def resizeevent(event):
    width=mainwindow.winfo_width()
    height=mainwindow.winfo_height()
    frame.configure(width=width,height=height)
    label1.place_configure(width=width)
    label2.place_configure(width=width)

    #Ajuste de rejilla por ancho de ventana
    if width < 370:
        iconframe.place_configure(x=0,width=width,height=height-140)
        eldesc1.configure(wraplength=245)
        eldesc2.configure(wraplength=245)
        eldesc3.configure(wraplength=245)
        eldesc4.configure(wraplength=245)
        eldesc5.configure(wraplength=245)
        eldesc6.configure(wraplength=245)
        eldesc7.configure(wraplength=245)
        eldesc8.configure(wraplength=245)
        eldesc9.configure(wraplength=245)
        eldesc10.configure(wraplength=245)
    elif width > 370 and width < 480:
        iconframe.place_configure(x=0,width=width,height=height-140)
        eldesc1.configure(wraplength=300)
        eldesc2.configure(wraplength=300)
        eldesc3.configure(wraplength=300)
        eldesc4.configure(wraplength=300)
        eldesc5.configure(wraplength=300)
        eldesc6.configure(wraplength=300)
        eldesc7.configure(wraplength=300)
        eldesc8.configure(wraplength=300)
        eldesc9.configure(wraplength=300)
        eldesc10.configure(wraplength=300)
    elif width > 480 and width < 600:
        iconframe.place_configure(x=0,width=width,height=height-140)
        element1.place_configure(relx=0,y=10,height=90,relwidth=1,rely=0,relheight=0)
        element2.place_configure(relx=0,y=90,height=90,relwidth=1,rely=0,relheight=0)
        element3.place_configure(relx=0,y=180,height=90,relwidth=1,rely=0,relheight=0)
        element4.place_configure(relx=0,y=270,height=90,relwidth=1,rely=0,relheight=0)
        element5.place_configure(relx=0,y=360,height=90,relwidth=1,rely=0,relheight=0)
        element6.place_configure(relx=0,y=450,height=90,relwidth=1,rely=0,relheight=0)
        element7.place_configure(relx=0,y=540,height=90,relwidth=1,rely=0,relheight=0)
        element8.place_configure(relx=0,y=630,height=90,relwidth=1,rely=0,relheight=0)
        element9.place_configure(relx=0,y=720,height=90,relwidth=1,rely=0,relheight=0)
        element10.place_configure(relx=0,y=810,height=90,relwidth=1,rely=0,relheight=0)

        eldesc1.configure(wraplength=400)
        eldesc2.configure(wraplength=400)
        eldesc3.configure(wraplength=400)
        eldesc4.configure(wraplength=400)
        eldesc5.configure(wraplength=400)
        eldesc6.configure(wraplength=400)
        eldesc7.configure(wraplength=400)
        eldesc8.configure(wraplength=400)
        eldesc9.configure(wraplength=400)
        eldesc10.configure(wraplength=400)
    elif width > 600 and width < 850:
        #Layout 5x2
        iconframe.place_configure(x=0,width=width,height=height-140)
        element1.place_configure(relx=0.033,relwidth=0.45,y=10,height=100)
        element2.place_configure(relx=0.516,relwidth=0.45,y=10,height=100)
        element3.place_configure(relx=0.033,relwidth=0.45,y=120,height=100)
        element4.place_configure(relx=0.516,relwidth=0.45,y=120,height=100)
        element5.place_configure(relx=0.033,relwidth=0.45,y=230,height=100)
        element6.place_configure(relx=0.516,relwidth=0.45,y=230,height=100)
        element7.place_configure(relx=0.033,relwidth=0.45,y=340,height=100)
        element8.place_configure(relx=0.516,relwidth=0.45,y=340,height=100)
        element9.place_configure(relx=0.033,relwidth=0.45,y=450,height=100)
        element10.place_configure(relx=0.516,relwidth=0.45,y=450,height=100)

        eldesc1.configure(wraplength=180)
        eldesc2.configure(wraplength=180)
        eldesc3.configure(wraplength=180)
        eldesc4.configure(wraplength=180)
        eldesc5.configure(wraplength=180)
        eldesc6.configure(wraplength=180)
        eldesc7.configure(wraplength=180)
        eldesc8.configure(wraplength=180)
        eldesc9.configure(wraplength=180)
        eldesc10.configure(wraplength=180) 
    elif width > 851 and width < 1100:
        #Layout 3x4
        iconframe.place_configure(x=0,width=width,height=height-140)
        element1.place_configure(relx=0.025,relwidth=0.30,y=10,height=100)
        element2.place_configure(relx=0.350,relwidth=0.30,y=10,height=100)
        element3.place_configure(relx=0.675,relwidth=0.30,y=10,height=100)
        element4.place_configure(relx=0.025,relwidth=0.30,y=120,height=100)
        element5.place_configure(relx=0.350,relwidth=0.30,y=120,height=100)
        element6.place_configure(relx=0.675,relwidth=0.30,y=120,height=100)
        element7.place_configure(relx=0.025,relwidth=0.30,y=230,height=100)
        element8.place_configure(relx=0.350,relwidth=0.30,y=230,height=100)
        element9.place_configure(relx=0.675,relwidth=0.30,y=230,height=100)
        element10.place_configure(relx=0.025,relwidth=0.30,y=340,height=100)
    elif width > 1100:
        #Layout 4x3
        iconframe.place_configure(x=(width/2)-540,y=100,width=1080,height=height-140)
        element1.place_configure(relx=0.020,relwidth=0.225,y=10,height=100)
        element2.place_configure(relx=0.265,relwidth=0.225,y=10,height=100)
        element3.place_configure(relx=0.510,relwidth=0.225,y=10,height=100)
        element4.place_configure(relx=0.755,relwidth=0.225,y=10,height=100)
        element5.place_configure(relx=0.020,relwidth=0.225,y=120,height=100)
        element6.place_configure(relx=0.265,relwidth=0.225,y=120,height=100)
        element7.place_configure(relx=0.510,relwidth=0.225,y=120,height=100)
        element8.place_configure(relx=0.755,relwidth=0.225,y=120,height=100)
        element9.place_configure(relx=0.020,relwidth=0.225,y=230,height=100)
        element10.place_configure(relx=0.265,relwidth=0.225,y=230,height=100)

mainwindow.bind("<Configure>",resizeevent)


mainwindow.mainloop()