1

我在下面编写了漂亮的 python 示例代码。现在我该如何做到这一点,当我退出然后重新启动程序时,它会记住刻度的最后位置?

import Tkinter

root = Tkinter.Tk()

root.sclX = Tkinter.Scale(root, from_=0, to=1500, orient='horizontal', resolution=1)
root.sclX.pack(ipadx=75)

root.resizable(False,False)
root.title('Scale')
root.mainloop()

编辑:

我尝试了以下代码

import Tkinter
import cPickle


root = Tkinter.Tk()

root.sclX = Tkinter.Scale(root, from_=0, to=1500, orient='horizontal', resolution=1)
root.sclX.pack(ipadx=75)



root.resizable(False,False)
root.title('Scale')


with open('myconfig.pk', 'wb') as f:
    cPickle.dump(f, root.config(), -1)
    cPickle.dump(f, root.sclX.config(), -1)
root.mainloop()

但是得到以下错误

Traceback (most recent call last):
  File "<string>", line 244, in run_nodebug
  File "C:\Python26\pickleexample.py", line 17, in <module>
    cPickle.dump(f, root.config(), -1)
TypeError: argument must have 'write' attribute
4

6 回答 6

5

将比例值写入文件并在启动时将其读取。这是一种方法(大致),

CONFIG_FILE = '/path/to/config/file'

root.sclX = ...

try:
    with open(CONFIG_FILE, 'r') as f:
        root.sclX.set(int(f.read()))
except IOError:    # this is what happens if the file doesn't exist
    pass

...
root.mainloop()

# this needs to run when your program exits
with open(CONFIG_FILE, 'w') as f:
    f.write(str(root.sclX.get()))

显然,例如,如果您想保存和恢复其他值,则可以使其更加健壮/复杂/复杂。

于 2010-06-27T20:03:26.310 回答
3

就在mainloop

import cPickle
with open('myconfig.pk', 'wb') as f:
  cPickle.dump(f, root.config(), -1)
  cPickle.dump(f, root.sclX.config(), -1)

并且,在随后的运行中(当.pk文件已经存在时),相应的cPickle.load调用将其取回并设置它...config(**k)(不幸的是,还需要一些技巧来确认cPickle腌制配置可以安全地重新加载)。

于 2010-06-27T20:11:12.273 回答
1

您可以告诉程序使用参数编写一个名为“save.txt”的文件,然后在进一步的执行中加载它:

有没有“save.txt”?

否:使用该参数写入一个新的保存文件。是:读取参数并将其传递给变量。

如果参数已更新,则将其重写到文件中。

我不是 Python 专家,但是应该有一些不错的库来读写文件:)

于 2010-06-27T20:07:19.873 回答
1

对于对象持久性,Python 中有一个不错的模块:搁置。

例如(两个脚本在同一个目录中)

脚本 1

import shelve

settings = shelve.open('mySettings')
settings['vroot_directory'] = commands.getoutput("pwd")

脚本 2

import shelve 

settings = shelve.open('mySettings')
root_directory_script1 = settings['vroot_directory'])   

rgds,

附言。对于一个更完整的例子,我的帖子的答案 gddc : Importing python variables of a program after its execution

于 2010-08-20T08:21:53.207 回答
0

一个简单的使用

help(cPickle.dump)

在解释器中将立即显示您应该尝试通过交换 f 和存储在调用中的对象来更改 Alex 的代码:

cPickle.dump(root.config(), f, -1)
cPickle.dump(root.sclX.config(), f, -1)
于 2010-06-28T01:11:28.107 回答
0

您可以使用 pickle 文件保护程序编写一个类,并使用 setter 和 getter 函数注册任何变量。使用我的这个紧凑且有条理的示例(Python 3)。如果您更喜欢手动存储和保存,请仅使用 CacheDict。

警告:请不要注册 tkintern 小部件或在 mainloop 之后可能会死的任何东西。

import os
import pickle
import atexit


class CacheDict(dict):
    __slots__ = ('fileName', 'loadedFile')

    def __init__(self, fileName: str, default: dict = {}):
        self.fileName = fileName
        self.loadedFile = None
        atexit.register(self.close)

        if os.path.exists(self.fileName):
            try:
                with open(self.fileName, "rb") as file:
                    self.loadedFile = pickle.load(file)
                    super().__init__(self.loadedFile)
                    return  # finished

            except Exception as e:
                pass

        super().__init__(default)

    def close(self):
        if self.loadedFile != self:
            print('CacheDict saving: ', self.fileName)
            with open(self.fileName, "wb") as file:
                pickle.dump(self, file)


class UserSettings:
    __slots__ = ('storage', 'access')

    def __init__(self, name: str = 'user_settings'):
        self.storage = CacheDict(name)
        self.access = {}
        atexit.register(self.Update)

    def Register(self, name, default_value, setter, getter):
        self.access[name] = (setter, getter)
        if name in self.storage:
            value = self.storage[name]
        else:
            self.storage[name] = default_value
            value = default_value
        setter(value)

    def Update(self):
        for key, (setter, getter) in self.access.items():
            self.storage[key] = getter()
            pass


import tkinter

userSettings = UserSettings('test_user_settings')
root = tkinter.Tk()

scaleVar = tkinter.IntVar()
userSettings.Register('ScalePosition', 0, scaleVar.set, scaleVar.get)  # !! use only Variable
scale = tkinter.Scale(root, from_=0, to=1500, orient='horizontal', resolution=1, variable=scaleVar)

scale.pack(ipadx=75)
root.resizable(False, False)
root.title('Scale')

root.mainloop()
于 2021-12-19T11:52:00.863 回答