无图不香....

.

技术点:

<1>Qt Gui.简单的控件和基础的qss知识足以

<2>Lua和C++交互。

编辑器部分基本上用的是网上某个不错的编辑器的源码。简单贴一下:

//codeeditor.h
#ifndef CODEEDITOR_H
#define CODEEDITOR_H#include <QPlainTextEdit>
#include <QObject>QT_BEGIN_NAMESPACE
class QPaintEvent;
class QResizeEvent;
class QSize;
class QWidget;
QT_END_NAMESPACEclass LineNumberArea;class CodeEditor : public QPlainTextEdit
{Q_OBJECTpublic:CodeEditor(QWidget *parent = 0);void lineNumberAreaPaintEvent(QPaintEvent *event);int lineNumberAreaWidth();protected:void resizeEvent(QResizeEvent *event);private slots:void updateLineNumberAreaWidth(int newBlockCount);void highlightCurrentLine();void updateLineNumberArea(const QRect &, int);private:LineNumberArea *lineNumberArea;
};class LineNumberArea : public QWidget{
public:LineNumberArea(CodeEditor *editor) : QWidget(editor) { codeEditor = editor; }QSize sizeHint() const { return QSize(codeEditor->lineNumberAreaWidth(), 0); }
protected:void paintEvent(QPaintEvent *event) { codeEditor->lineNumberAreaPaintEvent(event); }
private:CodeEditor *codeEditor;};
#endif
//codeeditor.cpp
#include "codeeditor.h"
#include <QWidget>
#include <QPainter>
#include <QTextBlock>CodeEditor::CodeEditor(QWidget *parent) : QPlainTextEdit(parent)
{lineNumberArea = new LineNumberArea(this);connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int)));connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int)));connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine()));updateLineNumberAreaWidth(0);highlightCurrentLine();
}int CodeEditor::lineNumberAreaWidth()
{int digits = 1;int max = qMax(1, blockCount());while (max >= 10) {max /= 10;++digits;}int space = 3 + fontMetrics().width(QLatin1Char('9')) * digits;return space;
}void CodeEditor::updateLineNumberAreaWidth(int /* newBlockCount */)
{setViewportMargins(lineNumberAreaWidth(), 0, 0, 0);
}void CodeEditor::updateLineNumberArea(const QRect &rect, int dy)
{if (dy)lineNumberArea->scroll(0, dy);elselineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height());if (rect.contains(viewport()->rect()))updateLineNumberAreaWidth(0);
}void CodeEditor::resizeEvent(QResizeEvent *e)
{QPlainTextEdit::resizeEvent(e);QRect cr = contentsRect();lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height()));
}void CodeEditor::highlightCurrentLine()
{QList<QTextEdit::ExtraSelection> extraSelections;if (!isReadOnly()) {QTextEdit::ExtraSelection selection;QColor lineColor = QColor(Qt::yellow).lighter(160);selection.format.setBackground(lineColor);selection.format.setProperty(QTextFormat::FullWidthSelection, true);selection.cursor = textCursor();selection.cursor.clearSelection();extraSelections.append(selection);}setExtraSelections(extraSelections);
}void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent *event)
{QPainter painter(lineNumberArea);painter.fillRect(event->rect(), Qt::lightGray);QTextBlock block = firstVisibleBlock();int blockNumber = block.blockNumber();int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top();int bottom = top + (int) blockBoundingRect(block).height();while (block.isValid() && top <= event->rect().bottom()) {if (block.isVisible() && bottom >= event->rect().top()) {QString number = QString::number(blockNumber + 1);painter.setPen(Qt::black);painter.drawText(0, top, lineNumberArea->width(), fontMetrics().height(),Qt::AlignRight, number);}block = block.next();top = bottom;bottom = top + (int) blockBoundingRect(block).height();++blockNumber;}
}

重点关注C++和Lua交互的部分:

(1)Lua库的编译。源文件可以到我的百度云盘链接下载:

