如何为自定义 MIME 类型实现剪贴板操作?
How to implement clipboard actions for custom mime-types?
我正在尝试在复杂的应用程序中实施 copy/cut/paste。
我有一个 QGraphicsScene
,它可以包含 QGraphicsItem
个不同子类型的子类型,相当复杂(Item
作为第二个父级存储自定义属性)。
我会 copy/cut 选择项目,然后将它们粘贴回原位。
我已经使用本地版本实现了它:项目列表。
void copyItemsActionOld()
{
foreach(QGraphicsItem* qItem, selectedItems())
{
Item* newItem = (dynamic_cast<Item*>(qItem))->createItemCopy();
m_itemClipboard.append(newItem);
}
}
粘贴时,我复制了剪贴板中的所有项目并将它们添加到场景中。就这么简单......
但是
我需要使用全局系统剪贴板实现它。
我看到创建自定义 MIME 类型就像在 QMimeData
对象上调用 setData
一样简单,在我组成格式名称之后......(我希望这是真的)
static const QString _mimeType("application/myItem");
void copyItemsAction()
{
QMimeData* _mimeData = new QMimeData;
2 QByteArray _itemData = ?????;
_mimeData->setData(_mimeType, _itemData);
QClipboard* _clipboard = QApplication::clipboard();
_clipboard->clear();
_clipboard->setMimeData(_mimeData);
}
void pasteItemsAction()
{
QClipboard* _clipboard = QApplication::clipboard();
const QMimeData* _mimeData = _clipboard->mimeData();
QStringList _formats = _mimeData->formats();
foreach (QString _format, _formats)
{
if (_format == _mimeType)
{
QByteArray _itemData = _mimeData->data(_mimeType);
3 // then do what ? How do I parse it ?
}
}
}
我的问题
1) copyItemsAction
和 pasteItemsAction
的上述片段是否接近剪贴板操作的工作方式?
2) 如何将项目数据放入 QByteArray
?
3) 如何解析 QByteArray
中的数据?
4) 我是否需要在其他任何地方注册自定义 MIME 类型? (除了我刚刚在我的两个功能中所做的);它会是多平台的吗?
我已经为所有项目实现了 save
和 load
功能。像...
void Item::saveItem(QDataStream &outFile)
{
outFile << type;
outFile << width;
outFile << color.name();
}
我可以使用它来将项目数据放入 QByteArray
吗? (如何?)
我走在了正确的轨道上,我不断地向我的问题添加代码,直到我找到如何让它工作:
static const QString _mimeType("application/myItem");
void copyItemsAction()
{
QByteArray _itemData;
QDataStream outData(&_itemData, QIODevice::WriteOnly);
outData << selectedItems().size();
foreach(QGraphicsItem* qItem, selectedItems())
{
Item* item = dynamic_cast<Item*>(qItem);
item->saveItem(outData);
}
QMimeData* _mimeData = new QMimeData;
_mimeData->setData(_mimeType, _itemData);
_mimeData->setText("My Items");
QClipboard* _clipboard = QApplication::clipboard();
_clipboard->clear();
_clipboard->setMimeData(_mimeData);
}
void pasteItemsAction()
{
QClipboard* _clipboard = QApplication::clipboard();
const QMimeData* _mimeData = _clipboard->mimeData();
QStringList _formats = _mimeData->formats();
foreach (QString _format, _formats)
{
if (_format == _mimeType)
{
QByteArray _itemData = _mimeData->data(_mimeType);
QDataStream inData(&_itemData, QIODevice::ReadOnly);
int itemsSize;
inData >> itemsSize;
for (int i = 0; i < itemsSize; ++i)
{
Item* item = ...
item->loadItem(inData);
}
}
}
}
所以,对于问题 1,是的,我的方向是正确的;
对于问题 2 和 3 - 我能够使用 QDataStream
将信息 to/from 序列化为 QByteArray
.
如果有更好/更有效/更快的方法,我很想知道...
对于问题 4 - 似乎我几乎可以使用任何字符串,如果我只想在我的应用程序的单个实例中 copy/paste。
如果我想在多个应用程序、我的应用程序的多个实例之间使用它,或者在 大多数 平台上进行拖放操作,也是如此。 (在我定位的嵌入式平台中,它似乎无法在多个 applications/instances 之间工作。)
警告 - 在 windows.
中打开另一个使用应用程序的剪贴板时,它经常失败
我正在尝试在复杂的应用程序中实施 copy/cut/paste。
我有一个 QGraphicsScene
,它可以包含 QGraphicsItem
个不同子类型的子类型,相当复杂(Item
作为第二个父级存储自定义属性)。
我会 copy/cut 选择项目,然后将它们粘贴回原位。
我已经使用本地版本实现了它:项目列表。
void copyItemsActionOld()
{
foreach(QGraphicsItem* qItem, selectedItems())
{
Item* newItem = (dynamic_cast<Item*>(qItem))->createItemCopy();
m_itemClipboard.append(newItem);
}
}
粘贴时,我复制了剪贴板中的所有项目并将它们添加到场景中。就这么简单......
但是
我需要使用全局系统剪贴板实现它。
我看到创建自定义 MIME 类型就像在 QMimeData
对象上调用 setData
一样简单,在我组成格式名称之后......(我希望这是真的)
static const QString _mimeType("application/myItem");
void copyItemsAction()
{
QMimeData* _mimeData = new QMimeData;
2 QByteArray _itemData = ?????;
_mimeData->setData(_mimeType, _itemData);
QClipboard* _clipboard = QApplication::clipboard();
_clipboard->clear();
_clipboard->setMimeData(_mimeData);
}
void pasteItemsAction()
{
QClipboard* _clipboard = QApplication::clipboard();
const QMimeData* _mimeData = _clipboard->mimeData();
QStringList _formats = _mimeData->formats();
foreach (QString _format, _formats)
{
if (_format == _mimeType)
{
QByteArray _itemData = _mimeData->data(_mimeType);
3 // then do what ? How do I parse it ?
}
}
}
我的问题
1) copyItemsAction
和 pasteItemsAction
的上述片段是否接近剪贴板操作的工作方式?
2) 如何将项目数据放入 QByteArray
?
3) 如何解析 QByteArray
中的数据?
4) 我是否需要在其他任何地方注册自定义 MIME 类型? (除了我刚刚在我的两个功能中所做的);它会是多平台的吗?
我已经为所有项目实现了 save
和 load
功能。像...
void Item::saveItem(QDataStream &outFile)
{
outFile << type;
outFile << width;
outFile << color.name();
}
我可以使用它来将项目数据放入 QByteArray
吗? (如何?)
我走在了正确的轨道上,我不断地向我的问题添加代码,直到我找到如何让它工作:
static const QString _mimeType("application/myItem");
void copyItemsAction()
{
QByteArray _itemData;
QDataStream outData(&_itemData, QIODevice::WriteOnly);
outData << selectedItems().size();
foreach(QGraphicsItem* qItem, selectedItems())
{
Item* item = dynamic_cast<Item*>(qItem);
item->saveItem(outData);
}
QMimeData* _mimeData = new QMimeData;
_mimeData->setData(_mimeType, _itemData);
_mimeData->setText("My Items");
QClipboard* _clipboard = QApplication::clipboard();
_clipboard->clear();
_clipboard->setMimeData(_mimeData);
}
void pasteItemsAction()
{
QClipboard* _clipboard = QApplication::clipboard();
const QMimeData* _mimeData = _clipboard->mimeData();
QStringList _formats = _mimeData->formats();
foreach (QString _format, _formats)
{
if (_format == _mimeType)
{
QByteArray _itemData = _mimeData->data(_mimeType);
QDataStream inData(&_itemData, QIODevice::ReadOnly);
int itemsSize;
inData >> itemsSize;
for (int i = 0; i < itemsSize; ++i)
{
Item* item = ...
item->loadItem(inData);
}
}
}
}
所以,对于问题 1,是的,我的方向是正确的;
对于问题 2 和 3 - 我能够使用 QDataStream
将信息 to/from 序列化为 QByteArray
.
如果有更好/更有效/更快的方法,我很想知道...
对于问题 4 - 似乎我几乎可以使用任何字符串,如果我只想在我的应用程序的单个实例中 copy/paste。
如果我想在多个应用程序、我的应用程序的多个实例之间使用它,或者在 大多数 平台上进行拖放操作,也是如此。 (在我定位的嵌入式平台中,它似乎无法在多个 applications/instances 之间工作。)
警告 - 在 windows.