syntax-highlighting qml qt5 qtquick2

syntax highlighting - Resaltado de sintaxis Qt5 en QML



syntax-highlighting qtquick2 (5)

Con un TextArea se puede usar textFormat: TextEdit.RichText para el formateo. Podemos usar TextArea::getText() para obtener el texto sin formato y establecer TextArea::text con el texto enriquecido. Aquí hay un ejemplo falso que:

  • Los identificadores en mayúsculas (por ejemplo, el botón) en púrpura
  • identificadores en minúsculas (por ejemplo, xyz) en rojo
  • convierte los números (ej. 123 456) en azul
  • y los símbolos (ej. = +;) permanecen negros

Aquí está el fragmento:

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 "&nbsp;" 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; } } }

Estoy trabajando en una presentación de QtQuick 2.0 y me gustaría insertar algunos ejemplos de código. ¿Es posible crear fácilmente un elemento qml de resaltado de sintaxis?

¿Puedes darme ejemplos de tecnologías e ideas sobre cómo lograrlo?

Gracias


Echa un vistazo a QSyntaxHighlighter .

Si necesita un elemento QML que resalte la sintaxis, puede crear su propio artículo extendiendo QDeclarativeItem y utilizando la utilidad anterior.


El elemento TextEdit Qt Quick expone una propiedad textDocument , de tipo QQuickTextDocument . Esto está explícitamente expuesto, por lo que puede usar QSyntaxHighlighter directamente con el documento.

QtQuick textEdit documentación para Qt 5.3


No hay una manera obvia de lograr el resaltado de sintaxis en QML.

Uno podría implementar su propio elemento declarativo, realizando el resaltado real con QSyntaxHighlighter pero luego tendría que definir sus propias reglas de resaltado para el idioma del código fuente en cuestión. No haría esa cantidad de codificación para una presentación.

En su lugar, mostraría el código en un elemento de WebView con el resaltado ya aplicado como marca HTML estática o con la ayuda de una biblioteca de resaltado de JavaScript, por ejemplo, highlight.js .

Actualización 1

Si el elemento de WebView es realmente inutilizable, incluso el elemento de Text simple con su soporte rudimentario de HTML debería ser suficiente para manejar el código fuente que resalta el caso de uso de datos si se alimenta con HTML estático.


en su archivo de aplicación:

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;

La función de plantilla para obtener objetos secundarios (devuelve la primera aparición de objectName, así que use nombres únicos para identificar objetos en sus archivos qml):

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; }

en su archivo qml use un TextEdit (dentro de un Flickable o lo que quiera) con la propiedad objectName establecida correctamente:

.... 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) } ....