Tom154ce
Tom154ce

Reputation: 35

TypeError: cannot pickle '_tkinter.tkapp' object

I'm trying to create a project which can take a users name and password and save it to a .yaml file. Unfortunately when trying to save the details, i receive the Type Error above. I've tried searching around to fix it but I haven't found any solution that I was able to successfully apply. If someone could advise me on how to fix this i'd really appreciate it! Code below:

import yaml
import tkinter as tk
from tkinter import CENTER, ttk

with open("settings.yaml","rb") as f:
  yaml_dict = yaml.load(f,yaml.CLoader)

class Window(tk.Tk):
    def __init__(self,row,h,w):
        super().__init__()
        self.title("Title")

        #Window configuration
        self.window_width = h #600 default
        self.window_height = w #200 default
        screen_width = self.winfo_screenwidth()
        screen_height = self.winfo_screenheight()
        center_x = int(screen_width/2 - self.window_width/2)
        center_y = int(screen_height/2 - self.window_height/2)

        self.geometry(f'{self.window_width}x{self.window_height}+{center_x}+{center_y}')
        self.resizable(False,False)
        #Grid configuration
        self.columnconfigure(0,weight=1)
        self.columnconfigure(1,weight=2)
        self.columnconfigure(2,weight=2)
        self.columnconfigure(3,weight=2)
        self.columnconfigure(4,weight=1)

        for _ in range(row):
            self.rowconfigure(row,weight=1)
            
    def close(self):
        self.destroy()

def saveCfg(self,name,password):            #issue
    yaml_dict['name'] = name
    yaml_dict['password'] = password
    with open('settings.yaml', 'w') as f:
        yaml.dump(yaml_dict,f)
    self.close()

def userConfig():
    cfgWindow = Window(8,300,200)
    cfgWindow.title("Bot Configuration")
    nameLabel = ttk.Label(cfgWindow, text=("Enter name below:"), font='TkFixedFont')
    nameLabel.grid(column=2,row=1)
    name = ttk.Entry(cfgWindow)
    name.grid(column=2,row=2)
    passwordLabel = ttk.Label(cfgWindow, text=("Enter password below:"), font='TkFixedFont')
    passwordLabel.grid(column=2,row=3)
    password = ttk.Entry(cfgWindow)
    password.grid(column=2,row=4)
    confirmButton = ttk.Button(cfgWindow, text="Save Details", command=lambda: saveCfg(cfgWindow,name,password))
    confirmButton.grid(column=2,row=5)
    cfgWindow.mainloop()

userConfig()

YAML file:

---
name: "name"
password: "password"

Upvotes: 0

Views: 932

Answers (1)

Dvir Berebi
Dvir Berebi

Reputation: 1566

You need to save the data (which might be called the "state") of the mentioned fields, instead of the tkinter object.

Please see:

BTW, storing passwords as plaintext is considered a bad approach, please research how to do that properly and securely.

Upvotes: 3

Related Questions