列表框更新全局列表内容

时间:2017-01-24 21:00:59

标签: python csv tkinter listbox frame

我正在制作用户导入CSV文件的GUI,并且可以点击执行这些文件功能的各种按钮,例如:绘制CSV图形,查看CSV的迷你表格等。每当导入文件时,它都会附加到名为file_list的全局列表中,并且我的函数通过此全局列表对文件起作用。

我有一个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()

2 个答案:

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

答案 1 :(得分: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() - 因此请使用Toplevel创建弹出窗口并删除第二个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()