问题
I am working on a QtQuick 2.0
presentation and I would like to embed some code samples. is it possible easily to create a syntax highlighting qml element.
Can you give me example technologies and ideas on how to achieve it.
Thanks
回答1:
Qt Quick's TextEdit
item exposes a textDocument
property, of type QQuickTextDocument
. This is explicitly exposed so you can use QSyntaxHighlighter
directly with the document.
QtQuick textEdit documentation for Qt 5.3
回答2:
There is no obvious way to achieve syntax highlighting in QML.
One could implement one's own declarative item, performing the actual highlighting with QSyntaxHighlighter but then one would have to define its own highlighting rules for language of the source code in question. I would't do that amount of coding for a presentation.
Instead I would display the code in a WebView item with the highlighting already applied as static HTML markup or with the help of a JavaScript highlighting library, for expample highlight.js.
Update 1
If the WebView
item is indeed unusable, even the simple Text item with its rudimentary HTML support should be enough to handle the source code highlighting usecase if fed with static HTML.
回答3:
in your app file:
QApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
QQuickTextDocument* doc = childObject<QQuickTextDocument*>(engine, "textEditor", "textDocument");
Q_ASSERT(doc != 0);
// QSyntaxHighlighter derrived class
MySyntaxHighlighter* parser = new MySyntaxHighlighter(doc->textDocument());
// use parser, see QSyntaxHighlighter doc...
int ret = app.exec();
delete parser;
return ret;
The template function to get child objects (returns the first occurence of objectName, so use unique names to identify objects in your qml files) :
template <class T> T childObject(QQmlApplicationEngine& engine,
const QString& objectName,
const QString& propertyName)
{
QList<QObject*> rootObjects = engine.rootObjects();
foreach (QObject* object, rootObjects)
{
QObject* child = object->findChild<QObject*>(objectName);
if (child != 0)
{
std::string s = propertyName.toStdString();
QObject* object = child->property(s.c_str()).value<QObject*>();
Q_ASSERT(object != 0);
T prop = dynamic_cast<T>(object);
Q_ASSERT(prop != 0);
return prop;
}
}
return (T) 0;
}
in your qml file use a TextEdit (inside a Flickable or whatever you want) with the objectName property correctly set:
....
TextEdit {
id: edit
objectName: "textEditor"
width: flick.width
height: flick.height
focus: true
font.family: "Courier New"
font.pointSize: 12
wrapMode: TextEdit.NoWrap
onCursorRectangleChanged: flick.ensureVisible(cursorRectangle)
}
....
回答4:
Take a look at QSyntaxHighlighter.
If you need a QML Item doing syntax highlighting, you can simply create your own by extending QDeclarativeItem
and using the utility above.
回答5:
With a TextArea
one can use textFormat: TextEdit.RichText
for formatting. We can use TextArea::getText()
to get the plain text and set TextArea::text
with the rich text. Here's a mock example that:
- uppercase identifiers (e.g. Button) into purple
- lowercase identifiers (e.g. x y z) into red
- turns numbers (e.g. 123 456) into blue
- and symbols (e.g. = + ;) stay black
Here's the snippet:
TextArea {
id: output
property bool processing: false
text: "<p>x = 123;</p><p>y = 456;</p><p>z = x + y;</p>"
textFormat: TextEdit.RichText
selectByMouse: true
onTextChanged: {
if (!processing) {
processing = true;
var p = cursorPosition;
var mu = getText(0, length);
mu = mu.replace(/([A-Z][A-Za-z]*|[a-z][A-Za-z]*|[0-9]+|[ \t\n]|['][^']*[']|[^A-Za-z0-9\t\n ])/g, function (f) {
console.log("f: ", JSON.stringify(f));
if (f.match(/^[A-Z][A-Za-z]*$/))
return "<span style='color:#800080'>" + f + "</span>";
if (f.match(/^[a-z][A-Za-z]*$/))
return "<span style='color:#800000'>" + f + "</span>";
else if (f.match(/^[0-9]+$/))
return "<span style='color:#0000ff'>" + f + "</span>";
else if (f.match(/^[ ]/))
return " "
else if (f.match(/^[\t\n]/))
return f;
else if (f.match(/^[']/))
return "<span style='color:#008000'>" + f + "</span>";
else
return f;
} );
text = mu;
cursorPosition = p;
processing = false;
}
}
}
来源:https://stackoverflow.com/questions/14791360/qt5-syntax-highlighting-in-qml