Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
代碼已上傳,有需要可以下載:
源代碼
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資料領?。ㄒ曨l教程+文檔+代碼+項目實戰)
在前面的課程中中,我們學習了怎么樣用代碼來把Qt的界面寫出來,代碼控制界面,控制力確實比較好,但是免不了復雜的代碼,而且需要豐富的想象力。
很多時候運行時的樣子,并不是我們想要的,所以說我們可以用Qt給我們提供的Qt Designer(界面設計師),拖拖拽拽就可以直觀的創建出程序大體的界面。
Qt資料領取→「鏈接」
*請認真填寫需求信息,我們會在24小時內與您取得聯系。