QScintilla: подсвечиваем синтаксис в приложении

Привет, $username!

UPD: вторая и третья часть цикла о QScintilla.

Сегодня я хочу рассказать вам про отличный проект — QScintilla, который подсвечивает синтаксис кода в Qt-приложениях. Нередко возникает необходимось что-то подсвечивать. Например: C++, Bash, PHP, Diff… Этот список можно продолжать и продолжать. Но вот решение: порт Scintilla на Qt: QScintilla.

В этом посте я расскажу как установить и пользоваться QScintilla в своих приложениях на примере Ubuntu Linux.

Установка


Начнем, пожалуй, с самого главного — с установки. Предлагаю собрать QScintilla и установить ее в систему. Для этого скачаем тарбол qscintilla. Распаковываем его в нужную нам папку. Теперь консолька. Выполняем пару нехитрых комманд:

cd Qt4
qmake
make
sudo make install

Отличненько. Если вы все сделали правильно, у вас в системе появиться libqscintilla2.so

Открываем Qt Creator


Ура! Можно начинать кодить. Открывааем криейтор — создаем проект. Теперь добавляем в профайл строчку:

LIBS += -lqscintilla2

Несложно догадаться что эта строчка подключает QScintilla. Теперь перейдем непосредственно к кодингу проекта. Конструктор mainwindow.cpp:

#include <QtGui>

#include <Qsci/qsciscintilla.h>
#include <Qsci/qscilexercpp.h>

#include "mainwindow.h"

MainWindow::MainWindow()
{
    textEdit = new QsciScintilla; // инитилизируем редактор
    textEdit->setUtf8(true); // мы же хотим читать кириллицу
    setCentralWidget(textEdit); // задаем редактор в ui
    QsciLexerCPP * lexCpp = new QsciLexerCPP(this); // создаем лексер (схему подсветки)
    textEdit->setLexer(lexCpp); // задаем С++ лексер нашему редактору
}

Не забываем добавить в MainWindow:

private:
    QSciScintilla *textEdit;


Можно смело компилировать — мы видим редактор который подсвечивает C++ код на ура.



Пока это не выглядит очень круто, но это только пока. А теперь начинаеться самое интересное. Предлагаю расширить наш редактор и украсить его. Дописываем в конструктор:

    //! Текущая строка кода и ее подсветка
    textEdit->setCaretLineVisible(true);
    textEdit->setCaretLineBackgroundColor(QColor("gainsboro"));

    //! Выравнивание
    textEdit->setAutoIndent(true);
    textEdit->setIndentationGuides(false);
    textEdit->setIndentationsUseTabs(true);
    textEdit->setIndentationWidth(4);

    //! margin это полоска слева, на которой обычно распологаются breakpoints
    textEdit->setMarginsBackgroundColor(QColor("gainsboro"));
    textEdit->setMarginLineNumbers(1, true);
    textEdit->setMarginWidth(1, 50);

    //! Авто-дополнение кода в зависимости от источника
    textEdit->setAutoCompletionSource(QsciScintilla::AcsAll);
    textEdit->setAutoCompletionCaseSensitivity(true);
    textEdit->setAutoCompletionReplaceWord(true);
    textEdit->setAutoCompletionUseSingle(QsciScintilla::AcusAlways);
    textEdit->setAutoCompletionThreshold(0);

    //! Подсветка соответствий скобок
    textEdit->setBraceMatching(QsciScintilla::SloppyBraceMatch);
    textEdit->setMatchedBraceBackgroundColor(Qt::yellow);
    textEdit->setUnmatchedBraceForegroundColor(Qt::blue);


Теперь получаем относительно рабочий редактор, который даже что-то умеет. Конечно у него есть много недостатков, но все они тоже исправимы.



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

Материалы



  • Исходники приложения которого мы с вами написали: qscintilla-demo
  • Оффициальная документация qscintilla


Спасибо за внимание, и удачного вам кодинга!

Similar posts

AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 28

    0
    Если что-то надо подсветить, использую QSyntaxHighlighter

    А это уже больше компонент, с разными плюшками
      +2
      Ну вы знаете, QSyntaxHighlighter это мягко говоря, мало. Он годится только для чего-то самого простого. Вы что сами пишите подсветку HTML или PHP и т.д?
      0
      пока что да, все что требуется это реализовать метод highlightBlock
      но и QScintilla, достаточно интересен, о нем не знал до вашей статьи
        +1
        Если эта статья увенчается успехом, я начну цикл про QScintilla. Так что, если повезет, узнаете еще).
        0
        Сегодня я хочу рассказать вам про отличный проект — QScintilla
        По моему личному опыту и моему личному мнению, могу сказать, что он вовсе не отличен. Намучился с ним немало — многие вещи кроме как костылями или правками в коде не решить. В общем, кроме негатива это название теперь ничего не вызывает.

        Если писать что-то серьёзное — лучше использовать «чистое» API Scintill'ы.
          0
          Не спорю. Но лично мне писать на чистом SCI пока сложно. Я наверное не настолько сильный программист, чтобы это реализовать на «низком» уровне.

          А насчет костылей — это правда). Есть моменты.
          +1
          А автодополнение будет?
            +2
            Да. QSciAPIs я распишу в следущих выпусках.
              0
              * следующих
            +1
            В тред призывается Mezomish, автор JuffEd. :)
              0
              JuffEd действительно написан с QScintilla. Причем довольно хорошо написан. Хороший проект — только вот нету изюминки, на мой взгляд.
                +1
                Вызывали? :)

                Проект QScintilla действительно хороший. Не без багов, со своими проблемами, порой даже со сломанным ABI между версиями, но практически безальтернативный по фичам и количеству поддерживаемых языков. Документация неплохая, но часто неполная. Некоторые фичи (по сравнению с оригинальной Scintilla) отсутствуют, мне порой приходилось курить API оригинальнй Scintilla и делать «raw» вызовы (удовольствие, прямо скажем, сравнимое с использованием чистого WinAPI ), но авторы порта довольно оперативно реагируют в мейл-листе и добавляют востребованные фичи. Патчи тоже принимают.
                  0
                  Можете подсказать тогда. Как проставить QPixmap для кастомного элемента в UserList?
                    0
                    К сожалению, не могу — я пока что не использовал изображения в UserList-ах.
                    0
                    Или, например, как решить эту проблему. :)
                      +1
                      Поправят скоро, я переписывался с парнем оттуда. А вообще, вы часто нажимаете мышкой в списке автодополнения? Я например все выбираю стрелочками.

                      P.S. А вообще нечего на windows сидеть)).
                        +1
                        Ну, я нечасто, а вот пользовательская аудитория негодует. :)

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

                        qsciscintilla.cpp, QsciScintilla::getIndentState(int):

                            char *text = new char[(epos - spos + 1) * 2];
                            // ...
                            if (bstart_off >= 0 && !bend_words)
                                for (int i = bstart_off * 2; text[i] != '\0'; i += 2)
                                    if (!QChar(text[i]).isSpace())
                                        return isNone;
                            // ...
                            delete[] text;
                        
                          +1
                          Да. Этот код присутствует в коде последнего стабл-релиза.
                            0
                            Такие вещи Andrey2008 любит рассматривать :)
                              0
                              Читал его статьи, довольно занимательно. :)
                          0
                          >Или, например, как решить эту проблему. :)

                          А тут как раз всё ясно: или ждать, когда пофиксят, или пофиксить самому и отправить патч :)
                            0
                            Ну, рано или поздно мне придётся этим заняться. Но, поскольку на данный момент есть вещи более приоритетные, то пока есть время ждать и надеяться. :)
                      0
                      А как насчет сворачивания блоков? Без проблем или с костылями?
                        0
                        Без проблем. Folding работает отлично. Я сейчас пишу IDE — да, там нужны модификации в самой qscintilla (мне не нравиться полоска черная:) ).
                          0
                          Встречал всякие редакторы, где то комментарии не хотят сворачиваться, то некоторые блоки типа for (при этом сворачиваются методы, условия и т.п.).
                          Это все настраивается (какие блоки можно сворачивать)?
                            0
                            Нет. Это не настраиваится. Она может сворачивать все (в зависимости от лексера).
                        0
                        А к виндовой версии Qt реально подключить этот модуль?
                          0
                          Конечно. Эго только надо собрать.

                        Only users with full accounts can post comments. Log in, please.