Qt中文本编辑器实现语法高亮功能(Qscitinlla)

Qt中文本编辑器实现语法高亮功能(Qscitinlla)

Scintilla是一个免费、跨平台、支持语法高亮的编辑控件。它完整支持源代码的编辑和调试,包括语法高亮、错误指示、代码完成(code completion)和调用提示(call tips)。能包含标记(marker)的页边(margin)可用于标记断点、折叠和高亮当前行。而QScintilla是Scintilla在QT上的移植。使用该库可以更为方便的开发Qt程序。

下面以windows开发为例:

Qscitinlla下载地址: https://riverbankcomputing.com/software/qscintilla/download

解压,在Qt4Qt5目录,用QtCreator打开qscintilla.pro,构建项目。

生成qscintilla2_qt5.lib或.a文件(本例子使用Qt5.7.1  MSVC2013)

 

1、创建QWidget工程

在.pro文件添加头文件以及动态链接库的引用:

INCLUDEPATH += C:/Users/pan/Desktop/QScintilla_gpl-2.10.1/Qt4Qt5
LIBS += -LC:/Users/pan/Desktop/QScintilla_gpl-2.10.1/build-qscintilla-Desktop_Qt_5_7_1_MSVC2013_64bit-Debug/debug/ -lqscintilla2_qt5d

或者不用添加INCLUDEPATH,直接将Qt4Qt5目录中的Qsci目录拷贝到工程中。

 

2、添加用到的头文件

//QsciScintilla作为QWidget的控件,需要添加该控件的头文件
#include <Qsci/qsciscintilla.h>
//以python语法作为例子,该语法分析器的头文件
#include <Qsci/qscilexerpython.h>
//设置代码提示功能,依靠QsciAPIs类实现
#include <Qsci/qsciapis.h>

  

3、设置具体功能代码

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{

    QsciScintilla *editor=new QsciScintilla(this);
    //设置语法
    QsciLexerPython *textLexer = new QsciLexerPython;//创建一个词法分析器
    editor->setLexer(textLexer);//给QsciScintilla设置词法分析器

    //行号提示
    editor->setMarginType(0,QsciScintilla::NumberMargin);//设置编号为0的页边显示行号。
    editor->setMarginLineNumbers(0,true);//对该页边启用行号
    editor->setMarginWidth(0,15);//设置页边宽度
    //代码提示
    QsciAPIs *apis = new QsciAPIs(textLexer);
    apis->add(QString("import"));
    apis->prepare();

    editor->setAutoCompletionSource(QsciScintilla::AcsAll);   //设置源,自动补全所有地方出现的
    editor->setAutoCompletionCaseSensitivity(true);   //设置自动补全大小写敏感
    editor->setAutoCompletionThreshold(1);    //设置每输入一个字符就会出现自动补全的提示

    pLayout = new QVBoxLayout(this);
    pLayout->addWidget(editor);
    pLayout->setContentsMargins(0,0,0,0);


}

  

说明:

行号显示功能:

QsciScintilla左边可显示页边(Margins)和标记(Markers)。

页边是位于文本显示区左边的一竖条区域,它可以用于显示行号、书签、断点标记等, Scintilla最多可以有5个页边(从左到右的编号为0~4)。

标记用来标记文本位置,如显示自定义的内容,譬如断点、错误位置等等,对于具有折叠功能的,可以使用32种标记(0-31),如果编辑器要支持代码折叠功能,需要预留25-31,这7个作为专用折叠标记。

自动补全功能:

a 定义一个QsciAPIs类,构造函数中将父类指向你前面定义的lexer类。 
b 调用其中的类对应的add方法或者load方法想要补全的关键字。

对于补全的关键字比较少的可以通过add添加,如果补全内容比较多,可以通过load添加。

QsciAPIs*apis = new QsciAPIs(textLexer);  
if(!apis->load(QString("D://api.txt")))  
    QMessageBox::warning(this,QString("提示"),QString("读取文件失败"));  
else  
    apis->prepare();  

c 调用类对应的prepare方法来准备好关键字。 

d 在你前面定义的QsciScintilla类中的相关方法,常见的方法包括:

