2017-01-24 40 views
0

我正在製作一個用戶導入CSV文件的GUI,並且可以單擊各種執行這些文件功能的按鈕,例如,繪製CSV圖表,查看CSV的小型表格等。每當導入文件時,它將被附加到名爲file_list的全局列表中,我的函數將通過此全局列表對文件起作用。Listbox更新全局列表內容

我有一個Listbox我顯示在我想要顯示用戶導入的文件列表的大型機中。我正在使用for循環來顯示Listbox中每個文件的名稱,但它似乎不工作。有關如何顯示這些文件名的提示?下面是我對主FrameListbox代碼:

from matplotlib import pyplot 
from csv import reader 
from dateutil import parser 
import tkinter as tk 
from tkinter import ttk 
from tkinter.filedialog import askopenfilename 
import pandas as pd 
from tkinter import Text, Scrollbar, Toplevel 

file_list = [] 

# i'm just including openfile here, which is essentially an import button. 

def openfile(): 
    name= askopenfilename() 
    # file_list is appended with name everytime openfile is clicked 
    rev = (name[::-1]) 
    i = rev.index('/') 
    name = ((rev[:i])[::-1]) 
    file_list.append(name) 
    main_dataview.insert(0, name) 
    with open(name, 'r') as f: 
     data = list(reader(f)) 
    popup = tk.Tk() 
    popup.wm_title("!") 
    # popups a message notifying what was imported 
    label = ttk.Label(popup, text=" %s was just imported" % (name), font=NORM_FONT) 
    label.pack(side="top", fill="x", pady=10) 
    B1 = ttk.Button(popup, text="Okay", command = popup.destroy) 
    B1.pack() 
    center(popup) 
    popup.mainloop() 

class CODAQ(tk.Tk): 

    def __init__(self, *args, **kwargs): 
     tk.Tk.__init__(self, *args, **kwargs) 
     tk.Tk.wm_title(self, "CODAQ") 

     # 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 openfile() functions 
     filemenu = tk.Menu(menubar, tearoff=0) 
     filemenu.add_command(label="Import a CSV File", command = openfile) 
     filemenu.add_command(label="Remove", command = remove) 
     menubar.add_cascade(label= "File", menu=filemenu) 

     # plot menu for creating graphs and figures  
     Plot = tk.Menu(menubar, tearoff =0) 
     Plot.add_command(label="Plot Most Recent CSV", command= popupgraph) 
     Plot.add_command(label="Plot an Imported CSV", command = dataselection_graph) 
     menubar.add_cascade(label="Plot", menu=Plot) 

     # viewdata menu for viewing data in a table 
     ViewData = tk.Menu(menubar, tearoff = 0) 
     ViewData.add_command(label="View most recent CSV" , command = viewcsv) 
     ViewData.add_command(label="View an Imported CSV",command = dataselection_viewcsv) 
     ViewData.add_command(label="View most recent CSV Variables",command = variable_extractor) 
     ViewData.add_command(label="View an Imported CSV's Variables", command = variable_extractor_sel) 
     menubar.add_cascade(label = "View Data", menu = ViewData) 

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

     self.frames = {} 
     # cycles through screens 
     for F in (WelcomeScreen, MainPage): 
      frame = F(container, self) 
      self.frames[F] = frame 
      frame.grid(row=0, column=0, sticky="nsew") 
     self.show_frame(WelcomeScreen) 

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

    # WelcomeScreen Object 
class WelcomeScreen(tk.Frame): 

    def __init__(self, parent, controller): 
     tk.Frame.__init__(self,parent) 
     label1 = ttk.Label(self, text="Welcome to CODAQ", font=LARGE_FONT) 
     label2 = ttk.Label(self, text="Begin by importing your Data", font=MEDIUM_FONT) 
     label1.pack(pady=0,padx=5) 
     label2.pack(pady=15,padx=10) 

     button = ttk.Button(self, text="Enter CODAQ", 
         command=lambda: controller.show_frame(MainPage)) 
     button.pack() 


    # mainpage object 
