Tkinter 通过菜单栏按钮存储文件名

Tkinter store filename through menubar button

我创建了一些函数,可以在我用 tkinter 制作的 GUI 中显示图形和 tables 个 csv 文件。

我有一个 menubar,带有一个 导入 按钮、一个 绘图 按钮和一个 table 按钮。 plottable 按钮分别可以成功绘制图表和 csv 文件的 tables。

我想做的是,当用户 select 按下 导入 按钮时,他们 select 一个他们选择的文件。然后,如果他们碰巧 select plot 按钮,绘图功能将作用于他们从 import 中选择的文件。此外,如果他们碰巧 select table 按钮,table 函数将作用于他们从 import[ 中选择的文件=42=].

我创建了一个名为 openfile() 的文件打开函数,它会记住打开的文件的名称。

问题是我不知道如何使用 menubaropenfile() 这样当 import 按钮被点击时,我的应用程序存储文件名。

关于我将如何做这件事的任何提示?

这是我为 menubaropenfile() 编写的代码:

def openfile():
    name= askopenfilename() 
    return (name[19:])

class MyApp(tk.Tk):

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

        tk.Tk.__init__(self, *args, **kwargs)

        tk.Tk.wm_title(self, "MyApp")
        # main frame
        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand = True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand = True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        # creates the menubar at the top of the window
        menubar = tk.Menu(container)

        # import menu for importing csv files, initializes a file opening function (tbd)
        filemenu = tk.Menu(menubar, tearoff=0)
        filemenu.add_command(label="Import a CSV File", command = file_openerfunction)
        menubar.add_cascade(label= "Import", menu=filemenu)

        # plot menu for creating graphs and figures
        Plot = tk.Menu(menubar, tearoff =0 )
        Plot.add_command(label="Plot My CSV File", command= popupgraph)
        menubar.add_cascade(label="Plot", menu=Plot)

        # table menu for viewing data in a table
        table = tk.Menu(menubar, tearoff = 0)
        table.add_command(label="View MY CSV File", command = table)
        table.add_cascade(label = "View Data", menu = table)

        tk.Tk.config(self, menu=table)
        ....
        ....

首先,我建议您采用面向对象的方法来拆分每个组件的行为。

这样,您将拥有一个 class 应用程序,您将在其中初始化应用程序的主要组件:

class App(tk.Tk):

    def __init__(self,parent):
        Tk.__init__(self,parent)
        self.parent = parent
        self.initialize()

    def initialize(self):
        ...

        ...
        # Menubar
        self.menubar = MyMenuBar(self)

        # Filemenu
        self.filemenu = MyFileMenu(self, menubar)

        # Plot
        self.plot = MyPlot(self, menubar)

        # The rest for all the other components
        ...

    def get_import_filename(self):
        # Ask the child for the filename and return it
        return self.filemenu.get_filename()

然后定义您的每个对象:

class MyPlot(tk.Menu):
      def __init__(self, parent, menubar):
           tk.Menu.__init__(self, menubar, tearoff=0)
           self.parent = parent
           self.initialize()

      def initialize(self):
          self.add_command(label="Plot My CSV File", command= self.popupgraph)  

      def popupgraph(self):
          # Ask the parent for the filename
          filename = self.parent.get_import_filename()
          # Do whatever with the filename...like open a file

class MyFileMenu(tk.Menu):
      def __init__(self, parent, menubar):
           tk.Menu.__init__(self, menubar, tearoff=0)
           self.parent = parent
           self.initialize()
      def initialize(self):
          self.add_command(label="Import a CSV File", command = file_opener)
      def file_opener(self):
          # Your file opener function goes here
          ...
          # At the end, save the imported file:
          self.filename = filename
      def get_filename(self):
          return self.filename

终于有主到运行啦:

def main():
    app = App(None)
    app.title('Auto login')
    app.mainloop()

if __name__ == "__main__":
    main()

otorrillas 解决方案运行良好。

我找到了另一种简单的方法来解决这个问题。为了让 GUI 记住从 import 中选择的文件,将文件名附加到列表中。然后,在列表元素上调用 popupgraph()viewcsv()。这是我的文件打开功能的新代码。

file_list = []

def openfile():
    name= askopenfilename() 
    file_list.append(name[19:])

我不明白您尝试做某些事情的方式(或者 为什么 在某些情况下您根本不这样做),但这是一个可运行的示例一个简单的 Choices 级联菜单,位于简单 tkinter 应用 window 的 upper-left 角。希望你';;能够适应并将其集成到您的项目代码中。

我制作了用于导入 CSV 文件的命令 file_openerfunction,一个 class 方法并让它调用 openfile() 函数,因为这样返回的值(文件名)可以是作为属性存储在 self.filename 中。这将允许它在创建后用于其他命令选择(因此他们将知道要操作的文件)。

try:
    import Tkinter as tk
    from tkFileDialog import askopenfilename
except ModuleNotFoundError:   $ Python 3
    import tkinter as tk
    from tkinter.filedialog import askopenfilename

def openfile():
    name = askopenfilename()
    return name[19:]

class MyApp(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.master.title("MyApp")

        self.pack(side="top", fill="both", expand=True)
        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(0, weight=1)

        top = self.winfo_toplevel()
        self.menubar = tk.Menu(top)
        top['menu'] = self.menubar

        self.submenu = tk.Menu(self.menubar)
        self.menubar.add_cascade(label='Choices', menu=self.submenu)

        self.submenu.add_command(label="Import a CSV File",
                                 command=self.file_openerfunction)
        self.submenu.add_command(label="Plot My CSV File",
                                 command=self.popupgraph)
        self.submenu.add_command(label="View MY CSV File",
                                 command=self.table)

    def file_openerfunction(self):
        self.filename = openfile()

    def popupgraph(self): pass
    def table(self): pass

app = MyApp()
app.mainloop()

我还建议您阅读并遵循 PEP 8 - Style Guide for Python Code 这将有助于规范您编写的代码并提高其可读性。