1 //語法高亮---QSyntaxHighlighter 2 //highlighter.h 3 class Highlighter : public QSyntaxHighlighter //定義一個類繼承自QSyntaxHightliaghter 4 { 5 Q_OBJECT //Qt宏定義,使用Qt元編程 6 7 public: 8 Highlighter(QTextDocument *parent = 0); //構造函數,傳遞一個QTextDocument對象給其父類 9 10 protected: 11 void highlightBlock(const QString &text) Q_DECL_OVERRIDE; //塊高亮使用的函數,自動調用 12 13 private: 14 struct HighlightingRule //語法規則結構體,包含正則表達式模式串和匹配的樣式 15 { 16 QRegExp pattern; 17 QTextCharFormat format; 18 }; 19 QVector<HighlightingRule> highlightingRules; //規則的集合,可以定義多個高亮規則 20 21 QRegExp commentStartExpression; //注釋的高亮,使用highliangBlock()匹配,下文提到 22 QRegExp commentEndExpression; 23 24 QTextCharFormat keywordFormat; //高亮樣式,關鍵詞,一下顧名思義 25 QTextCharFormat classFormat; 26 QTextCharFormat singleLineCommentFormat; 27 QTextCharFormat multiLineCommentFormat; 28 QTextCharFormat quotationFormat; 29 QTextCharFormat functionFormat; 30 }; 31 32 //highlighter.c 33 #include "highlighter.h" 34 35 Highlighter::Highlighter(QTextDocument *parent) //構造函數,主要是對詞語的高亮 36 : QSyntaxHighlighter(parent) 37 { 38 HighlightingRule rule; //高亮規則 39 40 keywordFormat.setForeground(Qt::darkBlue); //設定關鍵詞的高亮樣式 41 keywordFormat.setFontWeight(QFont::Bold); 42 QStringList keywordPatterns; //關鍵詞集合,關鍵都以正則表達式表示 43 keywordPatterns << "\\bchar\\b" << "\\bclass\\b" << "\\bconst\\b" 44 << "\\bdouble\\b" << "\\benum\\b" << "\\bexplicit\\b" 45 << "\\bfriend\\b" << "\\binline\\b" << "\\bint\\b" 46 << "\\blong\\b" << "\\bnamespace\\b" << "\\boperator\\b" 47 << "\\bprivate\\b" << "\\bprotected\\b" << "\\bpublic\\b" 48 << "\\bshort\\b" << "\\bsignals\\b" << "\\bsigned\\b" 49 << "\\bslots\\b" << "\\bstatic\\b" << "\\bstruct\\b" 50 << "\\btemplate\\b" << "\\btypedef\\b" << "\\btypename\\b" 51 << "\\bunion\\b" << "\\bunsigned\\b" << "\\bvirtual\\b" 52 << "\\bvoid\\b" << "\\bvolatile\\b"; 53 foreach (const QString &pattern, keywordPatterns) { //添加各個關鍵詞到高亮規則中 54 rule.pattern = QRegExp(pattern); 55 rule.format = keywordFormat; 56 highlightingRules.append(rule); 57 } 58 59 classFormat.setFontWeight(QFont::Bold); //添加Qt的類到高亮規則中 60 classFormat.setForeground(Qt::darkMagenta); 61 rule.pattern = QRegExp("\\bQ[A-Za-z]+\\b"); 62 rule.format = classFormat; 63 highlightingRules.append(rule); 64 65 singleLineCommentFormat.setForeground(Qt::red); //單行注釋 66 rule.pattern = QRegExp("//[^\n]*"); 67 rule.format = singleLineCommentFormat; 68 highlightingRules.append(rule); 69 70 multiLineCommentFormat.setForeground(Qt::red); //多行注釋,只設定了樣式,具體匹配在highlightBlock中設置 71 72 73 quotationFormat.setForeground(Qt::darkGreen); //字符串 74 rule.pattern = QRegExp("\".*\""); 75 rule.format = quotationFormat; 76 highlightingRules.append(rule); 77 78 79 functionFormat.setFontItalic(true); //函數 80 functionFormat.setForeground(Qt::blue); 81 rule.pattern = QRegExp("\\b[A-Za-z0-9_]+(?=\\()"); 82 rule.format = functionFormat; 83 highlightingRules.append(rule); 84 85 86 commentStartExpression = QRegExp("/\\*"); //多行注釋的匹配正則表達式 87 commentEndExpression = QRegExp("\\*/"); 88 } 89 90 91 void Highlighter::highlightBlock(const QString &text) //應用高亮規則,也用於區塊的高亮,比如多行注釋 92 { 93 foreach (const HighlightingRule &rule, highlightingRules) { //文本采用高亮規則 94 QRegExp expression(rule.pattern); 95 int index = expression.indexIn(text); 96 while (index >= 0) { 97 int length = expression.matchedLength(); 98 setFormat(index, length, rule.format); 99 index = expression.indexIn(text, index + length); 100 } 101 } 102 103 setCurrentBlockState(0); //以下是多行注釋的匹配 104 105 int startIndex = 0; 106 if (previousBlockState() != 1) 107 startIndex = commentStartExpression.indexIn(text); 108 109 while (startIndex >= 0) { 110 int endIndex = commentEndExpression.indexIn(text, startIndex); 111 int commentLength; 112 if (endIndex == -1) { 113 setCurrentBlockState(1); 114 commentLength = text.length() - startIndex; 115 } else { 116 commentLength = endIndex - startIndex 117 + commentEndExpression.matchedLength(); 118 } 119 setFormat(startIndex, commentLength, multiLineCommentFormat); 120 startIndex = commentStartExpression.indexIn(text, startIndex + commentLength); 121 } 122 } 123 //used in editor 124 void MainWindow::setupEditor() 125 { 126 QFont font; 127 font.setFamily("Courier"); 128 font.setFixedPitch(true); 129 font.setPointSize(10); 130 131 editor = new QTextEdit; 132 editor->setFont(font); 133 134 highlighter = new Highlighter(editor->document()); //調用方法,新建對象並傳遞document 135 136 QFile file("mainwindow.h"); 137 if (file.open(QFile::ReadOnly | QFile::Text)) 138 editor->setPlainText(file.readAll()); 139 }
效果: