使用 Tkinter 和 Pickle 加载和保存设置时出现问题

Trouble Loading and Saving Settings with Tkinter and Pickle

我写了一个简单的脚本来绘制仪器生成的一些数据,我想添加一些显示自定义选项。作为第一步,我为输出图添加了“宽度”和“高度”字段,我将其存储在名为 'Settings' 的 class 中。我想读取这些设置(如果它们存在)并显示它们,允许用户更改它们,并在程序关闭时保存它们。但是,现在当我 运行 代码,将宽度从默认的 7 更改为另一个值,并关闭程序时,我的调试语句报告:

settings loaded: 
7
closing:
7

我的代码相关部分如下:

import tkinter as tk
from tkinter import filedialog
import pandas as pd
import numpy as np
import math
import matplotlib.pyplot as plt
import matplotlib
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.pyplot import figure as Figure
import pickle 
import os

#create settings
settings = {
    'chartWidth': 7,
    'chartHeight': 5
    }
settingsfile = 'settings.pk' 

#... plotting functions

def exit():
    mode = 'ab' if os.path.exists(settingsfile) else 'wb'
    with open(settingsfile, mode) as f:
        pickle.dump(settings, f, pickle.HIGHEST_PROTOCOL)
        print('closing:')
        print(settings['chartWidth'])
    window.destroy()

                                                                                          
# Create the root window
window = tk.Tk()

canvas1 = tk.Canvas(window, width = 400, height = 200,  relief = 'raised', bg='white')
canvas1.pack()
  
window.wm_title('Table Plotting')  
      
button_getFile = tk.Button(window,
                        text = "Plot File", fg='white', bg='black',
                        command = plotFile)
  
button_exit = tk.Button(window,
                     text = "Exit", fg='white', bg='black',
                     command = exit)

label_Width = tk.Label(window, text = "Image Width: ", bg="white")
settings['chartWidth'] = tk.Entry(window, width=5)
settings['chartWidth'].insert(-1, settings['chartWidth'])

label_Height = tk.Label(window, text = "Image Height: ", bg="white")
settings['chartHeight'] = tk.Entry(window, width=5)
settings['chartHeight'].insert(-1, settings['chartHeight'])
  
canvas1.create_window(50, 25, window=label_Width)
canvas1.create_window(110, 25, window=settings['chartWidth'])
canvas1.create_window(250, 25, window=label_Height)
canvas1.create_window(310, 25, window=settings['chartHeight'])

canvas1.create_window(175, 50, window=button_getFile)
canvas1.create_window(175, 80, window=button_exit)

try:
    with open(settingsfile, 'rb') as f:
        try:
            settings = pickle.load(f)
            print('settings loaded: ')
            print(settings['chartWidth'])
        except: 
            pass
except:
    pass
     

# Let the window wait for any events
window.mainloop()

我在运行程序的时候,没有填默认值:https://imgur.com/acFYa3F

如果我注释掉 settings['chartWidth'].insert(-1, settings['chartWidth']) 行,输入字段是空白的,而不是由默认值填充。

并且如上所述,更改后的设置['chartWidth']似乎从未被保存过。有人可以给我一些关于如何获得正确 read/write 行为的指示吗?

您已经用 Entry 个小部件覆盖了 settings 中的值:

settings['chartWidth'] = tk.Entry(window, width=5)
...
settings['chartHeight'] = tk.Entry(window, width=5)

使用如下其他变量:

e_width = tk.Entry(window, width=5)
e_width.insert(-1, settings['chartWidth'])
...
e_height = tk.Entry(window, width=5)
e_height.insert(-1, settings['chartHeight'])
...
canvas1.create_window(110, 25, window=e_width)
...
canvas1.create_window(310, 25, window=e_height)

您还需要更新 settings,然后再保存到 exit() 函数中(最好使用另一个函数名称,因为 exit() 是一个内置函数)并始终覆盖 pickle 文件(文件存在时不使用追加模式):

def exit():
    try:
        settings['chartWidth'] = int(e_width.get())
        settings['chartHeight'] = int(e_height.get())

        #mode = 'ab' if os.path.exists(settingsfile) else 'wb'
        with open(settingsfile, "wb") as f:
            pickle.dump(settings, f, pickle.HIGHEST_PROTOCOL)
            print('closing:')
            print(settings['chartWidth'])
        window.destroy()
    except ValueError as e:
        print("Invalid value:", e)

最后,您需要在创建 Entry 小部件之前加载 pickle 文件,否则默认值始终用作那些 Entry 小部件中的初始文本。