我正在尝试创建代码编辑器,并希望在用户键入关键字后更改TextArea中关键字的颜色。我读到textFormat:Text.StyledText可以更改颜色,而无需将整个文本更改为HTML,但是在文本中添加标签不会更改颜色。在这里我使用粗体标记 代码-
TextArea{
Layout.alignment: Qt.AlignTop
id:ta
selectByMouse: true
selectByKeyboard: true
Layout.fillWidth:true
Layout.fillHeight: true
font.pointSize: 12
textMargin: 16
font.family:"courier new"
persistentSelection: true
textFormat: Text.StyledText
onActiveFocusChanged: {
menu_trig=0
}
onTextChanged: {
// check text
console.log(ta.text.slice(0,ta.text.length-3))
if(ta.text.slice(ta.text.length-3,ta.text.length)=="def")
{
ta_text.text=ta.text.substring(0,ta.text.length-3)+"<b>def</b>"}
}
Keys.onPressed: {
if(codeChange==0)
{codeChange=1
mainWindow.title=title.toString()+" *"}
}
Component.onCompleted: forceActiveFocus()
// color:"orange"}
答案 0 :(得分:0)
您必须使用QSyntaxHighlighter,因为在我看来,您正在尝试使其成为我基于this post实现的python编辑器。
syntaxhighlighter.h
#ifndef SYNTAXHIGHLIGHTER_H
#define SYNTAXHIGHLIGHTER_H
#include <QRegularExpression>
#include <QSyntaxHighlighter>
class QQuickTextDocument;
class HighlightingRule
{
public:
HighlightingRule(const QString &patternStr, int n, const QTextCharFormat &matchingFormat);
QString originalRuleStr;
QRegularExpression pattern;
int nth;
QTextCharFormat format;
};
class PythonSyntaxHighlighter : public QSyntaxHighlighter
{
Q_OBJECT
public:
PythonSyntaxHighlighter(QTextDocument *parent);
const QTextCharFormat getTextCharFormat(const QString &colorName, const QString &style = QString());
void initializeRules();
bool matchMultiline(const QString &text, const QRegularExpression &delimiter, const int inState, const QTextCharFormat &style);
protected:
void highlightBlock(const QString &text);
private:
QStringList keywords;
QStringList operators;
QStringList braces;
QHash<QString, QTextCharFormat> basicStyles;
QList<HighlightingRule> rules;
QRegularExpression triSingleQuote;
QRegularExpression triDoubleQuote;
};
class SyntaxHighlighterHelper: public QObject
{
Q_OBJECT
Q_PROPERTY(QQuickTextDocument *quickdocument READ quickdocument WRITE setQuickdocument NOTIFY quickdocumentChanged)
public:
SyntaxHighlighterHelper(QObject *parent=nullptr):
QObject(parent),
m_quickdocument(nullptr)
{}
QQuickTextDocument *quickdocument() const;
void setQuickdocument(QQuickTextDocument *quickdocument);
signals:
void quickdocumentChanged();
private:
QQuickTextDocument *m_quickdocument;
};
#endif // SYNTAXHIGHLIGHTER_H
syntaxhighlighter.cpp
#include "syntaxhighlighter.h"
#include <QQuickTextDocument>
HighlightingRule::HighlightingRule(const QString &patternStr, int n, const QTextCharFormat &matchingFormat)
{
originalRuleStr = patternStr;
pattern = QRegularExpression(patternStr);
nth = n;
format = matchingFormat;
}
PythonSyntaxHighlighter::PythonSyntaxHighlighter(QTextDocument *parent)
: QSyntaxHighlighter(parent)
{
keywords = QStringList() << "and" << "assert" << "break" << "class" << "continue" << "def" <<
"del" << "elif" << "else" << "except" << "exec" << "finally" <<
"for" << "from" << "global" << "if" << "import" << "in" <<
"is" << "lambda" << "not" << "or" << "pass" << "print" <<
"raise" << "return" << "try" << "while" << "yield" <<
"None" << "True" << "False";
operators = QStringList() << "=" <<
// Comparison
"==" << "!=" << "<" << "<=" << ">" << ">=" <<
// Arithmetic
"\\+" << "-" << "\\*" << "/" << "//" << "%" << "\\*\\*" <<
// In-place
"\\+=" << "-=" << "\\*=" << "/=" << "%=" <<
// Bitwise
"\\^" << "\\|" << "&" << "~" << ">>" << "<<";
braces = QStringList() << "{" << "}" << "\\(" << "\\)" << "\\[" << "]";
basicStyles.insert("keyword", getTextCharFormat("blue"));
basicStyles.insert("operator", getTextCharFormat("red"));
basicStyles.insert("brace", getTextCharFormat("darkGray"));
basicStyles.insert("defclass", getTextCharFormat("black", "bold"));
basicStyles.insert("brace", getTextCharFormat("darkGray"));
basicStyles.insert("string", getTextCharFormat("magenta"));
basicStyles.insert("string2", getTextCharFormat("darkMagenta"));
basicStyles.insert("comment", getTextCharFormat("darkGreen", "italic"));
basicStyles.insert("self", getTextCharFormat("black", "italic"));
basicStyles.insert("numbers", getTextCharFormat("brown"));
triSingleQuote.setPattern("'''");
triDoubleQuote.setPattern("\"\"\"");
initializeRules();
}
void PythonSyntaxHighlighter::initializeRules()
{
for(const QString & currKeyword: keywords)
{
rules.append(HighlightingRule(QString("\\b%1\\b").arg(currKeyword), 0, basicStyles.value("keyword")));
}
for(const QString & currOperator: operators)
{
rules.append(HighlightingRule(QString("%1").arg(currOperator), 0, basicStyles.value("operator")));
}
for(const QString &currBrace: braces)
{
rules.append(HighlightingRule(QString("%1").arg(currBrace), 0, basicStyles.value("brace")));
}
// 'self'
rules.append(HighlightingRule("\\bself\\b", 0, basicStyles.value("self")));
// Double-quoted string, possibly containing escape sequences
// FF: originally in python : r'"[^"\\]*(\\.[^"\\]*)*"'
rules.append(HighlightingRule("\"[^\"\\\\]*(\\\\.[^\"\\\\]*)*\"", 0, basicStyles.value("string")));
// Single-quoted string, possibly containing escape sequences
// FF: originally in python : r"'[^'\\]*(\\.[^'\\]*)*'"
rules.append(HighlightingRule("'[^'\\\\]*(\\\\.[^'\\\\]*)*'", 0, basicStyles.value("string")));
// 'def' followed by an identifier
// FF: originally: r'\bdef\b\s*(\w+)'
rules.append(HighlightingRule("\\bdef\\b\\s*(\\w+)", 1, basicStyles.value("defclass")));
// 'class' followed by an identifier
// FF: originally: r'\bclass\b\s*(\w+)'
rules.append(HighlightingRule("\\bclass\\b\\s*(\\w+)", 1, basicStyles.value("defclass")));
// From '#' until a newline
// FF: originally: r'#[^\\n]*'
rules.append(HighlightingRule("#[^\\n]*", 0, basicStyles.value("comment")));
// Numeric literals
rules.append(HighlightingRule("\\b[+-]?[0-9]+[lL]?\\b", 0, basicStyles.value("numbers"))); // r'\b[+-]?[0-9]+[lL]?\b'
rules.append(HighlightingRule("\\b[+-]?0[xX][0-9A-Fa-f]+[lL]?\\b", 0, basicStyles.value("numbers"))); // r'\b[+-]?0[xX][0-9A-Fa-f]+[lL]?\b'
rules.append(HighlightingRule("\\b[+-]?[0-9]+(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\\b", 0, basicStyles.value("numbers"))); // r'\b[+-]?[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\b'
}
void PythonSyntaxHighlighter::highlightBlock(const QString &text)
{
for(const HighlightingRule &rule: rules) {
QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text);
while (matchIterator.hasNext()) {
QRegularExpressionMatch match = matchIterator.next();
setFormat(match.capturedStart(), match.capturedLength(), rule.format);
}
}
setCurrentBlockState(0);
bool isInMultilne = matchMultiline(text, triSingleQuote, 1, basicStyles.value("string2"));
if (!isInMultilne)
isInMultilne = matchMultiline(text, triDoubleQuote, 2, basicStyles.value("string2"));
}
bool PythonSyntaxHighlighter::matchMultiline(const QString &text, const QRegularExpression &delimiter, const int inState, const QTextCharFormat &style)
{
QRegularExpressionMatch match;
int startIndex = 0;
if (previousBlockState() != 1)
startIndex = text.indexOf(delimiter);
while (startIndex >= 0) {
QRegularExpressionMatch match = delimiter.match(text, startIndex);
int endIndex = match.capturedStart();
int commentLength = 0;
if (endIndex == -1) {
setCurrentBlockState(1);
commentLength = text.length() - startIndex;
} else {
commentLength = endIndex - startIndex
+ match.capturedLength();
}
setFormat(startIndex, commentLength, style);
startIndex = text.indexOf(delimiter, startIndex + commentLength);
}
return currentBlockState() == inState;
}
const QTextCharFormat PythonSyntaxHighlighter::getTextCharFormat(const QString &colorName, const QString &style)
{
QTextCharFormat charFormat;
QColor color(colorName);
charFormat.setForeground(color);
if (style.contains("bold", Qt::CaseInsensitive))
charFormat.setFontWeight(QFont::Bold);
if (style.contains("italic", Qt::CaseInsensitive))
charFormat.setFontItalic(true);
return charFormat;
}
QQuickTextDocument *SyntaxHighlighterHelper::quickdocument() const
{
return m_quickdocument;
}
void SyntaxHighlighterHelper::setQuickdocument(QQuickTextDocument *quickdocument)
{
m_quickdocument = quickdocument;
if(m_quickdocument){
new PythonSyntaxHighlighter(m_quickdocument->textDocument());
}
}
main.cpp
// ...
qmlRegisterType<SyntaxHighlighterHelper>("Foo", 1, 0, "SyntaxHighlighterHelper");
// ...
main.qml
// ...
import Foo 1.0
// ...
SyntaxHighlighterHelper{
quickdocument: ta.textDocument
}
TextArea{
id:ta
anchors.fill: parent
selectByMouse: true
selectByKeyboard: true
font.pointSize: 12
textMargin: 16
font.family:"courier new"
persistentSelection: true
textFormat: Text.StyledText
tabStopDistance: 4*fontMetrics.advanceWidth(" ")
FontMetrics {
id: fontMetrics
font.family: ta.font
}
}
// ...
可以在here中找到示例。