如何为自定义mime类型实现剪贴板操作?

时间:2015-10-06 22:07:58

标签: qt mime-types clipboard qbytearray

我正在尝试在复杂的应用程序中实现复制/剪切/粘贴 我有一个QGraphicsScene可以包含各种子类型的QGraphicsItem个子类型,相当复杂(Item作为存储自定义属性的第二个父级)。
我会复制/剪切选定的项目,然后将它们粘贴到原位 我已经使用本地版本实现了它:项目列表。

void copyItemsActionOld()
{
    foreach(QGraphicsItem* qItem, selectedItems())
    {
        Item* newItem = (dynamic_cast<Item*>(qItem))->createItemCopy();
        m_itemClipboard.append(newItem);
    }
}

在粘贴时,我会复制剪贴板中的所有项目并将其添加到场景中。这么简单......

BUT

我需要使用全局系统剪贴板实现它。

我看到创建自定义mime类型就像在setData对象上调用QMimeData一样简单,在我编写格式名称之后......(我希望这是真的)

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)copyItemsActionpasteItemsAction的上述片段是否与剪贴板操作应该如何相关?

2)如何将项目数据放入QByteArray

3)如何解析QByteArray中的数据?

4)我是否需要在其他地方注册自定义mime类型? (除了我刚才在我的两个职能部门所做的事情);它会是多平台吗?

我已为所有项目实施了saveload功能。有点像...

void Item::saveItem(QDataStream &outFile)
{
    outFile << type;
    outFile << width;
    outFile << color.name();
}

我可以使用此功能将商品数据放入QByteArray吗? (怎么样?)

1 个答案:

答案 0 :(得分:1)

我是在正确的轨道上,我一直在为我的问题添加代码,直到我找到了如何使其工作:

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将信息序列化到QByteArray或来自proc sort data=sashelp.class out=work.class; by sex; run; *** GET COUNTS FOR EACH GROUP ***; proc freq data=class; tables sex / out=stats; run; *** CREATE ANNOTATE DATASET ***; data anno_stats; set stats (drop=percent); xsys='2'; ysys='1'; position='5'; function='label'; text='N=' || strip( put(count, 3.)); *** X COORDINATE IS THE GROUP VARIBLE IN THE BOXPLOT ***; *** USE VARIABLE XC INSTEAD OF X SINCE THIS IS A CHARACTER VARIABLE IN THIS EXAMPLE ***; xc=sex; *** Y COORDIANTE IS 3% ABOVE X-AXIS, BASED ON YSYS=1 ***; y=3; run; proc boxplot data=class anno=anno_stats; plot height * sex; run; 如果有更好/更有效/更快的方式,我很想知道......

对于问题4 - 似乎我可以使用任何字符串,如果我想要的是在我的应用程序的单个实例中复制/粘贴。
如果我想在多个应用程序,我的应用程序的多个实例之间使用它,或者在大多数平台上进行拖放操作,也是如此。 (它似乎不适用于我所针对的嵌入式平台中的多个应用程序/实例。)
警告 - 当在Windows中打开另一个使用应用程序的剪贴板时,它经常失败。