实现一个python代码编辑器

目录

qt的QWebEngineView类

python的flask 

bug1:跨域支持

bug2:XMLHttpRequest 没有把数据send过去

bug3:执行exec函数 name 'xx' is not defined

结果展示(qt显示html)

go的net/http


代码编辑器采用了monacoEditor,一个现成的编辑器。网上有很多文档介绍和开源项目,但是怎么说呢,跟着做,可以实现一个网页编辑器,可以高亮python的语法,但是没有python的提示,找不到可以参考的,js我也不会,看的着实云里雾里。
【提示】在VsCode上运行比较方便

--------------------开源项目-------------------------

我参考了这个

vue-monaco-editor-demo: vue 使用 monaco-editor 实现在线代码在线编辑器 (gitee.com)

下面python提示的第二个参考也可以(我试过了,这个内容比较丰富,但是编译出来的dist在qt上显示不出网页,所以用了上面这个) 

----------------------------------------------------------

目前我对实现一个python代码编辑器的理解是这样的:先搞一个前端的代码编辑器html,然后在你的工程里显示html。但是编辑器里的代码怎么运行,我还没有头绪。

目前的进度就是前端可以生成一个网页,可以写python代码,有高亮,但是没有python提示。

-------------------更新   python 提示 ----------------------

参考

如何实现一个在线代码编辑器_哔哩哔哩_bilibili

Vue3中使用Monaco Editor代码编辑器记录——主动触发代码补全功能(python和sql为例)~持续更新_monaco.languages.registercompletionitemprovider-优快云博客

------------------------------------------------------------------ 

ok,参考上面的两个,python提示出来了(就是下面的这块代码,加入初始化运行的函数里)。这个B站的视频,我觉得挺好的,听完感觉是逻辑清晰了(对我这种不会写网页的小白来说)

          monaco.languages.registerCompletionItemProvider('python', {
				provideCompletionItems: function () {
					let suggestions = [];
					// 这个keywords就是python.js文件中有的
					pythonLanguage.keywords.forEach(item => {
						suggestions.push({
							label: item,
							kind: monaco.languages.CompletionItemKind.Keyword,
							insertText: item
						});
					})
					return {
						// 最后要返回一个数组
						suggestions:suggestions
					};
			  },
		  });

下一步的计划是显示网页,尝试了几个不同的方法。这几个方法怎么说呢,都可以显示html,但是上一步的编译出来的html其实还要带文件夹一起,感觉文件大小有点大,对于一个项目来说,不是一个很好的选择。

qt的QWebEngineView类

        qt有一个类,QWebEngineView可以用来显示html,具体用法就是用load函数,传入html的路径。

【注意】这里的html是上一步的文件build后生成在dist文件里的html,要把整个dist文件夹拷过来放在qt的运行目录里。

    MonacoEditor w;
    QWebEngineView view(&w);
    QString path = QApplication::applicationDirPath() + "/dist/index.html";
    view.load(QUrl(path));
    w.setCentralWidget(&view);
    w.show();

python的flask 

        flask是python的一个Web 框架。下面的代码是网上教程看的。用flask可以装一个pycharm。

from flask import  Flask,render_template
app=Flask(__name__)         #实例化并命名为app实例
#启动这个WEB服务
@app.route('/')
def index():
    msg = "hello world"
    #在文件目录下创建Templates文件夹,里面新建index.html
    return render_template("index.html",data = msg)  # 加入变量传递  
    
if __name__=="__main__":
    app.run(port=8088,host="127.0.0.1",debug=True)

  更新:html作为前端,绑定端口8080,flask作为后端,绑定端口为8088。现在开始思考怎么让后端获取到前端输入的python代码。

bug1:跨域支持

        在尝试过程中,html使用XMLHttpRequest,用GET发送内容,但是对应的status是0,responseText是空。进入html按F12进入终端发现下面报错。就是跨域失败,网上有的说前端加header["Access-Control-Allow-Origin","*"];,但对我这个来说没有用,这里使用flask的跨域支持可以参考下面这个博客,使用flask_cors模块,问题成功解决。[736]Flask - 解决Access-Control-Allow-Origin跨域请求问题_flask make_response no 'access-control-allow-origi-优快云博客

在终端输入 pip install -U flask-cors,安装cors,然后再py文件中加入即可。

from flask import  Flask,render_template,request
from flask_cors import CORS
app=Flask(__name__)         #实例化并命名为app实例

# 跨域支持
CORS(app)

再html点击运行按钮,发现status状态已经是200,表示请求成功 。

 

