2015-10-06 3 views
0

Я пытаюсь реализовать copy/cut/paste в сложном приложении.
У меня есть QGraphicsScene, который может содержать QGraphicsItem подтипы разнообразных подтипов, довольно сложные (с Item как второй родитель, сохраняющий пользовательские свойства).
Я бы скопировал/вырезал выбранные предметы и вставил их обратно на место.
Я уже реализовал его, используя локальную версию: список элементов.Как реализовать действия с буфером обмена для пользовательских типов mime?

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

На вставке я делаю копию всех элементов в буфере обмена и добавляю их на место происшествия. Так просто .....

НО

мне нужно реализовать его с помощью глобальной системы буфер обмена.

Я видел, что создание пользовательского типа пантомимы так же просто, как вызов 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) Есть ли вышеуказанные фрагменты для copyItemsAction и pasteItemsAction где-нибудь рядом с тем, как должны работать действия в буфере обмена?

2) Как я могу поместить данные позиции в QByteArray?

3) Как разобрать данные в QByteArray?

4) Нужно ли мне регистрировать пользовательский тип mime в другом месте? (кроме того, что я только что сделал в двух моих функциях); и будет ли она многоплатформенной?

Я уже реализовал save и load функциональность для всех элементов. Что-то вроде ...

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.
Если есть лучший/более эффективный/быстрый путь, я хотел бы знать ...

На вопросе 4 - кажется, что я могу использовать только о любой строке, если все, что я хочу, чтобы скопировать/вставить в один экземпляр моего приложения.
Это также верно, если я хочу использовать его между несколькими приложениями, несколькими экземплярами моего приложения или для перетаскивания - на наиболее платформ.(Кажется, что это не работает между несколькими приложениями/экземплярами во встроенной платформе, на которую я нацелен.)
Caveat - он часто не работает, когда в Windows открыт другой буфер обмена с использованием приложения.