【问题标题】:Why QTextDocument background color changes only once?为什么 QTextDocument 背景颜色只改变一次?
【发布时间】:2021-02-05 09:05:27
【问题描述】:

我正在使用 Qt (https://doc.qt.io/qt-5/qtquickcontrols1-texteditor-example.html) 提供的示例中的 TextEditor。这是完整的代码https://code.qt.io/cgit/qt/qtquickcontrols.git/tree/examples/quickcontrols/controls/texteditor?h=5.15

我创建了一个自定义方法 void DocumentHandler::setBackgroundColor(const QColor &color) 来更改整个 HTML 文档的背景颜色。

我的问题是每当我调用一个方法来使用setDefaultStyleSheet 更改QTextDocument 的背景颜色时,它只执行一次。即,我的文档背景只更改一次。对于接下来的调用,我可以看到 qDebug 打印正确,但 setDefaultStyleSheet 不起作用。但是,所有内容都适用于普通文本,但不适用于 m_doc->toHtml()。

我该如何解决这个问题?

如果我更改 m_doc->setHtml("some random text"),它会按要求工作

...

QColor DocumentHandler::backgroundColor() const
{
    return m_backgroundColor;
}

void DocumentHandler::setBackgroundColor(const QColor &color)
{

    m_backgroundColor = color.name(); // QColor variable
    m_doc->setDefaultStyleSheet("body{background-color: '"+ color.name() +"'}"); // m_doc is QTextDocument *
    m_doc->setHtml(m_doc->toHtml());

    qDebug() << "BACKGROUND COLOR CHANGED" << color.name() ;
    emit backgroundColorChanged();
}

在 QML 中,我是这样称呼的

...
DocumentHandlerModel {
    id: document
    target: textArea
    cursorPosition: textArea.cursorPosition
    selectionStart: textArea.selectionStart
    selectionEnd: textArea.selectionEnd
    backgroundColor: colorDialog2.color
    onFontFamilyChanged: {
        var index = Qt.fontFamilies().indexOf(document.fontFamily)
        if (index === -1) {
            fontFamilyComboBox.currentIndex = 0
            fontFamilyComboBox.special = true
        } else {
            fontFamilyComboBox.currentIndex = index
            fontFamilyComboBox.special = false
        }
    }
    onError: {
        errorDialog.text = message
        errorDialog.visible = true
    }
}

【问题讨论】:

  • 这是否回答了您的问题:stackoverflow.com/a/26249813/5366641?
  • @scopchanov,即QLabel。我找不到QTextDocument 的任何此类方法。我认为你是对的。我需要以某种方式刷新它。但不知道具体方法
  • 确实如此。答案是小部件。 QTextDocument 工作方式不同。我现在的事业已经。给我一些时间来寻找解决方案,我会给你写一个答案。

标签: c++ qt qml


【解决方案1】:

原因

QTextDocument::setDefaultStyleSheet 的文档说:

注意:更改默认样式表不会对文档的现有内容产生任何影响。

您尝试通过在setDefaultStyleSheet 之后调用setHtml 来克服这个问题:

m_doc->setHtml(m_doc->toHtml());

但是,这不会产生预期的结果,因为setDefaultStyleSheet 实际上是通过bgcolor CSS 属性将背景颜色嵌入 HTML 中。

要对此进行测试,请添加

m_doc->setHtml("<html><body><p>Test</p></body></html>");
qDebug() << m_doc->toHtml();

之后

m_doc->setHtml(m_doc->toHtml());

来自&lt;html&gt;&lt;body&gt;&lt;p&gt;Test&lt;/p&gt;&lt;/body&gt;&lt;/html&gt; 的m_doc 的HTML 内容在使用#FF00FF 进行测试时变为:

"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\np, li { white-space: pre-wrap; }\n</style></head><body style=\" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;\" bgcolor=\"#ff00ff\">\n<p style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Test</p></body></html>"

注意:请注意分配:bgcolor=\"#ff00ff\。

因此,通过编写m_doc-&gt;setHtml(m_doc-&gt;toHtml());,您可以有效地返回旧颜色。这就是为什么颜色只在第一次改变的原因。

顺便说一下,这个小部件现在改变了它的颜色,但是已经丢失了它的内容。

解决方案

很难找到一个优雅的解决方案,因为在这种情况下,标记和样式并没有像真正的HTML 和CSS 那样分开,但是样式是由Qt 嵌入到标记中的。我想到的一件事是手动解析m_doc的内容。

注意:这样的解决方案非常脆弱,我强烈反对。也许不使用样式表,而是通过设置小部件的调色板来更改背景颜色,这会在屏幕上呈现 QTextDocument 的内容。

注意:在任何情况下,这似乎都不是预期的行为,至少它与文档中的描述不匹配,所以我会将其作为错误报告给 Qt,如果我你是吗?

示例

这是我为您编写的一个示例,用于演示建议的解决方案:

void DocumentHandler::setBackgroundColor(const QColor &color)
{
    const QString &bgcolor("bgcolor=\"");
    QString html(m_doc->toHtml());
    int n = html.indexOf(bgcolor, html.indexOf("<body"));
    int k = n + bgcolor.length();

    m_doc->setDefaultStyleSheet("body { background-color: '" + color.name() + "' }");

    if (n >= 0)
        html.replace(n + bgcolor.length(), html.mid(k, html.indexOf("\"", n + bgcolor.length()) - k).length(), color.name());

    m_doc->setHtml(html);
    m_backgroundColor = color.name(); // QColor variable

    emit backgroundColorChanged();
}

【讨论】:

  • 是的。这就是发生的事情
  • @Chilarai,很难找到一个优雅的解决方案,因为在这种情况下,标记和样式并没有像真正的 HTML 和 CSS 那样分开,而是由 Qt 嵌入到标记中。不过,我会试着弄清楚一些事情。
  • 是的,这不是一个优雅的解决方案。但它就像一个魅力。谢谢
猜你喜欢
  • 2018-05-30
  • 2012-02-19
  • 1970-01-01
  • 2020-11-01
  • 2014-06-23
  • 2021-05-28
  • 1970-01-01
  • 2012-04-02
相关资源
最近更新 更多