【问题标题】:How to implement clipboard actions for custom mime-types?如何为自定义 mime 类型实现剪贴板操作?
【发布时间】:2016-01-04 00:00:16
【问题描述】:

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

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) 以上copyItemsActionpasteItemsAction 的片段是否接近剪贴板操作的工作方式?

2) 如何将商品数据放入QByteArray 中?

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

4) 我需要在其他任何地方注册自定义 mime 类型吗? (除了我刚刚在我的两个函数中所做的);它会是多平台的吗?

我已经为所有项目实现了saveload 功能。比如……

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

我可以用它把物品数据放在QByteArray 中吗? (如何?)

【问题讨论】:

    标签: qt mime-types clipboard qbytearray


    【解决方案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 或从 QByteArray 序列化信息。
    如果有更好/更有效/更快的方法,我会喜欢要知道...

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

    【讨论】:

      猜你喜欢
      • 2013-12-19
      • 2015-10-25
      • 1970-01-01
      • 2020-05-15
      • 2017-08-21
      • 2021-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多