2012-03-19 55 views
3

我需要我的QT应用程序来创建表并将此表复制到剪贴板,以便它可以作为表粘贴到libreoffice Writer或MS Word以后。通过QT(或:将QTextDocument写入剪贴板)将(rtf)表复制到剪贴板中

我的第一个方法是为表创建的HTML代码,并将其与

QClipboard *clipboard = QApplication::clipboard(); 
QMimeData *mimeData = new QMimeData(); 
mimeData->setData("text/html", html.toUtf8()); 
clipboard->setMimeData(mimeData, QClipboard::Clipboard); 

这种做法没有奏效插入到剪贴板。粘贴时,将表格单元格相互追加并插入而不进行格式化。

我的第二种方法使用RTF:

QTextDocument rtfDocument; 
rtfDocument.setHtml(html); 

但是我发现没有办法这个另外,QTextDocument复制到剪贴板。有没有? 如果我能得到的RTF码出另外,QTextDocument的,我可以用一个办法像

QClipboard *clipboard = QApplication::clipboard(); 
QMimeData *mimeData = new QMimeData(); 
mimeData->setData("text/rtf", rtfDocument.getCode()); 
clipboard->setMimeData(mimeData, QClipboard::Clipboard); 

但我也没有找到一个函数返回的RTF代码。

编辑:

有了上次的代码框上方我有一个工作方式,以RTF代码复制到剪贴板。因此,任何可以创建代表表格的RTF代码的解决方案都可以解决我的问题。

+0

据对[这太问题]的答案(http://stackoverflow.com/questions/294343/read-and -write-rtf-files-with-c-qt),你可以用[librtf](http://sourceforge.net/projects/librtf/)进行RTF处理。我会检查一下。 – Attila 2012-03-26 15:44:13

+0

不幸的是,librtf只允许解析,不能创建rtf文件。 – Heinzi 2012-03-29 12:22:16

回答

2

你可以尝试使用QTextDocument::toHtml()和设置MIME类型为text/html

+0

这是我的第一个方法,它不起作用(详情见问题)。我自己编写了html代码,但这不应该是问题。当我将表格从Firefox中复制到LO Writer中时,我得到了同样的错误结果。我认为LO Writer只是忽略了html标签。 – Heinzi 2012-03-29 12:48:02

+0

我懂了。 Libreoffice忽略了html标签,因为我毕竟有一个错误。 – Heinzi 2012-03-29 13:48:12

0

我在gedit 1[tab space]2[tab space]3\n4[tab space]5[tab space]6中写道,并将其复制到电子表格中,并且工作正常。所以,我认为如果你使用“\ t”来分隔行,使用“\ n”来分隔行,它会起作用。

+0

我需要MS Word/LO Writer中的表格,而不是Excel/Calc中的表格。所以我认为我确实需要像rtf这样的格式。对不清楚的问题抱歉 - 我以一种更清楚的方式改变了它。 – Heinzi 2012-03-29 12:24:20

3

我不确定数据的来源是什么,但这里是我们用来将正常QTableView子类化以使其可复制的代码。一些代码已被删除,但你可以得到基本的想法。 RTF/HTML是矫枉过正的 - 所有电子表格都接受良好的'CSV'。

当然,如果您需要格式化,此答案根本无济于事。我不清楚你的问题,如果这是一个需求与否。

// Escapes a string according to RFC-4180 specification. 
static QString csvEscape(const QString &value) { 
    if (value.contains(QRegExp(QLatin1String("[\"\\n\\r,]")))) { 
    QString escaped(value); 
    escaped.replace(QLatin1String("\""), QLatin1String("\"\"")); 
    return QString::fromLatin1("\"%1\"").arg(escaped); 
    } else { 
    return value; 
    } 
} 

void ClipboardAwareTableView::Copy() const { 
    QModelIndexList indexes = selectedIndexes(); 

    Q_ASSERT(!indexes.isEmpty()); 
    if(indexes.isEmpty()) { 
    return; 
    } 

    // The default sort is by rows then columns. This is what we want. 
    qSort(indexes); 

    // Remember the mapping between model columns and visible columns. This is 
    // local instead of an instance member because it would need to be invalidated 
    // any time a column is added, removed, or moved. The minor performance hit 
    // is worth the simplicity. 
    QHash<int, int> map_cache; 

    // Before we start exporting text, we have to know the index of the left- 
    // most column in our selection range so we can add the appropriate number 
    // of column separators. 
    int minimum_column = GetViewColumnIndex(indexes.first().column(), &map_cache); 
    for (int i = 1; i < indexes.size(); ++i) { 
    minimum_column = 
     qMin(minimum_column, 
      GetViewColumnIndex(indexes.at(i).column(), &map_cache)); 
    } 

    // Keep track of the previous index so that we know if we need a new line and 
    // how many column separators to insert. We start with an invalid index. 
    QModelIndex previous; 

    QString text; 

    for (int i = 0; i < indexes.size(); ++i) { 
    QModelIndex current = indexes.at(i); 

    // Do we need to add a new line character? 
    if (previous.isValid() && current.row() != previous.row()) { 
     text.append(QLatin1String("\n")); 
    } 

    // Are we on a new line? 
    if (!previous.isValid() || current.row() != previous.row()) { 
     // Add enough separators to get from the minimum to the current column. 
     text.append(QString::fromLatin1(",") 
        .repeated(GetViewColumnIndex(current.column(), &map_cache) - 
          minimum_column)); 
    } else { 
     // Add enough separators to get from the previous to the current column. 
     text.append(QString::fromLatin1(",") 
        .repeated(GetViewColumnIndex(current.column(), &map_cache) - 
          GetViewColumnIndex(previous.column(), &map_cache))); 
    } 

    // Append the text. If the column delegate is a QStyledItemDelegate, we use 
    // the display text. 
    QStyledItemDelegate *delegate = 
     qobject_cast<QStyledItemDelegate*>(
      itemDelegateForColumn(current.column())); 
    if (delegate) { 
     text.append(csvEscape(delegate->displayText(current.data(), QLocale()))); 
    } else { 
     text.append(csvEscape(current.data().toString())); 
    } 

    previous = current; 
    } 

    qApp->clipboard()->setText(text); 
} 

int ClipboardAwareTableView::GetViewColumnIndex(
    int model_column_index, 
    QHash<int, int> *cached_mappings) const { 
    if (cached_mappings->contains(model_column_index)) { 
    return cached_mappings->value(model_column_index); 
    } 

    int view_index = 0; 
    for (int i = 0; i < model()->columnCount(); ++i) { 
    if (model_column_index == i) { 
     cached_mappings->insert(model_column_index, view_index); 
     return view_index; 
    } else if (!isColumnHidden(i)) { 
     ++view_index; 
    } 
    } 

    throw std::invalid_argument("model_column_index was out of range."); 
} 

void ClipboardAwareTableView::keyPressEvent(QKeyEvent *event) { 
    if (event->matches(QKeySequence::Copy) && !selectedIndexes().isEmpty()) { 
    Copy(); 
    event->accept(); 
    return; // The base class implementation will overwrite the clipboard. 
    } 

    event->ignore(); 
    QTableView::keyPressEvent(event); 
} 
+0

我需要MS Word/LO Writer中的表格,而不是Excel/Calc中的表格。所以我认为我确实需要像rtf这样的格式。对不清楚的问题抱歉 - 我以一种更清楚的方式改变了它。 – Heinzi 2012-03-29 12:23:51