Tkinter 笔记本中的可滚动页面



对于一个项目,我需要为 N 个子文件(数据集(指定一个特定的值,这个值可以均匀分布(此处省略(,只需要一个起始值和一个增量,或者不均匀分布,这意味着每个子文件都有自己的值。我决定使用笔记本来分隔这两种输入方法。

由于子文件的数量可以达到数百个,我需要一个滚动条,在咨询 Google 后,我发现要以这种方式使用滚动条,我需要使用画布并在其中放置一个框架,其中包含我想要滚动浏览的所有内容。

每次的数字都可能不同,所以我决定使用一个字典,该字典将被迭代填充,以包含所有"入口框架",每个框架都包含一个标签、一个输入字段和一个变量,汇总到一个自定义类IterEntryField中。创建类实例后,将其打包在一个容器框架中。for循环结束后,将容器框架放置在画布上,并为滚动条提供新的滚动区域。

from tkinter import *
from tkinter.ttk import Notebook
N = 25
class IterEntryField:
def __init__(self, frame, label):
self.frame = frame
self.label = label
def pack(self):
self.valLabel = Label(self.frame, text = self.label, anchor = 'w')
self.valLabel.pack(fill = X, side = LEFT)
self.variable = StringVar()
self.variable.set('0')
self.valEntry = Entry(self.frame, textvariable = self.variable)
self.valEntry.pack(fill = X, side = RIGHT)
def notebookpopup():
zSetupWindow = Toplevel(root)
zSetupWindow.geometry('{}x{}'.format(800, 300))
notebook = Notebook(zSetupWindow)
evspace = Frame(notebook)
notebook.add(evspace, text = "Evenly spaced values")
sOverflow = Label(evspace, text = 'Ignore this')
sOverflow.pack()
uevspace = Frame(notebook)
notebook.add(uevspace, text = "Individual values")
canvas = Canvas(uevspace, width = 800, height = 400)
vsb = Scrollbar(canvas, command=canvas.yview)
canvas.config(yscrollcommand = vsb.set)
canvas.pack(side = LEFT, fill = BOTH, expand = True)
vsb.pack(side = RIGHT, fill = Y)
entryContainer = Frame(canvas)
entryContainer.pack(fill = BOTH)
frameDict = {}
for i in range(0, N):
frameDict[i] = Frame(entryContainer)
frameDict[i].pack(fill = X)
entry = IterEntryField(frameDict[i], 'Z value for subfile {}'.format(i+1))
entry.pack()
canvas.create_window(200, 0, window = entryContainer)
canvas.config(scrollregion = (0,0,100,1000))
notebook.pack(fill = X)
root = Tk()
button = Button(root, text = 'new window', command = notebookpopup)
button.pack()
root.mainloop()

我在这个代码中遇到了三个问题:

  1. 页面非常短,只显示几行。

  2. 我无法弄清楚create_window中的"正确"偏移量.我以为0, 0会把它放在画布的左上角,但显然取而代之的是窗口的左上角。这可以通过canvasxcanvasy方法的反向来解决,但我找不到任何方法。

  3. 输入字段和标签挤在一起,而不是占据画布的整个宽度。当我仅使用笔记本页面框架作为容器时,这不是问题。

你的第一个问题可以追溯到你如何pack笔记本。只需将notebook.pack(...)更改为以下内容:

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

第二个可以通过在create_window方法中指定anchor位置来解决:

canvas.create_window(0, 0, window = entryContainer, anchor="nw")

我不明白第三个问题是什么 - 它看起来完全符合预期。

最新更新