如何将qundocommand保存到文件并重新加载?

时间:2012-05-02 21:53:35

标签: qt undo-redo

我正在使用qt的undo框架,它使用qundocommand来做一些应用程序支持undo。 有没有一种简单的方法可以将这些qundocommand保存到文件并重新加载?

3 个答案:

答案 0 :(得分:1)

没有内置方式。我不认为在会话之间保存撤消堆栈是很常见的。您必须通过迭代堆栈上的命令并使用QDataStream保存每个数据的唯一数据来自行序列化命令。它可能看起来像这样:

...
dataStream << undoStack->count(); // store number of commands

for (int i = 0; i < undoStack->count(); i++)
{
    // store each command's unique information
    dataStream << undoStack->command(i)->someMemberVariable;
}
...

然后,您将再次使用QDataStream将数据反序列化为QUndoCommands。

您可以使用QFile来处理文件管理。

答案 1 :(得分:1)

使用Qt的序列化,如下所述:

Serialization with Qt

然后在您的QUndoCommands中,您可以使用临时文件将数据写入其中:

http://qt-project.org/doc/qt-4.8/qtemporaryfile.html

但是,这可能会导致问题,因为每个文件都保持打开状态,因此在某些平台(Linux)上,您可能会用完打开的文件句柄。

要解决此问题,您必须创建一些处理命令的其他工厂类型对象 - 然后这可以自动传递对QTemporaryFile的引用。此工厂/ QUndoCommand care taker对象必须具有与QUndoCommands相同的生命周期。如果没有,则临时文件将从磁盘中删除,您的QUndoCommands将中断。

您可以做的另一件事是使用QUndoCommand作为您的真实撤销命令的代理 - 这意味着您可以节省相当多的内存,因为当您将撤消命令保存到文件时,您可以删除内部指针/将其设置为空值。然后稍后恢复。

答案 2 :(得分:1)

这是用于序列化/分配QUndoCommands的PyQt解决方案。棘手的部分是让父母先打电话给__init__,然后再给孩子打电话。此方法依赖于所有孩子的__setstate__在父对象的__getstate__之前被调用,这发生在腌制过程中,因为孩子在父元素的class UndoCommand(QUndoCommand): """ For pickling """ def __init__(self, text, parent=None): QUndoCommand.__init__(self, text, parent) self.__parent = parent self.__initialized = True # defined and initialized in __setstate__ # self.__child_states = {} def __getstate__(self): return { **{k: v for k, v in self.__dict__.items()}, '_UndoCommand__initialized': False, '_UndoCommand__text': self.text(), '_UndoCommand__children': [self.child(i) for i in range(self.childCount())] } def __setstate__(self, state): if hasattr(self, '_UndoCommand__initialized') and \ self.__initialized: return text = state['_UndoCommand__text'] parent = state['_UndoCommand__parent'] # type: UndoCommand if parent is not None and \ (not hasattr(parent, '_UndoCommand__initialized') or not parent.__initialized): # will be initialized in parent's __setstate__ if not hasattr(parent, '_UndoCommand__child_states'): setattr(parent, '_UndoCommand__child_states', {}) parent.__child_states[self] = state return # init must be called on unpickle-time to recreate Qt object UndoCommand.__init__(self, text, parent) for child in state['_UndoCommand__children']: child.__setstate__(self.__child_states[child]) self.__dict__ = {k: v for k, v in state.items()} @staticmethod def from_QUndoCommand(qc: QUndoCommand, parent=None): if type(qc) == QUndoCommand: qc.__class__ = UndoCommand qc.__initialized = True qc.__parent = parent children = [qc.child(i) for i in range(qc.childCount())] for child in children: UndoCommand.from_QUndoCommand(child, parent=qc) return qc 中返回。

public func interfaceNames() -> [String] {

        let MAX_INTERFACES = 128;

        var interfaceNames = [String]()
        let interfaceNamePtr = UnsafeMutablePointer<Int8>.allocate(capacity: Int(Int(IF_NAMESIZE)))
        for interfaceIndex in 1...MAX_INTERFACES {
            if (if_indextoname(UInt32(interfaceIndex), interfaceNamePtr) != nil){
                let interfaceName = String(cString: interfaceNamePtr)
                interfaceNames.append(interfaceName)
            } else {
                break
            }
        }

        interfaceNamePtr.deallocate()
        return interfaceNames
    }