使用滚动条在Canvas中显示大量数据

时间:2015-05-20 14:41:03

标签: python-3.x tkinter scrollbar

我在尝试在tkinter中显示一个大表时遇到问题。

首先,我尝试在画布中一次显示所有标签,但是超过几百行,程序关闭。所以我尝试创建一个可滚动的画布,每次滚动时都会更新:我收集滚动条的位置,并根据它的位置,显示相应的10个值。

但我无法使这段代码正常工作。目前它只显示黑色背景,右侧有滚动条。

以下是代码:

from tkinter import *

class Application(object):
    def __init__(self, parent):
        self.x = []
        for i in range(1, 1000):
            self.x.append(i)
        self.parent = parent 
        self.mainFrame =  Frame(self.parent)
        self.mainFrame.pack()
        self.canvas = Canvas(self.mainFrame, width = 200, height = 500, bg = "black")
        self.canvas.grid(row = 0, column = 0)
        self.scroll = Scrollbar(self.mainFrame, orient = VERTICAL, command = self.update)
        self.scroll.grid(row = 0, column = 1)

        self.canvas.configure(yscrollcommand = self.scroll.set)
        self.tabCursor = 0
        self.scrollPosition = self.scroll.get()

    def update(self):
        self.tabCursor = round(self.scrollPosition[0]*len(self.x))
        if ((len(self.x) - self.tabCursor) < 10):
            self.tabCursor = len(self.x) - 10
        for i in range(0, 10): #display 10 values
            label = Label(self.canvas, text = str(self.x[tabCursor + i]), width = 50)
            label.grid(column = 0, row = i)


if __name__ == '__main__':
    root = Tk()
    app = Application(root)
    root.mainloop()

编辑: 我终于有时间实施你的答案了。它看起来很好,但我无法使滚动条工作,我不知道为什么。

class TableauDeDonnees(object):
    "Tableau de données -- Onglet Tableau de données"
    def __init__(self, data, parent):
        self.parent = parent
        self.data = data
        print(self.data[0], self.data[1])
        print(len(self.data[0]), len(self.data[1]))
        self.labels = []
        self.navigationFrame = Frame(self.parent)
        self.canvas = Canvas(self.parent, bg = "black", width = 200, height = 500)
        self.mainFrame = Frame(self.canvas)
        self.navigationFrame.pack()
        print(len(data))
        for row in range(50):
            for column in range(len(data)):
                self.labels.append(Label(self.canvas, text = str(data[column][row])))
        for i in range(len(self.labels)):
            self.labels[i].grid(row = i // 2, column = i % 2, sticky = NSEW)
        self.boutonRetour = Button(self.navigationFrame, text = "Retour", command = lambda: self.move(-2))
        self.quickNav = Entry(self.navigationFrame, width = 3)
        self.quickNav.bind('<Return>', lambda x: self.move(self.quickNav.get()))
        self.boutonSuivant = Button(self.navigationFrame, text = "Suivant", command = lambda: self.move(0))

        temp  = divmod(len(data[0]), len(self.labels) // 2)
        self.pages = temp[0] + (1 if temp[1] else 0)

        self.position = Label(self.navigationFrame, text='Page 1 sur ' + str(self.pages))
        self.pageCourante = 1

        self.boutonRetour.grid(row = 0, column = 0)
        self.quickNav.grid(row = 0, column = 1)
        self.boutonSuivant.grid(row = 0, column = 2)
        self.position.grid(row = 0, column = 3)

        self.scroll = Scrollbar(self.parent, orient = VERTICAL, command = self.canvas.yview)
        self.canvas.configure(yscrollcommand = self.scroll.set)
        self.scroll.pack(side = RIGHT, fill='y')
        self.canvas.pack(side = LEFT, fill = 'both')

        self.canvas.create_window((4,4), window = self.mainFrame, anchor = "nw", tags = "frame")
        self.canvas.configure(yscrollcommand = self.scroll.set)
        self.mainFrame.bind("<Configure>", self.update)
        self.canvas.configure(scrollregion = self.canvas.bbox("all"))

    def update(self, event):
        self.canvas.configure(scrollregion = self.canvas.bbox("all"))

    def move(self, direction):
        if (self.pageCourante == 1 and direction == -2) or (self.pageCourante == self.pages and direction == 0):
            return
        if direction in (-2, 0):
            self.pageCourante += direction + 1
        else:
            try:
                temp = int(direction)
                if temp not in range(1, self.pages + 1):
                    return
            except ValueError:
                return
            else:
                self.pageCourante = temp
        for i in range(len(self.labels)):
            try:
                location = str(self.data[i % 2][len(self.labels)*(self.pageCourante - 1) + i])
            except IndexError:
                location = ''
            self.labels[i].config(text = location)
        self.position.config(text = 'Page ' + str(self.pageCourante) + ' sur ' + str(self.pages))

我不明白为什么滚动条不能正常工作。请注意,我的父母是笔记本。 此外,显示的项目数也存在问题。页面数量是正确的,但它似乎显示的结果超过了应该导致最后页面为空并且显示的最后一个值似乎正确。

感谢您的关注

1 个答案:

答案 0 :(得分:0)

滚动条不能无限制地连续创建新的小部件。您还遗漏了一些关键部分 - 遗憾的是,.createLogger并不像大多数Scrollbar小部件那样简单。

tkinter

如果您想一次只显示几个并提供类似论坛的界面,则可以使用from tkinter import * class Application(object): def __init__(self, parent): self.parent = parent self.canvas = Canvas(self.parent, bg='black', width = 200, height = 500) self.mainFrame = Frame(self.canvas) self.scroll = Scrollbar(self.parent, orient = VERTICAL, command=self.canvas.yview) self.canvas.configure(yscrollcommand=self.scroll.set) self.scroll.pack(side='right', fill='y') self.canvas.pack(side='left', fill='both') self.canvas.create_window((4,4), window=self.mainFrame, anchor="nw", tags="frame") self.canvas.configure(yscrollcommand = self.scroll.set) self.mainFrame.bind("<Configure>", self.update) self.x = [] for i in range(1000): self.x.append(Label(self.mainFrame, text=str(i))) self.x[i].grid() def update(self, event): self.canvas.configure(scrollregion=self.canvas.bbox("all")) if __name__ == '__main__': root = Tk() app = Application(root) root.mainloop() 在页面之间导航。此示例允许用户使用“后退”和“前进”按钮进行导航,并在框中输入页码并按 Enter

Button