IT Notes

QSyntaxHighlighter: Подсветка синтаксиса в Qt

Если приложение использует текстовое поле для ввода данных, то заметно упростить жизнь пользователю может подсветка синтаксиса. Не зря этот прием весьма интенсивно используется во всех IDE и текстовых редакторах для программистов.

В Qt подсветку синтаксиса легко реализовать с помощью QSyntaxHighlighter, принцип работы которого основан на паттерне Посетитель.

Создадим приложение, которое умеет подсвечивать введенный фрагмент текста:

syntax-highlighter-demo

Заголовочный файл mainwidget.h:

#ifndef MAINWIDGET_H
#define MAINWIDGET_H

#include <QWidget>
#include <QSyntaxHighlighter>

namespace Ui {
class MainWidget;
}

class SyntaxHighlighter;

// ********************************************************************************

class MainWidget : public QWidget {
    Q_OBJECT

public:
    explicit MainWidget( QWidget* parent = 0 );
    ~MainWidget();

private slots:
    void onFind();

private:
    Ui::MainWidget* ui;

    SyntaxHighlighter* m_highlighter;
};

// ********************************************************************************

class SyntaxHighlighter : public QSyntaxHighlighter {

public:
    SyntaxHighlighter( QTextDocument* parent );

    void highlightBlock( const QString& text );

    void setHighlightedString( const QString& str );

private:
    QString m_highlightedString;

};

#endif // MAINWIDGET_H

Здесь мы определяем главный виджет приложения и нашу реализацию класса подсветки синтаксиса, которая наследует QSyntaxHighlighter. Обратите внимание, что в конструкторе SyntaxHighlighter передается указатель на QTextDocument, к которому и привязывается подсветка синтаксиса.

Непосредственная реализация подсветки сосредоточена в виртуальной функции highlightBlock(). А строка, которую нужно подсветить, мы задаем с помощью нашей функции setHighlightedString().

Реализация mainwidget.cpp:

#include "mainwidget.h"
#include "ui_mainwidget.h"

// ********************************************************************************

MainWidget::MainWidget( QWidget* parent ) :
    QWidget( parent ),
    ui( new Ui::MainWidget ) {
    ui->setupUi( this );

    m_highlighter = new SyntaxHighlighter( ui->txt->document() );

    connect( ui->bnFind, SIGNAL( clicked( bool ) ), SLOT( onFind() ) );
}

MainWidget::~MainWidget() {
    delete ui;
}

void MainWidget::onFind() {
    if( m_highlighter ) {
        m_highlighter->setHighlightedString( ui->edSearchInput->text() );
    }
}

// ********************************************************************************

SyntaxHighlighter::SyntaxHighlighter( QTextDocument* parent ) :
    QSyntaxHighlighter( parent ) {
}

void SyntaxHighlighter::highlightBlock( const QString& text ) {
    if( m_highlightedString.isEmpty() ) {
        return;
    }

    QTextCharFormat fmt;
    fmt.setBackground( Qt::yellow );

    const int LEN = m_highlightedString.length();
    for(
        int index = text.indexOf( m_highlightedString );
        0 <= index;
        index = text.indexOf( m_highlightedString, index + LEN )
    ) {
        setFormat( index, LEN, fmt );
    }
}

void SyntaxHighlighter::setHighlightedString( const QString& str ) {
    m_highlightedString = str;
    rehighlight();
}

Ключевой частью реализации является фрагмент:

купить дом на кипре пафос.

void SyntaxHighlighter::highlightBlock( const QString& text ) {
    if( m_highlightedString.isEmpty() ) {
        return;
    }

    QTextCharFormat fmt;
    fmt.setBackground( Qt::yellow );

    const int LEN = m_highlightedString.length();
    for(
        int index = text.indexOf( m_highlightedString );
        0 <= index;
        index = text.indexOf( m_highlightedString, index + LEN )
    ) {
        setFormat( index, LEN, fmt );
    }
}

Этой функции автоматически передается каждый блок текста (в простейшем случае по одной строке), в котором проводится поиск, и в случае обнаружения соответствия задается формат QTextCharFormat.

Также обратите внимание на следующую функцию:

void SyntaxHighlighter::setHighlightedString( const QString& str ) {
    m_highlightedString = str;
    rehighlight();
}

Вызов rehighlight() обеспечивает принудительный запуск процесса подсветки синтаксиса для вновь заданной строки.

QSyntaxHighlighter позволяет реализовать и более сложные виды подсветки. Например, обрабатывать случаи многострочной подсветки, как в случаях многострочных комментариев /* … */.

Исходники

 Скачать пример использования QSyntaxHighlighter

Похожие публикации