bug2:XMLHttpRequest 没有把数据send过去

        刚解决完bug1,bug2就来了,一坑接一坑。

        后端收到的数据一直是None,百度上说法也挺多。有人说是前端的参数类型和后端的参数类型不匹配,有人说在前端加XMLHttpRequest.setRequestHeader("Content-type","application/json");,有人说是访问一个不存在的网页或者输入了一个错误的网址,也有可能是服务器的配置。

我这个是点击后端生成的网页发现不存在。后面发现时因为我的后端def index()函数没有return,加个return返回值就行了。

bug3:执行exec函数 name 'xx' is not defined

        这里返回的是标准输出。单单的print函数是没问题的,但是稍微复杂一点就会出现问题,会提示name 'xx' is not defined。

        在网上找一个简单的python代码测试

# 定义两个列表
list1 = [1, 2, 3, 4, 5]
list2 = [4, 5, 6, 7, 8]

# 使用列表推导式找出两个列表中不同的元素
difference = [item for item in list1 if item not in list2]
print(difference)

 后端收到的内容是这样的

exec执行data,前端返回报错。

但是list2是存在的,这个问题我不知道怎么解决,我试了其他的代码都是可以的,就这个有问题,暂时不管了。


【更新】在看下一个方法的时候,看到了argparse 模块

argparse是一个Python模块:命令行选项、参数和子命令解析器

1. argparse 模块可以让人轻松编写用户友好的命令行接口。程序定义它需要的参数
2. 其次,argparse 将弄清如何从 sys.argv 解析出那些参数。
3. argparse 模块还会自动生成帮助和使用手册,并在用户给程序传入无效参数时报出错误信息。

 

结果展示(qt显示html)

【提示】flask后端执行代码我用exec函数,实际上不太合适,`exec`可以执行任意代码,所以它可能带来安全问题和潜在的错误,如果是工业项目建议换其他的方法。

Python、Tornado、markdown编辑器

Tornado是什么?Tornado既是web server又是web框架

基于开源项目GitHub - vimior/PythonWebIDE: A Simple Python Web IDE

bug1: No module named 'distutils'

参考关于 No module named ‘distutils‘的错误_no module named 'distutils-优快云博客

在终端输入pip install setuptools即可解决。

go的net/http

        这个还没开始,等会去试。

