如何从组件 QTextDocument 获取 HTML 没有元信息的文本
How to get HTML text without meta information from component QTextDocument
描述
我在 QML 中创建了一个 TextArea
组件,类似于 this example, I created a DocumentHandler class based on a pointer to a QQuickTextDocument
, which is taken through the textDocument 属性。我需要这个以便能够格式化文本,即将其设为粗体、下划线、斜体、删除线等。
我需要什么
我需要获取文本,其中格式化部分将显示为 HTML 标签。
例如加粗文字最终我想得到的形式是<b>Bold text</b>
。或者例如 粗体和斜体文本 我想以 <b><i>Bold and italic text</i></b>
的形式获取(标签放置的顺序确实没关系)。
我试过的
我尝试使用 toHtml() 功能,但这个功能不适合我,因为:
- 它生成了很多我不需要的不必要信息。例如,对于 粗体文本 ,它返回以下结果:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
</style></head><body style=" font-family:'Roboto'; font-size:14px; font-weight:400; font-style:normal;">
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Bold text</span></p></body></html>
- 我需要表示文本的常用标签(
<b>
、<i>
等),这个函数是以style
属性的形式构成的<span>
标签。所以它用这一行改变了粗体:<span style=" font-weight:600;">
.
描述
如果我没理解错的话,目前无法使用 HTML 标签获取格式化文本,而没有 QTextDocument
使用 toHtml()
函数生成的元信息。因此,我决定使用 QTextCursor
class.
手动完成这项工作
代码
我有一个提供标签信息的结构:
struct Tag
{
Tag(const QString& openTag,
const QString& closeTag,
const std::function<bool(const QTextCursor& cursor)>& canBeOpened);
QString getOpenTag() const;
QString getCloseTag() const;
bool isOpened() const;
bool isClosed() const;
bool canBeOpened(const QTextCursor& cursor) const;
void open();
void close();
private:
std::function<bool(const QTextCursor&)> m_canBeOpened;
QString m_openTag;
QString m_closeTag;
bool m_isOpened{ false };
bool m_isClosed{ true };
};
我有一个 std::vector
这样的结构,我初始化如下:
m_tags{ { "<b>", "</b>", [](const QTextCursor& cursor) { return cursor.charFormat().fontWeight() == QFont::Bold; } },
{ "<i>", "</i>", [](const QTextCursor& cursor) { return cursor.charFormat().fontItalic(); } },
{ "<u>", "</u>", [](const QTextCursor& cursor) { return cursor.charFormat().fontUnderline(); } },
{ "<s>", "</s>", [](const QTextCursor& cursor) { return cursor.charFormat().fontStrikeOut(); } } }
最重要的是 getFormattedText()
函数,它使用这个 Tag
对象向量来 return 格式化文本。主要思想是在纯文本中手动放置标签,即开始标签放在格式开始的地方,结束标签放在格式结束的地方。关于文本中使用何种格式的信息可以从 QTextCursor
class 中获取,我们 can create 基于 QTextDocument
class 的对象。因此,我们有以下功能:
QString getFormattedText()
{
QTextCursor cursor{ textCursor() };
if (!cursor.isNull())
{
QString result{ cursor.document()->toPlainText() };
for (int i{}, offset{}; i < cursor.document()->characterCount(); ++i)
{
cursor.setPosition(i)
for (auto& tag : m_tags)
{
if (tag.canBeOpened(cursor))
{
if (!tag.isOpened())
{
result.insert(i - (i > 0 ? 1 : 0) + offset, tag.getOpenTag());
offset += tag.getOpenTag().size();
tag.open();
}
}
else if (!tag.isClosed())
{
result.insert(i - (i > 0 ? 1 : 0) + offset, tag.getCloseTag());
offset += tag.getCloseTag().size();
tag.close();
}
}
}
for (int i = m_tags.size() - 1; i >= 0; --i)
{
if (!m_tags[i].isClosed())
{
result.insert(result.size(), m_tags[i].getCloseTag());
m_tags[i].close();
}
}
return result;
}
return {};
}
粗体和斜体 文本将如下所示 <b><i>Bold and italic text</i></b>
描述
我在 QML 中创建了一个 TextArea
组件,类似于 this example, I created a DocumentHandler class based on a pointer to a QQuickTextDocument
, which is taken through the textDocument 属性。我需要这个以便能够格式化文本,即将其设为粗体、下划线、斜体、删除线等。
我需要什么
我需要获取文本,其中格式化部分将显示为 HTML 标签。
例如加粗文字最终我想得到的形式是<b>Bold text</b>
。或者例如 粗体和斜体文本 我想以 <b><i>Bold and italic text</i></b>
的形式获取(标签放置的顺序确实没关系)。
我试过的
我尝试使用 toHtml() 功能,但这个功能不适合我,因为:
- 它生成了很多我不需要的不必要信息。例如,对于 粗体文本 ,它返回以下结果:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
</style></head><body style=" font-family:'Roboto'; font-size:14px; font-weight:400; font-style:normal;">
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Bold text</span></p></body></html>
- 我需要表示文本的常用标签(
<b>
、<i>
等),这个函数是以style
属性的形式构成的<span>
标签。所以它用这一行改变了粗体:<span style=" font-weight:600;">
.
描述
如果我没理解错的话,目前无法使用 HTML 标签获取格式化文本,而没有 QTextDocument
使用 toHtml()
函数生成的元信息。因此,我决定使用 QTextCursor
class.
代码
我有一个提供标签信息的结构:
struct Tag
{
Tag(const QString& openTag,
const QString& closeTag,
const std::function<bool(const QTextCursor& cursor)>& canBeOpened);
QString getOpenTag() const;
QString getCloseTag() const;
bool isOpened() const;
bool isClosed() const;
bool canBeOpened(const QTextCursor& cursor) const;
void open();
void close();
private:
std::function<bool(const QTextCursor&)> m_canBeOpened;
QString m_openTag;
QString m_closeTag;
bool m_isOpened{ false };
bool m_isClosed{ true };
};
我有一个 std::vector
这样的结构,我初始化如下:
m_tags{ { "<b>", "</b>", [](const QTextCursor& cursor) { return cursor.charFormat().fontWeight() == QFont::Bold; } },
{ "<i>", "</i>", [](const QTextCursor& cursor) { return cursor.charFormat().fontItalic(); } },
{ "<u>", "</u>", [](const QTextCursor& cursor) { return cursor.charFormat().fontUnderline(); } },
{ "<s>", "</s>", [](const QTextCursor& cursor) { return cursor.charFormat().fontStrikeOut(); } } }
最重要的是 getFormattedText()
函数,它使用这个 Tag
对象向量来 return 格式化文本。主要思想是在纯文本中手动放置标签,即开始标签放在格式开始的地方,结束标签放在格式结束的地方。关于文本中使用何种格式的信息可以从 QTextCursor
class 中获取,我们 can create 基于 QTextDocument
class 的对象。因此,我们有以下功能:
QString getFormattedText()
{
QTextCursor cursor{ textCursor() };
if (!cursor.isNull())
{
QString result{ cursor.document()->toPlainText() };
for (int i{}, offset{}; i < cursor.document()->characterCount(); ++i)
{
cursor.setPosition(i)
for (auto& tag : m_tags)
{
if (tag.canBeOpened(cursor))
{
if (!tag.isOpened())
{
result.insert(i - (i > 0 ? 1 : 0) + offset, tag.getOpenTag());
offset += tag.getOpenTag().size();
tag.open();
}
}
else if (!tag.isClosed())
{
result.insert(i - (i > 0 ? 1 : 0) + offset, tag.getCloseTag());
offset += tag.getCloseTag().size();
tag.close();
}
}
}
for (int i = m_tags.size() - 1; i >= 0; --i)
{
if (!m_tags[i].isClosed())
{
result.insert(result.size(), m_tags[i].getCloseTag());
m_tags[i].close();
}
}
return result;
}
return {};
}
粗体和斜体 文本将如下所示 <b><i>Bold and italic text</i></b>