Python tkinter gui,它加载一个文件并可以打印出文件名

Python tkinter gui,它加载一个文件并可以打印出文件名,python,class,user-interface,tkinter,Python,Class,User Interface,Tkinter,我从python开始,我已经用matplotlib创建了一个很好的绘图函数。现在我想使用tkinter将函数插入GUI。 正如我从youtube和这个论坛学到的,我应该使用课堂。 不幸的是,我有一些问题。到目前为止,我还不了解所有细节的是: import tkinter as tk from tkinter import filedialog LARGE_FONT=('Verdana',12) class XPSPlotApp(tk.Tk): def __init__(self,

我从python开始,我已经用matplotlib创建了一个很好的绘图函数。现在我想使用tkinter将函数插入GUI。 正如我从youtube和这个论坛学到的,我应该使用课堂。 不幸的是,我有一些问题。到目前为止,我还不了解所有细节的是:

import tkinter as tk
from tkinter import filedialog

LARGE_FONT=('Verdana',12)


class XPSPlotApp(tk.Tk):

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

        container.pack(side='top',fill='both',expand=True)
        container.grid_rowconfigure(0,weight=1)#0 is min size
        container.grid_columnconfigure(0,weight=1)


        #adding a menubar#
        self.menuBar = tk.Menu(master=self)
        self.filemenu = tk.Menu(self.menuBar, tearoff=0)
        self.filemenu.add_command(label="Open", command=self.browse_file)
        self.filemenu.add_command(label="Quit!", command=self.quit)
        self.menuBar.add_cascade(label="File", menu=self.filemenu)
        self.config(menu=self.menuBar)

        self.frames={}

        for F in (HRXPSPlotter, SurveyXPSPlotter):

            frame=F(container,self)

            self.frames[F]=frame

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

        self.show_frame(HRXPSPlotter)

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

    #Question if it should be here because maybe overwrites the filename   form other window?
    def browse_file(self):
        self.filename =  filedialog.askopenfilename(initialdir = "E:/Images",title = "choose your file",filetypes = (("txt files","*.txt"),("all files","*.*")))
        print(self.filename)
    def printFN(self):
        print(self.filename)


class HRXPSPlotter(tk.Frame):

    def __init__(self,parent, controller):
        tk.Frame.__init__(self,parent)
        lable=tk.Label(self,text='Sart Page',font=LARGE_FONT)
        lable.pack(pady=10,padx=10)
        #button to go to another page
        button1=tk.Button(self, text='Visit Page 1',command=lambda:controller.show_frame(SurveyXPSPlotter))
        button1.pack()

class SurveyXPSPlotter(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        lable=tk.Label(self,text='Page One',font=LARGE_FONT)
        lable.pack(pady=10,padx=10)
        button1=tk.Button(self, text='Back to Page 1',command=lambda:controller.show_frame(HRXPSPlotter))
        button1.pack()

app=XPSPlotApp()
app.mainloop()
该程序有两页,因为我想使用不同的绘图仪和一个菜单,可以打开一个目录中的文件

现在我想实现一个函数,当我点击一个按钮时,它会打印出文件名+文件路径,但我不能让它工作吗?问题很简单,我真的不知道我必须在哪里定义函数-在_uinit_uuu中还是在子类中?而且。。。 命令=lambda:controller是如何工作的,它对我来说仍然很神奇! 为什么tk.Frame的pageOne方法而不是tk.tk的子类像_uinit__;这样?
我不会直接回答你们所有的三个子问题,因为它最终会成为一个关于tkinter的迷你教程。但是,我可以向您展示如何添加一个按钮来进行打印。特别注意添加了注释的行

下面是代码的修改版本,其中添加了一些内容,显示了可以在何处以及如何放置绘图函数。我还改变了编码风格,使其更符合标准,更具可读性

在一些地方,我还更改了变量的名称,以使这种基于tkinter的gui架构的操作更加清晰

import tkinter as tk
from tkinter import filedialog
LARGE_FONT=('Verdana', 12)


class XPSPlotApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        container = tk.Frame(self)
        container.pack(side='top', fill='both', expand=True)
        container.grid_rowconfigure(0, weight=1)  # 0 is min size
        container.grid_columnconfigure(0, weight=1)

        # Add menubar and subcommands.
        self.menuBar = tk.Menu(master=self)
        self.filemenu = tk.Menu(self.menuBar, tearoff=0)
        self.filemenu.add_command(label="Open", command=self.browse_file)
        self.filemenu.add_command(label="Plot", command=self.plot_file)  # ADDED
        self.filemenu.add_command(label="Quit!", command=self.quit)
        self.menuBar.add_cascade(label="File", menu=self.filemenu)
        self.config(menu=self.menuBar)

        self.frames={}

        for FrameSubclass in (HRXPSPlotter, SurveyXPSPlotter):
            frame = FrameSubclass(container, self)  # create class instance.
            self.frames[FrameSubclass] = frame
            frame.grid(row=0, column=1, sticky='nsew')

        self.show_frame(HRXPSPlotter)

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

    def browse_file(self):
        self.filename = filedialog.askopenfilename(
            initialdir="E:/Images", title="Choose your file",
            filetypes=(("text files", "*.txt"), ("all files", "*.*"))
        )
        print(self.filename)

    def plot_file(self):  # ADDED
        try:
            print('Plotting:', self.filename)
        except AttributeError:
            print('No filename has been selected to plot!')


class HRXPSPlotter(tk.Frame):
    def __init__(self, parent, controller):
        super().__init__(parent)
        label = tk.Label(self, text='Start Page', font=LARGE_FONT)
        label.pack(pady=10, padx=10)
        # Button to go to another page.
        button1 = tk.Button(self, text='Visit Page 1',
                        command=lambda: controller.show_frame(SurveyXPSPlotter))
        button1.pack()


class SurveyXPSPlotter(tk.Frame):
    def __init__(self, parent, controller):
        super().__init__(parent)
        label = tk.Label(self, text='Page One', font=LARGE_FONT)
        label.pack(pady=10, padx=10)
        # Button to go to another page.
        button1 = tk.Button(self, text='Back to Page 1',
                        command=lambda: controller.show_frame(HRXPSPlotter))
        button1.pack()


app=XPSPlotApp()
app.mainloop()
命令=lambda:controller.show_frame参数用于构造tk.Buttons创建一个匿名函数,该函数在按下相应按钮时调用controller.show_frame,而不是在创建按钮时调用


show_frame函数在self.frames字典中查找frame子类实例,该字典是在XPSPlotApp类_init__方法中创建的,并将其提升,使其成为显示的最上面的帧,从而有效地隐藏所有大小相同、位置相同但现在位于下面的其余帧它。

command=lambda:controller.show\u framesurveyxpslotter类似于def command:return controller.show\u framesurveyxpslotterthx。为了答案!我觉得我的问题不太正确。所以我想要的是在其他类中使用self.filename中存储的Path+filename来加载每个窗口中的数据,并使用另一个py文件中存储的函数来绘制它们。问题是我不知道如何在“子类”中使用self.filename,例如HRXPSPlotter?thx.MatthiasK:我的示例代码显示了在添加的XPSPlotApp.plot_文件方法中使用self.filename。你还想要什么?在另一个类中使用它的示例是什么?还有什么课?每个tk.Frame子类在构造时接收一个控制器参数。该对象是XPSPlotApp的一个实例,一旦Open菜单项运行了browse_file方法,该对象就会有一个filename属性。我在HRXPSPlotter$f=compxpsplotdata='c:/data/file_name.txt'.sizef=15$中有这个函数,现在我想用存储在超类中self.filename中的变量替换$'c:/data/file_name.txt'$。如果我在超类中定义了一个返回self.filename的方法,它总是返回:$AttributeError:“\u tkinter.tkapp”对象没有属性“filename”$?HRXPSPlotter是tk.Frame的子类,而不是XPSPlotApp,因此它永远不会有self.filename属性。您的代码将其分配给名为app的xpsplotapp实例,该实例是在代码的倒数第二行创建的,并且它仅在调用其browse\u file方法时才执行此操作。如果希望在tk.Frame子类方法中引用此属性,则需要保存传递给每个函数的u_init__函数的控制器参数。换句话说,属性是controller.filename。正如我说的controller.filename不工作->输出是'\u tkinter.tkapp'对象没有属性'filename',顺便问一下,str为什么在类中不工作?我以为是标准图书馆。他在工作吗?