2017-01-16 1 views
0

J'ai créé des fonctions qui peuvent afficher des graphiques et des tableaux de fichiers CSV dans une interface graphique que je crée avec tkinter.Nom du fichier de magasin Tkinter via le bouton de barre de menus

J'ai un menubar avec un bouton d'importation, un bouton de terrain, et un bouton de table . Le bouton plot et table peuvent respectivement tracer des graphiques et des tables de fichiers csv.

Ce que je voudrais faire, c'est quand l'utilisateur sélectionne le bouton importation, ils choisissent un fichier de leur choix. Ensuite, s'il leur arrive de sélectionner le bouton plot, la fonction de tracé fonctionne sur le fichier qu'ils ont choisi parmi et. De plus, s'il leur arrive de sélectionner le bouton table, la fonction table fonctionne sur le fichier qu'ils ont choisi parmi et.

J'ai créé une fonction d'ouverture de fichier appelée openfile() qui se souvient du nom du fichier ouvert.

Le problème est que je ne sais pas comment utiliser menubar et openfile() tels lorsque le bouton d'importation est cliquée, mes magasins d'application du nom de fichier.

Des conseils sur la façon dont j'irais faire cela?

Voici le code que j'ai écrit pour le menubar et openfile():

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) 
     .... 
     .... 

Répondre

1

Tout d'abord, je vous conseille de prendre un à diviser chaque comportement des composants approche orientée objet.

De cette façon, vous auriez une classe App, où vous initialiser les principaux composants de l'application:

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() 

Et puis définissez tous vos objets:

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 

Enfin, ont le principal pour l'exécuter:

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

if __name__ == "__main__": 
    main() 
+0

Merci une tonne! Cela fonctionne très bien. Je vais suivre votre conseil et changer mon code en une approche plus orientée objet. En ce qui concerne le problème d'ouverture de fichier, j'ai trouvé un moyen très simple pour l'interface graphique de se souvenir du fichier sélectionné: avoir le fichier sélectionné être stocké dans une liste, puis appeler popupgraph sur l'élément de la liste. –

+0

Pourquoi votre exemple a-t-il deux classes nommées 'MyPlot'? –

+0

@BryanOakley faute de frappe. Pardon. Modification maintenant – otorrillas

0

solution d'otorrillas a fonctionné parfaitement.

J'ai trouvé un autre moyen simple de résoudre ce problème. Pour que l'interface graphique se souvienne du fichier sélectionné à partir de importer, faites ajouter le nom de fichier à une liste. Ensuite, appelez popupgraph() et viewcsv() sur l'élément de liste. Voici le nouveau code pour ma fonction d'ouverture de fichier.

file_list = [] 

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

Je ne comprends pas la façon dont vous essayiez de faire certaines choses (ou pourquoi vous les faire du tout dans certains cas), mais voici un exemple runnable qui crée un Choices menu simple en cascade dans le coin supérieur gauche de la fenêtre de l'application tkinter simple.J'espère toi';; être capable de l'adapter et de l'intégrer dans le code de votre projet.

J'ai fait la commande pour importer des fichiers CSV, file_openerfunction, une méthode de classe et avoir appeler la fonction openfile() car de cette manière la valeur renvoyée (le nom de fichier) peut être magasin comme un attribut dans self.filename. Cela lui permettra d'être utilisé dans les autres choix de commande après sa création (afin qu'ils sachent quel fichier utiliser).

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() 

Je vous propose aussi de lire et de suivre la PEP 8 - Style Guide for Python Code qui contribuera à normaliser le code de votre écriture et d'améliorer sa lisibilité.