Прокручиваемая страница в Tkinter Notebook - PullRequest
1 голос
/ 23 сентября 2019

Для проекта мне нужно указать определенное значение для 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 поместит его в верхний левый угол холста, но, видимо, вместо него будет использован верхний левый угол окна.Возможно, это можно исправить с помощью некоторого обратного метода canvasx и canvasy, но я не смог найти ни одного.

  3. Вместо этого поля ввода и метки ограничены.занимая всю ширину холста.Это не было проблемой, когда я использовал только рамку страницы ноутбука в качестве контейнера.

1 Ответ

2 голосов
/ 23 сентября 2019

Ваша первая проблема восходит к тому, как вы pack ваш ноутбук.Просто измените notebook.pack(...) на ниже:

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

Второй можно решить, указав позицию anchor в вашем методе create_window:

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

Я непонять, в чем проблема 3 - она ​​выглядит именно так, как и ожидалось.

...