链接:https://pan.baidu.com/s/1l6K2xiNQJS8023g7J5lUdQ   提取码:oa2y

(2)c++/Lua交互,不做过多解释,查看下代码和注释即可。

// registerfunctions.h#ifndef REGISTERFUNCTIONS
#define REGISTERFUNCTIONStypedef int (*luaTestFunction)(lua_State *L);
//  加载lua头文件
#include "../lua/src/lua.hpp"#include <cmath>// 第一步:定义lua调用的函数
static int myadd(lua_State* L)
{double op1 = lua_tonumber(L, 1);double op2 = lua_tonumber(L, 2);lua_pushnumber(L, op1 + op2);return 1;
}static int mysub(lua_State* L)
{double op1 = lua_tonumber(L, 1);double op2 = lua_tonumber(L, 2);lua_pushnumber(L, op1 - op2);return 1;
}static int l_sin(lua_State *L)
{// 如果给定虚拟栈中索引处的元素可以转换为数字,则返回转换后的数字,否则报错。double d = luaL_checknumber(L, 1);lua_pushnumber(L, sin(d));  /* push result *//* 这里可以看出,C可以返回给Lua多个结果,* 通过多次调用lua_push*(),之后return返回结果的数量。*/return 1;  /* number of results */
}int myprint( lua_State* L )
{//...return 0;
}提供的接口函数
const int TestFUNCNUM = 4;
const luaTestFunction MFUNC_P[] =
{myadd,mysub,l_sin,myprint
};const QString MACROFUNCNAME[] =
{"cadd","csub","csin","myprint"
};#ifdef USING_LUA_REGISTER
//待Lua调用的C注册函数。
static int add2(lua_State* L)
{//检查栈中的参数是否合法,1表示Lua调用时的第一个参数(从左到右),依此类推。//如果Lua代码在调用时传递的参数不为number,该函数将报错并终止程序的执行。double op1 = luaL_checknumber(L,1);double op2 = luaL_checknumber(L,2);//将函数的结果压入栈中。如果有多个返回值,可以在这里多次压入栈中。lua_pushnumber(L,op1 + op2);//返回值用于提示该C函数的返回值数量,即压入栈中的返回值数量。return 1;
}//另一个待Lua调用的C注册函数。
static int sub2(lua_State* L)
{double op1 = luaL_checknumber(L,1);double op2 = luaL_checknumber(L,2);lua_pushnumber(L,op1 - op2);return 1;
}
#endif#endif // REGISTERFUNCTIONS
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <stdio.h>
#include <iostream>
#include "../lua/src/lua.hpp"
#include <QString>
using namespace std;
#include <QStringList>namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = 0);~MainWindow();// 注册C++函数void register_functions();int initLua();// 打印lua堆栈void PrintLuaStack();
private slots:void on_pushButton_clicked();     // 编译void on_openpushButton_clicked(); // 打开void on_savepushButton_clicked(); //保存
private:Ui::MainWindow *ui;lua_State *L;
};#endif // MAINWINDOW_H
// mainwindow.cpp#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "registerfunctions.h"#include <QProcess>
#include <QDebug>
#include <QIcon>
#include <QFile>
#include <QTextStream>
#include <QFileDialog>
#include <QTextCodec>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <stdlib.h>
#include <windows.h>
#include "../lua/src/lua.hpp"
#include "../lua/src/lauxlib.h"
#include "../lua/src/lualib.h"void initStyleSheet(QMainWindow* m){m->setStyleSheet("QMainWindow{""min-width: 700px;    ""min-height: 500px;   ""border-radius: 20;   ""}""QPushButton {""color: black;      ""border-width: 1px; ""border-color: #339;""border-style: solid;"//"border-radius: 2;   ""padding: 3px;       ""font-size: 12px;    ""padding-left: 5px;  ""padding-right: 5px; ""background-color:white;""width: 45;""height:15;""}""QPushButton:hover{""color:white;""background-color:purple;""}""QPushButton:pressed{""color:white;""background-color:red;""}");
}MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);setWindowTitle("Lua Code Editor");setWindowIcon(QIcon(":/images/lua.png"));ui->textEdit->setMaximumHeight(100);initStyleSheet(this);/// 设置按键的快捷方式ui->savepushButton->setShortcut(QKeySequence::Save);ui->openpushButton->setShortcut(QKeySequence::Open);ui->pushButton->setShortcut(QKeySequence(QLatin1String("Ctrl+P")));//新建虚拟机L = luaL_newstate();if(L == NULL){cout << "null" << endl;}//载入库luaL_openlibs(L);/// 加载注册函数initLua();#ifdef USING_LUA_REGISTERregister_functions();
#endif
}MainWindow::~MainWindow()
{delete ui;//关闭虚拟机lua_close(L);
}int MainWindow::initLua()
{for(int i = 0; i< TestFUNCNUM;i++){lua_pushcfunction(L, MFUNC_P[i]);    // 将C函数转换为Lua的"function"并压入虚拟栈。lua_setglobal(L, MACROFUNCNAME[i].toUtf8().constData());    // 弹出栈顶元素,并在Lua中用名为"mysin"的全局变量存储。}
}void MainWindow::register_functions()
{
#ifdef USING_LUA_REGISTERlua_register(L, "add2", add2);lua_register(L, "sub2", sub2);
#endif
}/// 编译
void MainWindow::on_pushButton_clicked()
{QFile printfile("C:\\Users\\Administrator\\Desktop\\_cplusplus_lua\\LuaCodeEditor\\print.lua");if(!printfile.open(QIODevice::ReadWrite | QIODevice::Text)) return;QTextStream fileStream(&printfile);fileStream.setCodec(QTextCodec::codecForName("utf-8"));// 消除含有中文时乱码的问题QString qsAll = fileStream.readAll();printfile.close();qsAll +=  ui->plainTextEdit->toPlainText();qDebug() << qsAll;luaL_dostring(L, qsAll.toLatin1().constData());::Sleep(2000);QFile file("D:\\GAME_LOG.txt");if(!file.open(QIODevice::ReadWrite | QIODevice::Text)) return;QTextStream Stream(&file  );Stream.setCodec(QTextCodec::codecForName("utf-8"));// 消除含有中文时乱码的问题QString logtext = Stream.readAll();qDebug() << logtext;ui->textEdit->append(logtext);file.close();}/// 打印堆栈信息
void MainWindow::PrintLuaStack()
{int stackTop=lua_gettop(L);//获取栈顶的索引值int nIdx = 0;int nType;printf("--stack top(v)(%d)--\n", stackTop);//显示栈中的元素for(nIdx = stackTop;nIdx > 0;--nIdx){nType = lua_type(L, nIdx);printf("(i:%d) %s(%s)\n",nIdx, lua_typename(L,nType), lua_tostring(L,nIdx));}printf("--stack bottom--\n");
}/// 打开文件
void MainWindow::on_openpushButton_clicked()
{ui->plainTextEdit->clear();QString filepath = QFileDialog::getOpenFileName(this,QString("open file"),QApplication::applicationDirPath(),"Lua File(*.lua)");QFile file(filepath);if(!file.open(QIODevice::ReadWrite | QIODevice::Text)) return;QTextStream fileStream(&file  );fileStream.setCodec(QTextCodec::codecForName("utf-8"));// 消除含有中文时乱码的问题QString qsAll = fileStream.readAll();ui->plainTextEdit->insertPlainText(qsAll);file.close();
}/// 保存文件
void MainWindow::on_savepushButton_clicked()
{QString filepath = QFileDialog::getSaveFileName(this,QString("save file"),QApplication::applicationDirPath(),"Lua File(*.lua)");QFile file(filepath);if(!file.open(QIODevice::ReadWrite | QIODevice::Text)) return;QTextStream in(&file);in.setCodec(QTextCodec::codecForName("utf-8"));in << ui->plainTextEdit->toPlainText();file.close();
}
// ui_mainwindow.h#ifndef UI_MAINWINDOW_H
#define UI_MAINWINDOW_H#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QHBoxLayout>
#include <QtGui/QHeaderView>
#include <QtGui/QMainWindow>
#include <QtGui/QPushButton>
#include <QtGui/QSpacerItem>
#include <QtGui/QTextEdit>
#include <QtGui/QVBoxLayout>
#include <QtGui/QWidget>
#include <codeeditor.h>QT_BEGIN_NAMESPACEclass Ui_MainWindow
{
public:QWidget *centralWidget;QVBoxLayout *verticalLayout;QHBoxLayout *horizontalLayout;QSpacerItem *horizontalSpacer;QPushButton *openpushButton;QPushButton *savepushButton;QPushButton *pushButton;CodeEditor *plainTextEdit;QTextEdit *textEdit;void setupUi(QMainWindow *MainWindow){if (MainWindow->objectName().isEmpty())MainWindow->setObjectName(QString::fromUtf8("MainWindow"));MainWindow->resize(551, 337);centralWidget = new QWidget(MainWindow);centralWidget->setObjectName(QString::fromUtf8("centralWidget"));verticalLayout = new QVBoxLayout(centralWidget);verticalLayout->setSpacing(6);verticalLayout->setContentsMargins(11, 11, 11, 11);verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));horizontalLayout = new QHBoxLayout();horizontalLayout->setSpacing(6);horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);horizontalLayout->addItem(horizontalSpacer);openpushButton = new QPushButton(centralWidget);openpushButton->setObjectName(QString::fromUtf8("openpushButton"));horizontalLayout->addWidget(openpushButton);savepushButton = new QPushButton(centralWidget);savepushButton->setObjectName(QString::fromUtf8("savepushButton"));horizontalLayout->addWidget(savepushButton);pushButton = new QPushButton(centralWidget);pushButton->setObjectName(QString::fromUtf8("pushButton"));horizontalLayout->addWidget(pushButton);verticalLayout->addLayout(horizontalLayout);plainTextEdit = new CodeEditor(centralWidget);plainTextEdit->setObjectName(QString::fromUtf8("plainTextEdit"));verticalLayout->addWidget(plainTextEdit);textEdit = new QTextEdit(centralWidget);textEdit->setObjectName(QString::fromUtf8("textEdit"));verticalLayout->addWidget(textEdit);MainWindow->setCentralWidget(centralWidget);retranslateUi(MainWindow);QMetaObject::connectSlotsByName(MainWindow);} // setupUivoid retranslateUi(QMainWindow *MainWindow){MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", 0, QApplication::UnicodeUTF8));openpushButton->setText(QApplication::translate("MainWindow", "Open", 0, QApplication::UnicodeUTF8));savepushButton->setText(QApplication::translate("MainWindow", "Save", 0, QApplication::UnicodeUTF8));pushButton->setText(QApplication::translate("MainWindow", "Compile", 0, QApplication::UnicodeUTF8));} // retranslateUi};namespace Ui {class MainWindow: public Ui_MainWindow {};
} // namespace UiQT_END_NAMESPACE#endif // UI_MAINWINDOW_H

仅供学习参考。存在bug和需要优化的地方。后续再完善(其实也是闲来无事,随便玩玩 )。

(1)luai脚本编译信息显示需要优化。

(2)lua脚本打开可以增加支持拖拽文件打开功能。

(3)..... 其他若干云云.....

基于Qt实现的自定义简易Lua脚本编辑器相关推荐

  1. Android lua编辑工具,Lua脚本编辑器app下载-Lua脚本编辑器手机版下载 v1.0.2_5577安卓网...

    Lua脚本编辑器app下载推荐给大家,这是一款非常简洁好用的打码编辑神器,用户轻松下载使用,对代码进行编辑.测试.查错等,手机也能写代码,支持多种文件格式,打开.导出.保存都很方便. [软件介绍] L ...

  2. oracle 编辑器 辅助,lua脚本编辑器下载执行oracle ddl

    二.利用adodc(ADODataControl)进行数据库链接: privateform_load() DimstrAsString'定义 str=App.Path IfRight(str,1)&l ...

  3. lua脚本编辑器SciTE设置背景颜色

    black=#000000 #C0C0C0 stdstyle.fg=fore:#C0C0C0 stdstyle.bg=back:$(black) stdstyle.syntaxerror=back:# ...

  4. 插件使用之加载自定义lua脚本

    为什么80%的码农都做不了架构师?>>>    xmake里面的lua脚本加载插件,可以让你方便调试和编写一些自定义的lua脚本,这个时候xmake就是一个纯lua的加载引擎.. 例 ...

  5. QT课程设计:基于QT的图像处理程序

    本文用于2022-23学年海哥QT课课程设计的制作过程索引 以下先贴放课设要求 课程设计 一.课程设计要求(每人1题) 基于QT Creator设计一个简易的数字图像处理软件,要求: 工程名含有姓名拼 ...

  6. 在windows程序中嵌入Lua脚本引擎--建立一个简易的“云命令”执行的系统

    在<在windows程序中嵌入Lua脚本引擎--使用VS IDE编译Luajit脚本引擎>开始处,我提到某公司被指责使用"云命令"暗杀一些软件.本文将讲述如何去模拟一个 ...

  7. 使用tolua++编译pkg,从而创建自定义类让Lua脚本使用

    2019独角兽企业重金招聘Python工程师标准>>> 在Lua第三篇中介绍了,如何在cocos2dx中使用Lua创建自定义类供Lua脚本调用使用,当时出于Himi对Lua研究不够深 ...

  8. 基于Lua脚本语言的嵌入式UART通信的实现

    随着变电站智能化程度的逐步提高,对温度.湿度等现场状态参量的采集需求也越来越多.就目前而言,在现场应用中,此类设备多采用RS232或RS485等UART串行通信方式和IED(Intelligent E ...

  9. Win32下 Qt与Lua交互使用(二):在Lua脚本中使用Qt类

    话接上篇.成功配置好Qt+Lua+toLua后,我们可以实现在Lua脚本中使用各个Qt的类.直接看代码吧. #include "include/lua.hpp" #include ...

最新文章

  1. 坑中速记整理! 使用 kotlin 写第一个 ReactNative Android 模块
  2. 经典算法面试题目-置矩阵行列元素为0(1.7)
  3. 69.数据库系统的两级映射(映像)
  4. 【维纳滤波】通过MATLAB自带的维纳滤波函数进行滤波
  5. huggingface实操_Transformers 简介(上)
  6. proxomitron 个人代理工具
  7. 月度开销(信息学奥赛一本通-T1243)
  8. Nodejs入门[在互联网上非常经常,非常疯狂的一个转载]
  9. Hibernate的单向N-N关联(四)
  10. 结对-贪吃蛇游戏-测试过程
  11. UML第二次作业 类图中类的表示
  12. 【操作系统实验】设备驱动(Linux环境下)
  13. 模拟电子技术,电力电子技术
  14. java yyyymmdd 的date_用Java解析YYYYMMdd日期的最快方法
  15. 解决MacOS系统字体不识别STXingkai问题
  16. Python——批量发送邮件(持续更新)
  17. 计算力矩——计算关节力矩以平衡端点力和力矩
  18. ionic 下拉刷新 — ion-refresher
  19. PTA - 二分查找
  20. Nexus 3 Docker仓库(hosted、proxy、group)模式 讲解

热门文章

  1. C++几种常用设计模式
  2. 校园招聘面试精典博文java
  3. 服务器如何开多个虚拟机,服务器运行多个虚拟机
  4. 05 | 计算机指令:让我们试试用纸带编程
  5. Word文档内容如何添加双删除线
  6. 在线音频、视频、图片测试链接
  7. CADENCE Allegro反白丝印的制作
  8. Android设计模式之建造者模式builder
  9. 关于es6新特性的总结
  10. creo 6.0—15 creo草绘尺寸标注、修改