Автоматическая прокрутка нескольких виджетов на холсте

Я использую несколько виджетов, размещенных на холсте, чтобы показать ход выполнения нескольких задач. Для этого я помещаю их в сетку на холсте в рамке. Почти все работает, но мне нужно, чтобы полоса прокрутки по умолчанию находилась в нижней части окна (рамки). Я пытался использовать vsb.set, чтобы заставить полосу прокрутки перейти в новое положение, но это не дало никакого эффекта. Если я использую обработчик событий для перемещения полосы прокрутки, я теряю контроль над ее движением. Я новичок и был бы признателен за некоторые советы. См. код ниже.

from tkinter import *
import tkinter as tk

class example(Frame):
    def __init__(self, root):
        Frame.__init__(self, root)
        self.initUI()

    def initUI(self):
        self.canvas = Canvas(root, borderwidth=0, background="#ffffff", height=300, width=700)
        self.frame = Frame(self.canvas, background="#ffffff")
        self.vsb = Scrollbar(root, orient="vertical", command=self.canvas.yview)
        self.canvas.configure(yscrollcommand=self.vsb.set)
        self.vsb.pack(side="right", fill="y")
        self.canvas.pack(side="left", fill="both", expand=True)
        self.canvas.create_window((4,4), window=self.frame, anchor="nw", tags="self.frame")
        self.frame.bind("<Configure>", self.onFrameConfigure)
        root.title("Issue with Scrolling through Widgets")
        self.populate()     

    def onFrameConfigure(self, event):
        ###Reset the scroll region to encompass the inner frame
        self.canvas.configure(scrollregion=self.canvas.bbox("all"))
        self.canvas.bind_all("<MouseWheel>", self._on_mousewheel)

    def _on_mousewheel(self, event):
        self.canvas.yview_scroll(-1*int(event.delta/120),"units" )

    def populate(self):
        ###Put in some fake data###
        for row in range(20):                        
            Txt = Text(self.frame, bg="white", borderwidth=1, height=1, width=40)
            Txt.grid(row = row, column = 0, rowspan = 1, columnspan = 1, sticky = W+E+N+S)
            line = "this is the first column for row %s" %row
            Txt.insert(END, str(line))
            Txt = Text(self.frame, bg="white", borderwidth=1, height=1, width=40)
            Txt.grid(row = row, column = 1, rowspan = 1, columnspan = 1, sticky = W+E+N+S)
            line = "this is the second column for row %s" %row
            Txt.insert(END, str(line))

if __name__ == "__main__":
    root=Tk()
    example(root).pack(side="top", fill="both", expand=True)
    root.mainloop()

person Island Guy    schedule 06.09.2016    source источник
comment
По умолчанию в нижней части окна вы говорите, что хотите, чтобы содержимое прокручивалось вниз, или вы имеете в виду, что хотите, чтобы фактическая полоса прокрутки находилась в другом физическом положении?   -  person Bryan Oakley    schedule 07.09.2016
comment
Я бы хотел, чтобы по умолчанию отображалось то, что было отправлено в окно последним.   -  person Island Guy    schedule 15.10.2016


Ответы (1)


Да, я хотел бы, чтобы полоса прокрутки перемещалась вниз по мере добавления новых данных в сетку. Я нашел решение, которое работает, но я не уверен, что оно правильное. Я изменил функцию onFrameConfigure на следующую.

def onFrameConfigure(self, event):  # Reset the scroll region to encompass the inner frame
    global insertFlag
    self.canvas.configure(scrollregion=self.canvas.bbox("all"))
    self.canvas.bind_all("<MouseWheel>", self._on_mousewheel)
    if insertFlag == 1:
        self.canvas.yview_scroll(20, "units")
        insertFlag = 0

а затем добавил в конец заполнения оператор if, чтобы установить глобальную переменную, как показано ниже.

def populate(self):
    global insertFlag
    for row in range(20):
        Txt = Text(self.frame, bg="white", borderwidth=1, height=1, width=40)
        Txt.grid(row = row, column = 0, rowspan = 1, columnspan = 1, sticky = W+E+N+S)
        line = "this is the second column for row %s" %row
        Txt.insert(END, str(line))
        Txt.see(END)
    insertFlag = 1

Как вы думаете, ваш вклад ценится.

person Island Guy    schedule 08.09.2016