【问题标题】:Qt: How to figure out the minimum size of rich text inside QTextEditQt:如何计算 QTextEdit 中富文本的最小大小
【发布时间】:2020-12-19 11:54:02
【问题描述】:

我有一个 QTextEdit,我初始化如下:

QTextEdit* textEdit = new QTextEdit();
textEdit->setReadOnly(true);
textEdit->setHtml("<p style=\"color:red; font-family:'Courier New';\">Raw Header</p>");
textEdit->setAlignment(Qt::AlignCenter);
textEdit->append("<p style=\"font-family:'Courier New'\">00000000<br />00000000<br />00000000<br />00000000</p>");
textEdit->setAlignment(Qt::AlignCenter);

这个 textEdit 后来被添加到 QGridLayout 中,在那个布局上它看起来像这样:

我想在没有滚动条的情况下文本仍然可见时将其调整为最小尺寸。 我能找到的每个建议的解决方案都假设 QTextEdit 已经可见,但这里不是这种情况。
我想在该对象的布局调用 show() 之前预先确定宽度/高度。

我尝试过的其他一些事情:
QTextDocument::size()
QTextDocument::idealWidth()
QTextDocument::pageSize()
QTextBlockFormat::lineHeight()(通过迭代 QTextDocument 中的所有 QTextBlock)

全部返回零,因为 QTextEdit 和里面的文本还没有渲染。
能做到吗?

【问题讨论】:

    标签: c++ qt qtextedit


    【解决方案1】:

    您可以使用QFontMetrics 估算呈现的文本尺寸,

    double stackMargins(const QList<double>& topMargins, const QList<double>& bottomMargins) {
        double total = topMargins[0] + bottomMargins[bottomMargins.size()-1];
        for(int i=1;i<topMargins.size();i++) {
            total += qMax(bottomMargins[i-1],topMargins[i]);
        }
        return total;
    }
    
    // assuming there are no spans within paragraphs and no images or tables or lists
    QSizeF estimateSize(QTextDocument* doc) {
        double width = 0;
        double height = 0;
        QList<double> topMargings;
        QList<double> bottomMargins;
        QTextFrame* frame = doc->rootFrame();
        QTextFrameFormat frameFormat = frame->frameFormat();
        for (QTextBlock it = doc->begin(); it != doc->end(); it = it.next())
        {
            QTextBlockFormat blockFormat = it.blockFormat();
            QTextCharFormat charFormat = it.charFormat();
            QFontMetrics fontMetrics(charFormat.font());
            QStringList lines = it.text().split(QChar(QChar::LineSeparator));
            double frameMargins = frameFormat.leftMargin() + frameFormat.rightMargin();
            double blockMargins = blockFormat.leftMargin() + blockFormat.rightMargin();
            for(const QString& line: lines) {
                // there are more margins (needs more research)
                double extraSpace = 2;
                double lineWidth = fontMetrics.horizontalAdvance(line) + extraSpace + blockMargins + frameMargins;
                width = qMax(width, lineWidth);
            }
            height += fontMetrics.height() * lines.size();
            topMargings << blockFormat.topMargin();
            bottomMargins << blockFormat.bottomMargin();
        }
        height += stackMargins(topMargings, bottomMargins);
        return QSizeF(width, height);
    }
    

    【讨论】:

      【解决方案2】:

      您也可以使用QTextDocument::size(),即使文档尚未呈现也可以使用(尽管它不能保证长行不会被换行)。

      QTextEdit* textEdit = new QTextEdit();
      QTextDocument* doc = new QTextDocument();
      QString html =
              "<div style=\"text-align: center;\">"
              "<p style=\"color:red; font-family:'Courier New';\">Raw Header</p>"
              "<p style=\"font-family:'Courier New'\">00000000<br />00000000<br />00000000<br />00000000</p>"
              "</div>";
      QTextOption textOption(Qt::AlignCenter);
      doc->setDefaultTextOption(QTextOption(Qt::AlignCenter)); // fixes center alignment in Qt4, not necessary in Qt5
      doc->setHtml(html);
      QSize size = doc->size().toSize() + QSize(2,2);
      textEdit->setGeometry(QRect(QPoint(100,100), size));
      textEdit->setReadOnly(true);
      textEdit->setDocument(doc);
      textEdit->show();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-05-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-04
        • 2018-10-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多