setAutoCompletionSource、setAutoCompletionCaseSensitivity、setAutoCompletionThreshold

其中,setAutoCompletionSource可设的属性包括:

枚举类型 描述
QsciScintilla::AcsNone 没有自动补全的资源,即禁用自动补全提示功能
QsciScintilla::AcsAll 所有可用的资源都要自动补全提示,包括当前文档中出现的名称和使用QsciAPIs类加入的名称
QsciScintilla::AcsDocument 当前文档中出现的名称都自动补全提示
QsciScintilla::AcsAPIs 使用QsciAPIs类加入的名称都自动补全提示

 

 至此,可以完成一个简单的python脚本编辑器。

<span>Qt中文本编辑器实现语法高亮功能(Qscitinlla)</span>

 

 

4、编码问题

Scintilla默认编码是ANSI ,所以输入中文字符会出现乱码

<span>Qt中文本编辑器实现语法高亮功能(Qscitinlla)</span>

 

可以给它设置为UTF-8,即添加代码:(顺便设置文本的字体)

//设置显示字体
editor->setFont(QFont("Courier New"));
//设置编码方式
editor->SendScintilla(QsciScintilla::SCI_SETCODEPAGE,QsciScintilla::SC_CP_UTF8);//设置编码为UTF-8

<span>Qt中文本编辑器实现语法高亮功能(Qscitinlla)</span>

 

5、高亮配色补充

然而,使用的过程中,对比一些其他的编辑器,发现存在问题:

该控件不支持python中的内置函数、以及一些编辑器通常把self也高亮实现。

可以看到源码中支持的高亮类型:

// Returns the foreground colour of the text for a style.
QColor QsciLexerPython::defaultColor(int style) const
{
    switch (style)
    {
    case Default:
        return QColor(0x80,0x80,0x80);

    case Comment:
        return QColor(0x00,0x7f,0x00);

    case Number:
        return QColor(0x00,0x7f,0x7f);

    case DoubleQuotedString:
    case SingleQuotedString:
        return QColor(0x7f,0x00,0x7f);

    case Keyword:
        return QColor(0x00,0x00,0x7f);

    case TripleSingleQuotedString:
    case TripleDoubleQuotedString:
        return QColor(0x7f,0x00,0x00);

    case ClassName:
        return QColor(0x00,0x00,0xff);

    case FunctionMethodName:
        return QColor(0x00,0x7f,0x7f);

    case Operator:
    case Identifier:
        break;

    case CommentBlock:
        return QColor(0x7f,0x7f,0x7f);

    case UnclosedString:
        return QColor(0x00,0x00,0x00);

    case HighlightedIdentifier:
        return QColor(0x40,0x70,0x90);

    case Decorator:
        return QColor(0x80,0x50,0x00);
    }

    return QsciLexer::defaultColor(style);
}

其中的关键字定义:

// The list of Python keywords that can be used by other friendly lexers.
const char *QsciLexerPython::keywordClass =
    "and as assert break class continue def del elif else except exec "
    "finally for from global if import in is lambda None not or pass "
    "print raise return try while with yield";

  

 

 

Enumerator

Default 

The default.

Comment 

A comment.

Number 

A number.

DoubleQuotedString 

A double-quoted string.

SingleQuotedString 

A single-quoted string.

Keyword 

A keyword.

TripleSingleQuotedString 

A triple single-quoted string.

TripleDoubleQuotedString 

A triple double-quoted string.

ClassName 

The name of a class.

FunctionMethodName 

The name of a function or method.

Operator 

An operator.

Identifier 

An identifier.

CommentBlock 

A comment block.

UnclosedString 

The end of a line where a string is not closed.

HighlightedIdentifier 

A highlighted identifier. These are defined by keyword set

  1. Reimplement keywords() to define keyword set 2.
Decorator 

A decorator.

可以看到,该插件中应该是不支持python的内置函数的,这个内置函数和版本有关。

在自己的python中输入dir(__builtins__),可将其重定向到文本中,记录好这些需要高亮的语句。

#################################

对于print,由于在python2中,print “xxx”是作为关键字存在的,而使用print(“xxx”)的方式其为一个内置函数。

