代碼已上傳,有需要可以下載:
源代碼
0.開發(fā)環(huán)境
看了那么多博客,沒幾個說明自己的開發(fā)環(huán)境的,所以開頭先說明一下這個代碼編輯器的開發(fā)環(huán)境
系統(tǒng) deepin15.5
內(nèi)核
Qt版本 5.8.0
1.編輯器預(yù)覽
下面進入正文,先來看一下這個編輯器的基本情況
有基本的語法高亮\自動補全\換行縮進\括號匹配.
菜單欄有基本功能的實現(xiàn),能選擇不同的語言來進行語法高亮.
基本上實現(xiàn)了一個代碼編輯器的基本功能.
接下來將從代碼編輯器主體的實現(xiàn)和菜單欄的實現(xiàn)開始說.
2.項目的創(chuàng)建
建立一個Qt Widgets Application.
設(shè)置默認(rèn).
3.QScintilla庫介紹
語法高亮\自動補全\換行縮進\括號匹配\行號顯示的功能主要由一個重要的外部庫實現(xiàn)--Scintilla
官網(wǎng):https://www.scintilla.org
Qt下這個庫叫QScintilla
下載:http://pyqt.sourceforge.net
說明文檔:http://pyqt.sourceforge.net/Docs/QScintilla2/index.html
功能的實現(xiàn)主要參照了兩人的博客,在此非常感謝(ps:兩人的QScintilla都打錯了)
Qt文本高亮控件Qscitinlla的用法
Qt中文本編輯器實現(xiàn)語法高亮功能(Qscitinlla)
在此要修正一下兩個博客說到的QScintilla的配置問題
在.pro文件添加頭文件以及動態(tài)鏈接庫的引用:
INCLUDEPATH += Qt4Qt5文件夾的地址
然后Qt中右鍵工程選擇添加外部庫
選擇編譯生成的.a文件.
這樣pro文件就添加了外部庫的內(nèi)容.
4.實現(xiàn) 語法高亮\自動補全\換行縮進\括號匹配\行號顯示
代碼實現(xiàn)編輯器主體的QWidget界面
//widget.h
class widget : public QWidget
{
Q_OBJECT
public:
widget(QWidget *parent = 0);
//~widget();
QsciScintilla *geteditor(){ //返回QScintilla的對象指針
return editor;
}
void setLexer(const QString &);//設(shè)置不同語言的詞法分析器
private:
QsciScintilla *editor=new QsciScintilla(this);
};
#endif // WIDGET_H
源文件實現(xiàn)widget類的構(gòu)造函數(shù)和設(shè)置詞法分析器函數(shù)
構(gòu)造函數(shù)先實現(xiàn)行號提示\界面顯示\字體和編碼方式編碼方式設(shè)置為UTF-8,不然中文會亂碼設(shè)置編碼格式還有其他更簡短的函數(shù)實現(xiàn),具體查看QScintilla庫的說明文件.
//行號提示
editor->setMarginType(0,QsciScintilla::NumberMargin);//設(shè)置編號為0的頁邊顯示行號。
editor->setMarginLineNumbers(0,true);//對該頁邊啟用行號
editor->setMarginWidth(0,15);//設(shè)置頁邊寬度
//界面
QVBoxLayout *pLayout = new QVBoxLayout(this);
pLayout->addWidget(editor);
pLayout->setContentsMargins(0,0,0,0);
//設(shè)置顯示字體
editor->setFont(QFont("Courier 10 Pitch"));
//設(shè)置編碼方式
editor->SendScintilla(QsciScintilla::SCI_SETCODEPAGE,QsciScintilla::SC_CP_UTF8);//設(shè)置編碼為UTF-8
下面是widget函數(shù)內(nèi)的setLexer函數(shù)的實現(xiàn)
設(shè)置詞法分析器函數(shù)
QsciLexer *textLexer;
textLexer = new QsciLexerCPP;
editor->setLexer(textLexer);//給QsciScintilla設(shè)置詞法分析器
先設(shè)置好詞法分析器再設(shè)置代碼提示等功能
//代碼提示
QsciAPIs *apis = new QsciAPIs(textLexer);
apis->prepare();
editor->setAutoCompletionSource(QsciScintilla::AcsAll); //設(shè)置源,自動補全所有地方出現(xiàn)的
editor->setAutoCompletionCaseSensitivity(true); //設(shè)置自動補全大小寫敏感
editor->setAutoCompletionThreshold(2); //設(shè)置每輸入2個字符就會出現(xiàn)自動補全的提示
//設(shè)置自動縮進
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);
至此代碼編輯器的功能基本實現(xiàn)
5.MainWindow的基本設(shè)置
構(gòu)造函數(shù)要加上widget對象和當(dāng)前文本的文件名
private:
widget *WidGet=new widget(this);
QString currentName;//當(dāng)前文本的文件名
對應(yīng)的構(gòu)造函數(shù)實現(xiàn)要加上
setWindowTitle(tr("Qt代碼編輯器"));
this->resize(QSize(600,500)); //設(shè)置初始窗口大小
setCentralWidget(WidGet); //設(shè)主體為代碼編輯器
其他基本為槽函數(shù),下面會講到
6.文件功能的實現(xiàn) 新建\打開\保存\另存為\關(guān)閉
這里就用到了QMainWindow的功能函數(shù).
具體功能的實現(xiàn)參照了下面的博客
[轉(zhuǎn)載]Qt -- MainWindow實現(xiàn)文本新建/打開/保存/另存
沒改動的地方就不貼出來了
#1 基本上textEdit.document()對象改為
WidGet->geteditor()
#2 打開函數(shù)(非槽函數(shù))實現(xiàn)
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);
}
}
增加了根據(jù)文件名設(shè)置語法分析器
WidGet->setLexer(fileName);
*注意 這是widget類中的setLexer函數(shù),修改上面widget類中的setLexer函數(shù)實現(xiàn)根據(jù)不同文件名的后綴來實現(xiàn)不同語言的詞法分析器.
修改textEdit.setPlainText(in.readAll())為
WidGet->geteditor()->setText(in.readAll());
#3 另存為函數(shù)
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;
}
第七行函數(shù)可以實現(xiàn)在保存的時候選擇不同的文件類型
選擇的類型字符串保存在第八行的slcStr中對
之后的代碼根據(jù)slcStr而在保存的文件中添加后綴來更改文件類型
7.菜單欄增加對不同語言的選擇以實現(xiàn)對不同語言的語法高亮
做法和在菜單欄增添打開\保存等功能的做法大同小異
語言選擇的槽函數(shù)(以c為例)
void wgsetLexercpp(){
WidGet->setLexer(".cpp");
}
這樣就可以實現(xiàn)語言的選擇
8.總結(jié)
主要需要熟悉QScintilla庫的使用
難度不大但不能只依賴庫函數(shù)
要結(jié)合自己本身c語言的知識
代理(Delegate)就是在視圖組件上為編輯數(shù)據(jù)提供編輯器,如在表格組件中編輯一個單元格的數(shù)據(jù)時,缺省是使用一個QLineEdit編輯框。代理負責(zé)從數(shù)據(jù)模型獲取相應(yīng)的數(shù)據(jù),然后顯示在編輯器里,修改數(shù)據(jù)后,又將其保存到數(shù)據(jù)模型中。
QAbstractItemDelegate是所有代理類的基類,作為抽象類,它不能直接使用。它的一個子類QStyledItemDelegate,是Qt的視圖組件缺省使用的代理類。
對于一些特殊的數(shù)據(jù)編輯需求,例如只允許輸入整型數(shù),使用一個QSpinBox作為代理組件更恰當(dāng),從列表中選擇數(shù)據(jù)時使用一個QComboBox作為代理組件更好。這時,就可以從QStyledItemDelegate繼承創(chuàng)建自定義代理類
當(dāng)我們導(dǎo)入數(shù)據(jù)文件進行編輯時,QTableView組件為每個單元格提供的是缺省的代理編輯組件,就是一個QLineEdit組件。
在編輯框里可以輸入任何數(shù)據(jù),所以比較通用。但是有些情況下,希望根據(jù)數(shù)據(jù)的類型限定使用不同的編輯組件,例如第1列我們要求是整數(shù),使用QSpinBox作為編輯組件更合適
Qt資料領(lǐng)取(視頻教程+文檔+代碼+項目實戰(zhàn))
在前面的課程中中,我們學(xué)習(xí)了怎么樣用代碼來把Qt的界面寫出來,代碼控制界面,控制力確實比較好,但是免不了復(fù)雜的代碼,而且需要豐富的想象力。
很多時候運行時的樣子,并不是我們想要的,所以說我們可以用Qt給我們提供的Qt Designer(界面設(shè)計師),拖拖拽拽就可以直觀的創(chuàng)建出程序大體的界面。
Qt資料領(lǐng)取→「鏈接」
*請認(rèn)真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。