整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

Linux下Qt制作代码编辑器

代码已上传,有需要可以下载:

源代码

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语言的知识

理的定义

代理(Delegate)就是在视图组件上为编辑数据提供编辑器,如在表格组件中编辑一个单元格的数据时,缺省是使用一个QLineEdit编辑框。代理负责从数据模型获取相应的数据,然后显示在编辑器里,修改数据后,又将其保存到数据模型中。

QAbstractItemDelegate是所有代理类的基类,作为抽象类,它不能直接使用。它的一个子类QStyledItemDelegate,是Qt的视图组件缺省使用的代理类。

对于一些特殊的数据编辑需求,例如只允许输入整型数,使用一个QSpinBox作为代理组件更恰当,从列表中选择数据时使用一个QComboBox作为代理组件更好。这时,就可以从QStyledItemDelegate继承创建自定义代理类

自定义代理的功能

当我们导入数据文件进行编辑时,QTableView组件为每个单元格提供的是缺省的代理编辑组件,就是一个QLineEdit组件。

在编辑框里可以输入任何数据,所以比较通用。但是有些情况下,希望根据数据的类型限定使用不同的编辑组件,例如第1列我们要求是整数,使用QSpinBox作为编辑组件更合适

Qt资料领取(视频教程+文档+代码+项目实战)

esigner设计师的使用

在前面的课程中中,我们学习了怎么样用代码来把Qt的界面写出来,代码控制界面,控制力确实比较好,但是免不了复杂的代码,而且需要丰富的想象力。

很多时候运行时的样子,并不是我们想要的,所以说我们可以用Qt给我们提供的Qt Designer(界面设计师),拖拖拽拽就可以直观的创建出程序大体的界面。

1.1 创建带UI文件的项目

  • 双击.ui文件打开设计师界面

  • 设计师面板介绍
    • 组件面板:窗口左侧是界面设计组件面板,分为多个组,如Layouts、Buttons、Display Widgets等,界面设计的常见组件都可以在组件面板里找到。
    • 中间主要区域是待设计的窗体。如果要将某个组件放置到窗体上时,从组件面板上拖放一个组件到窗体上即可。例如,先放一个 Label 和一个 Push Button 到窗体上。
    • Signals 和 Slots 编辑器与 Action 编辑器是位于待设计窗体下方的两个编辑器。Signals 和Slots 编辑器用于可视化地进行信号与槽的关联,Action 编辑器用于可视化设计 Action。
    • 布局和界面设计工具栏:窗口上方的一个工具栏,工具栏上的按钮主要实现布局和界面设计。
    • 对象浏览器(Object Inspector):窗口右上方是 Object Inspector,用树状视图显示窗体上各组件之间的布局包含关系,视图有两列,显示每个组件的对象名称(ObjectName)和类名称。
    • 属性编辑器(Property Editor):窗口右下方是属性编辑器,是界面设计时最常用到的编辑器。属性编辑器显示某个选中的组件或窗体的各种属性及其取值,可以在属性编辑器里修改这些属性的值。

Qt资料领取→「链接」