class MainPage(tk.Frame): 

    def __init__(self, parent, controller): 
     tk.Frame.__init__(self, parent) 
     label = ttk.Label(self, text="My Data", font=LARGE_FONT) 
     label.grid(row= 0, column = 0, pady = (10,15), padx = (90,0)) 

     main_dataview = tk.Listbox(self, font=NORM_FONT) 
     main_dataview.config(width = 44, borderwidth = 7) 

     main_dataview.grid(row=1, column=0, columnspan = 2) 

     # scroll bar functionality  
     scroll_y = Scrollbar(self, orient="vertical", command=main_dataview.yview) 
     scroll_y.grid(row=1, column=2, sticky="nsew") 
     # bind txt to scrollbar 
     main_dataview.configure(yscrollcommand=scroll_y.set) 


app = CODAQ() 
# size of screen 
app.minsize(width=1000, height = 500) 
app.mainloop() 
+0

大概這'for'在執行當'file_list'爲空時開始。當'file_list'竄改內容時它不會自動執行。將新元素添加到'file_list'時,您必須手動更新'Listbox'。 – furas

+0

@furas我將如何去手動更新它?我嘗試使用updateidletask,但我不知道它是如何工作的 –

+0

'updateidletask'用於重新繪製小部件,但您必須再次使用'main_dataview.insert(0,file)'在每次用戶導入新文件時向'Listbox'添加元素。 – furas

回答

0

我用self.main_dataview有其他功能/班訪問Listbox

我把openfile()class CODAQ有機會獲得self.framesself.frames[Mainpage].main_dataview - 所以現在我可以將導入的文件

self.frames[MainPage].main_dataview.insert(0, name) 

BTW:tkinter應該只有一個Tk()窗口和一個mainloop() - 所以在使用要創建彈出窗口並刪除第二個mainloop()。或者利用現有的信息窗口像

tkinter.messagebox.showinfo('!', " %s was just imported" % (name)) 

獲取文件名,不完整路徑,可以使用

name = os.path.basename(name) 

工作代碼:

from matplotlib import pyplot 
from csv import reader 
from dateutil import parser 
import pandas as pd 

import tkinter as tk 
from tkinter import ttk 
from tkinter.filedialog import askopenfilename 
from tkinter import Text, Scrollbar, Toplevel 
from tkinter.messagebox import showinfo 

import os.path 

MEDIUM_FONT = (20,) 
LARGE_FONT = (20,) 
NORM_FONT = (20,) 

# i'm just including openfile here, which is essentially an import button. 

class CODAQ(tk.Tk): 

    def __init__(self, *args, **kwargs): 
     tk.Tk.__init__(self, *args, **kwargs) 
     tk.Tk.wm_title(self, "CODAQ") 

     # size of screen 
     self.minsize(width=1000, height = 500) 

     self.file_list = [] # <-- 

     # 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 openfile() functions 
     filemenu = tk.Menu(menubar, tearoff=0) 
     filemenu.add_command(label="Import a CSV File", command=self.openfile) # <-- 
     #filemenu.add_command(label="Remove", command = remove) 
     menubar.add_cascade(label= "File", menu=filemenu) 

     # plot menu for creating graphs and figures 
     Plot = tk.Menu(menubar, tearoff =0) 
     #Plot.add_command(label="Plot Most Recent CSV", command= popupgraph) 
     #Plot.add_command(label="Plot an Imported CSV", command = dataselection_graph) 
     menubar.add_cascade(label="Plot", menu=Plot) 

     # viewdata menu for viewing data in a table 
     ViewData = tk.Menu(menubar, tearoff = 0) 
     #ViewData.add_command(label="View most recent CSV" , command = viewcsv) 
     #ViewData.add_command(label="View an Imported CSV",command = dataselection_viewcsv) 
     #ViewData.add_command(label="View most recent CSV Variables",command = variable_extractor) 
     #ViewData.add_command(label="View an Imported CSV's Variables", command = variable_extractor_sel) 
     menubar.add_cascade(label = "View Data", menu = ViewData) 

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

     self.frames = {} 
     # cycles through screens 
     for F in (WelcomeScreen, MainPage): 
      frame = F(container, self) 
      self.frames[F] = frame 
      frame.grid(row=0, column=0, sticky="nsew") 
     self.show_frame(WelcomeScreen) 

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


    def openfile(self): 
     name = askopenfilename() 

     # file_list is appended with name everytime openfile is clicked 
     #rev = (name[::-1]) 
     #i = rev.index('/') 
     #name = ((rev[:i])[::-1]) 

     name = os.path.basename(name) # <--- 

     self.file_list.append(name) 

     self.frames[MainPage].main_dataview.insert(0, name) # <-- 

     with open(name, 'r') as f: 
      data = list(reader(f)) 

     showinfo('!', " %s was just imported" % (name)) 

     #popup = tk.Toplevel() # <-- 
     #popup.wm_title("!") 
     # popups a message notifying what was imported 
     #label = ttk.Label(popup, text=" %s was just imported" % (name), font=NORM_FONT) 
     #label.pack(side="top", fill="x", pady=10) 
     #B1 = ttk.Button(popup, text="Okay", command=popup.destroy) 
     #B1.pack() 
     #center(popup) 

