2016-05-31 74 views
0

我正在嘗試將文件路徑存儲到一個文件,以便當我的應用程序打開時,文件路徑可以重新加載而不必重新輸入。爲此,我試圖使用pickle模塊將數據「轉儲」到文件中。但是,我收到以下錯誤:試圖存儲一個對象,但不能pickle ttk類

Traceback (most recent call last): 
    File "C:\Program Files\python34\lib\tkinter\__init__.py", line 1533, in __call__ 
    return self.func(*args) 
    File "H:\Documents\Python Scripts\GUI.py", line 71, in <lambda> 
    ttk.Button(mainframe, text="Browse", command=lambda:askfile(usbpath)).grid(column=2,row=2,sticky = E) 
    File "H:\Documents\Python Scripts\GUI.py", line 26, in askfile 
    pickle.dump(pathtype, f) 
_pickle.PicklingError: Can't pickle <class 'tkapp'>: attribute lookup tkapp on __main__ failed 

我不明白如何避免這種情況。我完整的代碼如下:

#Modules 
from tkinter import * 
from tkinter import ttk 
from tkinter.filedialog import askopenfilename 
import pickle 
import shutil 

#Functions 
def popup(info): 
    popup = Tk() 
    popup.wm_title("Attention") 
    popup.attributes("-toolwindow",1) 
    label = ttk.Label(popup, text=info) 
    label.pack(side="top", fill="x", pady=10) 
    ttk.Button(popup, text="OK", command=popup.destroy).pack() 
    popup.mainloop() 

def stopProg(e): 
    root.destroy() 
def statuslabel(window, message): 
    ttk.Label(window, text=message).grid(column=2, row=1) 
def askfile(pathtype): 
    filename = askopenfilename(parent=mainframe,title='Choose a file') 
    pathtype.set(filename) 
    f = open('store.pickle','wb') 
    pickle.dump(pathtype, f) 
    f.close() 

def copyfiles(src,dst): 
    sourcefile = src.get() 
    if sourcefile.endswith(".txt"): 
     try: 
      shutil.copy(dst.get(),r'H:\Documents\folder\backups') 
      shutil.copy(sourcefile,dst.get()) 
      statuslabel(mainframe, "Done") 
     except IOError: 
      statuslabel(mainframe, "Error") 
      popup("Error occured: Please check your paths") 
    else: 
     popup("Bad filetype or no file selected") 
#GUI 
root = Tk() 
root.title('PPSSPP Save Management') 
mainframe = ttk.Frame(root, padding = "3 3 12 12") 
mainframe.grid(column=0, row=0, sticky=(N, W, E, S)) 
mainframe.columnconfigure(0, weight=1) 
mainframe.rowconfigure(0, weight=1) 

try: 
    open('store.pickle','x').close() 
except FileExistsError: 
    statuslabel(mainframe, "Load") 

f = open('store.pickle', 'rb') 
try: 
    usbpath = StringVar() 
    usbpath.set(pickle.load(f)) 
except EOFError: 
    usbpath = StringVar() 
try: 
    homepath = StringVar() 
    homepath.set(pickle.load(f)) 
except EOFError: 
    homepath = StringVar() 
f.close() 

usbpath_entry = ttk.Entry(mainframe,width = 60,textvariable=usbpath) 
usbpath_entry.grid(column=1, row=2, sticky=(W,E)) 
ttk.Label(mainframe, text="USB(PSP) Path").grid(column=1,row=1,sticky=W) 
ttk.Button(mainframe, text="Browse", command=lambda:askfile(usbpath)).grid(column=2,row=2,sticky = E) 
ttk.Label(mainframe, text="PC (PPSSPP) Path").grid(column=1,row=3,sticky=W) 
homepath_entry = ttk.Entry(mainframe,width = 60,textvariable=homepath) 
homepath_entry.grid(column=1,row=4, sticky=(W,E)) 
ttk.Button(mainframe, text="Browse", command=lambda:askfile(homepath)).grid(column=2, row =4,sticky=E) 

ttk.Button(mainframe, text="USB -> PC", command=lambda:copyfiles(usbpath,homepath)).grid(column=2,row=5,sticky=(N,S,W,E)) 
ttk.Button(mainframe, text="PC -> USB", command=lambda:copyfiles(homepath,usbpath)).grid(column=2,row=6,sticky=(N,S,W,E)) 
+2

您試圖醃製小部件而不是小部件中的文本。那真的是你想要做的嗎?爲什麼使用pickle而不是僅僅寫一個文件的路徑? –

+0

我不需要存儲小部件,我只需要在小部件中存儲文本(文件路徑)。 – SolidSnackDrive

回答

1

此按鈕askfile電話和發送一條STRINGVAR()

ttk.Button(mainframe, text="Browse", command=lambda:askfile(usbpath)).grid(column=2,row=2,sticky = E) 

功能然後嘗試以酸洗STRINGVAR,而不是文件名

def askfile(pathtype): ## pathtype=StrinVar 
    ## omitted code 
    pickle.dump(pathtype, f) 
+1

所以,而不是OP應該做....(你的答案似乎缺乏一點) –

+1

我不知道OP打算做什麼,所以只能解釋爲什麼錯誤消息被提出。假設通常是不正確的並且導致浪費時間,作爲所有線程的一般規則。 –

+1

@CurlyJoe:問題的第一句話是「我試圖將文件路徑存儲到文件中」。我要求(並得到)澄清,他們確實只需要來自小部件的文本而不是實際的小部件。 –

相關問題