wxWidgets使用wxStyledTextCtrl(Scintilla编辑器)的正确姿势

开发CuteMySQL/CuteSqlite开源客户端的时候,需要使用Scintilla编辑器,来高亮显示SQL语句,作为C/C++领域最成熟稳定又小巧的开源编辑器,Scintilla提供了强大的功能,wxWidgets对Scintilla进行包装后的是控件类:wxStyledTextCtrl。下面我们用正确的姿势来打开使用它。

先看下效果:

我们对该SQL编辑器的需求是:

1.显示行号

2.SQL语法高亮

3.输入SQL智能提示

4.适配DARK风格

好的,我们直接看下源码,程序员还是代码说话,其他都是废话,不多说了。

一,初始化编辑器语法的代码

cpp 复制代码
void QSqlEditor::setupSqlSyntax(int nSize, const char* face)
{
	// - lex setup (lex语法解释器配置)
	SetLexer(wxSTC_LEX_SQL); // 选择SQL解释器
	// Divide each styling byte into lexical class bits (default: 5) and indicator
	// bits (default: 3). If a lexer requires more than 32 lexical states, then this
	// is used to expand the possible states.
	// 将每个样式字节划分为词法类位(默认值:5)和指示符位(默认值:3)。
	// 如果词法分析器需要超过 32 个词法状态,则用于扩展可能的状态。
	// SetStyleBitsEx(5);
	StyleSetForeground(wxSTC_STYLE_DEFAULT, wxColour(255, 0, 0)); // 编辑器的文本默认的前景色(文本默认的颜色)
	StyleSetBackground(wxSTC_STYLE_DEFAULT, bkgColor); // 编辑器默认的背景色
	StyleClearAll(); // 清理编辑器所有的样式


	// - Other
	SetIndent(4); // 缩进4字符
	SetIndentationGuides(wxSTC_IV_LOOKBOTH); // 显示或隐藏缩进参考线
	UsePopUpEx(true); // 设置当用户在某些区域上按错鼠标按钮时是否自动显示弹出菜单
	
	// Error marker
	MarkerDefine(0, wxSTC_MARK_ARROW); // 设置用于箭头标记编号的符号,以及(可选)前景色(第三参数)和背景色(第四参数)
	MarkerSetBackground(0, wxColour(255, 255, 255)); // 设置第0个Marker的背景色
	MarkerSetForeground(0, wxColour(0, 0, 0)); // 设置第0个Marker的前景色

	// Font And Size 编辑器的字体和大小
	wxFont font(wxSize(0, nSize), wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, face);
	StyleSetFont(wxSTC_STYLE_DEFAULT, font);
	StyleSetSize(wxSTC_STYLE_DEFAULT, nSize);

	// - Margins
    // number margin 
	SetMarginType(0, wxSTC_MARGIN_NUMBER); // 行号边距,将边距设置为数字。此处设置第0个边距是行号数字
	SetMarginWidth(0, 37); // 设置边距宽度,第0个边距边宽
	// SetMarginBackground(0, bkgColor); // 注意,这里不生效的原因是SetMarginBackground只对SC_MARGIN_COLOUR类型的margin生效,这里第0边距是wxSTC_MARGIN_NUMBER
	

	// folding margin 折叠线边距
	SetMarginMask(1, wxSTC_MASK_FOLDERS);  // 设置第2个边距为折叠标记
	SetMarginWidth(1, 12); // 设置边距宽度,第2个边距边宽
	SetMarginSensitive(1, true); // 使第2个边距对鼠标单击敏感或不敏感。

	// - Choose folding icons 选择折叠的小图标
	MarkerDefine(wxSTC_MARKNUM_FOLDEROPEN, wxSTC_MARK_BOXMINUS); // 定义折叠线打开的图标:方框减号
	MarkerDefine(wxSTC_MARKNUM_FOLDER, wxSTC_MARK_BOXPLUS); // 定义折叠线收缩的图标:方框加号
	MarkerDefine(wxSTC_MARKNUM_FOLDERSUB, wxSTC_MARK_VLINE); // 定义子折叠线:VLINE
	MarkerDefine(wxSTC_MARKNUM_FOLDERTAIL, wxSTC_MARK_LCORNER); // 定义折叠线结束的图标:L型拐角
	MarkerDefine(wxSTC_MARKNUM_FOLDEREND, wxSTC_MARK_BOXPLUSCONNECTED); // 定义折叠线结束的图标:方框加号连接
	MarkerDefine(wxSTC_MARKNUM_FOLDEROPENMID, wxSTC_MARK_BOXMINUSCONNECTED); // 定义折叠线打开中间的图标:方框减号连接
	MarkerDefine(wxSTC_MARKNUM_FOLDERMIDTAIL, wxSTC_MARK_LCORNERCURVE); // 定义折叠线中间收尾的图标:T型拐角曲线

	// - Choose folding icon colours 选择折叠的小图标颜色
	MarkerSetForeground(wxSTC_MARKNUM_FOLDEROPEN, textColor); // 设置折叠线打开小图标的前景色
	MarkerSetBackground(wxSTC_MARKNUM_FOLDEROPEN, bkgColor); // 设置折叠线打开小图标的背景色
	MarkerSetForeground(wxSTC_MARKNUM_FOLDER, textColor); // 设置折叠线收缩小图标的前景色
	MarkerSetBackground(wxSTC_MARKNUM_FOLDER, bkgColor); // 设置折叠线收缩小图标的背景色
	MarkerSetForeground(wxSTC_MARKNUM_FOLDERSUB, textColor); // 设置子折叠线的背景色
	MarkerSetBackground(wxSTC_MARKNUM_FOLDERSUB, textColor); // 设置子折叠线的背景色
	MarkerSetForeground(wxSTC_MARKNUM_FOLDERTAIL, textColor); // 设置折叠线收缩结束小图标的背景色
	MarkerSetBackground(wxSTC_MARKNUM_FOLDERTAIL, textColor); // 设置折叠线收缩结束小图标的背景色
	MarkerSetForeground(wxSTC_MARKNUM_FOLDEREND, textColor); // 设置折叠线结束小图标的前景色
	MarkerSetBackground(wxSTC_MARKNUM_FOLDEREND, bkgColor); // 设置折叠线结束小图标的背景色
	MarkerSetForeground(wxSTC_MARKNUM_FOLDEROPENMID, textColor); // 设置折叠线打开中间小图标的前景色
	MarkerSetBackground(wxSTC_MARKNUM_FOLDEROPENMID, bkgColor); // 设置折叠线打开中间小图标的背景色
	MarkerSetForeground(wxSTC_MARKNUM_FOLDERMIDTAIL, textColor); // 设置折叠线中间收尾的小图标的前景色
	MarkerSetBackground(wxSTC_MARKNUM_FOLDERMIDTAIL, textColor); // 设置折叠线中间收尾的小图标的背景色

	// 行号文本颜色,仅仅对SetMarginType(0, wxSTC_MARGIN_NUMBER);起作用
	StyleSetForeground(wxSTC_STYLE_LINENUMBER, textColor);
	// 行号背景颜色	
	StyleSetBackground(wxSTC_STYLE_LINENUMBER, bkgColor2);
	// 折叠边背景色
	SetFoldMarginHiColour(true, bkgColor2);
	SetFoldMarginColour(true, bkgColor2);

	// - Set carlet 光标
	// Color of Carlet 光标的颜色
	SetCaretForeground(wxColour(0x00CEC0D6));
	// Width of Carlet 光标大小
	SetCaretWidth(2);
	// set the caret blinking time to 400 milliseconds 光标闪烁间隔
	SetCaretPeriod(400);

	// - Set caret line colour (设置光标所处行的颜色)
	SetCaretLineBackground(wxColour(38, 40, 46)); // 光标所处行的背景色
	SetCaretLineVisible(true); // 显示光标所处行

	// - Comment block (注释块)
	StyleSetForeground(wxSTC_SQL_DEFAULT, wxColour(0, 0, 0)); // 默认SQL的前景色
	StyleSetForeground(wxSTC_SQL_COMMENT, wxColour(32768)); // SQL注释的前景色

	// - Single comment line (注释行)
	StyleSetForeground(wxSTC_SQL_COMMENTLINE, wxColour(32768)); // 默认SQL注释的前景色

	// - SQL number 数字
	StyleSetForeground(wxSTC_SQL_NUMBER, wxColour(0x002AACB8)); // SQL数字的前景色
	StyleSetBold(wxSTC_SQL_NUMBER, true); // SQL数字加粗

	// - SQL string/operator/identifier (字符串/操作符/标识符)
	StyleSetForeground(wxSTC_SQL_STRING, wxColour(0x00cc99ff)); // SQL字符串的前景色
	StyleSetForeground(wxSTC_SQL_CHARACTER, wxColour(0x00cc99ff)); // SQL字符的前景色
	StyleSetForeground(wxSTC_SQL_OPERATOR, wxColour(0x00BCBEC4)); // SQL操作符的前景色
	StyleSetBold(wxSTC_SQL_OPERATOR, true); // SQL操作符加粗
	StyleSetForeground(wxSTC_SQL_IDENTIFIER, wxColour(0x00BCBEC4));// SQL标识符的前景色

	// - Color Of Selection (选中的颜色)
	SetSelBackground(true, wxColour(49, 106, 197)); // 选中项启用并设置背景色
	SetSelForeground(true, wxColour(255, 255, 255)); // 选中项启用并设置前景色

	// Set Keywords
	wxString keywords(sqlKeyWords);
	SetKeyWords(0, keywords);
	// Color Of Keyword
	StyleSetForeground(wxSTC_SQL_WORD, wxColour(0x00ff9966)); // 0x00CF8E6D
	StyleSetForeground(wxSTC_SQL_WORD2, wxColour(0x00ff9966));
	StyleSetForeground(wxSTC_SQL_USER1, wxColour(0x00ff9966));

	// 自动停顿的字符
	AutoCompStops(autoStopChars);

	// ignore the cmd key for CTRL+[key] 忽略CTRL+[key]
	int  n = static_cast<int>(sizeof(ignoreCtrlKey));
	for (int i = 0; i < n; i++) {
		CmdKeyClear(ignoreCtrlKey[i], wxSTC_KEYMOD_CTRL);
	}
	
	// Working Fold 
	SetProperty("fold", "1");
	SetProperty("fold.compact", "1");
	SetProperty("fold.html", "1");
	SetProperty("fold.html.preprocessor", "1");
	SetProperty("fold.comment", "1");
	SetProperty("fold.at.else", "1");
	SetProperty("fold.flags", "1");
	SetProperty("fold.preprocessor", "1");
	SetProperty("styling.within.preprocessor", "1");

	// set tab width to 4
	SetTabWidth(4);
}

二,未完待续。。。

三, 完整代码请看:

Github查看代码https://github.com/CuteBitSoft/CuteMySQL/tree/master/src/ui/common/editor

相关推荐
Quz12 分钟前
QScreen在Qt5.15与Qt6.8版本下的区别
c++·qt·ui
就叫飞六吧19 分钟前
Electron和C/C++开发桌面应用对比
c语言·开发语言·c++·visual studio
7yewh1 小时前
LeetCode 力扣 热题 100道(二十)三数之和(C++)
c语言·数据结构·c++·算法·leetcode
编程之路,妙趣横生2 小时前
list使用
c++
Hu_go__2 小时前
nano编辑器的使用
编辑器
sweetheart7-72 小时前
LeetCode5. 最长回文子串(2024冬季每日一题 35)
c++·算法·leetcode·动态规划·力扣
涵涵子RUSH3 小时前
预处理内容
开发语言·c++·算法
汝即来归3 小时前
如何实现对象的克隆?如何实现单例模式?
开发语言·javascript·jvm·c++
_nirvana_w_3 小时前
深入探索 C++ 编程技巧:从案例中学习高效实践
c++·学习·rpc