zoukankan      html  css  js  c++  java
  • PyQt5 打造编辑器

    效果如下

    • 多标签
    • 智能提示
    • 快捷键

    思路

    编辑器(右侧部分)采用 monaco editor ,monaco editor是微软开源的编辑器,使用TypeScript编写,是大名鼎鼎的VSCode编辑器的内核。所以其使用习惯和VSCode完全相同。 monaco editor

    monaco editor 是需要运行在浏览器中的(supports IE 11, Edge, Chrome, Firefox, Safari and Opera.), 那么怎么能将它嵌入Qt中呢? Qwebengineview 控件可以帮我们实现.

    1. 定义编辑器类

    Editor类继承自QWebEngineView,所以才能使用load方法加载本地HTML文件

    import os
    from PyQt5 import QtWidgets
    from PyQt5.QtCore import QUrl
    from PyQt5.QtWebEngineWidgets import QWebEngineView
    
    
    class Editor(QWebEngineView):
        def __init__(self, par):
            super().__init__(par)
            self.editor_flag = []
    
            # 这里是本地html路径,需根据实际情况进行修改.
            self.editor_index = (os.path.split(os.path.realpath(__file__))[0]) + "/../utils/index.html"
            self.load(QUrl.fromLocalFile(self.editor_index))
    
        def get_value(self, callback):
            """设置编辑器内容"""
            self.page().runJavaScript("monaco.editor.getModels()[0].getValue()", callback)
    
        def set_value(self, data):
            """获取编辑器内容"""
            import base64
            data = base64.b64encode(data.encode())
            data = data.decode()
            self.page().runJavaScript("monaco.editor.getModels()[0].setValue(Base.decode('{}'))".format(data))
    
        def change_language(self, lan):
            """切换智能提示语言"""
            self.page().runJavaScript("monaco.editor.setModelLanguage(monaco.editor.getModels()[0],'{}')".format(lan))
    
    
    if __name__ == "__main__":
        import sys
        app = QtWidgets.QApplication(sys.argv)
        w = Editor(None)
        w.setWindowTitle('Editor')
        w.show()
        sys.exit(app.exec_())
    

    index.html 其实就是monaco editor 的入口,内容如下:

    引入的monaco editor文件需要自行下载 下载地址

    <!DOCTYPE html>
    <html>
    <head>
        <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
        <style type="text/css">
            html, body {
                 100%;
                height: 100%;
                margin: 0;
                padding: 0;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
    
    <div id="container" style="100%;height:100%"></div>
    
    <!-- 引入base64方法,设置编辑器内容时使用-->
    <script src="./base64.js"></script>   
    <!-- 根据实际路径进行修改 -->
    <script src="./package/dev/vs/loader.js"></script>
    <script>
        // <!-- 根据实际路径进行修改 -->
        require.config({paths: {'vs': './package/dev/vs'}});
        require(['vs/editor/editor.main'], function () {
            monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
            noSemanticValidation: true,
            noSyntaxValidation: true
        });
            editor = monaco.editor.create(document.getElementById('container'), {
                value: "",
                language: 'javascript',  //默认语言
                mouseWheelZoom:true,     // 鼠标滚轮缩放
                wordWrap:"on",           // 自动换行
                scrollBeyondLastLine:false,
                minimap:{
                    enabled:false          // 显示右侧小地图
                }
            });
            window.onresize = function () {
                editor.layout();
            };
        });
    </script>
    </body>
    </html>
    

    启动后效果如下:

    2. 在主界面中添加编辑器标签(多标签的实现)

    • 增加标签
    • 关闭标签

    QTabwidget刚好可以满足多标签的需求,下面有几个问题要解决:

    1. 每个标签右上角显示关闭按钮
      默认情况下,标签是不显示关闭按钮的,可以通过设置self.tabWidget.setTabsClosable(True)方法显示出关闭按钮.

    2. 关闭按钮点击事件

      self.tabWidget.tabCloseRequested.connect(self.closeTab)
      
      def closeTab(self):
      # 获取当前处于激活状态的标签
      i = self.tabWidget.currentIndex()
      self.tabWidget.removeTab(i)
      
    3. 增加页面

      new_tab = Editor(self)
      self.tabWidget.addTab(new_tab, tab_name)
      self.tabWidget.setCurrentWidget(new_tab)
      
  • 相关阅读:
    关于GridView Master-Detail 不支持明细属性为IEnumerable、IList问题
    GridControl摘录
    DevExpress中chartControl中实现统计图功能
    DevExpress中GridControl列转义的实现方法
    DevExpress实现根据行,列索引来获取RepositoryItem的方法
    修改yum源为阿里云的
    使用sendmail来发邮件
    nginx默认访问目录时显示403错误
    同时调整lv分区的大小(减少一个,增加另一个)
    ORA-00257错误的解决办法
  • 原文地址:https://www.cnblogs.com/aloe-n/p/9583949.html
Copyright © 2011-2022 走看看