gpt4 book ai didi

python - 滚动框架内的 Canvas

转载 作者:太空宇宙 更新时间:2023-11-03 14:56:06 25 4
gpt4 key购买 nike

我目前正在努力在滚动框架内使用 Tkinter Canvas 。我所说的滚动框架是指 Gonzo 在另一个线程( Python Tkinter scrollbar for frame )的答案中给出的框架 Canvas 结构。我已经适应了这个概念并添加了水平滚动条。现在,在内部框架的顶部,我想放置一 block 具有给定最小尺寸的 Canvas 。如果这个最小尺寸小于内部框架(或整个窗口),则没有问题(因为不需要滚动)。但是,如果我将窗口(以及框架)的大小调整为小于 Canvas 的值(这是滚动条应该有用的条件),则 Canvas 不会被拉伸(stretch)到所需的大小(在下面的示例中,不是宽度=500px)而是在框架的较小尺寸(宽度=400px)处被截断。滚动条处于事件状态,它们滚动仍为 500 像素的内部框架。

下面我为您提供有关代码和问题的更多详细信息。

感谢您的调查。我感谢对这个问题的任何帮助,也许我只是做了一些明显错误的事情。

干杯,C.

ScrollFrame类(存储在scrollframe.py中):

from Tkinter import *

class ScrollFrame(Frame):
def __init__(self, parent, yscroll=True, xscroll=True, *args, **kw):
Frame.__init__(self, parent, *args, **kw)
self.canvas = Canvas(self, bd=0, highlightthickness=0)
if xscroll:
hscrollbar = Scrollbar(self, orient=HORIZONTAL)
hscrollbar.pack(fill=X, side=BOTTOM, expand=FALSE)
self.canvas.config(xscrollcommand=hscrollbar.set)
hscrollbar.config(command=self.canvas.xview)
if yscroll:
vscrollbar = Scrollbar(self, orient=VERTICAL)
vscrollbar.pack(fill=Y, side=RIGHT, expand=FALSE)
self.canvas.config(yscrollcommand=vscrollbar.set)
vscrollbar.config(command=self.canvas.yview)
self.canvas.pack(side=LEFT, fill=BOTH, expand=TRUE)

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

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

# 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())
print "interior req: ",size,(interior.winfo_width(),interior.winfo_height())
self.canvas.config(scrollregion="0 0 %s %s" % size)
if interior.winfo_reqwidth() != self.canvas.winfo_width() or interior.winfo_reqheight() != sel f.canvas.winfo_height():
# update the canvas's width to fit the inner frame
self.canvas.config(width=interior.winfo_reqwidth(), height=interior.winfo_reqheight(),)
interior.bind('<Configure>', _configure_interior)

def _configure_canvas(event):
if interior.winfo_reqwidth() != self.canvas.winfo_width() or interior.winfo_reqheight() != sel f.canvas.winfo_height():
# update the inner frame's width to fill the canvas
self.canvas.itemconfigure(self.interior_id, width=self.canvas.winfo_width(), height=self.c anvas.winfo_height())
self.canvas.bind('<Configure>', _configure_canvas)

主要代码: 从 Tkinter 导入 * 从滚动框架导入 *

root = Tk()
root.geometry("400x300")

frame = Frame(root, bg="blue")
frame.pack(expand=True, fill=BOTH)

sf = ScrollFrame(frame, bg="yellow")
sf.pack(expand=True, fill=BOTH)

sf.interior.config(width=500, height=400)
canvas = Canvas(sf.interior, width=500, height=400, bg="green")
canvas.pack(expand=True, fill=BOTH, side="top")

root.mainloop()

运行时,如下所示:1.canvas at top left corner (not yet scrolled)2.canvas at bottom right corner (after scrolling)

问题:绿色 Canvas 应该是请求的大小(500/400),但它似乎是滚动条附加到的祖母框架的大小(400/300)而不是内部框架,这是一个滚动的 (500/400) 的框架,它是 Canvas 的母框架。

最佳答案

_configure_canvas 方法是问题的根源。它将 self.interior 框架的大小调整为 self.canvas 的宽度,并且由于 canvas 已包含选项 expand=True, fill=BOTH,大小调整为 400x300。

此外,这个函数并不是获取滚动框所必需的,唯一需要的是每次 self.interior 时调整 self.canvas 滚动区域的大小调整大小。

修改后的代码如下:

from Tkinter import *

class ScrollFrame(Frame):
def __init__(self, parent, yscroll=True, xscroll=True, *args, **kw):
Frame.__init__(self, parent, *args, **kw)
self.canvas = Canvas(self, bd=0, highlightthickness=0)
if xscroll:
hscrollbar = Scrollbar(self, orient=HORIZONTAL)
hscrollbar.pack(fill=X, side=BOTTOM, expand=FALSE)
self.canvas.config(xscrollcommand=hscrollbar.set)
hscrollbar.config(command=self.canvas.xview)
if yscroll:
vscrollbar = Scrollbar(self, orient=VERTICAL)
vscrollbar.pack(fill=Y, side=RIGHT, expand=FALSE)
self.canvas.config(yscrollcommand=vscrollbar.set)
vscrollbar.config(command=self.canvas.yview)
self.canvas.pack(side=LEFT, fill=BOTH, expand=TRUE)

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

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

# track changes to the frame width and update the scrollregion
def _configure_interior(event):
# update the scrollbars to match the size of the inner frame
self.canvas.config(scrollregion=self.canvas.bbox('all'))
interior.bind('<Configure>', _configure_interior)

root = Tk()
root.geometry("400x300")

frame = Frame(root, bg="blue")
frame.pack(expand=True, fill=BOTH)

sf = ScrollFrame(frame, bg="yellow")
sf.pack(expand=True, fill=BOTH)

sf.interior.config(width=500, height=400)
canvas = Canvas(sf.interior, width=500, height=400, bg="green")
canvas.pack(expand=True, fill=BOTH, side="top")

root.mainloop()

关于python - 滚动框架内的 Canvas ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45568338/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com