2013-05-29 382 views
3

我试图用Tkinter Canvasself._canvas)使用create_window函数创建窗口。该函数的窗口字段为Tkinter Frameself._tableFrame)。有人可以帮我解决如何使self._tableFrame自动扩展到self._canvas的大小(即使窗口大小由用户更改)?Tkinter画布create_window()

代码:

from Tkinter import Scrollbar as tkScrollBar 
from Tkinter import Frame as tkFrame 
from Tkinter import Canvas as tkCanvas 
from Tkinter import Entry as tkEntry 
from Tkinter import StringVar as tkStringVar 
from Tkinter import Tk, HORIZONTAL, N, S, E, W, RIGHT, LEFT, BOTTOM, X, Y, BOTH 
from Tkinter import TOP 


class Widget(tkFrame): 
    def __init__(self, master=None): 
     tkFrame.__init__(self, master) 

     self._str = tkStringVar() 
     self._widget = tkEntry(self) 

     self._widget.config(textvariable=self._str, borderwidth=1, width=0) 
     self._widget.pack(expand=True, fill=X) 

    def settext(self, str_): 
     self._str.set(str_) 

    def gettext(self): 
     return self._str.get() 


class Application(tkFrame): 
    def __init__(self, rows, cols, master=None): 
     tkFrame.__init__(self, master) 

     yScroll = tkScrollBar(self) 
     xScroll = tkScrollBar(self, orient=HORIZONTAL) 

     self._canvas = tkCanvas(self, 
       yscrollcommand=yScroll.set, xscrollcommand=xScroll.set) 
     yScroll.config(command=self._canvas.yview) 
     xScroll.config(command=self._canvas.xview) 

     self._table  = [[0 for x in range(rows)] for x in range(cols)] 
     self._tableFrame = tkFrame(self._canvas) 

     for col in range(cols): 
      self._tableFrame.grid_columnconfigure(col, weight=1) 
      for row in range(rows): 
       self._table[row][col] = Widget(master=self._tableFrame) 
       self._table[row][col].settext("(%d, %d)" % (row, col)) 
       self._table[row][col].grid(row=row, column=col, sticky=E+W) 

     # For debugging 
     self._canvas.config(background="blue") 
     self._tableFrame.config(background="red") 

     yScroll.pack(side=RIGHT, fill=Y) 
     xScroll.pack(side=BOTTOM, fill=X) 

     self._canvas.create_window(0, 0, window=self._tableFrame, anchor=N+W) 
     self._canvas.pack(side=LEFT, fill=BOTH, expand=True) 


tkRoot = Tk() 

# Application Size and Center the Application 
appSize = (800, 600) 
w  = tkRoot.winfo_screenwidth() 
h  = tkRoot.winfo_screenheight() 

x = w/2 - appSize[0]/2 
y = h/2 - appSize[1]/2 
tkRoot.geometry("%dx%d+%d+%d" % (appSize + (x, y))) 
tkRoot.update_idletasks() # Force geometry update 

app = Application(5, 5, master=tkRoot) 
app.pack(side=TOP, fill=BOTH, expand=True) 
tkRoot.mainloop() 

回答

7

可以与事件<Configure>结合self._canvas,然后调用itemconfig与帧的id添加到画布(不直接引用到插件):

def __init__(self, rows, cols, master=None): 
    # ... 
    self._frame_id = self._canvas.create_window(0, 0, window=self._tableFrame, anchor=N+W) 
    self._canvas.pack(side=LEFT, fill=BOTH, expand=True) 
    self._canvas.bind("<Configure>", self.resize_frame) 

def resize_frame(self, e): 
    self._canvas.itemconfig(self._frame_id, height=e.height, width=e.width) 

顺便说一句,我建议你改写你的import陈述,在我看来这是相当重复的,unpythonic

import Tkinter as tk 
# Use tk.Tk, tk.Canvas, etc.