使用 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
小部件中的初始文本。
我写了一个简单的脚本来绘制仪器生成的一些数据,我想添加一些显示自定义选项。作为第一步,我为输出图添加了“宽度”和“高度”字段,我将其存储在名为 '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
小部件中的初始文本。