Qt - 使用QString :: arg将文本对齐到列中

时间:2016-06-21 16:00:39

标签: c++ string qt format

我使用QString :: arg格式化字符串,我需要在列中格式化字符串。例如:

78.0    78.0    78.0
0.0     0.0     78.0
69.0    56.0    0.0

现在我为每列使用d += QString("%1").arg("78.0", -50, ' ');,然后d += '\n'使用新行。

唯一的问题是空格字符与数字的宽度不同,所以事情变得不对齐:

misalignment

我想知道的是如何将文本对齐到列中?感谢。

1 个答案:

答案 0 :(得分:1)

您可以使用QTextEdit及其丰富的文本布局功能。然后,您可以以编程方式生成html表:

// https://github.com/KubaO/stackoverflown/tree/master/questions/textedit-columns-37949301
#include <QtWidgets>

template <typename It, typename F>
QString toTable(It begin, It end, int columns, F && format, 
                const QString & attributes = QString()) {
   if (begin == end) return QString();
   QString output = QStringLiteral("<table %1>").arg(attributes);
   int n = 0;
   for (; begin != end; ++begin) {
      if (!n) output += "<tr>";
      output += "<td>" + format(*begin) + "</td>";
      if (++n == columns) {
         n = 0;
         output += "</tr>";
      }
   }
   output += "</table>";
   return output;
}

如果您要将大量数据加载到QTextEdit,则可以在单独的线程中创建QTextDocument,将其填充到那里,然后将其传输到QTextEdit:< / p>

#include <QtConcurrent>

void setHtml(QTextEdit * edit, const QString & html) {
  QtConcurrent::run([=]{
    // runs in a worker thread
    auto doc = new QTextDocument;
    doc->setHtml(html);
    doc->moveToThread(edit->thread());
    QObject src;
    src.connect(&src, &QObject::destroyed, qApp, [=]{
      // runs in the main thread
      doc->setParent(edit);
      edit->setDocument(doc);
    });
  });
}

以类似的方式,也可以将QTextEdit的渲染转移到工作线程,尽管这是我必须在一个单独的问题中解决的问题。该方法类似于the one in this answer

让我们使用它:

int main(int argc, char ** argv) {
   QApplication app{argc, argv};
   double const table[] {
      78.0,    78.0,    78.0,
      0.0,     0.0,     78.0,
      69.0,    56.0,    0.0};
   QTextEdit edit;
   setHtml(&edit, toTable(std::begin(table), std::end(table), 3,
                          [](double arg){ return QString::number(arg, 'f', 1); },
                          "width=\"100%\""));
   edit.setReadOnly(true);
   edit.show();
   return app.exec();
}