可滚动框架未填充 canvas
Scrollable frame does not fill canvas
我使用 Python 2.7 并且我有一个可滚动的框架,其中 canvas 没有缩小以适应我想要滚动的框架。
我查看了这个问题的答案,但当我 运行 它时它不起作用:
当我在 canvas 中打印框架的宽度时,它显示为 0。
我也在我的电脑上 运行 这个问题的答案中的代码:
但它仍然会在标签左侧显示白色 canvas,并且在删除标签时不会调整大小。
看起来像这样:
这是我的代码,基于这个问题的答案:
Adding a scrollbar to a group of widgets in Tkinter
from Tkinter import *
class Scrollable_frame(Frame):
def __init__(self, parent, title, values):
self.parent = parent
Frame.__init__(self, self.parent)
self.canvas = Canvas(self, borderwidth=0, background="#ffffff")
self.scrollbar = Scrollbar(self, command=self.canvas.yview)
self.innerFrame = Radiobutton_frame(self.canvas,title,values)
self.canvas.configure(yscrollcommand=self.scrollbar.set)
self.canvas.grid(row=0, column=0, sticky= N+S)
self.scrollbar.grid(row=0, column=1, sticky = N+S)
self.canvas.create_window((0,0),window = self.innerFrame,anchor="nw")
self.innerFrame.bind("<Configure>", self.set_canvas_scrollregion)
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
def set_canvas_scrollregion(self, event):
width = event.width - 4
self.canvas.itemconfigure("self.innerFrame ", width=width)
self.canvas.config(scrollregion=self.canvas.bbox("all"))
class Radiobutton_frame(LabelFrame):
def __init__(self, parent, title, values):
"""
In: parent - Canvas
title - String
values - List of Int
"""
self.radiobuttons = {}
self.parent = parent
self.selection = StringVar()
self.selection.set("init")
LabelFrame.__init__(self, self.parent, text = title)
for value in values:
self.add_radiobutton(value)
def add_radiobutton(self, value):
"""
Adds a radiobutton to the frame.
In: item - String
"""
# Associate to same variable to make them function as a group
self.radiobuttons[value] = Radiobutton(master = self,
variable = self.selection,
text = value,
value = value)
self.radiobuttons[value].pack(anchor=W)
# Usage example
root = Tk()
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
scrollableFrame = Scrollable_frame(root, "Canvas not resizing", range(30))
scrollableFrame.grid(row=0, column=0, sticky=N+S+E+W)
if __name__ == '__main__':
root.mainloop()
我认为上面问题的代码片段不适合 a Minimal, Complete, and Verifiable example 但至少它是可运行的。
与
相比,你犯了三个错误
其中最重要的是在链接的问题中,OP 在您不使用的地方使用了选项 tags
。替换:
self.canvas.create_window((0,0),window = self.innerFrame,anchor="nw")
与:
self.canvas.create_window((0,0),window = self.innerFrame, anchor="nw", tags="my_tag")
另一个错误是您将框架的大小调整事件与实际 Canvas 的大小调整事件绑定在一起, 中也指出了这一点。替换:
self.innerFrame.bind("<Configure>", self.set_canvas_scrollregion)
与:
self.canvas.bind("<Configure>", self.set_canvas_scrollregion)
最后,tkinter 似乎不接受带标签的 space 字符,替换为:
self.canvas.itemconfigure("self.innerFrame ", width=width)
与:
self.canvas.itemconfigure("my_tag", width=width)
最后,你应该有:
from Tkinter import *
class Scrollable_frame(Frame):
def __init__(self, parent, title, values):
self.parent = parent
Frame.__init__(self, self.parent)
self.canvas = Canvas(self, borderwidth=0, background="#ffffff")
self.scrollbar = Scrollbar(self, command=self.canvas.yview)
self.innerFrame = Radiobutton_frame(self.canvas,title,values)
self.canvas.configure(yscrollcommand=self.scrollbar.set)
self.canvas.grid(row=0, column=0, sticky= N+S)
self.scrollbar.grid(row=0, column=1, sticky = N+S)
self.canvas.create_window((0,0),window = self.innerFrame,anchor="nw",
tags="my_tag")
self.canvas.bind("<Configure>", self.set_canvas_scrollregion)
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
def set_canvas_scrollregion(self, event):
width = event.width - 4
self.canvas.itemconfigure("my_tag", width=width)
self.canvas.config(scrollregion=self.canvas.bbox("all"))
class Radiobutton_frame(LabelFrame):
def __init__(self, parent, title, values):
"""
In: parent - Canvas
title - String
values - List of Int
"""
self.radiobuttons = {}
self.parent = parent
self.selection = StringVar()
self.selection.set("init")
LabelFrame.__init__(self, self.parent, text = title)
for value in values:
self.add_radiobutton(value)
def add_radiobutton(self, value):
"""
Adds a radiobutton to the frame.
In: item - String
"""
# Associate to same variable to make them function as a group
self.radiobuttons[value] = Radiobutton(master = self,
variable = self.selection,
text = value,
value = value)
self.radiobuttons[value].pack(anchor=W)
# Usage example
root = Tk()
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
scrollableFrame = Scrollable_frame(root, "Canvas not resizing", range(30))
scrollableFrame.grid(row=0, column=0, sticky=N+S+E+W)
if __name__ == '__main__':
root.mainloop()
我使用 Python 2.7 并且我有一个可滚动的框架,其中 canvas 没有缩小以适应我想要滚动的框架。
我查看了这个问题的答案,但当我 运行 它时它不起作用:
当我在 canvas 中打印框架的宽度时,它显示为 0。
我也在我的电脑上 运行 这个问题的答案中的代码:
看起来像这样:
这是我的代码,基于这个问题的答案: Adding a scrollbar to a group of widgets in Tkinter
from Tkinter import *
class Scrollable_frame(Frame):
def __init__(self, parent, title, values):
self.parent = parent
Frame.__init__(self, self.parent)
self.canvas = Canvas(self, borderwidth=0, background="#ffffff")
self.scrollbar = Scrollbar(self, command=self.canvas.yview)
self.innerFrame = Radiobutton_frame(self.canvas,title,values)
self.canvas.configure(yscrollcommand=self.scrollbar.set)
self.canvas.grid(row=0, column=0, sticky= N+S)
self.scrollbar.grid(row=0, column=1, sticky = N+S)
self.canvas.create_window((0,0),window = self.innerFrame,anchor="nw")
self.innerFrame.bind("<Configure>", self.set_canvas_scrollregion)
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
def set_canvas_scrollregion(self, event):
width = event.width - 4
self.canvas.itemconfigure("self.innerFrame ", width=width)
self.canvas.config(scrollregion=self.canvas.bbox("all"))
class Radiobutton_frame(LabelFrame):
def __init__(self, parent, title, values):
"""
In: parent - Canvas
title - String
values - List of Int
"""
self.radiobuttons = {}
self.parent = parent
self.selection = StringVar()
self.selection.set("init")
LabelFrame.__init__(self, self.parent, text = title)
for value in values:
self.add_radiobutton(value)
def add_radiobutton(self, value):
"""
Adds a radiobutton to the frame.
In: item - String
"""
# Associate to same variable to make them function as a group
self.radiobuttons[value] = Radiobutton(master = self,
variable = self.selection,
text = value,
value = value)
self.radiobuttons[value].pack(anchor=W)
# Usage example
root = Tk()
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
scrollableFrame = Scrollable_frame(root, "Canvas not resizing", range(30))
scrollableFrame.grid(row=0, column=0, sticky=N+S+E+W)
if __name__ == '__main__':
root.mainloop()
我认为上面问题的代码片段不适合 a Minimal, Complete, and Verifiable example 但至少它是可运行的。
与
其中最重要的是在链接的问题中,OP 在您不使用的地方使用了选项 tags
。替换:
self.canvas.create_window((0,0),window = self.innerFrame,anchor="nw")
与:
self.canvas.create_window((0,0),window = self.innerFrame, anchor="nw", tags="my_tag")
另一个错误是您将框架的大小调整事件与实际 Canvas 的大小调整事件绑定在一起,
self.innerFrame.bind("<Configure>", self.set_canvas_scrollregion)
与:
self.canvas.bind("<Configure>", self.set_canvas_scrollregion)
最后,tkinter 似乎不接受带标签的 space 字符,替换为:
self.canvas.itemconfigure("self.innerFrame ", width=width)
与:
self.canvas.itemconfigure("my_tag", width=width)
最后,你应该有:
from Tkinter import *
class Scrollable_frame(Frame):
def __init__(self, parent, title, values):
self.parent = parent
Frame.__init__(self, self.parent)
self.canvas = Canvas(self, borderwidth=0, background="#ffffff")
self.scrollbar = Scrollbar(self, command=self.canvas.yview)
self.innerFrame = Radiobutton_frame(self.canvas,title,values)
self.canvas.configure(yscrollcommand=self.scrollbar.set)
self.canvas.grid(row=0, column=0, sticky= N+S)
self.scrollbar.grid(row=0, column=1, sticky = N+S)
self.canvas.create_window((0,0),window = self.innerFrame,anchor="nw",
tags="my_tag")
self.canvas.bind("<Configure>", self.set_canvas_scrollregion)
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
def set_canvas_scrollregion(self, event):
width = event.width - 4
self.canvas.itemconfigure("my_tag", width=width)
self.canvas.config(scrollregion=self.canvas.bbox("all"))
class Radiobutton_frame(LabelFrame):
def __init__(self, parent, title, values):
"""
In: parent - Canvas
title - String
values - List of Int
"""
self.radiobuttons = {}
self.parent = parent
self.selection = StringVar()
self.selection.set("init")
LabelFrame.__init__(self, self.parent, text = title)
for value in values:
self.add_radiobutton(value)
def add_radiobutton(self, value):
"""
Adds a radiobutton to the frame.
In: item - String
"""
# Associate to same variable to make them function as a group
self.radiobuttons[value] = Radiobutton(master = self,
variable = self.selection,
text = value,
value = value)
self.radiobuttons[value].pack(anchor=W)
# Usage example
root = Tk()
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
scrollableFrame = Scrollable_frame(root, "Canvas not resizing", range(30))
scrollableFrame.grid(row=0, column=0, sticky=N+S+E+W)
if __name__ == '__main__':
root.mainloop()