如何在 Tkinter 中获得带有滚动条的 Frame?

Posted

技术标签:

【中文标题】如何在 Tkinter 中获得带有滚动条的 Frame?【英文标题】:How could I get a Frame with a scrollbar in Tkinter? 【发布时间】:2010-12-24 19:40:40 【问题描述】:

我想要一个Frame,用户可以在其中添加应用程序所需的任意数量的文本字段。

应用程序以一个文本字段和该文本字段下方的按钮开始。当用户按下按钮时,将在第一个文本条目下方添加一个新的文本条目(这可能会重复无数次)。在窗口中间,会有一个Text 小部件,用来显示文字:)

但是,我在文档中注意到了这一点:

This widget is used to implement scrolled listboxes, canvases, and text fields.

有没有办法将ScrollbarFrame 一起使用?

【问题讨论】:

【参考方案1】:

如果你可以使用 Tix,还有一个 ScrolledWindow 小部件,它有一个 window 框架和一个或两个 Scrollbar 小部件:

import Tix as tk

r= tk.Tk()
r.title("test scrolled window")
sw= tk.ScrolledWindow(r, scrollbar=tk.Y) # just the vertical scrollbar
sw.pack(fill=tk.BOTH, expand=1)
for i in xrange(10):
    e= tk.Entry(sw.window)
    e.pack()
r.mainloop()

更改根窗口的大小。您需要在 Entry 小部件的 focus_get 事件中添加代码,以便在通过键盘切换时滚动 ScrolledWindow。

否则,您将不得不使用 Canvas 小部件(您可以添加标签、条目和文本子小部件)并自己编写更多代码来实现所需的功能。

【讨论】:

【参考方案2】:

以下是自动隐藏滚动条的示例,仅在您使用grid几何管理器时才有效,取自@987654321 @文档:

from tkinter import *


class AutoScrollbar(Scrollbar):
    # A scrollbar that hides itself if it's not needed.
    # Only works if you use the grid geometry manager!
    def set(self, lo, hi):
        if float(lo) <= 0.0 and float(hi) >= 1.0:
            # grid_remove is currently missing from Tkinter!
            self.tk.call("grid", "remove", self)
        else:
            self.grid()
        Scrollbar.set(self, lo, hi)
    def pack(self, **kw):
        raise TclError("cannot use pack with this widget")
    def place(self, **kw):
        raise TclError("cannot use place with this widget")


# create scrolled canvas

root = Tk()

vscrollbar = AutoScrollbar(root)
vscrollbar.grid(row=0, column=1, sticky=N+S)
hscrollbar = AutoScrollbar(root, orient=HORIZONTAL)
hscrollbar.grid(row=1, column=0, sticky=E+W)

canvas = Canvas(root, yscrollcommand=vscrollbar.set, xscrollcommand=hscrollbar.set)
canvas.grid(row=0, column=0, sticky=N+S+E+W)

vscrollbar.config(command=canvas.yview)
hscrollbar.config(command=canvas.xview)

# make the canvas expandable
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)

# create canvas contents
frame = Frame(canvas)
frame.rowconfigure(1, weight=1)
frame.columnconfigure(1, weight=1)

rows = 5
for i in range(1, rows):
    for j in range(1, 10):
        button = Button(frame, text="%d, %d" % (i,j))
        button.grid(row=i, column=j, sticky='news')

canvas.create_window(0, 0, anchor=NW, window=frame)
frame.update_idletasks()
canvas.config(scrollregion=canvas.bbox("all"))

root.mainloop()

【讨论】:

我认为这个问题无关紧要。我刚刚下载了适用于 Windows 的 Python 2.6.6,它带有 Tix。所以,它似乎和 Tkinter 一样好用。 我试图将这个答案中的代码重构为它自己的可重用class,但没有成功。如果您有时间在这里查看我的问题,我将不胜感激:***.com/questions/30018148/… 另外,Rinzler,您为什么将此代码作为编辑而不是作为答案发布? 2010 年的现有 cmets 现在没有任何意义了,而我对这段代码的支持最终会变成与代码无关的清算人。您应该发布一个新答案,然后回滚您的编辑。 我们如何在 place() 中使用相同的方法

以上是关于如何在 Tkinter 中获得带有滚动条的 Frame?的主要内容,如果未能解决你的问题,请参考以下文章

Tkinter 如何正确设置组合框滚动条的样式

在 tkinter 中更改滚动条的外观(使用 ttk 样式)

tkinter:在画布上使用滚动条

在Canvas tkinter上动态更改滚动条的长度

如何在没有(减号)滚动条的情况下获得屏幕宽度?

如何编码 tkinter “scrolledtext” 模块