<think>我们正在讨论如何使用monaco-editor来格式化Python代码。根据引用[^1],我们知道monaco-editor支持代码格式化功能。但是,需要注意的是,monaco-editor本身并不内置针对各种语言的具体格式化规则,通常需要配置相应的格式化提供程序(formatter)。对于Python代码,我们需要使用一个外部的格式化工具(如autopep8、black或yapf)或者使用monaco-editor能够调用的格式化服务。然而,由于monaco-editor运行在浏览器环境中,我们通常不能直接调用这些Python工具(因为它们需要在服务器端运行)。因此,我们需要考虑以下两种方式:1.使用monaco-editor的语言服务注册一个格式化提供程序,这个提供程序调用一个后端服务(该后端服务使用上述Python格式化工具)。2.使用可以在浏览器中运行的Python格式化工具(例如,使用Pyodide或WebAssembly版本的工具),但这可能比较复杂。但是,monaco-editor自带了针对JavaScript/TypeScript等语言的格式化功能,对于其他语言需要额外配置。由于我们无法直接在浏览器中运行Python代码格式化工具(除非有对应的WebAssembly版本),因此实际应用中通常通过向后端发送格式化请求来实现。步骤大致如下:1.初始化monaco-editor。2.为Python注册一个格式化程序(通过monaco.languages.registerDocumentFormattingEditProvider)。3.在格式化程序内部,发送当前代码到后端服务,获取格式化后的代码,然后返回编辑操作(TextEdit的数组)。下面是一个示例代码:```javascript//初始化编辑器consteditor=monaco.editor.create(document.getElementById('container'),{value:"print('HelloWorld')",language:'python'});//注册格式化提供程序monaco.languages.registerDocumentFormattingEditProvider('python',{provideDocumentFormattingEdits:function(model,options,token){//这里我们模拟一个格式化的操作,实际应该发送到后端returnnewPromise((resolve,reject)=>{//模拟调用后端格式化服务//假设我们有一个函数callFormatService发送代码到后端并返回格式化后的文本callFormatService(model.getValue()).then(formattedCode=>{//计算整个文档的范围(从第一行第一列到最后一行最后一列)constlastLine=model.getLineCount();constlastColumn=model.getLineMaxColumn(lastLine);constrange={startLineNumber:1,startColumn:1,endLineNumber:lastLine,endColumn:lastColumn};//返回一个TextEdit数组,用于替换整个文档resolve([{text:formattedCode,range:range}]);}).catch(err=>reject(err));});}});//假设的调用后端服务的函数functioncallFormatService(code){//实际项目中,这里使用fetch或axios发送请求到你的后端API//后端API调用类似autopep8或black的工具格式化代码,然后返回//这里我们简单模拟,直接返回一段格式化后的代码(实际中这个格式化可能只是简单的缩进调整)returnnewPromise((resolve)=>{//模拟网络延迟setTimeout(()=>{//这里应该返回从后端获取的格式化后的代码//注意:这只是一个示例,实际格式化工作由后端完成resolve(code);//实际中需要替换为格式化后的代码},200);});}```在上面的代码中,我们注册了一个格式化提供程序,当用户触发格式化操作时(通常是按下快捷键,如Alt+Shift+F),就会调用这个提供程序。该提供程序将整个代码发送到后端服务,并获取格式化后的代码,然后用它替换原来的代码。注意:上面的代码只是一个示例,你需要替换`callFormatService`函数为实际的后端调用。后端服务需要实现一个API,接收Python代码,然后使用如autopep8、black等工具格式化,并将结果返回。另外,你也可以在浏览器端使用一些轻量级的格式化规则(比如只调整缩进)来模拟格式化,但这样无法与专业的Python格式化工具相比。§§相关问题§§1.如何配置monaco-editor来支持Python的语法高亮和自动补全?2.monaco-editor除了代码格式化外还有哪些功能?3.如何为monaco-editor添加自定义的快捷键(如绑定格式化操作)?4.如何在前端项目中集成monaco-editor?</think> 我将指导你在 Monaco Editor实现 Python 代码格式化,并提供完整的解决方案。 ### 使用 Monaco Editor 格式化 Python 代码 要使用 Monaco Editor 格式化 Python 代码,需按照以下步骤操作: 1. **安装 Monaco Editor** ```bash npm install monaco-editor # 或使用 CDN <script src="https://cdn.jsdelivr.net/npm/monaco-editor@0.21.2/min/vs/loader.js"></script> ``` 2. **基础编辑器配置** ```html <div id="container" style="height:400px;border:1px solid #ccc"></div> <script> require.config({ paths: { 'vs': 'https://cdn.jsdelivr.net/npm/monaco-editor@0.21.2/min/vs' }}); require(['vs/editor/editor.main'], function() { // 创建编辑器实例 const editor = monaco.editor.create(document.getElementById('container'), { value: "# 输入Python代码\nimport sys\n\nfor i in range(10):\n print(i)", language: 'python', minimap: { enabled: false }, automaticLayout: true }); }); </script> ``` 3. **添加格式化功能** ```javascript // 注册格式化提供程序 monaco.languages.registerDocumentFormattingEditProvider('python', { provideDocumentFormattingEdits: function(model, options) { // 使用 autopep8 或 black 等工具格式化代码 const formattedCode = formatPythonCode(model.getValue()); return [{ text: formattedCode, range: model.getFullModelRange() }]; } }); // 格式化功能实现(需对接格式化API) async function formatPythonCode(code) { // 实际项目中应调用后端格式化服务 const response = await fetch('/api/format-python', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ code }) }); return await response.json().formattedCode; } ``` ### 格式化的实现建议 1. **后端格式化服务** ```python # Python Flask 示例(需安装 autopep8) from flask import Flask, jsonify, request import autopep8 app = Flask(__name__) @app.route('/api/format-python', methods=['POST']) def format_code(): code = request.json['code'] formatted = autopep8.fix_code(code) return jsonify(formattedCode=formatted) ``` 2. **关键功能触发方式** ```javascript // 手动触发格式化(快捷键:Alt + Shift + F) editor.addCommand( monaco.KeyMod.Alt | monaco.KeyMod.Shift | monaco.KeyCode.KeyF, () => editor.getAction('editor.action.formatDocument').run() ); ``` ### 注意事项 1. Monaco Editor 本身不包含 Python 格式化逻辑,需配合后端的 Python 格式化工具如: - $ \text{autopep8} $ - $ \text{black} $ - $ \text{yapf} $ 2. 完整实现需要安全考虑,避免执行不受信任的代码[^1] ### 集成效果 Monaco Editor 提供出色的代码编辑体验,包括: - 语法高亮($ \text{Python} $ 语法) - 智能提示 - 错误检查 - 代码折叠 - 格式化集成
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值