├── About.png ├── HJ-Editor-Code.PNG ├── HJ-Editor-Run.PNG ├── HJ-Editor.pro ├── HJ-Editor.pro.user ├── New.png ├── Open.png ├── README.md ├── Redo.png ├── Run.png ├── Save.png ├── Setting.png ├── Undo.png ├── codeeditor.cpp ├── codeeditor.h ├── completelistwidget.cpp ├── completelistwidget.h ├── console.cpp ├── console.h ├── highlighter.cpp ├── highlighter.h ├── icon.icns ├── icon.ico ├── icon.png ├── image.qrc ├── main.cpp ├── mainwindow.cpp ├── mainwindow.h ├── mainwindow.ui └── stop.png /About.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m-iDev-0792/HJ-Editor/bf4d55f2522ca24850f136f79efcf1e3e893ebba/About.png -------------------------------------------------------------------------------- /HJ-Editor-Code.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m-iDev-0792/HJ-Editor/bf4d55f2522ca24850f136f79efcf1e3e893ebba/HJ-Editor-Code.PNG -------------------------------------------------------------------------------- /HJ-Editor-Run.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m-iDev-0792/HJ-Editor/bf4d55f2522ca24850f136f79efcf1e3e893ebba/HJ-Editor-Run.PNG -------------------------------------------------------------------------------- /HJ-Editor.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2017-07-02T19:19:03 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | 9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 10 | 11 | TARGET = HJ-Editor 12 | TEMPLATE = app 13 | 14 | # The following define makes your compiler emit warnings if you use 15 | # any feature of Qt which as been marked as deprecated (the exact warnings 16 | # depend on your compiler). Please consult the documentation of the 17 | # deprecated API in order to know how to port your code away from it. 18 | DEFINES += QT_DEPRECATED_WARNINGS 19 | 20 | # You can also make your code fail to compile if you use deprecated APIs. 21 | # In order to do so, uncomment the following line. 22 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 23 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 24 | 25 | 26 | SOURCES += \ 27 | main.cpp \ 28 | mainwindow.cpp \ 29 | codeeditor.cpp \ 30 | highlighter.cpp \ 31 | completelistwidget.cpp \ 32 | console.cpp 33 | 34 | HEADERS += \ 35 | mainwindow.h \ 36 | codeeditor.h \ 37 | highlighter.h \ 38 | completelistwidget.h \ 39 | console.h 40 | 41 | FORMS += \ 42 | mainwindow.ui 43 | 44 | RESOURCES += \ 45 | image.qrc 46 | 47 | ICON = icon.icns 48 | -------------------------------------------------------------------------------- /HJ-Editor.pro.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | EnvironmentId 7 | {5b894e47-8948-4d05-8b6e-4858ef8d2b4f} 8 | 9 | 10 | ProjectExplorer.Project.ActiveTarget 11 | 0 12 | 13 | 14 | ProjectExplorer.Project.EditorSettings 15 | 16 | true 17 | false 18 | true 19 | 20 | Cpp 21 | 22 | CppGlobal 23 | 24 | 25 | 26 | QmlJS 27 | 28 | QmlJSGlobal 29 | 30 | 31 | 2 32 | UTF-8 33 | false 34 | 4 35 | false 36 | 80 37 | true 38 | true 39 | 1 40 | true 41 | false 42 | 0 43 | true 44 | true 45 | 0 46 | 8 47 | true 48 | 1 49 | true 50 | true 51 | true 52 | false 53 | 54 | 55 | 56 | ProjectExplorer.Project.PluginSettings 57 | 58 | 59 | 60 | ProjectExplorer.Project.Target.0 61 | 62 | Desktop Qt 5.9.0 clang 64bit 63 | Desktop Qt 5.9.0 clang 64bit 64 | qt.59.clang_64_kit 65 | 1 66 | 0 67 | 0 68 | 69 | /Users/hezhenbang/Documents/Qt Projects/build-HJ-Editor-Desktop_Qt_5_9_0_clang_64bit-Debug 70 | 71 | 72 | true 73 | qmake 74 | 75 | QtProjectManager.QMakeBuildStep 76 | true 77 | 78 | false 79 | false 80 | false 81 | 82 | 83 | true 84 | Make 85 | 86 | Qt4ProjectManager.MakeStep 87 | 88 | -w 89 | -r 90 | 91 | false 92 | 93 | 94 | 95 | 2 96 | 构建 97 | 98 | ProjectExplorer.BuildSteps.Build 99 | 100 | 101 | 102 | true 103 | Make 104 | 105 | Qt4ProjectManager.MakeStep 106 | 107 | -w 108 | -r 109 | 110 | true 111 | clean 112 | 113 | 114 | 1 115 | 清理 116 | 117 | ProjectExplorer.BuildSteps.Clean 118 | 119 | 2 120 | false 121 | 122 | Debug 123 | 124 | Qt4ProjectManager.Qt4BuildConfiguration 125 | 2 126 | true 127 | 128 | 129 | /Users/hezhenbang/Documents/Qt Projects/build-HJ-Editor-Desktop_Qt_5_9_0_clang_64bit-Release 130 | 131 | 132 | true 133 | qmake 134 | 135 | QtProjectManager.QMakeBuildStep 136 | false 137 | 138 | false 139 | false 140 | false 141 | 142 | 143 | true 144 | Make 145 | 146 | Qt4ProjectManager.MakeStep 147 | 148 | -w 149 | -r 150 | 151 | false 152 | 153 | 154 | 155 | 2 156 | 构建 157 | 158 | ProjectExplorer.BuildSteps.Build 159 | 160 | 161 | 162 | true 163 | Make 164 | 165 | Qt4ProjectManager.MakeStep 166 | 167 | -w 168 | -r 169 | 170 | true 171 | clean 172 | 173 | 174 | 1 175 | 清理 176 | 177 | ProjectExplorer.BuildSteps.Clean 178 | 179 | 2 180 | false 181 | 182 | Release 183 | 184 | Qt4ProjectManager.Qt4BuildConfiguration 185 | 0 186 | true 187 | 188 | 189 | /Users/hezhenbang/Documents/Qt Projects/build-HJ-Editor-Desktop_Qt_5_9_0_clang_64bit-Profile 190 | 191 | 192 | true 193 | qmake 194 | 195 | QtProjectManager.QMakeBuildStep 196 | true 197 | 198 | false 199 | true 200 | false 201 | 202 | 203 | true 204 | Make 205 | 206 | Qt4ProjectManager.MakeStep 207 | 208 | -w 209 | -r 210 | 211 | false 212 | 213 | 214 | 215 | 2 216 | 构建 217 | 218 | ProjectExplorer.BuildSteps.Build 219 | 220 | 221 | 222 | true 223 | Make 224 | 225 | Qt4ProjectManager.MakeStep 226 | 227 | -w 228 | -r 229 | 230 | true 231 | clean 232 | 233 | 234 | 1 235 | 清理 236 | 237 | ProjectExplorer.BuildSteps.Clean 238 | 239 | 2 240 | false 241 | 242 | Profile 243 | 244 | Qt4ProjectManager.Qt4BuildConfiguration 245 | 0 246 | true 247 | 248 | 3 249 | 250 | 251 | 0 252 | 部署 253 | 254 | ProjectExplorer.BuildSteps.Deploy 255 | 256 | 1 257 | 在本地部署 258 | 259 | ProjectExplorer.DefaultDeployConfiguration 260 | 261 | 1 262 | 263 | 264 | false 265 | false 266 | 1000 267 | 268 | true 269 | 270 | false 271 | false 272 | false 273 | false 274 | true 275 | 0.01 276 | 10 277 | true 278 | 1 279 | 25 280 | 281 | 1 282 | true 283 | false 284 | true 285 | valgrind 286 | 287 | 0 288 | 1 289 | 2 290 | 3 291 | 4 292 | 5 293 | 6 294 | 7 295 | 8 296 | 9 297 | 10 298 | 11 299 | 12 300 | 13 301 | 14 302 | 303 | 2 304 | 305 | HJ-Editor 306 | 307 | Qt4ProjectManager.Qt4RunConfiguration:/Users/hezhenbang/Documents/Qt Projects/HJ-Editor/HJ-Editor.pro 308 | true 309 | 310 | HJ-Editor.pro 311 | false 312 | 313 | /Users/hezhenbang/Documents/Qt Projects/build-HJ-Editor-Desktop_Qt_5_9_0_clang_64bit-Release/HJ-Editor.app/Contents/MacOS 314 | 3768 315 | false 316 | true 317 | false 318 | false 319 | true 320 | 321 | 1 322 | 323 | 324 | 325 | ProjectExplorer.Project.TargetCount 326 | 1 327 | 328 | 329 | ProjectExplorer.Project.Updater.FileVersion 330 | 18 331 | 332 | 333 | Version 334 | 18 335 | 336 | 337 | -------------------------------------------------------------------------------- /New.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m-iDev-0792/HJ-Editor/bf4d55f2522ca24850f136f79efcf1e3e893ebba/New.png -------------------------------------------------------------------------------- /Open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m-iDev-0792/HJ-Editor/bf4d55f2522ca24850f136f79efcf1e3e893ebba/Open.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HJ-Editor 2 | 简单的C++ IDE,带联想、代码高亮、编译运行等功能 3 | 4 | 联想: 5 | ![](HJ-Editor-Code.PNG) 6 | 7 | 运行: 8 | ![](HJ-Editor-Run.PNG) 9 | 10 | 编译运行功能需要安装好g++,在Mac下无需更改设置,win下需要自己配置g++路径 11 | 12 | 13 | -------------------------------------------------------------------------------- /Redo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m-iDev-0792/HJ-Editor/bf4d55f2522ca24850f136f79efcf1e3e893ebba/Redo.png -------------------------------------------------------------------------------- /Run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m-iDev-0792/HJ-Editor/bf4d55f2522ca24850f136f79efcf1e3e893ebba/Run.png -------------------------------------------------------------------------------- /Save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m-iDev-0792/HJ-Editor/bf4d55f2522ca24850f136f79efcf1e3e893ebba/Save.png -------------------------------------------------------------------------------- /Setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m-iDev-0792/HJ-Editor/bf4d55f2522ca24850f136f79efcf1e3e893ebba/Setting.png -------------------------------------------------------------------------------- /Undo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m-iDev-0792/HJ-Editor/bf4d55f2522ca24850f136f79efcf1e3e893ebba/Undo.png -------------------------------------------------------------------------------- /codeeditor.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "codeeditor.h" 4 | //![constructor] 5 | 6 | CodeEditor::CodeEditor(QWidget *parent) : QPlainTextEdit(parent) 7 | { 8 | lineNumberArea = new LineNumberArea(this); 9 | 10 | connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int))); 11 | connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int))); 12 | connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine())); 13 | connect(this,SIGNAL(cursorPositionChanged()),this,SLOT(showCompleteWidget())); 14 | 15 | updateLineNumberAreaWidth(0); 16 | highlightCurrentLine(); 17 | //set color value 18 | lineColor.setRgb(56,60,69); 19 | editorColor.setRgb(34,39,49); 20 | 21 | //set background color 22 | QPalette p = this->palette(); 23 | p.setColor(QPalette::Active, QPalette::Base, editorColor); 24 | p.setColor(QPalette::Inactive, QPalette::Base, editorColor); 25 | p.setColor(QPalette::Text,Qt::white); 26 | this->setPalette(p); 27 | //初始化补全列表 28 | setUpCompleteList(); 29 | completeWidget= new CompleteListWidget(this); 30 | completeWidget->hide(); 31 | completeWidget->setMaximumHeight(fontMetrics().height()*5); 32 | completeState=CompleteState::Hide; 33 | } 34 | 35 | //![constructor] 36 | 37 | //![extraAreaWidth] 38 | 39 | int CodeEditor::lineNumberAreaWidth() 40 | { 41 | int digits = 1;//行数数字的位数 42 | int max = qMax(1, blockCount()); 43 | while (max >= 10) { 44 | max /= 10; 45 | ++digits; 46 | } 47 | if(digits<3)digits=3; 48 | 49 | int space = 3 + fontMetrics().width(QLatin1Char('9')) * digits; 50 | 51 | return space; 52 | } 53 | 54 | //![extraAreaWidth] 55 | 56 | //![slotUpdateExtraAreaWidth] 57 | 58 | //设定左边留白的宽度,参数无效,没有用到 59 | void CodeEditor::updateLineNumberAreaWidth(int /* newBlockCount */) 60 | { 61 | setViewportMargins(lineNumberAreaWidth(), 0, 0, 0); 62 | } 63 | 64 | //![slotUpdateExtraAreaWidth] 65 | 66 | //![slotUpdateRequest] 67 | //文本框滚动时同时滚动行数 68 | void CodeEditor::updateLineNumberArea(const QRect &rect, int dy) 69 | { 70 | if (dy) 71 | lineNumberArea->scroll(0, dy); 72 | else 73 | lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height()); 74 | 75 | if (rect.contains(viewport()->rect())) 76 | updateLineNumberAreaWidth(0); 77 | 78 | } 79 | 80 | //![slotUpdateRequest] 81 | 82 | //![resizeEvent] 83 | //尺寸调整函数 84 | void CodeEditor::resizeEvent(QResizeEvent *e) 85 | { 86 | QPlainTextEdit::resizeEvent(e); 87 | 88 | QRect cr = contentsRect(); 89 | lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height())); 90 | } 91 | 92 | //![resizeEvent] 93 | 94 | //![cursorPositionChanged] 95 | 96 | void CodeEditor::highlightCurrentLine() 97 | { 98 | QList extraSelections; 99 | 100 | if (!isReadOnly()) { 101 | QTextEdit::ExtraSelection selection; 102 | 103 | QColor lineColor = QColor(Qt::red).lighter(160); 104 | 105 | selection.format.setBackground(lineColor); 106 | selection.format.setProperty(QTextFormat::FullWidthSelection, true); 107 | selection.cursor = textCursor(); 108 | selection.cursor.clearSelection(); 109 | extraSelections.append(selection); 110 | } 111 | 112 | setExtraSelections(extraSelections); 113 | } 114 | 115 | //![cursorPositionChanged] 116 | 117 | //![extraAreaPaintEvent_0] 118 | //打印行号,此函数被paintEvent 调用,paintEvent在头文件里被重写 119 | void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent *event) 120 | { 121 | QPainter painter(lineNumberArea); 122 | painter.fillRect(event->rect(), lineColor); 123 | 124 | //![extraAreaPaintEvent_0] 125 | 126 | //![extraAreaPaintEvent_1] 127 | QTextBlock block = firstVisibleBlock(); 128 | int blockNumber = block.blockNumber(); 129 | int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top(); 130 | int bottom = top + (int) blockBoundingRect(block).height(); 131 | //![extraAreaPaintEvent_1] 132 | 133 | //![extraAreaPaintEvent_2] 134 | while (block.isValid() && top <= event->rect().bottom()) { 135 | if (block.isVisible() && bottom >= event->rect().top()) { 136 | QString number = QString::number(blockNumber + 1); 137 | painter.setPen(Qt::lightGray); 138 | painter.drawText(0, top, lineNumberArea->width(), fontMetrics().height(), 139 | Qt::AlignCenter, number); 140 | } 141 | 142 | block = block.next(); 143 | top = bottom; 144 | bottom = top + (int) blockBoundingRect(block).height(); 145 | ++blockNumber; 146 | } 147 | } 148 | //![extraAreaPaintEvent_2] 149 | 150 | //自动补全 151 | void CodeEditor::keyPressEvent(QKeyEvent *event){ 152 | //qDebug()<key(); 153 | if(event->modifiers()==Qt::ShiftModifier&&event->key()==40){ 154 | this->insertPlainText(tr("()")); 155 | this->moveCursor(QTextCursor::PreviousCharacter); 156 | } 157 | else if(event->modifiers()==Qt::ShiftModifier&&event->key()==34){ 158 | this->insertPlainText(tr("\"\"")); 159 | this->moveCursor(QTextCursor::PreviousCharacter); 160 | } 161 | else if(event->key()==16777235&&completeState==CompleteState::Showing){ 162 | if(completeWidget->currentRow()>0) 163 | completeWidget->setCurrentRow(completeWidget->currentRow()-1); 164 | } 165 | else if(event->key()==16777237&&(completeState==CompleteState::Showing)){ 166 | if(completeWidget->currentRow()count()-1) 167 | completeWidget->setCurrentRow(completeWidget->currentRow()+1); 168 | } 169 | else if(event->key()==Qt::Key_Return&&(completeState==CompleteState::Showing)){ 170 | QString insertText=completeWidget->currentItem()->text(); 171 | QString word=this->getWordOfCursor(); 172 | completeState=CompleteState::Ignore; 173 | for(int i=0;itextCursor().deletePreviousChar(); 175 | this->insertPlainText(insertText); 176 | if(insertText.contains(tr("#include"))) 177 | this->moveCursor(QTextCursor::PreviousCharacter); 178 | completeState=CompleteState::Hide; 179 | completeWidget->hide(); 180 | }//* 181 | else if(event->key()==Qt::Key_Return){//回车下行层级自动缩进功能 182 | //获得本行的文本 183 | QString temp=this->document()->findBlockByLineNumber(this->textCursor().blockNumber()).text(); 184 | QPlainTextEdit::keyPressEvent(event); 185 | if(temp.count()<=0)return; 186 | //输出回车那一行的前距 187 | foreach(const QChar &c,temp){ 188 | if(c.isSpace())this->insertPlainText(c); 189 | else break; 190 | } 191 | //如果是for() while() switch() if()则缩进一个tab,一种粗略地做法可能会出错 192 | if(temp.at(temp.count()-1)==')'&&(temp.contains(tr("for("))||temp.contains(tr("while(")) 193 | ||temp.contains(tr("switch("))||temp.contains(tr("if(")))) 194 | this->insertPlainText(tr("\t")); 195 | //如果是{ 则缩进并补} 196 | if(temp.at(temp.count()-1)=='{'){ 197 | this->insertPlainText(tr("\t")); 198 | QTextCursor cursor=this->textCursor(); 199 | int pos=this->textCursor().position(); 200 | this->insertPlainText(tr("\n")); 201 | foreach(const QChar &c,temp){ 202 | if(c.isSpace())this->insertPlainText(c); 203 | else break; 204 | } 205 | this->insertPlainText(tr("}")); 206 | cursor.setPosition(pos); 207 | this->setTextCursor(cursor);//返回中间一行 208 | } 209 | }//*/ 210 | else if(event->key()==Qt::Key_Backspace){ 211 | switch(this->document()->characterAt(this->textCursor().position()-1).toLatin1()){ 212 | case '(': 213 | QPlainTextEdit::keyPressEvent(event); 214 | if(this->document()->characterAt(this->textCursor().position())==')'){ 215 | this->textCursor().deleteChar(); 216 | }break; 217 | case '\"': 218 | QPlainTextEdit::keyPressEvent(event); 219 | if(this->document()->characterAt(this->textCursor().position())=='\"'){ 220 | this->textCursor().deleteChar(); 221 | }break; 222 | case '<': 223 | QPlainTextEdit::keyPressEvent(event); 224 | if(this->document()->characterAt(this->textCursor().position())=='>'){ 225 | this->textCursor().deleteChar(); 226 | }break; 227 | default: 228 | QPlainTextEdit::keyPressEvent(event); 229 | } 230 | } 231 | else{ 232 | QPlainTextEdit::keyPressEvent(event); 233 | //qDebug()<key(); 234 | } 235 | } 236 | void CodeEditor::setUpCompleteList(){ 237 | completeList<< "char" << "class" << "const" 238 | << "double" << "enum" << "explicit" 239 | << "friend" << "inline" << "int" 240 | << "long" << "namespace" << "operator" 241 | << "private" << "protected" << "public" 242 | << "short" << "signals" << "signed" 243 | << "slots" << "static" << "struct" 244 | << "template" << "typedef" << "typename" 245 | << "union" << "unsigned" << "virtual" 246 | << "void" << "volatile" << "bool"<<"using"<<"constexpr" 247 | <<"sizeof"<<"if"<<"for"<<"foreach"<<"while"<<"do"<<"case" 248 | <<"break"<<"continue"<<"template"<<"delete"<<"new" 249 | <<"default"<<"try"<<"return"<<"throw"<<"catch"<<"goto"<<"else" 250 | <<"extren"<<"this"<<"switch"<<"#include <>"<<"#include \"\""<<"#define"<<"iostream"; 251 | } 252 | //得到当前光标位置的字符串 253 | QString CodeEditor::getWordOfCursor(){ 254 | int pos=this->textCursor().position()-1; 255 | QVector words; 256 | QString result; 257 | QChar ch=this->document()->characterAt(pos+1); 258 | if(ch.isDigit()||ch.isLetter()||ch==' ')return result; 259 | ch=this->document()->characterAt(pos); 260 | if(ch==' ')return result; 261 | while(ch.isDigit()||ch.isLetter()||ch=='_'||ch=='#'){ 262 | words.append(ch); 263 | pos--; 264 | ch=this->document()->characterAt(pos); 265 | } 266 | for(int i=words.size()-1;i>=0;i--) 267 | result+=words[i]; 268 | return result; 269 | 270 | } 271 | 272 | void CodeEditor::showCompleteWidget(){ 273 | if(completeState==CompleteState::Ignore)return;//忽略光标和文本变化的响应,避免陷入事件死循环和互相钳制 274 | completeWidget->hide(); 275 | completeState=CompleteState::Hide; 276 | QString word=this->getWordOfCursor(); 277 | completeWidget->clear(); 278 | if(!word.isEmpty()){//光标所在单词是不是合法(能不能联想) 279 | int maxSize=0; 280 | QMap distance; 281 | vector itemList; 282 | foreach(const QString &temp,completeList){ 283 | if(temp.contains(word)){ 284 | //completeWidget->addItem(new QListWidgetItem(temp)); 285 | itemList.push_back(temp); 286 | distance[temp]=CompleteListWidget::ldistance(temp.toStdString(),word.toStdString()); 287 | if(temp.length()>maxSize)maxSize=temp.length(); 288 | 289 | } 290 | } 291 | //有没有匹配的字符 292 | if(itemList.size()>0){//如果有的话 293 | sort(itemList.begin(),itemList.end(),[&](const QString &s1,const QString &s2)->bool{return distance[s1]addItem(new QListWidgetItem(item)); 296 | } 297 | 298 | int x=this->getCompleteWidgetX(); 299 | int y=this->cursorRect().y()+fontMetrics().height(); 300 | 301 | completeWidget->move(x,y); 302 | if(completeWidget->count()>5)completeWidget->setFixedHeight(fontMetrics().height()*6); 303 | else completeWidget->setFixedHeight(fontMetrics().height()*(completeWidget->count()+1)); 304 | completeWidget->setFixedWidth((fontMetrics().width(QLatin1Char('9'))+6)*maxSize); 305 | completeWidget->show(); 306 | completeState=CompleteState::Showing; 307 | completeWidget->setCurrentRow(0,QItemSelectionModel::Select); 308 | } 309 | } 310 | 311 | } 312 | int CodeEditor::getCompleteWidgetX(){ 313 | QTextCursor cursor=this->textCursor(); 314 | int pos=cursor.position()-1; 315 | int origianlPos=pos+1; 316 | QChar ch; 317 | ch=this->document()->characterAt(pos); 318 | while((ch.isDigit()||ch.isLetter()||ch=='_'||ch=='#')&&pos>0){ 319 | pos--; 320 | ch=this->document()->characterAt(pos); 321 | } 322 | pos++; 323 | completeState=CompleteState::Ignore; 324 | cursor.setPosition(pos); 325 | this->setTextCursor(cursor); 326 | int x=this->cursorRect().x()+2*fontMetrics().width(QLatin1Char('9')); 327 | cursor.setPosition(origianlPos); 328 | this->setTextCursor(cursor); 329 | completeState=CompleteState::Hide; 330 | return x; 331 | } 332 | -------------------------------------------------------------------------------- /codeeditor.h: -------------------------------------------------------------------------------- 1 | #ifndef CODEEDITOR_H 2 | #define CODEEDITOR_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "completelistwidget.h" 10 | #include 11 | QT_BEGIN_NAMESPACE 12 | class QPaintEvent; 13 | class QResizeEvent; 14 | class QSize; 15 | class QWidget; 16 | QT_END_NAMESPACE 17 | 18 | class LineNumberArea; 19 | 20 | //![codeeditordefinition] 21 | 22 | class CodeEditor : public QPlainTextEdit 23 | { 24 | Q_OBJECT 25 | 26 | public: 27 | CodeEditor(QWidget *parent = 0); 28 | 29 | void lineNumberAreaPaintEvent(QPaintEvent *event); 30 | int lineNumberAreaWidth(); 31 | void setUpCompleteList(); 32 | 33 | protected: 34 | void resizeEvent(QResizeEvent *event) override; 35 | void keyPressEvent(QKeyEvent *event) override; 36 | 37 | private slots: 38 | void updateLineNumberAreaWidth(int newBlockCount); 39 | void highlightCurrentLine(); 40 | void updateLineNumberArea(const QRect &, int); 41 | void showCompleteWidget(); 42 | //void completeWidgetKeyDown(); 43 | 44 | private: 45 | QWidget *lineNumberArea; 46 | QColor lineColor; 47 | QColor editorColor; 48 | QStringList completeList;//储存自动填充的关键字 49 | //QListWidget *completeWidget; 50 | CompleteListWidget *completeWidget; 51 | QString getWordOfCursor(); 52 | int completeState; 53 | int getCompleteWidgetX(); 54 | }; 55 | 56 | //![codeeditordefinition] 57 | //![extraarea] 58 | 59 | class LineNumberArea : public QWidget 60 | { 61 | public: 62 | LineNumberArea(CodeEditor *editor) : QWidget(editor) { 63 | codeEditor = editor; 64 | } 65 | 66 | QSize sizeHint() const override { 67 | return QSize(codeEditor->lineNumberAreaWidth(), 0); 68 | } 69 | 70 | protected: 71 | void paintEvent(QPaintEvent *event) override { 72 | codeEditor->lineNumberAreaPaintEvent(event); 73 | 74 | } 75 | 76 | private: 77 | CodeEditor *codeEditor; 78 | }; 79 | enum CompleteState{ 80 | Ignore=0, 81 | Showing=1, 82 | Hide=2 83 | }; 84 | 85 | //![extraarea] 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /completelistwidget.cpp: -------------------------------------------------------------------------------- 1 | #include "completelistwidget.h" 2 | 3 | CompleteListWidget::CompleteListWidget(QWidget *parent):QListWidget(parent) 4 | { 5 | p=(QPlainTextEdit*)parent; 6 | backgroundColor=Qt::lightGray;//.setRgb(34,39,49); 7 | highlightColor.setRgb(22,165,248); 8 | QPalette palette=this->palette(); 9 | palette.setColor(QPalette::Active,QPalette::Highlight,highlightColor); 10 | palette.setColor(QPalette::Inactive,QPalette::Highlight,highlightColor); 11 | palette.setColor(QPalette::Active, QPalette::Base,backgroundColor); 12 | palette.setColor(QPalette::Inactive, QPalette::Base, backgroundColor); 13 | palette.setColor(QPalette::Text,Qt::white); 14 | this->setPalette(palette); 15 | } 16 | void CompleteListWidget::keyPressEvent(QKeyEvent *event){ 17 | if(event->key()==16777235||event->key()==16777237){ 18 | QListWidget::keyPressEvent(event); 19 | }else{ 20 | QApplication::sendEvent(p,event); 21 | p->setFocus(); 22 | } 23 | } 24 | int CompleteListWidget::ldistance(const std::string source, const std::string target){ 25 | //step 1 26 | 27 | int n = source.length(); 28 | int m = target.length(); 29 | if (m == 0) return n; 30 | if (n == 0) return m; 31 | //Construct a matrix 32 | typedef vector< vector > Tmatrix; 33 | Tmatrix matrix(n + 1); 34 | for (int i = 0; i <= n; i++) matrix[i].resize(m + 1); 35 | //step 2 Initialize 36 | for (int i = 1; i <= n; i++) matrix[i][0] = i; 37 | for (int i = 1; i <= m; i++) matrix[0][i] = i; 38 | //step 3 39 | for (int i = 1; i <= n; i++) 40 | { 41 | const char si = source[i - 1]; 42 | //step 4 43 | for (int j = 1; j <= m; j++) 44 | { 45 | const char dj = target[j - 1]; 46 | //step 5 47 | int cost; 48 | if (si == dj){ 49 | cost = 0; 50 | } 51 | else{ 52 | cost = 1; 53 | } 54 | //step 6 55 | const int above = matrix[i - 1][j] + 1; 56 | const int left = matrix[i][j - 1] + 1; 57 | const int diag = matrix[i - 1][j - 1] + cost; 58 | matrix[i][j] = min(above, min(left, diag)); 59 | } 60 | }//step7 61 | return matrix[n][m]; 62 | 63 | } 64 | -------------------------------------------------------------------------------- /completelistwidget.h: -------------------------------------------------------------------------------- 1 | #ifndef COMPLETELISTWIDGET_H 2 | #define COMPLETELISTWIDGET_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | using std::string; 13 | using std::vector; 14 | using std::min; 15 | class CompleteListWidget : public QListWidget 16 | { 17 | public: 18 | CompleteListWidget(QWidget *parent=0); 19 | static int ldistance(const string source, const string target); 20 | protected: 21 | void keyPressEvent(QKeyEvent *event) override; 22 | private: 23 | QPlainTextEdit* p; 24 | QColor backgroundColor; 25 | QColor highlightColor; 26 | }; 27 | 28 | #endif // COMPLETELISTWIDGET_H 29 | -------------------------------------------------------------------------------- /console.cpp: -------------------------------------------------------------------------------- 1 | #include "console.h" 2 | 3 | Console::Console(QWidget* parent):QPlainTextEdit(parent) 4 | { 5 | connect(this,SIGNAL(cursorPositionChanged()),this,SLOT(resetCursorPosition())); 6 | QColor editorColor; 7 | editorColor.setRgb(34,39,49); 8 | 9 | //set background color 10 | QPalette p = this->palette(); 11 | p.setColor(QPalette::Active, QPalette::Base, editorColor); 12 | p.setColor(QPalette::Inactive, QPalette::Base, editorColor); 13 | p.setColor(QPalette::Text,Qt::white); 14 | this->setPalette(p); 15 | } 16 | void Console::keyPressEvent(QKeyEvent *event){ 17 | if(event->key()==Qt::Key_Backspace&&this->textCursor().atBlockStart())return; 18 | if(event->key()==Qt::Key_Return){ 19 | QString data=(this->textCursor()).block().text()+tr("\n"); 20 | qDebug()<<"sending data: "<inputData(data); 22 | } 23 | QPlainTextEdit::keyPressEvent(event); 24 | } 25 | void Console::resetCursorPosition(){ 26 | QTextCursor cursor=this->textCursor(); 27 | cursor.movePosition(QTextCursor::End,QTextCursor::MoveAnchor); 28 | this->setTextCursor(cursor); 29 | } 30 | -------------------------------------------------------------------------------- /console.h: -------------------------------------------------------------------------------- 1 | #ifndef CONSOLE_H 2 | #define CONSOLE_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "mainwindow.h" 10 | class Console : public QPlainTextEdit 11 | { 12 | Q_OBJECT 13 | public: 14 | Console(QWidget* parent=0); 15 | MainWindow *parentWindow; 16 | protected: 17 | void keyPressEvent(QKeyEvent *event)override; 18 | protected slots: 19 | void resetCursorPosition(); 20 | }; 21 | 22 | #endif // CONSOLE_H 23 | -------------------------------------------------------------------------------- /highlighter.cpp: -------------------------------------------------------------------------------- 1 | #include "highlighter.h" 2 | 3 | //! [0] 4 | Highlighter::Highlighter(QTextDocument *parent) 5 | : QSyntaxHighlighter(parent) 6 | { 7 | HighlightingRule rule; 8 | 9 | keywordFormat.setForeground(QColor(201,81,116)); 10 | keywordFormat.setFontWeight(QFont::Bold); 11 | QStringList keywordPatterns; 12 | keywordPatterns << "\\bchar\\b" << "\\bclass\\b" << "\\bconst\\b" 13 | << "\\bdouble\\b" << "\\benum\\b" << "\\bexplicit\\b" 14 | << "\\bfriend\\b" << "\\binline\\b" << "\\bint\\b" 15 | << "\\blong\\b" << "\\bnamespace\\b" << "\\boperator\\b" 16 | << "\\bprivate\\b" << "\\bprotected\\b" << "\\bpublic\\b" 17 | << "\\bshort\\b" << "\\bsignals\\b" << "\\bsigned\\b" 18 | << "\\bslots\\b" << "\\bstatic\\b" << "\\bstruct\\b" 19 | << "\\btemplate\\b" << "\\btypedef\\b" << "\\btypename\\b" 20 | << "\\bunion\\b" << "\\bunsigned\\b" << "\\bvirtual\\b" 21 | << "\\bvoid\\b" << "\\bvolatile\\b" << "\\bbool\\b"<<"\\busing\\b"<<"\\bconstexpr\\b" 22 | <<"\\bsizeof\\b"<<"\\bif\\b"<<"\\bfor\\b"<<"\\bforeach\\b"<<"\\bwhile\\b"<<"\\bdo\\b"<<"\\bcase\\b" 23 | <<"\\bbreak\\b"<<"\\bcontinue\\b"<<"\\btemplate\\b"<<"\\bdelete\\b"<<"\\bnew\\b" 24 | <<"\\bdefault\\b"<<"\\btry\\b"<<"\\breturn\\b"<<"\\bthrow\\b"<<"\\bcatch\\b"<<"\\bgoto\\b"<<"\\belse\\b" 25 | <<"\\bextren\\b"<<"\\bthis\\b"<<"\\bswitch\\b"<<"\\binclude\\b"<<"\\bdefine\\b"; 26 | foreach (const QString &pattern, keywordPatterns) { 27 | rule.pattern = QRegularExpression(pattern); 28 | rule.format = keywordFormat; 29 | highlightingRules.append(rule); 30 | //! [0] //! [1] 31 | } 32 | //! [1] 33 | 34 | //! [2] 35 | //类 规则 36 | classFormat.setFontWeight(QFont::Bold); 37 | classFormat.setForeground(Qt::darkMagenta); 38 | rule.pattern = QRegularExpression("(?<=class\\s)\\w*"); 39 | rule.format = classFormat; 40 | highlightingRules.append(rule); 41 | //! [2] 42 | 43 | //! [3] 44 | //注释代码 规则 45 | singleLineCommentFormat.setForeground(Qt::green); 46 | rule.pattern = QRegularExpression("//[^\n]*"); 47 | rule.format = singleLineCommentFormat; 48 | highlightingRules.append(rule); 49 | 50 | multiLineCommentFormat.setForeground(Qt::green); 51 | //! [3] 52 | 53 | //! [4] 54 | //头文件包含规则 55 | quotationFormat.setForeground(Qt::darkGreen); 56 | rule.pattern = QRegularExpression("(?<=#include\\s)(<.*>)|(?<=#include)(<.*>)|(?<=#include\\s)(\".*\")|(?<=#include)(\".*\")|\".*\""); 57 | rule.format = quotationFormat; 58 | highlightingRules.append(rule); 59 | //! [4] 60 | 61 | //! [5] 62 | //函数 规则 63 | functionFormat.setFontItalic(true); 64 | functionFormat.setForeground(QColor(115,182,209)); 65 | rule.pattern = QRegularExpression("\\b[A-Za-z0-9_]+(?=\\()"); 66 | rule.format = functionFormat; 67 | highlightingRules.append(rule); 68 | //! [5] 69 | 70 | //! [6] 71 | commentStartExpression = QRegularExpression("/\\*"); 72 | commentEndExpression = QRegularExpression("\\*/"); 73 | } 74 | //! [6] 75 | 76 | //! [7] 77 | void Highlighter::highlightBlock(const QString &text) 78 | { 79 | foreach (const HighlightingRule &rule, highlightingRules) { 80 | QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text); 81 | while (matchIterator.hasNext()) { 82 | QRegularExpressionMatch match = matchIterator.next(); 83 | setFormat(match.capturedStart(), match.capturedLength(), rule.format); 84 | } 85 | } 86 | //! [7] //! [8] 87 | setCurrentBlockState(0); 88 | //! [8] 89 | 90 | //! [9] 91 | int startIndex = 0; 92 | if (previousBlockState() != 1) 93 | startIndex = text.indexOf(commentStartExpression); 94 | 95 | //! [9] //! [10] 96 | while (startIndex >= 0) { 97 | //! [10] //! [11] 98 | QRegularExpressionMatch match = commentEndExpression.match(text, startIndex); 99 | int endIndex = match.capturedStart(); 100 | int commentLength = 0; 101 | if (endIndex == -1) { 102 | setCurrentBlockState(1); 103 | commentLength = text.length() - startIndex; 104 | } else { 105 | commentLength = endIndex - startIndex 106 | + match.capturedLength(); 107 | } 108 | setFormat(startIndex, commentLength, multiLineCommentFormat); 109 | startIndex = text.indexOf(commentStartExpression, startIndex + commentLength); 110 | } 111 | } 112 | //! [11] 113 | -------------------------------------------------------------------------------- /highlighter.h: -------------------------------------------------------------------------------- 1 | #ifndef HIGHLIGHTER_H 2 | #define HIGHLIGHTER_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | QT_BEGIN_NAMESPACE 9 | class QTextDocument; 10 | QT_END_NAMESPACE 11 | 12 | //! [0] 13 | class Highlighter : public QSyntaxHighlighter 14 | { 15 | Q_OBJECT 16 | 17 | public: 18 | Highlighter(QTextDocument *parent = 0); 19 | 20 | protected: 21 | void highlightBlock(const QString &text) override; 22 | 23 | private: 24 | struct HighlightingRule 25 | { 26 | QRegularExpression pattern; 27 | QTextCharFormat format; 28 | }; 29 | QVector highlightingRules; 30 | 31 | QRegularExpression commentStartExpression; 32 | QRegularExpression commentEndExpression; 33 | 34 | QTextCharFormat keywordFormat; 35 | QTextCharFormat classFormat; 36 | QTextCharFormat singleLineCommentFormat; 37 | QTextCharFormat multiLineCommentFormat; 38 | QTextCharFormat quotationFormat; 39 | QTextCharFormat functionFormat; 40 | }; 41 | //! [0] 42 | 43 | #endif // HIGHLIGHTER_H 44 | -------------------------------------------------------------------------------- /icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m-iDev-0792/HJ-Editor/bf4d55f2522ca24850f136f79efcf1e3e893ebba/icon.icns -------------------------------------------------------------------------------- /icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m-iDev-0792/HJ-Editor/bf4d55f2522ca24850f136f79efcf1e3e893ebba/icon.ico -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m-iDev-0792/HJ-Editor/bf4d55f2522ca24850f136f79efcf1e3e893ebba/icon.png -------------------------------------------------------------------------------- /image.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | About.png 4 | New.png 5 | Open.png 6 | Save.png 7 | Redo.png 8 | Undo.png 9 | Run.png 10 | Setting.png 11 | stop.png 12 | 13 | 14 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | QApplication a(argc, argv); 7 | MainWindow w; 8 | w.show(); 9 | 10 | return a.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /mainwindow.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include "ui_mainwindow.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | MainWindow::MainWindow(QWidget *parent) : 8 | QMainWindow(parent), 9 | ui(new Ui::MainWindow) 10 | { 11 | firstLoad=true; 12 | ui->setupUi(this); 13 | setUpHighlighter(); 14 | //init status bar 15 | ui->outputText->parentWindow=this; 16 | ui->statusBar->showMessage(tr("Ready")); 17 | //--------init toolbar------------ 18 | //ui->statusBar->setStyleSheet("QStatusBar{background:rgb(50,50,50);}"); 19 | ui->mainToolBar->setMovable(false); 20 | ui->mainToolBar->setStyleSheet("QToolButton:hover {background-color:darkgray} QToolBar {background: rgb(82,82,82);border: none;}"); 21 | //-------------------------------- 22 | 23 | runIcon.addPixmap(QPixmap(":/image/Run.png")); 24 | stopIcon.addPixmap(QPixmap(":/image/stop.png")); 25 | 26 | //---------窗口背景颜色------------- 27 | QPalette windowPalette=this->palette(); 28 | windowPalette.setColor(QPalette::Active,QPalette::Window,QColor(82,82,82)); 29 | windowPalette.setColor(QPalette::Inactive,QPalette::Window,QColor(82,82,82)); 30 | this->setPalette(windowPalette); 31 | //-------------------------------- 32 | initFileData(); 33 | connect(ui->actionNewFile,SIGNAL(triggered(bool)),this,SLOT(newFile())); 34 | connect(ui->actionOpen,SIGNAL(triggered(bool)),this,SLOT(openFile())); 35 | connect(ui->actionSave_File,SIGNAL(triggered(bool)),this,SLOT(saveFile())); 36 | connect(ui->actionUndo,SIGNAL(triggered(bool)),this,SLOT(undo())); 37 | connect(ui->actionRedo,SIGNAL(triggered(bool)),this,SLOT(redo())); 38 | connect(ui->editor,SIGNAL(textChanged()),this,SLOT(changeSaveState())); 39 | connect(ui->actionRun,SIGNAL(triggered(bool)),this,SLOT(run())); 40 | connect(&process,SIGNAL(finished(int)),this,SLOT(runFinished(int))); 41 | connect(&process,SIGNAL(readyReadStandardOutput()),this,SLOT(updateOutput())); 42 | connect(&process,SIGNAL(readyReadStandardError()),this,SLOT(updateError())); 43 | connect(ui->actionAbout,SIGNAL(triggered(bool)),this,SLOT(about())); 44 | fileSaved=true; 45 | } 46 | 47 | MainWindow::~MainWindow() 48 | { 49 | delete ui; 50 | } 51 | void MainWindow::setUpHighlighter(){ 52 | QFont font; 53 | font.setFamily("Courier"); 54 | font.setFixedPitch(true); 55 | //font.setPointSize(20); 56 | ui->editor->setFont(font); 57 | ui->editor->setTabStopWidth(fontMetrics().width(QLatin1Char('9'))*4); 58 | highlighter=new Highlighter(ui->editor->document()); 59 | } 60 | 61 | void MainWindow::resizeEvent(QResizeEvent *event){ 62 | QMainWindow::resizeEvent(event); 63 | ui->editor->setGeometry(10,0,width()-20,height()-ui->statusBar->height()-ui->mainToolBar->height()-80-15); 64 | ui->outputText->setGeometry(10,ui->editor->height()+10,this->width()-20,80); 65 | } 66 | void MainWindow::initFileData(){ 67 | fileName=tr("Untitled.cpp"); 68 | filePath=tr("~/Desktop/Untitled.cpp"); 69 | fileSaved=true; 70 | isRunning=false; 71 | } 72 | void MainWindow::undo(){ 73 | ui->editor->undo(); 74 | } 75 | void MainWindow::redo(){ 76 | ui->editor->redo(); 77 | } 78 | void MainWindow::saveFile(){ 79 | QString savePath=QFileDialog::getSaveFileName(this,tr("选择保存路径与文件名"),fileName,tr("Cpp File(*.cpp *.c *.h)")); 80 | if(!savePath.isEmpty()){ 81 | QFile out(savePath); 82 | out.open(QIODevice::WriteOnly|QIODevice::Text); 83 | QTextStream str(&out); 84 | str<editor->toPlainText(); 85 | out.close(); 86 | fileSaved=true; 87 | QRegularExpression re(tr("(?<=\\/)\\w+\\.cpp|(?<=\\/)\\w+\\.c|(?<=\\/)\\w+\\.h")); 88 | fileName=re.match(savePath).captured(); 89 | filePath=savePath; 90 | this->setWindowTitle(tr("HJ Editor - ")+fileName); 91 | } 92 | } 93 | void MainWindow::newFile(){ 94 | MainWindow *newWindow=new MainWindow(); 95 | QRect newPos=this->geometry(); 96 | newWindow->setGeometry(newPos.x()+10,newPos.y()+10,newPos.width(),newPos.height()); 97 | newWindow->show(); 98 | } 99 | void MainWindow::openFile(){ 100 | if(!fileSaved){ 101 | if(QMessageBox::Save==QMessageBox::question(this,tr("文件未保存"),tr("当前文件没有保存,是否保存?"),QMessageBox::Save,QMessageBox::Cancel)) 102 | saveFile(); 103 | } 104 | QString openPath=QFileDialog::getOpenFileName(this,tr("选择要打开的文件"),filePath,tr("Cpp File(*.cpp *.c *.h)")); 105 | if(!openPath.isEmpty()){ 106 | QFile in(openPath); 107 | in.open(QIODevice::ReadOnly|QIODevice::Text); 108 | QTextStream str(&in); 109 | ui->editor->setPlainText(str.readAll()); 110 | QRegularExpression re(tr("(?<=\\/)\\w+\\.cpp|(?<=\\/)\\w+\\.c|(?<=\\/)\\w+\\.h")); 111 | fileName=re.match(openPath).captured(); 112 | this->setWindowTitle(tr("HJ Editor - ")+fileName); 113 | filePath=openPath; 114 | fileSaved=true; 115 | } 116 | } 117 | void MainWindow::run(){ 118 | if(isRunning){ 119 | process.terminate(); 120 | ui->actionRun->setIcon(runIcon); 121 | return; 122 | } 123 | if(!fileSaved){ 124 | if(QMessageBox::Save==QMessageBox::question(this,tr("文件未保存"),tr("文件保存后才能运行,是否保存?"),QMessageBox::Save,QMessageBox::Cancel)) 125 | saveFile(); 126 | } 127 | if(fileSaved){ 128 | //if(process!=nullptr)delete process; 129 | isRunning=true; 130 | ui->statusBar->showMessage(tr("程序运行中...")); 131 | ui->outputText->clear(); 132 | output.clear(); 133 | error.clear(); 134 | QString buildPath; 135 | QRegularExpression re(tr(".*(?=\\.cpp)|.*(?=\\.c)|.*(?=\\.h)")); 136 | buildPath=re.match(filePath).captured(); 137 | //qDebug()<outputText->setFocus(); 141 | ui->actionRun->setIcon(stopIcon); 142 | } 143 | } 144 | void MainWindow::runFinished(int code){ 145 | ui->actionRun->setIcon(runIcon); 146 | isRunning=false; 147 | qDebug()<outputText->setPlainText(output+tr("\n")+error); 153 | ui->outputText->setPlainText(ui->outputText->toPlainText()+output);//+tr("\n")); 154 | } 155 | void MainWindow::updateError(){ 156 | error=QString::fromLocal8Bit(process.readAllStandardError()); 157 | //ui->outputText->setPlainText(output+tr("\n")+error); 158 | ui->outputText->setPlainText(ui->outputText->toPlainText()+error);//+tr("\n")); 159 | process.terminate(); 160 | isRunning=false; 161 | } 162 | void MainWindow::inputData(QString data){ 163 | if(isRunning)process.write(data.toLocal8Bit()); 164 | } 165 | void MainWindow::closeEvent(QCloseEvent *event){ 166 | if(!fileSaved){ 167 | if(QMessageBox::Save==QMessageBox::question(this,tr("未保存就要退出?"),tr("当前文件没有保存,是否保存?不保存文件改动将会丢失"),QMessageBox::Save,QMessageBox::Cancel)) 168 | saveFile(); 169 | fileSaved=true; 170 | } 171 | } 172 | void MainWindow::about(){ 173 | QMessageBox::information(this,tr("关于"),tr(" HJ-Editor v1.0 \n 何振邦倾情奉献 \n更多信息访问huajihome.cn"),QMessageBox::Ok); 174 | } 175 | -------------------------------------------------------------------------------- /mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | #include "highlighter.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | namespace Ui { 11 | class MainWindow; 12 | } 13 | 14 | class MainWindow : public QMainWindow 15 | { 16 | Q_OBJECT 17 | 18 | public: 19 | explicit MainWindow(QWidget *parent = 0); 20 | ~MainWindow(); 21 | private: 22 | QIcon runIcon; 23 | QIcon stopIcon; 24 | Ui::MainWindow *ui; 25 | Highlighter *highlighter; 26 | QProcess process; 27 | void setUpHighlighter(); 28 | //---------记录文件信息---------- 29 | QString fileName; 30 | QString filePath; 31 | bool fileSaved; 32 | bool isRunning; 33 | //bool fileEdited; 34 | void initFileData(); 35 | bool firstLoad; 36 | //----------------------------- 37 | 38 | 39 | //---------code running data--- 40 | QString output; 41 | QString error; 42 | //----------------------------- 43 | public slots: 44 | void changeSaveState(){ 45 | //qDebug()<<"changed"; 46 | if(firstLoad&&fileSaved){ 47 | this->setWindowTitle(tr("HJ Editor - ")+fileName); 48 | firstLoad=false; 49 | return; 50 | } 51 | fileSaved=false; 52 | this->setWindowTitle(tr("HJ Editor - ")+fileName+tr("*")); 53 | } 54 | 55 | //---------工具栏响应函数--------- 56 | void newFile(); 57 | void saveFile(); 58 | void openFile(); 59 | void undo(); 60 | void redo(); 61 | void run(); 62 | //------------------------------ 63 | void runFinished(int code); 64 | void updateOutput(); 65 | void updateError(); 66 | void about(); 67 | public: 68 | void inputData(QString data); 69 | protected: 70 | void resizeEvent(QResizeEvent* event)override; 71 | void closeEvent(QCloseEvent* event)override; 72 | }; 73 | 74 | #endif // MAINWINDOW_H 75 | -------------------------------------------------------------------------------- /mainwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 630 10 | 508 11 | 12 | 13 | 14 | HJ Editor 15 | 16 | 17 | 18 | 19 | 20 | 10 21 | 0 22 | 611 23 | 331 24 | 25 | 26 | 27 | 28 | 29 | 30 | 10 31 | 340 32 | 611 33 | 81 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 0 42 | 0 43 | 630 44 | 22 45 | 46 | 47 | 48 | 49 | 文件 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 编辑 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 帮助 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 24 78 | 24 79 | 80 | 81 | 82 | Qt::ToolButtonIconOnly 83 | 84 | 85 | TopToolBarArea 86 | 87 | 88 | false 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | :/image/New.png:/image/New.png 103 | 104 | 105 | 新建 106 | 107 | 108 | 新建一个C++代码文件 109 | 110 | 111 | Ctrl+N 112 | 113 | 114 | 115 | 116 | 117 | :/image/Open.png:/image/Open.png 118 | 119 | 120 | 打开... 121 | 122 | 123 | 打开文件... 124 | 125 | 126 | Ctrl+O 127 | 128 | 129 | 130 | 131 | 全选 132 | 133 | 134 | 选择全部文本 135 | 136 | 137 | Ctrl+A 138 | 139 | 140 | 141 | 142 | 143 | :/image/Undo.png:/image/Undo.png 144 | 145 | 146 | 撤销 147 | 148 | 149 | Ctrl+Z 150 | 151 | 152 | 153 | 154 | 155 | :/image/Redo.png:/image/Redo.png 156 | 157 | 158 | 重做 159 | 160 | 161 | Ctrl+Shift+Z 162 | 163 | 164 | 165 | 166 | 关于 HJ Editor 167 | 168 | 169 | 关于 HJ Editor 170 | 171 | 172 | 173 | 174 | 说明文档 175 | 176 | 177 | 查看说明文档 178 | 179 | 180 | 181 | 182 | 183 | :/image/Save.png:/image/Save.png 184 | 185 | 186 | 保存文件 187 | 188 | 189 | 保存文件 190 | 191 | 192 | Ctrl+S 193 | 194 | 195 | 196 | 197 | 198 | :/image/Run.png:/image/Run.png 199 | 200 | 201 | 运行 202 | 203 | 204 | 编译并运行代码 205 | 206 | 207 | Ctrl+R 208 | 209 | 210 | 211 | 212 | 213 | :/image/Setting.png:/image/Setting.png 214 | 215 | 216 | 设置 217 | 218 | 219 | 更改编辑器的设置 220 | 221 | 222 | false 223 | 224 | 225 | 226 | 227 | 228 | 229 | CodeEditor 230 | QPlainTextEdit 231 |
codeeditor.h
232 |
233 | 234 | Console 235 | QPlainTextEdit 236 |
console.h
237 |
238 |
239 | 240 | 241 |
242 | -------------------------------------------------------------------------------- /stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m-iDev-0792/HJ-Editor/bf4d55f2522ca24850f136f79efcf1e3e893ebba/stop.png --------------------------------------------------------------------------------