2015-10-06 65 views
0

我想在複雜的應用程序中實現複製/剪切/粘貼。
我有一個QGraphicsScene可以包含QGraphicsItem不同亞型的子類型,相當複雜(與Item作爲第二個父存儲自定義屬性)。
我會複製/剪切選定的項目,並將其粘貼回原處。
我已經使用本地版本實現了它:項目列表。如何實現自定義MIME類型的剪貼板操作?

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? (如何?)

回答

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中打開另一個使用應用程序的剪貼板時,它經常失敗。