gpt4 book ai didi

python - 滚动条小部件在网格中布局时将不起作用

转载 作者:行者123 更新时间:2023-12-01 01:42:39 26 4
gpt4 key购买 nike

当将 Python3 与 tkinter 库一起使用时,我多次遇到需要可滚动框架(具有垂直和水平滚动功能)才能包含一组相关小部件的情况。由于滚动条不容易附加到框架上(我听说您可以将滚动条附加到 Canvas 上,但不能附加到框架上),我决定创建自己的 ScrolledFrame 类 - 一个使用带有 Canvas 小部件的滚动条,在其中显示一个框架。

在大多数情况下,它运行得很好。我使用 .pack() 方法布置了滚动条和 Canvas 。但因为它们是经过 pack() 处理的,所以垂直小部件会一直下降到屏幕底部,而不是留下空白区域。 (运行我的代码看看我的意思。)

#!/bin/env python3
# File: scrolledframe.py
# Written by: J-L


import tkinter as tk


class ScrolledFrame(tk.Frame):
def __init__(self, parent, **kwargs):
# Create the "scaffolding" widgets:
self.outerFrame = outerFrame = tk.Frame(parent, **kwargs)
self.canvas = canvas = tk.Canvas(outerFrame)
self.vscroll = vscroll = tk.Scrollbar(outerFrame, orient='vertical')
self.hscroll = hscroll = tk.Scrollbar(outerFrame, orient='horizontal')

# Pack/grid the vscroll, hscroll, and canvas widgets into their frame:
usePack = True
if usePack: # use .pack()
vscroll.pack(side='right', fill='y')
hscroll.pack(side='bottom', fill='x')
canvas.pack(fill='both', expand=True)
else: # use .grid()
canvas.grid(row=0, column=0, sticky='nsew')
vscroll.grid(row=0, column=1, sticky='ns')
hscroll.grid(row=1, column=0, sticky='ew')

# Hook up the commands for vscroll, hscroll, and canvas widgets:
vscroll.configure(command=canvas.yview)
hscroll.configure(command=canvas.xview)
canvas.configure(yscrollcommand=vscroll.set,
xscrollcommand=hscroll.set)

# Now create this very obejct (the innerFrame) as part of the canvas:
super().__init__(canvas)
innerFrame = self
canvas.create_window((0, 0), window=innerFrame)
innerFrame.bind('<Configure>',
lambda event: canvas.configure(scrollregion=canvas.bbox('all'),
width=event.width,
height=event.height))


# Accessor methods to access the four widgets involved:
def outer_frame(self): return self.outerFrame
def vscroll(self): return self.vscroll
def hscroll(self): return self.hscroll
def inner_frame(self): return self # (included for completeness)


# When .pack(), .grid(), or .place() is called on this object,
# it should be invoked on the outerFrame, attaching that to its
# parent widget:
def pack(self, **kwargs): self.outerFrame.pack(**kwargs)
def grid(self, **kwargs): self.outerFrame.grid(**kwargs)
def place(self, **kwargs): self.outerFrame.place(**kwargs)


def doExample():
# Create the main window:
root = tk.Tk()
root.title('ScrolledFrame Example')

# Create the scrolledFrame and a quit button:
scrolledFrame = ScrolledFrame(root)
scrolledFrame.pack()
tk.Button(root, text='Quit', command=root.quit).pack(side='bottom')

# Create some labels to display inside the scrolledFrame:
for i in range(1, 30+1):
tk.Label(scrolledFrame,
text='This is the text inside label #{}.'.format(i)
).grid(row=i-1, column=0)

# Start the GUI:
root.mainloop()


if __name__ == '__main__':
doExample()

说实话,这不是一个大问题,但我后来考虑使用 .grid() 布局方法,将每个滚动条放在自己的行和列中。

在代码的第 18 行附近,我添加了这一行:

usePack = True

如果将其从 True 更改为 False,滚动条和 Canvas 小部件将使用 .grid() 进行布局,而不是使用 .grid() .pack(),然后您就可以看到我在说什么了。

因此,当我使用 .grid() 布局滚动条时,垂直滚动条下方的空间确实按照我的预期出现,但现在所有滚动条都不起作用!

这对我来说似乎很奇怪,因为我不明白为什么简单地更改小部件的布局管理就会使它们的行为有所不同。

问题 1:我做错了什么导致滚动条在使用 .grid() 布局时无法工作?

此外,我注意到,使用 .pack().grid() 时,“退出”按钮将立即移出窗口。我将窗口大小调整为比开始时短。

问题 2:有没有办法可以强制“退出”按钮保留在窗口上(当窗口调整大小时),但会牺牲 ScrolledFrame 的性能?

预先感谢您的所有帮助!

最佳答案

What am I doing wrong that prevents the scrollbars from working when they are laid-out with .grid()?

问题是您没有告诉grid如何处理额外的空间,以及当没有足够的空间时该怎么做。因此,小部件恰好占用了它们所需的空间。

使用pack,您可以告诉它使用fillexpand 选项填充所有分配的空间。使用网格,您需要为 Canvas 所在的行和列赋予非零权重。

添加这两行,您将获得与 pack 相同的 grid 行为:

outerFrame.grid_rowconfigure(0, weight=1)
outerFrame.grid_columnconfigure(0, weight=1)

假设您希望它完全填充窗口,则在打包 scrolledFrame 时,您可能还需要使用 fillexpand 选项。

scrolledFrame.pack(fill="both", expand=True)

Is there a way I can force the "Quit" button to stay on the window (when the window is resizing), at the expense of my ScrolledFrame?

在调用 pack 其他小部件之前对其调用 pack 。当没有足够的空间容纳所有小部件并且 tkinter 必须减小一个或多个小部件的大小以使其适合时,它首先会减小添加的最后一个小部件的大小。

关于python - 滚动条小部件在网格中布局时将不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51709861/

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