我正在使用qt的undo框架,它使用qundocommand来做一些应用程序支持undo。 有没有一种简单的方法可以将这些qundocommand保存到文件并重新加载?
答案 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的序列化,如下所述:
然后在您的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
}