Python Tkinter 滚动条摇晃滚动
Python Tkinter Scrollbar Shaky Scrolling
简介: 我的 Python Tkinter 应用程序设计为在侧面有一个滚动条,这样如果 window 已调整大小,仍可通过滚动条查看应用程序。为此,我将包含所有内容的框架放在 canvas 中,并使用滚动条控制 canvas。在 window 调整大小时,我有一个名为 resizeCanvas 的函数可以调整 canvas.
的大小
问题: 在我调整 window 的大小后,滚动条可以正常工作,但它似乎跳来跳去,坐立不安就像癫痫发作一样。但是,在初始化时滚动条工作顺利。所以调整 window 的大小似乎是问题所在。 关于为什么滚动条会这样运行有什么建议吗?
应用层次结构:
- Tkinter 根目录
- frame(只是 canvas 的容器)
- canvas(滚动条附在这个canvas上)
- frame(内容在该frame中)
注意:Python 2.7.2
代码片段:
myframe=Frame(root,width=winx,height=winy)
myframe.place(x=0,y=0)
canvas = Tkinter.Canvas(myframe,width=winx,height=winy)
frame = Frame(canvas,width=winx,height=winy)
myscrollbar=Scrollbar(myframe,orient="vertical")
myscrollbar.configure(command=canvas.yview)
canvas.configure(yscrollcommand=myscrollbar.set)
myscrollbar.pack(side="left",fill="y")
canvas.pack(side="left")
canvas.create_window((0,0),window=frame,anchor='nw')
frame.bind("<Configure>", initializeCanvas)
bind("<Configure>", resizeCanvas)
def initializeCanvas(self, event):
canvas.configure(scrollregion=self.canvas.bbox("all"),width=winx,height=winy)
def resizeCanvas(self, event):
update()
cwidth = self.winfo_width()
cheight = self.winfo_height()
canvas.config(width=cwidth, height=cheight)
完整代码:
import sys
#external python files are in the includes folder
sys.path.insert(0, 'includes')
import webbrowser
import os
import Tkinter
import tkFileDialog
import tkMessageBox
import ConfigParser
from ttk import *
import tkFont
import Tix
# configurations held in this variable
config = ConfigParser.RawConfigParser()
# pady padding for create buttons
py = 15
# padx padding for create buttons
px = 5
# padding on left side for indenting elements
indentx = 25
winx = 815
winy = 515
# array to hold features
FEATURES =['']
# wrapper class for GUI
class AppTk(Tkinter.Tk):
def __init__(self, parent):
Tkinter.Tk.__init__(self, parent)
self.parent = parent
self.settings = "./settings/settings.cfg"
self.initialize_gui()
self.minsize(winx, 100)
sizex = winx
sizey = winy
posx = 100
posy = 100
self.wm_geometry("%dx%d+%d+%d" % (sizex, sizey, posx, posy))
try:
self.iconbitmap('./imgs/favicon.ico')
except Exception, e:
print "\n****Error occurred (GUI_MBD_File_Creator.init): favicon not found!"
# Setup grid of elements in GUI
# action: on start of application
def initialize_gui(self):
# ----------------------------------------------------
# START Settings frame initialization
# ----------------------------------------------------
self.myframe=Frame(self,width=winx,height=winy)
self.myframe.place(x=0,y=0)
self.canvas = Tkinter.Canvas(self.myframe,width=winx,height=winy)
self.frame = Frame(self.canvas,width=winx,height=winy)
self.myscrollbar=Scrollbar(self.myframe,orient="vertical")
self.myscrollbar.configure(command=self.canvas.yview)
self.canvas.configure(yscrollcommand=self.myscrollbar.set)
self.myscrollbar.pack(side="left",fill="y")
self.canvas.pack(side="left")
self.canvas.create_window((0,0),window=self.frame,anchor='nw')
self.frame.bind("<Configure>",self.initializeCanvas)
self.bind("<Configure>",self.resizeCanvas)
frameFont = tkFont.Font(size=13, weight=tkFont.BOLD)
self.frameSettings = Tkinter.LabelFrame(self.frame, text="Settings: fill these out first", relief="groove", borderwidth="3", font=frameFont)
self.frameSettings.grid(sticky="EW", padx=px, pady=(5,15))
labelSpreadsheet = Label(self.frameSettings, text="1. Spreadsheet Path:")
labelSpreadsheet.grid(row=0, column=0, sticky='W', padx=(indentx,0))
variableSpreadsheet = Tkinter.StringVar()
self.entrySpreadsheet = Entry(self.frameSettings, textvariable=variableSpreadsheet, width=90, state=Tkinter.DISABLED)
self.entrySpreadsheet.grid(row=0, column=1, sticky='W', padx=px, pady=5)
self.entrySpreadsheet.svar = variableSpreadsheet
buttonSpreadsheet = Button(self.frameSettings, text="Browse...")
buttonSpreadsheet.grid(row=0, column=2, sticky='W', padx=(0,10))
labelPath = Label(self.frameSettings, text="2. Root Save Path:")
labelPath.grid(row=1, column=0, sticky='W', padx=(indentx,0))
variablePath = Tkinter.StringVar()
self.entryPath = Entry(self.frameSettings, textvariable=variablePath, width=90, state=Tkinter.DISABLED)
self.entryPath.grid(row=1, column=1, sticky='W', padx=px, pady=(5,10))
self.entryPath.svar = variablePath
buttonPath = Button(self.frameSettings, text="Browse...")
buttonPath.grid(row=1, column=2, sticky='W', padx=(0,10), pady=(0,5))
# ----------------------------------------------------
# START Creation Menu frame initialization
# ----------------------------------------------------
self.frameCreationIndividual = Tkinter.LabelFrame(self.frame, text="Feature Files Creation Menu", relief="groove", borderwidth="3", font=frameFont)
self.frameCreationIndividual.grid(sticky="EW", padx=px, pady=(5,15))
labelReq = Label(self.frameCreationIndividual, text="3. Feature(s):")
labelReq.grid(row=0, column=0, sticky='NW', pady=(5,0), padx=(indentx,15))
self.scrollbarReq = Scrollbar(self.frameCreationIndividual)
self.scrollbarReq.grid(row=1, column=3, rowspan=16, sticky="NSW", pady=(0,15),padx=(0,20))
variableSelectAll = Tkinter.IntVar()
self.checkSelectAll = Checkbutton(self.frameCreationIndividual, text = "Select All", variable = variableSelectAll, onvalue = 1, offvalue = 0)
self.checkSelectAll.grid(row=0, column=1, columnspan=2, sticky='NE', padx=px, pady=(5,0))
self.checkSelectAll.svar = variableSelectAll
labelReq = Label(self.frameCreationIndividual, text="4. Files:")
labelReq.grid(row=0, column=5, sticky='NW', pady=(5,0), padx=15)
variableIndividualFFS = Tkinter.IntVar()
self.checkIndividualFFS = Checkbutton(self.frameCreationIndividual, text = "Create Feature File", variable = variableIndividualFFS, onvalue = 1, offvalue = 0)
self.checkIndividualFFS.grid(row=1, column=5, sticky='NW', padx=15)
self.checkIndividualFFS.svar = variableIndividualFFS
variableIndividualSFS = Tkinter.IntVar()
self.checkIndividualSFS = Checkbutton(self.frameCreationIndividual, text = "Create SubFeature Files", variable = variableIndividualSFS, onvalue = 1, offvalue = 0)
self.checkIndividualSFS.grid(row=2, column=5, sticky='NW', padx=15)
self.checkIndividualSFS.svar = variableIndividualSFS
variableIndividualDO = Tkinter.IntVar()
self.checkIndividualDO = Checkbutton(self.frameCreationIndividual, text = "Create Doc Outline", variable = variableIndividualDO, onvalue = 1, offvalue = 0)
self.checkIndividualDO.grid(row=3, column=5, sticky='NW', padx=15)
self.checkIndividualDO.svar = variableIndividualDO
variableIndividualDWR = Tkinter.IntVar()
self.checkIndividualDWR = Checkbutton(self.frameCreationIndividual, text = "Create Doc With Requirements", variable = variableIndividualDWR, onvalue = 1, offvalue = 0)
self.checkIndividualDWR.grid(row=4, column=5, sticky='NW', padx=(15,30))
self.checkIndividualDWR.svar = variableIndividualDWR
self.buttonIndividualAll = Button(self.frameCreationIndividual, text="Create...", width=43)
self.buttonIndividualAll.grid(row=1, column=6, rowspan=4, sticky='NESW', padx=px)
# ----------------------------------------------------
# START Entire System Creation frame initialization
# ----------------------------------------------------
self.frameCreationSystem = Tkinter.LabelFrame(self.frame, text="System Creation Menu", relief="groove", borderwidth="3", font=frameFont)
self.frameCreationSystem.grid(sticky="EW", padx=px, pady=15)
self.buttonLAIF = Button(self.frameCreationSystem, text="Create Layers/App Integration Files", width=35)
self.buttonLAIF.grid(row=11, column=0, sticky='NESW', ipady=5, padx=(indentx,0), pady=(16,8))
self.buttonDO = Button(self.frameCreationSystem, text="Create Entire Doc Outline")
self.buttonDO.grid(row=12, column=0, sticky='NESW', ipady=5, padx=(indentx,0), pady=(8,10))
# ----------------------------------------------------
# START Feature Tab Creation Frame initialization
# ----------------------------------------------------
self.frameCreationNew = Tkinter.LabelFrame(self.frame, text="Feature Tab Creation Menu", relief="groove", borderwidth="3", font=frameFont)
self.frameCreationNew.grid(sticky="EW", padx=px, pady=(15,5))
labelIssueSpreadsheet = Label(self.frameCreationNew, text="2. Feature Spreadsheet Path:")
labelIssueSpreadsheet.grid(row=0, column=0, sticky='W', padx=(indentx,0))
variableIssueSpreadsheet = Tkinter.StringVar()
self.entryIssueSpreadsheet = Entry(self.frameCreationNew, textvariable=variableIssueSpreadsheet, width=83, state=Tkinter.DISABLED)
self.entryIssueSpreadsheet.grid(row=0, column=1, sticky='W', padx=px, pady=5)
self.entryIssueSpreadsheet.svar = variableIssueSpreadsheet
buttonIssueSpreadsheet = Button(self.frameCreationNew, text="Browse...")
buttonIssueSpreadsheet.grid(row=0, column=2, sticky='W')
labelFeatureTab = Label(self.frameCreationNew, text="3. Feature Name:")
labelFeatureTab.grid(row=1, column=0, sticky='W', padx=(indentx,0))
variableFeatureTab = Tkinter.StringVar()
self.entryFeatureTab = Entry(self.frameCreationNew, textvariable=variableFeatureTab, width=83)
self.entryFeatureTab.grid(row=1, column=1, sticky='W', padx=px, pady=5)
self.entryFeatureTab.svar = variableFeatureTab
labelFeatureAbbrv = Label(self.frameCreationNew, text="4. Feature Abbreviation:")
labelFeatureAbbrv.grid(row=2, column=0, sticky='W', padx=(indentx,0))
variableFeatureAbbrv = Tkinter.StringVar()
self.entryFeatureAbbrv = Entry(self.frameCreationNew, textvariable=variableFeatureAbbrv, width=83)
self.entryFeatureAbbrv.grid(row=2, column=1, sticky='W', padx=px, pady=5)
self.entryFeatureAbbrv.svar = variableFeatureAbbrv
self.buttonNewFeature = Button(self.frameCreationNew, text="Create Feature Tab", width=35)
self.buttonNewFeature.grid(row=3, column=0, columnspan =2, sticky='NWS', ipady=5, pady=(8,10), padx=(indentx,0))
# ----------------------------------------------------
# START general purpose methods
# ----------------------------------------------------
def initializeCanvas(self, event):
self.canvas.configure(scrollregion=self.canvas.bbox("all"),width=winx,height=winy)
def resizeCanvas(self, event):
self.update()
cwidth = self.winfo_width()
cheight = self.winfo_height()
self.canvas.config(scrollregion=self.canvas.bbox("all"), width=cwidth, height=cheight)
# ----------------------------------------------------
# Initialize application
# ----------------------------------------------------
if __name__ == "__main__":
app = AppTk(None)
app.title("MBD File Creator")
app.mainloop()
虽然可能存在其他错误,但您有一个非常严重的缺陷:您正在为 <Configure>
事件创建到 self
的绑定。因为 self
是根 window 的实例,所以 您创建的每个小部件都继承此绑定 。您的 resizeCanvas
方法在启动时实际上被调用了数百次,在 window 调整大小时被调用了数百次。
您还遇到了在事件处理程序中调用 update
的问题。一般来说,这是不好的。实际上,它就像调用 mainloop
一样,因为它不会 return 直到处理完所有事件。如果您的代码导致更多事件被处理(例如重新配置 window 并导致 <configure>
事件触发,您最终会进入递归循环。
您可能需要删除对 self.update()
and/or 的调用,将其替换为危险性较小的 self.update_idletasks()
。您还需要删除 self
上的 <Configure>
绑定,或者在您需要检查哪个小部件导致事件触发的方法中(即:检查 event.widget 是根window).
首先尝试将 canvas.create_window
保存到如下变量:
self.windows_item = canvas.create_window((0,0),window=frame,anchor='nw')
然后在resizeCanvas
的最后调用下面的方法:
def update(self):
"Update the canvas and the scrollregion"
self.update_idletasks()
canvas.config(scrollregion=canvas.bbox(self.windows_item))
希望对您有所帮助!
其中大部分在此处找到:
简介: 我的 Python Tkinter 应用程序设计为在侧面有一个滚动条,这样如果 window 已调整大小,仍可通过滚动条查看应用程序。为此,我将包含所有内容的框架放在 canvas 中,并使用滚动条控制 canvas。在 window 调整大小时,我有一个名为 resizeCanvas 的函数可以调整 canvas.
的大小问题: 在我调整 window 的大小后,滚动条可以正常工作,但它似乎跳来跳去,坐立不安就像癫痫发作一样。但是,在初始化时滚动条工作顺利。所以调整 window 的大小似乎是问题所在。 关于为什么滚动条会这样运行有什么建议吗?
应用层次结构:
- Tkinter 根目录
- frame(只是 canvas 的容器)
- canvas(滚动条附在这个canvas上)
- frame(内容在该frame中)
- canvas(滚动条附在这个canvas上)
- frame(只是 canvas 的容器)
注意:Python 2.7.2
代码片段:
myframe=Frame(root,width=winx,height=winy)
myframe.place(x=0,y=0)
canvas = Tkinter.Canvas(myframe,width=winx,height=winy)
frame = Frame(canvas,width=winx,height=winy)
myscrollbar=Scrollbar(myframe,orient="vertical")
myscrollbar.configure(command=canvas.yview)
canvas.configure(yscrollcommand=myscrollbar.set)
myscrollbar.pack(side="left",fill="y")
canvas.pack(side="left")
canvas.create_window((0,0),window=frame,anchor='nw')
frame.bind("<Configure>", initializeCanvas)
bind("<Configure>", resizeCanvas)
def initializeCanvas(self, event):
canvas.configure(scrollregion=self.canvas.bbox("all"),width=winx,height=winy)
def resizeCanvas(self, event):
update()
cwidth = self.winfo_width()
cheight = self.winfo_height()
canvas.config(width=cwidth, height=cheight)
完整代码:
import sys
#external python files are in the includes folder
sys.path.insert(0, 'includes')
import webbrowser
import os
import Tkinter
import tkFileDialog
import tkMessageBox
import ConfigParser
from ttk import *
import tkFont
import Tix
# configurations held in this variable
config = ConfigParser.RawConfigParser()
# pady padding for create buttons
py = 15
# padx padding for create buttons
px = 5
# padding on left side for indenting elements
indentx = 25
winx = 815
winy = 515
# array to hold features
FEATURES =['']
# wrapper class for GUI
class AppTk(Tkinter.Tk):
def __init__(self, parent):
Tkinter.Tk.__init__(self, parent)
self.parent = parent
self.settings = "./settings/settings.cfg"
self.initialize_gui()
self.minsize(winx, 100)
sizex = winx
sizey = winy
posx = 100
posy = 100
self.wm_geometry("%dx%d+%d+%d" % (sizex, sizey, posx, posy))
try:
self.iconbitmap('./imgs/favicon.ico')
except Exception, e:
print "\n****Error occurred (GUI_MBD_File_Creator.init): favicon not found!"
# Setup grid of elements in GUI
# action: on start of application
def initialize_gui(self):
# ----------------------------------------------------
# START Settings frame initialization
# ----------------------------------------------------
self.myframe=Frame(self,width=winx,height=winy)
self.myframe.place(x=0,y=0)
self.canvas = Tkinter.Canvas(self.myframe,width=winx,height=winy)
self.frame = Frame(self.canvas,width=winx,height=winy)
self.myscrollbar=Scrollbar(self.myframe,orient="vertical")
self.myscrollbar.configure(command=self.canvas.yview)
self.canvas.configure(yscrollcommand=self.myscrollbar.set)
self.myscrollbar.pack(side="left",fill="y")
self.canvas.pack(side="left")
self.canvas.create_window((0,0),window=self.frame,anchor='nw')
self.frame.bind("<Configure>",self.initializeCanvas)
self.bind("<Configure>",self.resizeCanvas)
frameFont = tkFont.Font(size=13, weight=tkFont.BOLD)
self.frameSettings = Tkinter.LabelFrame(self.frame, text="Settings: fill these out first", relief="groove", borderwidth="3", font=frameFont)
self.frameSettings.grid(sticky="EW", padx=px, pady=(5,15))
labelSpreadsheet = Label(self.frameSettings, text="1. Spreadsheet Path:")
labelSpreadsheet.grid(row=0, column=0, sticky='W', padx=(indentx,0))
variableSpreadsheet = Tkinter.StringVar()
self.entrySpreadsheet = Entry(self.frameSettings, textvariable=variableSpreadsheet, width=90, state=Tkinter.DISABLED)
self.entrySpreadsheet.grid(row=0, column=1, sticky='W', padx=px, pady=5)
self.entrySpreadsheet.svar = variableSpreadsheet
buttonSpreadsheet = Button(self.frameSettings, text="Browse...")
buttonSpreadsheet.grid(row=0, column=2, sticky='W', padx=(0,10))
labelPath = Label(self.frameSettings, text="2. Root Save Path:")
labelPath.grid(row=1, column=0, sticky='W', padx=(indentx,0))
variablePath = Tkinter.StringVar()
self.entryPath = Entry(self.frameSettings, textvariable=variablePath, width=90, state=Tkinter.DISABLED)
self.entryPath.grid(row=1, column=1, sticky='W', padx=px, pady=(5,10))
self.entryPath.svar = variablePath
buttonPath = Button(self.frameSettings, text="Browse...")
buttonPath.grid(row=1, column=2, sticky='W', padx=(0,10), pady=(0,5))
# ----------------------------------------------------
# START Creation Menu frame initialization
# ----------------------------------------------------
self.frameCreationIndividual = Tkinter.LabelFrame(self.frame, text="Feature Files Creation Menu", relief="groove", borderwidth="3", font=frameFont)
self.frameCreationIndividual.grid(sticky="EW", padx=px, pady=(5,15))
labelReq = Label(self.frameCreationIndividual, text="3. Feature(s):")
labelReq.grid(row=0, column=0, sticky='NW', pady=(5,0), padx=(indentx,15))
self.scrollbarReq = Scrollbar(self.frameCreationIndividual)
self.scrollbarReq.grid(row=1, column=3, rowspan=16, sticky="NSW", pady=(0,15),padx=(0,20))
variableSelectAll = Tkinter.IntVar()
self.checkSelectAll = Checkbutton(self.frameCreationIndividual, text = "Select All", variable = variableSelectAll, onvalue = 1, offvalue = 0)
self.checkSelectAll.grid(row=0, column=1, columnspan=2, sticky='NE', padx=px, pady=(5,0))
self.checkSelectAll.svar = variableSelectAll
labelReq = Label(self.frameCreationIndividual, text="4. Files:")
labelReq.grid(row=0, column=5, sticky='NW', pady=(5,0), padx=15)
variableIndividualFFS = Tkinter.IntVar()
self.checkIndividualFFS = Checkbutton(self.frameCreationIndividual, text = "Create Feature File", variable = variableIndividualFFS, onvalue = 1, offvalue = 0)
self.checkIndividualFFS.grid(row=1, column=5, sticky='NW', padx=15)
self.checkIndividualFFS.svar = variableIndividualFFS
variableIndividualSFS = Tkinter.IntVar()
self.checkIndividualSFS = Checkbutton(self.frameCreationIndividual, text = "Create SubFeature Files", variable = variableIndividualSFS, onvalue = 1, offvalue = 0)
self.checkIndividualSFS.grid(row=2, column=5, sticky='NW', padx=15)
self.checkIndividualSFS.svar = variableIndividualSFS
variableIndividualDO = Tkinter.IntVar()
self.checkIndividualDO = Checkbutton(self.frameCreationIndividual, text = "Create Doc Outline", variable = variableIndividualDO, onvalue = 1, offvalue = 0)
self.checkIndividualDO.grid(row=3, column=5, sticky='NW', padx=15)
self.checkIndividualDO.svar = variableIndividualDO
variableIndividualDWR = Tkinter.IntVar()
self.checkIndividualDWR = Checkbutton(self.frameCreationIndividual, text = "Create Doc With Requirements", variable = variableIndividualDWR, onvalue = 1, offvalue = 0)
self.checkIndividualDWR.grid(row=4, column=5, sticky='NW', padx=(15,30))
self.checkIndividualDWR.svar = variableIndividualDWR
self.buttonIndividualAll = Button(self.frameCreationIndividual, text="Create...", width=43)
self.buttonIndividualAll.grid(row=1, column=6, rowspan=4, sticky='NESW', padx=px)
# ----------------------------------------------------
# START Entire System Creation frame initialization
# ----------------------------------------------------
self.frameCreationSystem = Tkinter.LabelFrame(self.frame, text="System Creation Menu", relief="groove", borderwidth="3", font=frameFont)
self.frameCreationSystem.grid(sticky="EW", padx=px, pady=15)
self.buttonLAIF = Button(self.frameCreationSystem, text="Create Layers/App Integration Files", width=35)
self.buttonLAIF.grid(row=11, column=0, sticky='NESW', ipady=5, padx=(indentx,0), pady=(16,8))
self.buttonDO = Button(self.frameCreationSystem, text="Create Entire Doc Outline")
self.buttonDO.grid(row=12, column=0, sticky='NESW', ipady=5, padx=(indentx,0), pady=(8,10))
# ----------------------------------------------------
# START Feature Tab Creation Frame initialization
# ----------------------------------------------------
self.frameCreationNew = Tkinter.LabelFrame(self.frame, text="Feature Tab Creation Menu", relief="groove", borderwidth="3", font=frameFont)
self.frameCreationNew.grid(sticky="EW", padx=px, pady=(15,5))
labelIssueSpreadsheet = Label(self.frameCreationNew, text="2. Feature Spreadsheet Path:")
labelIssueSpreadsheet.grid(row=0, column=0, sticky='W', padx=(indentx,0))
variableIssueSpreadsheet = Tkinter.StringVar()
self.entryIssueSpreadsheet = Entry(self.frameCreationNew, textvariable=variableIssueSpreadsheet, width=83, state=Tkinter.DISABLED)
self.entryIssueSpreadsheet.grid(row=0, column=1, sticky='W', padx=px, pady=5)
self.entryIssueSpreadsheet.svar = variableIssueSpreadsheet
buttonIssueSpreadsheet = Button(self.frameCreationNew, text="Browse...")
buttonIssueSpreadsheet.grid(row=0, column=2, sticky='W')
labelFeatureTab = Label(self.frameCreationNew, text="3. Feature Name:")
labelFeatureTab.grid(row=1, column=0, sticky='W', padx=(indentx,0))
variableFeatureTab = Tkinter.StringVar()
self.entryFeatureTab = Entry(self.frameCreationNew, textvariable=variableFeatureTab, width=83)
self.entryFeatureTab.grid(row=1, column=1, sticky='W', padx=px, pady=5)
self.entryFeatureTab.svar = variableFeatureTab
labelFeatureAbbrv = Label(self.frameCreationNew, text="4. Feature Abbreviation:")
labelFeatureAbbrv.grid(row=2, column=0, sticky='W', padx=(indentx,0))
variableFeatureAbbrv = Tkinter.StringVar()
self.entryFeatureAbbrv = Entry(self.frameCreationNew, textvariable=variableFeatureAbbrv, width=83)
self.entryFeatureAbbrv.grid(row=2, column=1, sticky='W', padx=px, pady=5)
self.entryFeatureAbbrv.svar = variableFeatureAbbrv
self.buttonNewFeature = Button(self.frameCreationNew, text="Create Feature Tab", width=35)
self.buttonNewFeature.grid(row=3, column=0, columnspan =2, sticky='NWS', ipady=5, pady=(8,10), padx=(indentx,0))
# ----------------------------------------------------
# START general purpose methods
# ----------------------------------------------------
def initializeCanvas(self, event):
self.canvas.configure(scrollregion=self.canvas.bbox("all"),width=winx,height=winy)
def resizeCanvas(self, event):
self.update()
cwidth = self.winfo_width()
cheight = self.winfo_height()
self.canvas.config(scrollregion=self.canvas.bbox("all"), width=cwidth, height=cheight)
# ----------------------------------------------------
# Initialize application
# ----------------------------------------------------
if __name__ == "__main__":
app = AppTk(None)
app.title("MBD File Creator")
app.mainloop()
虽然可能存在其他错误,但您有一个非常严重的缺陷:您正在为 <Configure>
事件创建到 self
的绑定。因为 self
是根 window 的实例,所以 您创建的每个小部件都继承此绑定 。您的 resizeCanvas
方法在启动时实际上被调用了数百次,在 window 调整大小时被调用了数百次。
您还遇到了在事件处理程序中调用 update
的问题。一般来说,这是不好的。实际上,它就像调用 mainloop
一样,因为它不会 return 直到处理完所有事件。如果您的代码导致更多事件被处理(例如重新配置 window 并导致 <configure>
事件触发,您最终会进入递归循环。
您可能需要删除对 self.update()
and/or 的调用,将其替换为危险性较小的 self.update_idletasks()
。您还需要删除 self
上的 <Configure>
绑定,或者在您需要检查哪个小部件导致事件触发的方法中(即:检查 event.widget 是根window).
首先尝试将 canvas.create_window
保存到如下变量:
self.windows_item = canvas.create_window((0,0),window=frame,anchor='nw')
然后在resizeCanvas
的最后调用下面的方法:
def update(self):
"Update the canvas and the scrollregion"
self.update_idletasks()
canvas.config(scrollregion=canvas.bbox(self.windows_item))
希望对您有所帮助!
其中大部分在此处找到: