通过QT将(rtf)表复制到剪贴板(或:将QTextDocument写入剪贴板)
Copying a (rtf) table into the clipboard via QT (or: Writing a QTextDocument into clipboard)
我需要我的QT应用程序来创建一个表,并将此表复制到剪贴板中,以便以后可以将其作为表粘贴到libreoffice Writer或MS Word中。
我的第一种方法是为表创建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复制到剪贴板的方法。有吗?如果我能从QTextDocument中获得RTF代码,我可以使用类似的方法
QClipboard *clipboard = QApplication::clipboard();
QMimeData *mimeData = new QMimeData();
mimeData->setData("text/rtf", rtfDocument.getCode());
clipboard->setMimeData(mimeData, QClipboard::Clipboard);
但我也没有找到返回rtf代码的函数。
编辑:
使用上面的最后一个代码框,我有一种将rtf代码复制到剪贴板的工作方法。因此,任何可以创建表示表的RTF代码的解决方案都可以解决我的问题。
我不确定您的数据源是什么,但这里是我们用来对普通QTableView
进行子类化以使其可复制的代码。有些代码已经被删掉了,但你可以得到基本的想法。RTF/HTML太夸张了——所有的电子表格都接受好的ol’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);
}
您可以尝试使用QTextDocument::toHtml()并将mime类型设置为text/html/
我在gedit 1[tab space]2[tab space]3n4[tab space]5[tab space]6
中编写并复制到电子表格中,它就工作了。所以,我认为如果用"\t"分隔行中的单元格,用"\n"分隔行,它会起作用。
相关文章:
- C++剪贴板队列粘贴随机结果?
- 将缓冲区复制到剪贴板 [换行错误]
- wxWidgets mac剪贴板在3.1.3上坏了?
- 获取剪贴板数据(CF_HDROP)在剪切和粘贴中失败
- 在 UWP 中找不到剪贴板
- 剪贴板数据上使用的全局大小函数会导致错误
- 将矢量复制到剪贴板
- 通过EventFilter到剪贴板获取QlineEdit的某些属性
- 如何使用OlesetClipboard将我的COM对象放置在剪贴板上时解决问题
- 使用 WIC 阅读剪贴板
- 文本到剪贴板
- 在QT应用程序和Windows Explorer之间剪切和粘贴剪贴板交换
- Linux/C++ 将字符串复制到剪贴板
- 从表视图复制到剪贴板
- 在可以选择剪贴板副本时,如何禁用Ccombobox
- 无法将 HTML 格式的 unicode(wchar_t 使用)复制到剪贴板
- BitBlt从剪贴板复制位图会给出错误的颜色
- 将文本复制到 MFC 中的剪贴板
- 如何在程序或网站处于活动状态时禁用剪贴板和任务切换操作
- Xorg 选择剪贴板