Подсветка синтаксиса Qt5 в QML - программирование
Подтвердить что ты не робот

Подсветка синтаксиса Qt5 в QML

Я работаю над презентацией QtQuick 2.0, и я хотел бы вставить некоторые примеры кода. возможно ли легко создать элемент qml подсветки синтаксиса.

Можете ли вы дать мне примеры технологий и идей о том, как их достичь.

Спасибо

4b9b3361

Ответ 1

Элемент Qt Quick TextEdit предоставляет свойство textDocument типа QQuickTextDocument. Это явно открыто, поэтому вы можете использовать QSyntaxHighlighter непосредственно с документом.

Документация QtQuick textEdit для Qt 5.3

Ответ 2

Нет очевидного способа добиться подсветки синтаксиса в QML.

Можно реализовать один собственный декларативный элемент, выполнив фактическое выделение с помощью QSyntaxHighlighter, но тогда нужно было бы определить свои собственные правила подсветки для языка исходного кода. Я бы не сделал такой код для презентации.

Вместо этого я бы отображал код в элементе WebView с подсветкой, уже примененной как статическая разметка HTML или с помощью JavaScript выделение библиотеки, для примера highlight.js.

Обновление 1

Если элемент WebView действительно непригоден, даже простой элемент Text с его рудиментарная поддержка HTML должна быть достаточной для обработки исходного кода, выделяющего usecase, если он загружен статическим HTML.

Ответ 3

в вашем файле приложения:

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;

Функция шаблона для получения дочерних объектов (возвращает первое появление objectName, поэтому используйте уникальные имена для идентификации объектов в ваших 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;
}

в вашем qml файле используйте TextEdit (внутри Flickable или что угодно) с правильным значением свойства objectName:

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

Посмотрите QSyntaxHighlighter.

Если вам нужен элемент QML, выполняющий подсветку синтаксиса, вы можете просто создать свой собственный, расширив QDeclarativeItem и используя утилиту выше.

Ответ 5

С помощью TextArea для форматирования можно использовать textFormat: TextEdit.RichText. Мы можем использовать TextArea::getText() для получения простого текста и установить TextArea::text с помощью богатого текста. Вот пример:

  • идентификаторы верхнего регистра (например, кнопка) в фиолетовый
  • идентификаторы нижнего регистра (например, x y z) в красный
  • превращает числа (например, 123 456) в синие.
  • и символы (например, = +;) остаются черными

Здесь фрагмент:

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