故,在python中输入:

import keyword

print keywold.kwlist

  可以在输出结果中看到print,而内置函数中也可以看到。

 

#################################

 参考上表中对于HighligetedIdentifier的介绍,可以知道,其对于自定义的值,kewords()函数传递的set值为2,重写keywords()函数,定义类如下:

pythontest.h

class QsciLexerPythonTest : public QsciLexerPython
{
    //Q_OBJECT
public:
    const char *keywords(int set) const;
};

  

pythontest.cpp

const char * QsciLexerPythonTest::keywords(int set) const
{

    if(set == 2)
    {
        return "self str";
    }

    return QsciLexerPython::keywords(set);
}

  注意,继承的类中不要有Q_OBJECT宏,否则会出现:error LNK2001: 无法解析的外部符号

 在Widget类中定义颜色:

textLexer->setColor(QColor(Qt::gray),QsciLexerPython::Comment);    //设置自带的注释行为灰色
textLexer->setColor(QColor(Qt::black),QsciLexerPython::FunctionMethodName);
textLexer->setColor(QColor(Qt::black),QsciLexerPython::ClassName);
textLexer->setColor(QColor(Qt::darkBlue),QsciLexerPython::Keyword);

textLexer->setColor(QColor(Qt::red),QsciLexerPython::HighlightedIdentifier);

  

这样,对于self、str两个自定义的关键字就可以用红色高亮。

<span>Qt中文本编辑器实现语法高亮功能(Qscitinlla)</span>

 

 

 

 

 

 

可以看到,使用这个库开发是比较方便的,对比Qt自带的QSyntaxHighlighter控件要好很多!

 

 

  

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/119488.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • MemoryBarrier方法[通俗易懂]

    MemoryBarrier方法[通俗易懂]查了下MSDN的解释:MemoryBarrierisrequiredonlyonmultiprocessorsystemswithweakmemoryordering(forexample,asystememployingmultipleIntelItaniumprocessors).Syn…

  • serialized objects

    serialized objectsThisstartedagain…athreadfrom*****:WhatdoyouconsiderabestpracticeforserialVersionUID?T______________________________________________From:*******Sent:Thursday,Nov…

  • 在虚拟机上安装XP系统「建议收藏」

    在虚拟机上安装XP系统「建议收藏」WindowsXP番茄家园的安装点击”文件”–>”新建”–>”虚拟机”–>弹出”新建虚拟机向导”的欢迎界面.–>”下一步”配置你的新虚拟机,选择”典型”–>”下一步”选择客户机操作系统–>”MicrosoftWindows”-,版本:WindowsXPProfessional–>”下一…

  • ActivityManager_activity管理器

    ActivityManager_activity管理器ActivityManager在操作系统中有重要的作用,本文利用操作系统源码,逐步理清ActivityManager的框架,并从静态类结构图和动态序列图两个角度分别进行剖析,从而帮助开发人员加强对系统框架及进程通信机制的理解。ActivityManager的作用参照SDK的说明,可见ActivityManager的功能是与系统中所有运行着的Activity交互提供了接口,主要的接口围绕着运

  • java字符串分割split没内容_python字符串分割

    java字符串分割split没内容_python字符串分割Java中分割字符串的函数是split。  publicString[]split(Stringregex,intlimit),用Stringregex来分割字符串,返回值是字符串数组Stringword=”小王,小魏,小明,小红”;String[]words=word.split(“,”);//注意这里要用字符串数组接收System.out.println(words

  • 【Zigbee】进阶篇(1) Zigbee协议栈创建简单项目,协议栈、事件、消息学习[通俗易懂]

    【Zigbee】进阶篇(1) Zigbee协议栈创建简单项目,协议栈、事件、消息学习[通俗易懂]本篇文章:主要是协议栈的介绍,使用协议栈完成一个简单例子,协调器创建网络的相关问题,学会在协议栈中自定义事件等。正文如下:一、Zigbee协议栈1)Z-stack协议栈是什么?2)Zigbee协议栈分为应用层、网络层、MAC层、物理层.二、Z-stack协议栈1)安装配置协议栈2)创建协议栈项目3)信道4)事件5)消息

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号