2024-04-25 00:15:37 发布
网友
我正在开发一个pythontkinter应用程序,它将yaml文件中的初始数据读入层次树视图,供用户进一步编辑。在
要实现“savedata”和“undo”函数,我是否应该遍历treeview并将数据重新构造为要序列化的python对象(pickle)? 或者,是否有一个python模块允许指定要保存的treeview和输出文件?在
开箱即用,答案是不,您不能序列化TreeView。dill可能是开箱即用序列化的最佳选择……但它无法pickle一个TreeView对象。在
TreeView
dill
>>> import ttk >>> import Tkinter as tk >>> >>> f = tk.Frame() >>> t = ttk.Treeview(f) >>> >>> import dill >>> dill.pickles(t) False >>> dill.detect.errors(t) PicklingError("Can't pickle 'tkapp' object: <tkapp object at 0x10eda75e0>",) >>>
您可能能够弄清楚如何pickle一个TreeView,然后将该方法添加到pickle注册表中……但是,这可能需要您进行一些认真的工作,以找出事情是如何未能pickle的。在
pickle
您可以看到发生了什么,它击中了Tkinter.Tk对象的__dict__,并在试图对某个进行pickle时死亡。在
Tkinter.Tk
__dict__
那个的东西是一个tkapp对象。在
tkapp
因此,如果您想进一步挖掘,您可以使用dill.detect中的方法来帮助您确切地揭示为什么它不酸洗……并尝试绕过它。在
dill.detect
我怀疑酸洗是正确的方法。您可能也不希望将状态从treeview拉到一个影子类中,然后保存该类。问题是treeview在构建时并没有考虑到要保存state的良好分离。在
treeview
如果您可以重新设计,将应用程序的状态与小部件本身完全分离,那么这更有可能实现您想要的效果。所以,当你问How to serialize a treeview,这并不是你要问的。您想知道如何保存应用程序的状态。在
How to serialize a treeview
有些软件包可以很容易地做到这一点。我建议你看看enaml和/或{}。enaml是一个声明性标记,它要求您构建一个描述应用程序接口如何工作的类。它迫使你把你正在显示的东西的内部工作与必要的代码分开来操作用户界面…它以一种非常容易构建的方式来实现,在这种方式下,应用程序的状态与用户界面的连线是分开的。因此,您构建的类的实例在任何时候都包含应用程序的状态,而不管它是否有UI,或者有两个或三个UI。它使保存应用程序的状态变得非常容易,因为您不必这样做 担心保存UI的状态UI没有状态,只是布局在应用程序的顶部。那么你就不必担心小部件的酸洗
enaml
查看enaml这里:https://github.com/nucleic/enaml
还有traits这里:http://docs.enthought.com/traits
traits
我怀疑是否有任何Python模块可以满足您的需要,即使有,我也不认为您会希望围绕使用它来构建应用程序。取而代之的是,你最好将事情解耦,并将主要数据存储在独立于人机界面的东西中(人机界面可能是图形化的,也可能不是图形化的,将来可能会发生变化或发生变化)。这有时被称为应用程序“模型”。在
这样做将允许您加载和保存它,而不管当前的人机界面是什么。因此,例如,如果内部模型由一个或多个Python对象组成,那么您就可以自由地使用pickle。或者,您可以将数据保存回一个yaml格式的文件中,这样可以很容易地在以后再次加载它,因为程序已经可以这样做了。在
同样,当用户编辑TreeView时,应该对模型进行等效的更改以保持两者的同步。在
从编码中抽出一些时间,熟悉一下Model–View–Controller (MVC)设计模式。在
开箱即用,答案是不,您不能序列化
TreeView
。dill
可能是开箱即用序列化的最佳选择……但它无法pickle一个TreeView
对象。在您可能能够弄清楚如何pickle一个
TreeView
,然后将该方法添加到pickle
注册表中……但是,这可能需要您进行一些认真的工作,以找出事情是如何未能pickle的。在您可以看到发生了什么,它击中了
^{pr2}$Tkinter.Tk
对象的__dict__
,并在试图对某个进行pickle时死亡。在那个的东西是一个
tkapp
对象。在因此,如果您想进一步挖掘,您可以使用
dill.detect
中的方法来帮助您确切地揭示为什么它不酸洗……并尝试绕过它。在我怀疑酸洗是正确的方法。您可能也不希望将状态从
treeview
拉到一个影子类中,然后保存该类。问题是treeview在构建时并没有考虑到要保存state的良好分离。在如果您可以重新设计,将应用程序的状态与小部件本身完全分离,那么这更有可能实现您想要的效果。所以,当你问
How to serialize a treeview
,这并不是你要问的。您想知道如何保存应用程序的状态。在有些软件包可以很容易地做到这一点。我建议你看看}。
enaml
和/或{enaml
是一个声明性标记,它要求您构建一个描述应用程序接口如何工作的类。它迫使你把你正在显示的东西的内部工作与必要的代码分开来操作用户界面…它以一种非常容易构建的方式来实现,在这种方式下,应用程序的状态与用户界面的连线是分开的。因此,您构建的类的实例在任何时候都包含应用程序的状态,而不管它是否有UI,或者有两个或三个UI。它使保存应用程序的状态变得非常容易,因为您不必这样做 担心保存UI的状态UI没有状态,只是布局在应用程序的顶部。那么你就不必担心小部件的酸洗查看
enaml
这里:https://github.com/nucleic/enaml还有
traits
这里:http://docs.enthought.com/traits我怀疑是否有任何Python模块可以满足您的需要,即使有,我也不认为您会希望围绕使用它来构建应用程序。取而代之的是,你最好将事情解耦,并将主要数据存储在独立于人机界面的东西中(人机界面可能是图形化的,也可能不是图形化的,将来可能会发生变化或发生变化)。这有时被称为应用程序“模型”。在
这样做将允许您加载和保存它,而不管当前的人机界面是什么。因此,例如,如果内部模型由一个或多个Python对象组成,那么您就可以自由地使用
pickle
。或者,您可以将数据保存回一个yaml格式的文件中,这样可以很容易地在以后再次加载它,因为程序已经可以这样做了。在同样,当用户编辑TreeView时,应该对模型进行等效的更改以保持两者的同步。在
从编码中抽出一些时间,熟悉一下Model–View–Controller (MVC)设计模式。在
相关问题 更多 >
编程相关推荐