三站合一网站来个网站

当前位置: 首页 > news >正文

三站合一网站,来个网站,一站式手机网站制作,旅游景点网站建设设计说明开发CuteMySQL/CuteSqlite开源客户端的时候#xff0c;需要使用Scintilla编辑器#xff0c;来高亮显示SQL语句#xff0c;作为C/C领域最成熟稳定又小巧的开源编辑器#xff0c;Scintilla提供了强大的功能#xff0c;wxWidgets对Scintilla进行包装后的是控件类#xff1a;… 开发CuteMySQL/CuteSqlite开源客户端的时候需要使用Scintilla编辑器来高亮显示SQL语句作为C/C领域最成熟稳定又小巧的开源编辑器Scintilla提供了强大的功能wxWidgets对Scintilla进行包装后的是控件类wxStyledTextCtrl。下面我们用正确的姿势来打开使用它。 先看下效果 我们对该SQL编辑器的需求是 1.显示行号 2.SQL语法高亮 3.输入SQL智能提示 4.适配DARK风格 好的我们直接看下源码程序员还是代码说话其他都是废话不多说了。 一、声明wxStyledTextCtrl的子类QSqlEditor #pragma once #include wx/stc/stc.h #include vectorclass QSqlEditor : public wxStyledTextCtrl {…// 重要函数一初始化编辑器适配SQL语法高亮行号等void setupSqlSyntax(int nSize, const char* face);// 重要函数二自动弹出智能提示参数tags为表名视图字段名函数存储过程等void autoShow(const std::vectorstd::string tags);// 重要函数三自动替换光标当前单词void autoReplaceWord();private:……}; 二、初始化编辑器适配SQL语法 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(); // 清理编辑器所有的样式// - OtherSetIndent(4); // 缩进4字符SetIndentationGuides(wxSTC_IV_LOOKBOTH); // 显示或隐藏缩进参考线UsePopUpEx(true); // 设置当用户在某些区域上按错鼠标按钮时是否自动显示弹出菜单// Error markerMarkerDefine(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); // 定义子折叠线:VLINEMarkerDefine(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 KeywordswxString keywords(sqlKeyWords);SetKeyWords(0, keywords);// Color Of KeywordStyleSetForeground(wxSTC_SQL_WORD, wxColour(0x00ff9966)); // 0x00CF8E6DStyleSetForeground(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_castint(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 4SetTabWidth(4); } 上述初始化代码实现了SQL语法高亮行号折叠线以及适配DARK风格的功能。因此我们的4个需求已经实现了3个下面我们再用代码实现智能提示。 三、智能提示 智能提示我们首先需要一个外层QSqlEditor的类QueryPageEditor该类主要的作用 1.创建编辑器并显示到界面上。 2.捕捉QSqlEditor的各类事件。 3.调用QSqlEditor::autoShow函数实现智能提示。 我们通过捕捉wxStyledTextCtrl的EVT_STC_AUTOCOMP_SELECTION事件来实现智能提示。声明的代码简略如下 class QueryPageEditor : public QPanelDatabaseSupplier {DECLARE_EVENT_TABLE() public:… private:…// 编辑器QSqlEditor* editor;// 创建编辑器void createEditor();// 响应EVT_STC_CHARADDED字符输入智能提示void OnStcCharAdded(wxStyledTextEvent event);// 响应EVT_STC_AUTOCOMP_SELECTION自动替换当前单词void OnAutoCSelection(wxStyledTextEvent event); }// 事件表 BEGIN_EVENT_TABLE(QueryPageEditor, wxPanel)…EVT_STC_CHARADDED(Config::DATABASE_QUERY_EDITOR_ID, OnStcCharAdded) // 字符输入 EVT_STC_AUTOCOMP_SELECTION(Config::DATABASE_QUERY_EDITOR_ID, OnAutoCSelection) // 提示选择… END_EVENT_TABLE()// 创建创建编辑器 void QueryPageEditor::createEditor() {…editor new QSqlEditor();editor-Create(this, Config::DATABASE_QUERY_EDITOR_ID, wxDefaultPosition, wxDefaultSize, wxNO_BORDER | wxCLIP_CHILDREN);editor-setup(12, FN(Courier New).c_str());editor-SetFocus();… }// 响应EVT_STC_CHARADDED字符输入智能提示 void QueryPageEditor::OnStcCharAdded(wxStyledTextEvent event) {wxString line, preline, word;line editor-GetCurLine();if (line.empty()) {return ;}preline editor-getPrePositionTextOfCurLine();word editor-getCurWord();size_t curPosInLine editor-getCurPosInLine();std::vectorstd::string tags delegate-getTags(line.ToStdString(), preline.ToStdString(), word.ToStdString(), curPosInLine);editor-autoShow(tags); }// 响应EVT_STC_AUTOCOMP_SELECTION自动替换当前单词 void QueryPageEditor::OnAutoCSelection(wxStyledTextEvent event) {wxString selText editor-GetSelectedText();if (selText.empty()) {editor-autoReplaceWord();return;}if ((char)selText.at(0) (char)selText.Last() ) {editor-autoReplaceSelectTag();return;}editor-autoReplaceWord(); } 然后我们再看下上述类调用两个编辑器实现的函数 editor-autoShow(tags); // 参数tags : 要提示的单词比如表名函数字段名等 editor-autoReplaceWord(); // 自动替换光标当前的单词 // 自动提示参数tags : 要提示的单词比如表名函数字段名等 void QSqlEditor::autoShow(const std::vectorstd::string tags) {if (tags.empty()) {return;}size_t n tags.size();size_t sum 0;std::for_each(tags.begin(), tags.end(), sum {sum str.size();});char* itemList new char[tags.size() sum];memset(itemList, 0, tags.size() sum);char * ptr itemList;for (size_t i 0; i n; i) {std::string tag tags.at(i);if (i n - 1) {tag separator;}memcpy(ptr, tag.c_str(), tag.size());ptr tag.size();}AutoCompSetSeparator(separator);AutoCompSetIgnoreCase(true);AutoCompSetCaseInsensitiveBehaviour(1);AutoCompStops(autoStopChars);AutoCompShow(0, itemList);delete[] itemList; }// 自动替换光标当前的单词 void QSqlEditor::autoReplaceWord() {int curPos GetCurrentPos();int start WordStartPosition(curPos, true);int end WordEndPosition(curPos, true);SetSelection(start, end);wxString text AutoCompGetCurrentText();replaceSelText(text);AutoCompCancel(); }好了最后一个需求输入SQL智能提示也完成了。  四, 完整代码 Github - 类QSqlEditor代码https://github.com/CuteBitSoft/CuteMySQL/tree/master/src/ui/common/editor Github - 类QueryPageEditor代码https://github.com/CuteBitSoft/CuteMySQL/tree/master/src/ui/database/rightview/page/editor