Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/apache/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 通过QT将(rtf)表复制到剪贴板(或:将QTextDocument写入剪贴板)_C++_Qt_Clipboard_Rtf - Fatal编程技术网

C++ 通过QT将(rtf)表复制到剪贴板(或:将QTextDocument写入剪贴板)

C++ 通过QT将(rtf)表复制到剪贴板(或:将QTextDocument写入剪贴板),c++,qt,clipboard,rtf,C++,Qt,Clipboard,Rtf,我需要我的QT应用程序创建一个表并将该表复制到剪贴板中,以便以后可以将其作为表粘贴到libreoffice Writer或MS Word中 我的第一种方法是为表创建html代码,并使用 QClipboard *clipboard = QApplication::clipboard(); QMimeData *mimeData = new QMimeData(); mimeData->setData("text/html", html.toUtf8()); clipboard->set

我需要我的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代码的解决方案都可以解决我的问题。

我在gedit中编写了
1[tab space]2[tab space]3\n4[tab space]5[tab space]6
,并将其复制到电子表格中,它成功了。因此,我认为如果您使用“\t”来分隔行中的单元格,使用“\n”来分隔行,它会起作用。

我不确定您的数据源是什么,但下面是我们用来对普通
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);
}
//根据RFC-4180规范对字符串进行转义。
静态QString csvEscape(常量QString和值){
if(value.contains(QRegExp(QLatin1String(“[\”\\n\\r,]”))){
QString转义(值);
转义。替换(QLatin1String(\”),QLatin1String(\”);
返回QString::fromLatin1(\%1\).arg(转义);
}否则{
返回值;
}
}
void ClipboardAwareTableView::Copy()常量{
QModelIndexList index=selectedindex();
Q_ASSERT(!index.isEmpty());
if(index.isEmpty()){
返回;
}
//默认排序是按行然后按列。这是我们想要的。
qSort(索引);
//记住模型列和可见列之间的映射
//本地而不是实例成员,因为需要使其无效
//无论何时添加、删除或移动列,都会影响较小的性能
//简单是值得的。
QHash映射缓存;
//在开始导出文本之前,我们必须知道左边的索引-
//选择范围中的大多数列,以便添加适当的数字
//柱分离器的设计。
int minimum_column=GetViewColumnIndex(index.first().column(),&map_缓存);
对于(int i=1;i显示文本(current.data(),QLocale()));
}否则{
append(csvEscape(current.data().toString());
}
先前=当前;
}
qApp->clipboard()->setText(文本);
}
int-ClipboardAwareTableView::GetViewColumnIndex(
int model_column_index,
QHash*缓存的_映射)常量{
if(缓存的映射->包含(模型列索引)){
返回缓存的\u映射->值(模型\u列\u索引);
}
int view_index=0;
对于(int i=0;icolumnCount();++i){
if(模型列索引=i){
缓存的映射->插入(模型列索引、视图索引);
返回视图索引;
}如果(!isColumnHidden(i))为else{
++视图索引;
}
}
throw std::无效的_参数(“模型_列_索引超出范围”);
}
void ClipboardAwareTableView::keyPressEvent(QKeyEvent*event){
如果(事件->匹配(QKeySequence::Copy)&&!SelectedIndex().isEmpty()){
复制();
事件->接受();
return;//基类实现将覆盖剪贴板。
}
事件->忽略();
QTableView::按键事件(事件);
}

您可以尝试使用,并将mime类型设置为text/html

根据上的答案,您可以使用进行RTF处理。我想检查一下。不幸的是,librtf只允许解析,不允许创建rtf文件。我需要MS Word/LO Writer中的表,而不是Excel/Calc中的表。所以我想我确实需要rtf这样的格式。抱歉,问题不清楚-我对其进行了更改,使其更加清晰。我需要MS Word/LO Writer格式的表格,而不是Excel/Calc格式的表格。因此,我认为我确实需要rtf格式。很抱歉,问题不清楚-我对其进行了修改,使其更加清晰。这是我的第一个方法,它不起作用(详情请参见问题)。我写的html公司