Qt5 Syntax Highlighting in QML

佐手、 提交于 2019-12-20 11:49:50

问题


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


来源:https://stackoverflow.com/questions/14791360/qt5-syntax-highlighting-in-qml

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!