在Tkinter中更改视图时如何更新列表框?

时间:2019-03-30 10:24:04

标签: python tkinter

更改视图时,我需要更新列表框,但是我不知道该怎么做。在第一页上,我要向列表中添加一些项目,在第二页上,它应显示列表框中的所有项目。

# -*- coding: utf-8 -*-

from tkinter import *


tb1 = [["Kofola", "0,5","30"]]


class SeaofBTCapp(Tk):

    def __init__(self, *args, **kwargs):

        Tk.__init__(self, *args, **kwargs)
        container = Frame(self)

        container.pack(side="top", fill="both", expand = True)

        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}

        for F in (StartPage, PageOne):

            frame = F(container, self)

            self.frames[F] = frame

            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame(StartPage)

    def show_frame(self, cont):

        frame = self.frames[cont]
        frame.tkraise()


class StartPage(Frame):

    def __init__(self, parent, controller):
        Frame.__init__(self,parent)
        label = Label(self, text="Start Page")
        label.pack(pady=10,padx=10)

        button = Button(self, text="Visit Page 1",
                            command=lambda: controller.show_frame(PageOne))
        button.pack()

        button2 = Button(self, text="add",
                            command=self.add)
        button2.pack()

    def add(self):
        tb1.append(["Radegast", "0,5","30"])
        print(tb1)



class PageOne(Frame):

    def __init__(self, parent, controller):
        Frame.__init__(self, parent)
        label = Label(self, text="Page One!!!")
        label.pack(pady=10,padx=10)

        button1 = Button(self, text="Back to Home",
                            command=lambda: controller.show_frame(StartPage))
        button1.pack()

        self.bill=Listbox(self)
        self.bill.pack()



        for item in tb1:
            co=" ".join(str(x) for x in item)
            self.bill.insert(END, co)

app = SeaofBTCapp()
app.mainloop()

1 个答案:

答案 0 :(得分:2)

PageOne类中,您在tb1中仅读取列表__init__()。要使tb1中的更改显示在列表框中,您还必须使用新的更改后的列表更新列表框。

列表也有问题。正如在全局名称空间中定义的那样,您的应用将依赖于此。我建议您在SeaofBTCapp() __init__()函数中定义它,然后可以通过controller对象访问它:

class SeaofBTCapp(Tk):
    def __init__(self, *args, **kwargs):
        Tk.__init__(self, *args, **kwargs)
        self.tb1 = [["Kofola", "0,5","30"]]
        ... etc ...

class StartPage(Frame):
    def __init__(self, parent, controller):
        self.controller = controller
        ... etc ...

    def add(self):
        self.controller.tb1.append(["Radegast", "0,5","30"])
        ... etc ...

然后将update()方法添加到PageOne()类中,该类将更新列表框并从add()方法中调用它。我通过控制器方法update_pageone()进行调用。参见下面的完整示例:

from tkinter import *

class SeaofBTCapp(Tk):
    def __init__(self, *args, **kwargs):
        Tk.__init__(self, *args, **kwargs)
        self.tb1 = [["Kofola", "0,5","30"]] # Create instance variable tb1
        container = Frame(self)
        container.pack(side="top", fill="both", expand = True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}
        for F in (StartPage, PageOne):
            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame(StartPage)

    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise()

    def update_pageone(self):
        self.frames[PageOne].update()   # Call update on PageOne

class StartPage(Frame):
    def __init__(self, parent, controller):
        self.controller = controller    # Remember the controller
        Frame.__init__(self,parent)
        label = Label(self, text="Start Page")
        label.pack(pady=10,padx=10)

        button = Button(self, text="Visit Page 1",
                            command=lambda: self.controller.show_frame(PageOne))
        button.pack()
        button2 = Button(self, text="add", command=self.add)
        button2.pack()

    def add(self):
        self.controller.tb1.append(["Radegast", "0,5","30"])
        self.controller.update_pageone()    # Asking controller for an update


class PageOne(Frame):
    def __init__(self, parent, controller):
        self.controller = controller    # Remember the controller
        Frame.__init__(self, parent)
        label = Label(self, text="Page One!!!")
        label.pack(pady=10,padx=10)

        button1 = Button(self, text="Back to Home",
                            command=lambda: controller.show_frame(StartPage))
        button1.pack()

        self.bill = Listbox(self)
        self.bill.pack()

        for item in controller.tb1:
            co = " ".join(str(x) for x in item)
            self.bill.insert(END, co)

    def update(self):
        # Delete all from Listbox bill
        self.bill.delete(0, 'end')
        # Add revised table into Listbox bill
        for item in self.controller.tb1:
            co = " ".join(str(x) for x in item)
            self.bill.insert(END, co)

app = SeaofBTCapp()
app.mainloop()