# --- WelcomeScreen Object --- 

class WelcomeScreen(tk.Frame): 

    def __init__(self, parent, controller): 
     tk.Frame.__init__(self,parent) 
     label1 = ttk.Label(self, text="Welcome to CODAQ", font=LARGE_FONT) 
     label2 = ttk.Label(self, text="Begin by importing your Data", font=MEDIUM_FONT) 
     label1.pack(pady=0,padx=5) 
     label2.pack(pady=15,padx=10) 

     button = ttk.Button(self, text="Enter CODAQ", 
         command=lambda: controller.show_frame(MainPage)) 
     button.pack() 

# --- mainpage object --- 

class MainPage(tk.Frame): 

    def __init__(self, parent, controller): 
     tk.Frame.__init__(self, parent) 
     label = ttk.Label(self, text="My Data", font=LARGE_FONT) 
     label.grid(row= 0, column = 0, pady = (10,15), padx = (90,0)) 

     self.main_dataview = tk.Listbox(self, font=NORM_FONT) 
     self.main_dataview.config(width = 44, borderwidth = 7) 

     self.main_dataview.grid(row=1, column=0, columnspan = 2) 

     # scroll bar functionality 
     scroll_y = Scrollbar(self, orient="vertical", command=self.main_dataview.yview) 
     scroll_y.grid(row=1, column=2, sticky="nsew") 
     # bind txt to scrollbar 
     self.main_dataview.configure(yscrollcommand=scroll_y.set) 

# --- main --- 

app = CODAQ() 
app.mainloop() 
+0

非常感謝這麼多人,這個作品 –

0

猜測了,因爲你已經離開了這麼多你的問題,但這裏有一個可運行的例子,顯示更新tk.Listbox的內容。

try: 
    import Tkinter as tk 
    import tkFont 
    import ttk 
except ImportError: # Python 3 
    import tkinter as tk 
    import tkinter.font as tkFont 
    import tkinter.ttk as ttk 

class MainPage(tk.Frame): 

    def __init__(self, parent, controller): 
     tk.Frame.__init__(self, parent) 
     label = ttk.Label(self, text="My Data") 
     label.grid(row=0, column=0, pady=(10, 15), padx=(90, 0)) 

     main_dataview = tk.Listbox(self) 
     main_dataview.config(width=44, borderwidth=7) 
     main_dataview.grid(row=1, column=0, columnspan=2) 

     for file in file_list: 
      main_dataview.insert(tk.END, file) 

     # make attributes for other methods to use 
     self.main_dataview = main_dataview 
     self.next_file_number = len(file_list) + 1 

     # scroll bar functionality 
     scroll_y = tk.Scrollbar(self, orient="vertical", command=main_dataview.yview) 
     scroll_y.grid(row=1, column=2, sticky="nsew") 
     # bind txt to scrollbar 
     main_dataview.configure(yscrollcommand=scroll_y.set) 

     # something to create new listbox entries 
     add_button = tk.Button(self, text='Add file', command=self.add_file) 
     add_button.grid(row=3, column=0) 

    def add_file(self): 
     """Add a file to the listbox.""" 
     self.main_dataview.insert(tk.END, 'file_{}'.format(self.next_file_number)) 
     self.next_file_number += 1 

# define global variable 
file_list = ['file_1', 'file_2', 'file_3'] 

root = tk.Tk() 
mp = MainPage(root, None) 
mp.pack() # MainPage is a widget, needs to have layout manager method called upon it 
root.mainloop()