Qt5语法在QML中突出显示

时间:2013-02-09 20:41:45

标签: syntax-highlighting qml qt5 qtquick2

我正在进行QtQuick 2.0演示,我想嵌入一些代码示例。是否可以轻松创建突出显示qml元素的语法。

您能否举例说明如何实现它的示例技术和想法。

由于

5 个答案:

答案 0 :(得分:8)

在QML中没有明显的方法来实现语法高亮。

可以实现一个自己的声明项,用QSyntaxHighlighter执行实际的突出显示,但是必须为所讨论的源代码的语言定义自己的突出显示规则。我不会为演示文稿做那么多的编码。

相反,我会在WebView项目中显示代码,突出显示已经应用为静态HTML标记,或者在JavaScript突出显示库的帮助下,用于示例highlight.js

更新1

如果WebView项确实无法使用,即使简单的Text项及其rudimentary HTML support应足以处理突出显示用例的源代码(如果使用静态HTML)。

答案 1 :(得分:8)

Qt Quick的TextEdit项会公开类型为textDocument的{​​{1}}属性。这是明确公开的,因此您可以直接使用QQuickTextDocument文档。

QtQuick textEdit documentation for Qt 5.3

答案 2 :(得分:5)

在你的app文件中:

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

答案 3 :(得分:3)

看看QSyntaxHighlighter

如果您需要使用语法突出显示的QML项目,您可以通过扩展QDeclarativeItem并使用上面的实用程序来创建自己的项目。

答案 4 :(得分:0)

使用TextArea可以使用textFormat: TextEdit.RichText进行格式化。我们可以使用TextArea::getText()获取纯文本,并使用富文本设置TextArea::text。这是一个模拟的例子:

  • 大写标识符(例如Button)变为紫色
  • 小写标识符(例如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;
            }
        }
    }