源代码已上传,有需要可以下载:
源代码
0.开发环境
看了那么多博客,没几个说明自己的开发环境的,所以开头先说明一下这个代码编辑器的开发环境
系统 deepin15.5
内核
qt版本 5.8.0
1.编辑器预览
下面进入正文,先来看一下这个编辑器的基本情况
有基本的语法高亮\自动补全\换行缩进\括号匹配.
菜单栏有基本功能的实现,能选择不同的语言来进行语法高亮.
基本上实现了一个代码编辑器的基本功能.
接下来将从代码编辑器主体的实现和菜单栏的实现开始说.
2.项目的创建
建立一个Qt Widgets Application.
设置默认.
3.QScintilla库介绍
语法高亮\自动补全\换行缩进\括号匹配\行号显示的功能主要由一个重要的外部库实现–Scintilla
官网:https://www.scintilla.org
Qt下这个库叫QScintilla
下载:http://pyqt.sourceforge.net
说明文档:http://pyqt.sourceforge.net/Docs/QScintilla2/index.html
功能的实现主要参照了两人的博客,在此非常感谢(ps:两人的QScintilla都打错了)
Qt文本高亮控件Qscitinlla的用法
Qt中文本编辑器实现语法高亮功能(Qscitinlla)
在此要修正一下两个博客说到的QScintilla的配置问题
在.pro文件添加头文件以及动态链接库的引用:
INCLUDEPATH += Qt4Qt5文件夹的地址
然后Qt中右键工程选择添加外部库
选择编译生成的.a文件.
这样pro文件就添加了外部库的内容.
4.实现 语法高亮\自动补全\换行缩进\括号匹配\行号显示
代码实现编辑器主体的QWidget界面
//widget.h
class widget : public QWidget
{
Q_OBJECT
public:
widget(QWidget *parent = 0);
//~widget();
QsciScintilla *geteditor(){ //返回QScintilla的对象指针
return editor;
}
void setLexer(const QString &);//设置不同语言的词法分析器
private:
QsciScintilla *editor=new QsciScintilla(this);
};
endif // WIDGET_H
源文件实现widget类的构造函数和设置词法分析器函数
构造函数先实现行号提示\界面显示\字体和编码方式编码方式设置为UTF-8,不然中文会乱码设置编码格式还有其他更简短的函数实现,具体查看QScintilla库的说明文件.
//行号提示
editor->setMarginType(0,QsciScintilla::NumberMargin);//设置编号为0的页边显示行号。
editor->setMarginLineNumbers(0,true);//对该页边启用行号
editor->setMarginWidth(0,15);//设置页边宽度
//界面
QVBoxLayout *pLayout = new QVBoxLayout(this);
pLayout->addWidget(editor);
pLayout->setContentsMargins(0,0,0,0);
//设置显示字体
editor->setFont(QFont(“Courier 10 Pitch”));
//设置编码方式
editor->SendScintilla(QsciScintilla::SCI_SETCODEPAGE,QsciScintilla::SC_CP_UTF8);//设置编码为UTF-8
下面是widget函数内的setLexer函数的实现
设置词法分析器函数
QsciLexer *textLexer;
textLexer = new QsciLexerCPP;
editor->setLexer(textLexer);//给QsciScintilla设置词法分析器
先设置好词法分析器再设置代码提示等功能
//代码提示
QsciAPIs *apis = new QsciAPIs(textLexer);
apis->prepare();
editor->setAutoCompletionSource(QsciScintilla::AcsAll); //设置源,自动补全所有地方出现的
editor->setAutoCompletionCaseSensitivity(true); //设置自动补全大小写敏感
editor->setAutoCompletionThreshold(2); //设置每输入2个字符就会出现自动补全的提示
//设置自动缩进
editor->setAutoIndent(true);
//显示选中行号
editor->setCaretLineVisible(true);
editor->setCaretLineBackgroundColor(Qt::lightGray);
//Enables or disables, according to enable, this display of indentation guides.
editor->setIndentationGuides(true);
//显示行号背景颜色
//editor->setMarginsBackgroundColor(Qt::gray);
//It is ignored if an indicator is being used. The default is blue.
editor->setUnmatchedBraceForegroundColor(Qt::blue);
//括号匹配
editor->setBraceMatching(QsciScintilla::SloppyBraceMatch);
至此代码编辑器的功能基本实现
5.MainWindow的基本设置
构造函数要加上widget对象和当前文本的文件名
private:
widget *WidGet=new widget(this);
QString currentName;//当前文本的文件名
对应的构造函数实现要加上
setWindowTitle(tr(“Qt代码编辑器”));
this->resize(QSize(600,500)); //设置初始窗口大小
setCentralWidget(WidGet); //设主体为代码编辑器
其他基本为槽函数,下面会讲到
6.文件功能的实现 新建\打开\保存\另存为\关闭
这里就用到了QMainWindow的功能函数.
具体功能的实现参照了下面的博客
[转载]Qt — MainWindow实现文本新建/打开/保存/另存
没改动的地方就不贴出来了
1 基本上textEdit.document()对象改为
WidGet->geteditor()
2 打开函数(非槽函数)实现
void MainWindow::loadFile(const QString &fileName)
{
QFile file(fileName);
WidGet->setLexer(fileName);
if(!file.open(QFile::ReadOnly|QFile::Text))
{
QMessageBox::critical(this,
“critical”,
“cannot read file”
);
return;
}
else
{
QTextStream in(&file);
WidGet->geteditor()->setText(in.readAll());
setCurrentFile(fileName);
}
}
增加了根据文件名设置语法分析器
WidGet->setLexer(fileName);
*注意 这是widget类中的setLexer函数,修改上面widget类中的setLexer函数实现根据不同文件名的后缀来实现不同语言的词法分析器.
修改textEdit.setPlainText(in.readAll())为
WidGet->geteditor()->setText(in.readAll());
3 另存为函数
bool MainWindow::slotSaveAs()
{
QString slcStr;
QString fileName =QFileDialog::getSaveFileName(this,
QString::fromLocal8Bit(“文件另存为”),
“”,
tr(“Config Files(*);;text(*.txt);;C(*.cpp);;python(*.py);;Java(*.java);;HTML(*html)”),
&slcStr
);
if(slcStr.startsWith(“text”)&&!fileName.endsWith(“.txt”)){
fileName+=”.txt”;
}
if(slcStr.startsWith(“C”)&&!fileName.endsWith(“.cpp”)){
fileName+=”.cpp”;
}
if(slcStr.startsWith(“python”)&&!fileName.endsWith(“.py”)){
fileName+=”.py”;
}
if(slcStr.startsWith(“Java”)&&!fileName.endsWith(“.java”)){
fileName+=”.py”;
}
if(slcStr.startsWith(“HTML”)&&!fileName.endsWith(“.html”)){
fileName+=”.py”;
}
if(fileName.isNull())
return false;
else if(saveFile(fileName))
loadFile(fileName);
else return false;
}
第七行函数可以实现在保存的时候选择不同的文件类型
选择的类型字符串保存在第八行的slcStr中对
之后的代码根据slcStr而在保存的文件中添加后缀来更改文件类型
7.菜单栏增加对不同语言的选择以实现对不同语言的语法高亮
做法和在菜单栏增添打开\保存等功能的做法大同小异
语言选择的槽函数(以c为例)
void wgsetLexercpp(){
WidGet->setLexer(“.cpp”);
}
这样就可以实现语言的选择
8.总结
主要需要熟悉QScintilla库的使用
难度不大但不能只依赖库函数
要结合自己本身c语言的知识
评论0