如何使用tkinter在python中将数据从一个类传输到另一个类?

时间:2014-11-05 22:38:00

标签: python tkinter

我不知道如何将我的数据从一个类转移到另一个类。在下面的代码中,我使用来自Tkinter的askdirectory命令导入了一些图像,一旦我有了导入图像的目录。然后,我获得有关数据的一些信息,例如扩展数量和图像数量。 (我知道这两个值会相同)。我应该提一下,这个数据是直接在PageOne1类中找到的,它是在一个从PageOne1类调用的函数中处理的。

一旦在变量中定义了这个数据,我就需要能够在一个不同的类中使用它,这个类是一旦点击导入数据的按钮就会提高的,这只是为了让它看起来不同而且用户知道发生了什么事。

问题是: 如何将数据从一个类传输到另一个类? E.G,在我的代码中,我想将数据从PageOne1类传输到PageOne2。 有了这些正在传输的数据,我想在标签中显示它。

#structure for this code NOT created by me - found on stackoverflow.com
import tkinter as tk
from tkinter import filedialog as tkFileDialog
import math, operator, functools, os, glob, imghdr
from PIL import Image, ImageFilter, ImageChops
#fonts
TITLE_FONT = ("Helvetica", 16, "bold","underline") #define font
BODY_FONT = ("Helvetica", 12) #define font
#define app
def show_frame(self, c): #raise a chosen frame
    '''Show a frame for the given class'''
    frame = self.frames[c]
    frame.tkraise()
class SampleApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        # the container will contain all frames stacked on top of each other, the frame to be displayed will be raised higher
        container = tk.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, PageOne1, PageOne2,):
            frame = F(container, self)
            self.frames[F] = frame
            # put all of the pages in the same location;
            # the one on the top of the stacking order
            # will be the one that is visible
            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame(StartPage)

    def show_frame(self, c): #raise a chosen frame
        '''Show a frame for the given class'''
        frame = self.frames[c]
        frame.tkraise()

    def choose(self):
        image_list = []
        extlist = []
        root = tk.Tk()
        root.withdraw()
        file = tkFileDialog.askdirectory(parent=root,title="Choose directory")
        if len(file) > 0:#validate the directory
            print( "You chose %s" % file) #state where the directory is
        for filename in glob.glob(file+"/*"):
            print(filename)
            im=Image.open(filename)
            image_list.append(im)
            ext = imghdr.what(filename)
            extlist.append(ext)
        print("Loop completed")
        extlistlen = len(extlist)
        image_listlen = len(image_list)
                    #these  are the two pieces of data I want to transfer to PageOne2
        self.show_frame(PageOne2)
#frames
class StartPage(tk.Frame): #title/menu/selection page
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text="LTC Meteor Detection Program", font=TITLE_FONT) #using labels as they can be updated at any point without updating the GUI, if the data is to be manipulated by the user canvas will be used
        label.pack(side="top", fill="x", pady=10) #pady offers padding between label and GUI border

        button1 = tk.Button(self, text="Import Images",
                            command=lambda: controller.show_frame(PageOne1)) #if button1 chosen, controller.show_frame will raise the frame higher
                            #lambda and controller being used as commands to raise the frames
        button2 = tk.Button(self, text="RMS Base Comparison",
                            command=lambda: controller.show_frame(PageTwo1))
        button3 = tk.Button(self, text="Export Images",
                            command=lambda: controller.show_frame(PageThree1))
        buttonexit = tk.Button(self,text="Quit",
                            command=lambda:app.destroy())
        button1.pack()
        button2.pack()
        button3.pack()
        buttonexit.pack()

class PageOne1(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text = "Import Images", font=TITLE_FONT)
        label.pack(side="top", fill="x", pady=10)
        button = tk.Button(self, text="Select directory",
                           command=controller.choose)
        button.pack()
        button = tk.Button(self, text="Return To Menu",
                           command=lambda: controller.show_frame(StartPage))
        button.pack()



#for reference:
#fileName = tkFileDialog.asksaveasfilename(parent=root,filetypes=myFormats ,title="Save the image as...")

class PageOne2(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text = "Import Images", font=TITLE_FONT)
        label.pack(side="top", fill="x", pady=10)
        label = tk.Label(self, text = ("Number of images: ",image_listlen2," Number of different extensions: ",extlistlen2))
        label.pack(side="top", fill="x", pady=10)
        button = tk.Button(self, text="Return To Menu",
                           command=lambda: controller.show_frame(StartPage))
        button.pack()

if __name__ == "__main__":
    app = SampleApp()
    app.mainloop()

1 个答案:

答案 0 :(得分:0)

您必须保留对类的引用。我已经删除了所有不必要的代码,所以只需

    self.frames = {}
    for F in (StartPage, PageOne1, PageOne2,):
        frame = F(container, self)
        self.frames[F] = frame

保持。然后,您可以轻松地引用属于类属性的数据。

class StartPage():
    def __init__(self):
        ## declare and iteger and a string
        self.sp_1=1
        self.sp_2="abc"

class PageOne1():
    def __init__(self):
        ## declare a list and dictionary
        self.sp_1=[1, 2, 3, 4, 5]
        self.sp_2={"abc":1, "def":2}

class YourApp():
    def __init__(self):
        self.frames = {}
        for F in (StartPage, PageOne1):
            frame = F()
            self.frames[F] = frame

        ## print instance attributes from other classes
        for class_idx in self.frames:
            instance=self.frames[class_idx]
            print "\n", instance.sp_1
            print instance.sp_2

YP=YourApp()