QSyantaxHighlighterでテキストのハイライト表示
テキストエディターで特定のワードを色付けしたり太字にしたりしてハイライト表示したいときはQSyantaxHighlighterを使うと楽にテキストを装飾できます。
QSyantaxHighlighterはそれ単体で使うのではなく、QTextEditなどのエディタークラスと一緒に利用します。
手順は次の通りです。
- QSyantaxHighlighterクラスの拡張
- エディターにQSyantaxHighlighterを実装する
QSyantaxHighlighterクラスの拡張
初めに次のようにQSyantaxHighlighterクラスを拡張したハイライタークラスを作ります。
ここでは、MySyantaxHighlighterというクラスを作成します。
MySyntaxHighlighter.hclass MySyntaxHighlighter : public QSyntaxHighlighter { Q_OBJECT public: explicit EditorHighlighter(QTextDocument *document) : QSyntaxHighlighter(document){} virtual ~EditorHighlighter(){} virtual void highlightBlock(const QString &text) { //強調表示する単語の文字フォーマット QTextCharFormat format; format.setForground(Qt::red); //文字色を赤色にする format.setFontWeight(QFont::Bold); //太字にする。 QStringList keyWordPatterns << "\\bchar\\b" << "\\bshort\\b" << "\\bint\\b" << "\\blong\\b" << "\\bfloat\\b" << "\\bdouble\\b"; //強調する単語のパターン foreach(const QString &pattern, keyWordPatterns){ QRegExp regexp(pattern); int index = regexp.indexIn(text); while(index >= 0){ int length = regexp.matchedLength(); setFormat(index, length, format); //赤色で強調表示 index = regexp.indexIn(text, index + length); } } } };
エディタークラスに何か入力されるたびにsetFormat関数が呼ばれ、パターンに一致した文字列を色や形などのフォーマットを変えて強調表示することができます。
文字列のパターン検索にはQRegExpクラスを使い、正規表現を利用して単語単位で強調表示する文字列を探しています。例えば"\\bchar\\b"という正規表現を使うと"char"という文字列が文章全体で単語(前後にスペースがある状態)として存在しているときだけにマッチさせることができます。
QTexEditにハイライターを実装する
拡張したハイライターをQTextEditなどに実装することで初めてテキストを強調表示することができます。
実装するといっても次のようにQTextEditが持っているQTextDocumentをハイライターに渡すだけです。
#include "MySyntaxHighlighter.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); QTextEdit editor(0); MySyntaxHighlighter highlighter = new MySyntaxHighlighter(editor.document()); //エディターのQTextDocumentオブジェクトを渡す editor.show(); return app.exec(); }
このようにハイライターを実装したエディターで特定のワードを入力すると次のようにその単語がハイライトして表示されます。
正規表現のパターン
ハイライターのパターン一致に使われるQRegExpクラスでよく使う便利な正規表現には次のものがあります。
・部分一致
文字列全体の中で部分一致させるには次のように"\b"または"\B"を使います。
QString str = "Hello Qt"; ///検索される文字列 QRegExp regexp1("\\bHe\\b"); regexp1.indexIn(str); ///"He"は単語単位で含まれていないから-1が返る QRegExp regexp2("\\bHello\\b"); regexp2.indexIn(str); ///"Hello"は単語として含まれているから一致したインデックス番号(0)が返る QRegexp regexp3("\\BHe\\B"); regexp3.indexIn(str); ///"He"は単語の一部だから一致する QRegExp regexp4("\\BHello\\B"); ///"Hello"は単語だから一致しない
"\b"を使った場合は単語単位、"\B"を使った場合は文字列に検索文字列が含まれていれば一致することになります。
・ワイルドカード
"*"や"?"などのワイルドカードも使うことができます。ただしその場合はQRegExpクラスのsetPatternSyantax関数にQRegExp::Wildcardを渡す必要があります。
ワイルドカードを使えばある文字列と文字列の間にある文字列をあいまい検索でき、"*"の場合は文字数が不定で、"?"を使った場合は"?"の文字数分だけあいまい検索できます。
QString str = "Wildcard Text"; QRegExp regexp1("W*d"); regexp1.setPatternSyantax(QRegExp::Wildcard); regexp1.indexIn(str); ///"Wildcard"と一致 QRegExp regexp2("Wi??card"); regexp2.setPatternSyantax(QRegExp::Wildcard); regexp2.indexIn(str); ///"Wildcard"と一致
以上、テキストのハイライト表示の方法でした。では、また!