如何在 Qt 中使用 QSyntaxHighlighter class 在 QML TextEdit 上实现富文本逻辑?
How to implement rich text logic on QML TextEdit with QSyntaxHighlighter class in Qt?
我的 QML 文件中有一个 TextEdit,我有一个 QSyntaxHighlighter C++ class。我想在 C++ class 中指定突出显示逻辑并将其应用于 TextEdit,但我不确定如何在 QML 对象和 C++ class 之间建立连接。你也可以提供一些示例代码吗?我找不到如何使用 Qt 文档实现它。
您可以使用 TextEdit::textDocument
, which holds an instance of QQuickTextDocument
,获得对可以传递给 QSyntaxHighlighter
构造函数的基础 QTextDocument
的访问权。
万一有人需要更详细的解释。
首先,我在自定义 C++ class.
中创建了一个 Q_PROPERTY
Q_PROPERTY(QQuickTextDocument* mainTextEdit READ mainTextEdit WRITE setMainTextEdit NOTIFY mainTextEditChanged)
然后我将textEdit.textDocument
分配给QML中的Q_PROPERTY。
customClass.mainTextEdit = textEdit.textDocument
然后我调用initHighlighter()
(函数必须是Q_INVOKABLE) in my QML which calls the constructor of my highlighter class and passes it the text document of the textEdit。
void initHighlighter()
{
Highlighter *highlighter;
highlighter = new Highlighter(m_mainTextEdit->textDocument());
}
注意:自定义荧光笔class需要派生自QSyntaxHighlighter。
实施示例:
HighlightComponent.h
class HighlightComponent : public QObject
{
Q_OBJECT
//@formatter:off
Q_PROPERTY(QString text
READ getText
WRITE setText
NOTIFY textChanged)
//@formatter:on
using inherited = QObject;
public:
explicit HighlightComponent(QObject* parent = nullptr);
static void registerQmlType();
const QString& getText()
{
return _text;
}
void setText(const QString& newText)
{
if (newText != _text)
{
_text = newText;
emit textChanged();
}
}
Q_INVOKABLE void onCompleted();
signals:
void textChanged();
private:
std::unique_ptr<QSyntaxHighlighter> _highlight;
QString _text = "";
};
HighlightComponent.cpp
HighlightComponent::HighlightComponent(QObject* parent)
: inherited(parent)
{
}
void HighlightComponent::onCompleted()
{
auto property = parent()->property("textDocument");
auto textDocument = property.value<QQuickTextDocument*>();
auto document = textDocument->textDocument();
//TODO init here your QSyntaxHighlighter
}
void HighlightComponent::registerQmlType()
{
qmlRegisterType<HighlightComponent>("com.HighlightComponent", 1, 0, "HighlightComponent");
}
main.cpp
int main(int argc, char* argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
HighlightComponent::registerQmlType();
engine.load(QUrl(QStringLiteral("qrc:/view/main.qml")));
return app.exec();
}
示例 QML
TextArea {
id: testTextArea
text: testTextArea.text
//inputMethodHints: Qt.ImhNoPredictiveText
onTextChanged: {
testTextArea.text = text
}
HighlightComponent {
id: testTextArea
Component.onCompleted: onCompleted()
}
}
链接:
https://wiki.qt.io/How_to_Bind_a_QML_Property_to_a_C%2B%2B_Function
http://doc.qt.io/qt-5/qtqml-cppintegration-exposecppattributes.html
http://wiki.qt.io/Spell-Checking-with-Hunspell
http://doc.qt.io/qt-5/qtqml-cppintegration-interactqmlfromcpp.html
http://doc.qt.io/qt-5/qtwidgets-richtext-syntaxhighlighter-example.html
我的 QML 文件中有一个 TextEdit,我有一个 QSyntaxHighlighter C++ class。我想在 C++ class 中指定突出显示逻辑并将其应用于 TextEdit,但我不确定如何在 QML 对象和 C++ class 之间建立连接。你也可以提供一些示例代码吗?我找不到如何使用 Qt 文档实现它。
您可以使用 TextEdit::textDocument
, which holds an instance of QQuickTextDocument
,获得对可以传递给 QSyntaxHighlighter
构造函数的基础 QTextDocument
的访问权。
万一有人需要更详细的解释。 首先,我在自定义 C++ class.
中创建了一个 Q_PROPERTYQ_PROPERTY(QQuickTextDocument* mainTextEdit READ mainTextEdit WRITE setMainTextEdit NOTIFY mainTextEditChanged)
然后我将textEdit.textDocument
分配给QML中的Q_PROPERTY。
customClass.mainTextEdit = textEdit.textDocument
然后我调用initHighlighter()
(函数必须是Q_INVOKABLE) in my QML which calls the constructor of my highlighter class and passes it the text document of the textEdit。
void initHighlighter()
{
Highlighter *highlighter;
highlighter = new Highlighter(m_mainTextEdit->textDocument());
}
注意:自定义荧光笔class需要派生自QSyntaxHighlighter。
实施示例:
HighlightComponent.h
class HighlightComponent : public QObject
{
Q_OBJECT
//@formatter:off
Q_PROPERTY(QString text
READ getText
WRITE setText
NOTIFY textChanged)
//@formatter:on
using inherited = QObject;
public:
explicit HighlightComponent(QObject* parent = nullptr);
static void registerQmlType();
const QString& getText()
{
return _text;
}
void setText(const QString& newText)
{
if (newText != _text)
{
_text = newText;
emit textChanged();
}
}
Q_INVOKABLE void onCompleted();
signals:
void textChanged();
private:
std::unique_ptr<QSyntaxHighlighter> _highlight;
QString _text = "";
};
HighlightComponent.cpp
HighlightComponent::HighlightComponent(QObject* parent)
: inherited(parent)
{
}
void HighlightComponent::onCompleted()
{
auto property = parent()->property("textDocument");
auto textDocument = property.value<QQuickTextDocument*>();
auto document = textDocument->textDocument();
//TODO init here your QSyntaxHighlighter
}
void HighlightComponent::registerQmlType()
{
qmlRegisterType<HighlightComponent>("com.HighlightComponent", 1, 0, "HighlightComponent");
}
main.cpp
int main(int argc, char* argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
HighlightComponent::registerQmlType();
engine.load(QUrl(QStringLiteral("qrc:/view/main.qml")));
return app.exec();
}
示例 QML
TextArea {
id: testTextArea
text: testTextArea.text
//inputMethodHints: Qt.ImhNoPredictiveText
onTextChanged: {
testTextArea.text = text
}
HighlightComponent {
id: testTextArea
Component.onCompleted: onCompleted()
}
}
链接:
https://wiki.qt.io/How_to_Bind_a_QML_Property_to_a_C%2B%2B_Function
http://doc.qt.io/qt-5/qtqml-cppintegration-exposecppattributes.html
http://wiki.qt.io/Spell-Checking-with-Hunspell
http://doc.qt.io/qt-5/qtqml-cppintegration-interactqmlfromcpp.html
http://doc.qt.io/qt-5/qtwidgets-richtext-syntaxhighlighter-example.html