На этом шаге рассмотрим добавление расцветки синтаксиса QTextEdit.
Расцветка и форматирование способствуют более удобному восприятию структуры текста программы. Добавить расцветку синтаксиса в QTextEdit очень просто, для этого нужно унаследовать класс QSyntaxHighlighter и реализовать в унаследованном классе метод highlightBlock().
Следующий простой пример выделяет цифры в тексте красным цветом:
/*virtual*/ void MyHighlighter::highlightBlock(const QString& str) { for (int i = 0; i < str.length(); ++i) { if (str.at(i).isNumber()) { setFormat(i, 1, Qt::red); } } }
В метод highlightBlock() передается одна строка текста. В первом параметре метода setFormat() передаем стартовое значение, второй параметр задает количество символов (в нашем случае 1), а в последнем параметре передаем цвет для расцветки (в нашем случае Qt::red). Вместо цвета в последнем параметре можно также передавать и шрифт (QFont).
Для того чтобы применить объект класса расцветки к объекту QTextEdit, нужно при создании передать ему указатель на объект QTextDocument. Например:
MyHighlighter* pHighlighter = new MyHighlighter(ptxt->document());
Как видно из примера, для применения расцветки синтаксиса нужен указатель на объект класса QTextDocument, а это значит, что применение расцветки не ограничивается только классом QTextEdit, и ее можно применять ко всем классам, имеющим в своем распоряжении объект класса QTextDocument. В число таких классов входят, например, QTextBrowser, QTextFrame, QTextTable, класс элемента текста QGraphicsTextItem графического представления и другие классы.
В следующем примере реализуем виджет, который делает расцветку программ на языке C++ в стиле Borland (рис. 1).
Рис.1. Пример расцветки текста
В листинге приводится текст заголовочного файла:
#ifndef SYNTAXHIGHLIGHTER_H #define SYNTAXHIGHLIGHTER_H #include <QSyntaxHighlighter> class QTextDocument; //класс SyntaxHighlighter наследуется от класса QSyntaxHighlighter class SyntaxHighlighter: public QSyntaxHighlighter { Q_OBJECT private: QStringList m_lstKeywords; protected: //определены перечисления NormalState, //InsideCStyleComment и InsideCString, //они нам понадобятся далее для определения текущего состояния фрагмента enum { NormalState = -1, InsideCStyleComment, InsideCString }; //перегружаем метод highlightBlock(), который нам //необходим для реализации собственной расцветки синтаксиса virtual void highlightBlock(const QString&); //метод getKeyword() будет давать ответ на вопрос, //является ли строка на указанной позиции ключевым //словом языка C++ или определением Qt QString getKeyword(int i, const QString& str) const; public: //конструктор SyntaxHighlighter(QTextDocument* parent = 0); }; #endif // SYNTAXHIGHLIGHTER_H
Приведем текст файла main.cpp:
#include <QApplication> #include <QTextEdit> #include <QFont> #include <QPalette> #include <QFile> #include "SyntaxHighlighter.h" int main (int argc, char** argv) { QApplication app(argc, argv); app.setApplicationDisplayName("Расцветка текста"); //создаем виджет txt класса QTextEdit QTextEdit txt; //создаем объект шрифта fnt QFont fnt("Lucida Console", 9, QFont::Normal); //устанавливаем его в нашем редакторе вызовом метода //setDefaultFont() из объекта документа редактора txt.document()->setDefaultFont(fnt); //создаем объект расцветки синтаксиса созданного нами //класса SyntaxHighlighter и передаем ему в качестве //предка указатель на объект документа нашего редактора //этот объект позаботится об его уничтожении при своем разрушении new SyntaxHighlighter(txt.document()); //создаем объект палитры pal, он нам нужен, чтобы QPalette pal = txt.palette(); //установить цвет фона (темно-синий) по умолчанию pal.setColor(QPalette::Base, Qt::darkBlue); //установить цвет шрифта (желтый) по умолчанию pal.setColor(QPalette::Text, Qt::yellow); txt.setPalette(pal); //отображаем наш редактор вызовом метода show() txt.show(); //задаем его размеры методом resize() txt.resize(740, 480); //создаем объект файла с именем SyntaxHighlighter.cpp QFile file("SyntaxHighlighter.cpp"); //открываем файл для чтения file.open(QFile::ReadOnly); //его текст считывается методом readAll() и //устанавливается в редакторе вызовом метода setPlainText() txt.setPlainText(QLatin1String(file.readAll())); return app.exec(); }
Приведем текст файла SyntaxHighlighter.cpp:
#include "SyntaxHighlighter.h" //в конструкторе мы инициализируем объект списка //m_lstKeywords ключевыми словами SyntaxHighlighter::SyntaxHighlighter(QTextDocument* parent/*= 0*/) : QSyntaxHighlighter(parent) { m_lstKeywords << "foreach" << "bool" << "int" << "void" << "double" << "float" << "char" << "delete" << "class" << "const" << "virtual" << "mutable" << "this" << "struct" << "union" << "throw" << "for" << "if" << "else" << "false" << "namespace" << "switch" << "case" << "public" << "private" << "protected" << "new" << "return" << "using" << "true" << "->" << ">>" << "<<" << ">" << "<" << "(" << ")" << "{" << "}" << "[" << "]" << "+" << "-" << "*" << "/" << "=" << "!" << "." << "," << ";" << ":" << "&" << "emit" << "connect" << "SIGNAL" << "|" << "SLOT" << "slots" << "signals"; } /*В метод highlightBlock() передается только одна строка текста, но не все концепции синтаксиса ограничиваются одной строкой. Поэтому мы ввели для этих случаев три состояния:
- NormalState — нормальное состояние, при котором должна использоваться расцветка, задаваемая нашей палитрой;
- InsideCString — состояние, в котором текущая позиция находится внутри строки, в этом случае цвет текста должен быть бирюзовым Qt::cyan;
- InsideCStyleComment — состояние, когда текущая позиция находится в комментарии вида /*...*/, в этом случае цвет текста должен быть темно-серым Qt::darkGray.*/
Файлы приложения можно взять Предыдущий шаг
Содержание
Следующий шаг