Если приложение использует текстовое поле для ввода данных, то заметно упростить жизнь пользователю может подсветка синтаксиса. Не зря этот прием весьма интенсивно используется во всех IDE и текстовых редакторах для программистов. В Qt подсветку синтаксиса легко реализовать с помощью QSyntaxHighlighter, принцип работы которого основан на паттерне Посетитель.
Создадим приложение, которое умеет подсвечивать введенный фрагмент текста.
Заголовочный файл mainwidget.h:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
[crayon-6628f6289afd4939362820 inline="true" class="lang-cpp"]#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 |
[/crayon]
Здесь мы определяем главный виджет приложения и нашу реализацию класса подсветки синтаксиса, которая наследует
QSyntaxHighlighter. Обратите внимание, что в конструкторе
SyntaxHighlighter передается указатель на
QTextDocument, к которому и привязывается подсветка синтаксиса.
Непосредственная реализация подсветки сосредоточена в виртуальной функции highlightBlock(). А строка, которую нужно подсветить, мы задаем с помощью нашей функции setHighlightedString().
Реализация mainwidget.cpp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
[crayon-6628f6289afdd269282478 inline="true" class="lang-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(); } |
[/crayon]
Ключевой частью реализации является фрагмент:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
[crayon-6628f6289afe2707285644 inline="true" class="lang-cpp"]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 ); } } |
[/crayon]
Этой функции автоматически передается каждый блок текста (в простейшем случае по одной строке), в котором проводится поиск, и в случае обнаружения соответствия задается формат
QTextCharFormat.
Также обратите внимание на следующую функцию:
1 2 3 4 5 |
[crayon-6628f6289afe5110141223 inline="true" class="lang-cpp"]void SyntaxHighlighter::setHighlightedString( const QString& str ) { m_highlightedString = str; rehighlight(); } |
[/crayon]
Вызов
rehighlight() обеспечивает принудительный запуск процесса подсветки синтаксиса для вновь заданной строки.