QScintilla for Python 中文文档
1. QScintilla for Python介绍
1.1 什么是QScintilla?
Scintilla
Scintilla是一个免费的“源代码编辑组件”。
- Scintilla只是一个软件模块,不是那种直接运行的桌面程序。但我们可以利用它来开发代码编辑器桌面应用程序。
- Scintilla的目标是“源代码编辑”。它包括支持语法样式,错误指示器,代码完成和调用提示等功能…
Scintilla是一个用于构建自己的IDE的软件工具!大名鼎鼎的Notepad ++无疑是最受欢迎的基于Scintilla的源代码编辑器。Scintilla的官方网站:https://www.scintilla.org/
--------------------------------
QScintilla
QScintilla是用C++编写的一个可以应用在Qt程序中,为Qt程序快速创建编辑器界面的模块。
--------------------------------
QScintilla for Python
Qt
有基于python接口的pyqt5
.现在QScintilla
也有基于python接口的QScintilla for PyQt
.在pyqt程序中我们也可以快速开发一个自己的IDE桌面应用程序了。
比如像下面这样的(来自官方的样图):
1.2 安装
- 如果你没有安装pyqt5,请先安装pyqt5。
# 安装pyqt5
pip install pyqt5
- 安装QScintilla
# 安装qscintilla
pip install qscintilla
1.3 类层次结构
1. QScintilla包
当您为Python安装QScintilla时,它会被添加到PyQt5包中:
PyQt5
|---PyQt5.QtCore
|---PyQt5.QtGui
|--- ...
|---PyQt5.QSci
...
所有QScintilla类都在PyQt5.QSci包中分组. 接下来我们一个个看看
2. QSciScintillaBase和QSciScintilla
最基本的类是QSciScintillaBase
。它是文本编辑的基类。正如您在下图中看到的,此类直接从PyQt5中的QAbstractScrollArea
类继承。这是一个相当逻辑的选择,不是吗?实际上,每个文本编辑器都可以某种方式滚动。
该QSciScintillaBase
类不会是你将与直接交互的类。它非常低级,因此很难使用。QScintilla提供了一个高级子类:QSciScintilla
。您的文本编辑器将是此类的对象。它有一个非常类似Qt的API,所以Qt粉丝会有宾至如归的感觉。在某些情况下,这个高级课程可能缺少您需要的非常具体的功能。那时你可以从超类QSciScintillaBase
调用函数。
3. QSciLexer
语法高亮所需的对象称为词法分析器。一旦创建并配置了这样的词法分析器对象,就需要将其插入文本编辑器(这是QSciScintilla类中的对象)。Huray,文本编辑器中的代码可以获得彩虹的所有颜色!
但是你如何制作一个词法分析器对象呢?QScintilla为此提供了QSciLexer
类。类本身是抽象的,因此在创建对象之前需要先将其子类化:
4. QSciAPIs
一个好的文本编辑器提供的不仅仅是语法高亮。例如,考虑呼叫提示和自动完成。这些功能存在于QSciAPIs
类中。您需要从该类创建一个对象并将其插入您的lexer
对象:
2. 尝试编写一个简单的桌面编辑器应用
我们用pyqt5和QScintilla来编写一个简单的桌面编辑器应用:
该QMainWindow
的对象是你的GUI的窗口。您可以为它定义布局,并将所有组件(窗口小部件)一个接一个地填充到窗口中。我们这里只有两个组件:QPushButton
和QsciScintilla
对象。我们真的不需要按钮,但无论如何我们都把它放在那里。该QsciScintilla
对象就是它的全部。这是QScintilla编辑!我们简单的编辑器不需要词法分析器或其他复杂的东西。所以现在不需要QsciLexer
和QsciAPIs
类。
在构建GUI时,我通常从子类化QMainWindow
类开始。首先我定义窗口的几何形状,接下来我创建一个中心框架:self.__frm
。此框架将是我GUI中所有小部件的父级。我为这个框架定义了一个布局:self.__lyt
使得所有添加的小部件垂直定位,一个在另一个之下。
如您所知,我创建了两个小部件:QPushButton
和QsciScintilla
编辑器。我将它们添加到布局中,如下所示:
self.__lyt.addWidget(self.__btn)
self.__lyt.addWidget(self.__editor)
完整示例:
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.Qsci import *
class CustomMainWindow(QMainWindow):
def __init__(self):
super(CustomMainWindow, self).__init__()
# 1. 设置窗口的宽高和标题
self.setGeometry(300, 300, 800, 400)
self.setWindowTitle("QScintilla Test")
# 2. 创建一个frame,并设置布局
self.__frm = QFrame(self)
self.__frm.setStyleSheet("QWidget { background-color: #ffeaeaea }")
self.__lyt = QVBoxLayout()
self.__frm.setLayout(self.__lyt)
self.setCentralWidget(self.__frm)
self.__myFont = QFont()
self.__myFont.setPointSize(14)
# 3. 添加按钮
self.__btn = QPushButton("Qsci")
self.__btn.setFixedWidth(50)
self.__btn.setFixedHeight(50)
self.__btn.clicked.connect(self.__btn_action)
self.__btn.setFont(self.__myFont)
self.__lyt.addWidget(self.__btn)
# 创建编辑器
self.__editor = QsciScintilla()
self.__editor.setText("Hello\n")
self.__editor.append("world")
self.__editor.setLexer(None)
self.__editor.setUtf8(True) # Set encoding to UTF-8
self.__editor.setFont(self.__myFont) # Will be overridden by lexer!
# 把编辑器添加到布局
self.__lyt.addWidget(self.__editor)
self.show()
def __btn_action(self):
print("Hello World!")
if __name__ == '__main__':
app = QApplication(sys.argv)
QApplication.setStyle(QStyleFactory.create('Fusion'))
myGUI = CustomMainWindow()
sys.exit(app.exec_())
执行代码,我们就可以看到一个嵌入了QScintilla
编辑器的窗口。
3. 常见的设置选项
3.1 文字断行
没有文字断行设置可能会导致一行文本变得越来越长,最终挤出了编辑界面。文本换行会自动中断该行,以便所有内容都适合可视窗口。但请注意,换行不会增加行号
,这太棒了!想象一下,如果您的文本编辑器开始使用行号,那只是因为您的显示器不是那么宽…
断行模式
文字断行有很多种。您可以使用该功能设置模式 setWrapMode(WRAP_MODE)
:
WrapNone 无断行模式
self.__editor.setWrapMode(QsciScintilla.WrapNone)
WrapWord 按单词断行模式
self.__editor.setWrapMode(QsciScintilla.WrapWord)
WrapCharacter 按字符断行模式
self.__editor.setWrapMode(QsciScintilla.WrapCharacter)
WrapWhitespace 按空格断行模式
self.__editor.setWrapMode(QsciScintilla.WrapWhitespace)
断行视觉标志
文本断行可以在QScintilla中可视化:
setWrapVisualFlags(endFlag, startFlag, indent)
我们来看看参数:
-
endFlag
# WrapFlagNone 无结束标志 self.__editor.setWrapVisualFlags(endFlag =QsciScintilla.WrapFlagNone,...)
# WrapFlagByText 在文本后添加断行标志 self.__editor.setWrapVisualFlags(endFlag =QsciScintilla.WrapFlagByText,...)
# WrapFlagByBorder 在显示边界添加断行标志 self.__editor.setWrapVisualFlags(endFlag =QsciScintilla.WrapFlagByBorder,...)
# WrapFlagInMargin 在页边添加断行标志 self.__editor.setWrapVisualFlags(endFlag =QsciScintilla.WrapFlagInMargin,...)
-
startFlag
# WrapFlagNone 无开始标志 self.__editor.setWrapVisualFlags(startFlag =QsciScintilla.WrapFlagNone,...)
# WrapFlagByText 或 WrapFlagByBorder 在文本前添加断行标志 self.__editor.setWrapVisualFlags(startFlag =QsciScintilla.WrapFlagByText,...)
# WrapFlagInMargin 在页边前添加断行标志 self.__editor.setWrapVisualFlags(startFlag =QsciScintilla.WrapFlagInMargin,...)
请注意,此值在应用于参数’endFlag’时具有相同的效果。
-
indent
此参数设置每个断行缩进的空格数。它必须是整数值。只有在缩进模式
设置为“固定”时才能看到它的效果(参见下一段)。
断行缩进模式
如果你需要,断行可以有缩进。
setWrapIndentMode(indent_mode)
相关参数:
# WrapIndentFixed
self.__editor.setWrapIndentMode(QsciScintilla.WrapIndentFixed)
不要忘记设置wrap-indentation的固定值。请参阅上一段中的’indent’参数。
# WrapIndentSame
self.__editor.setWrapIndentMode(QsciScintilla.WrapIndentSame)
断行缩进与原始行相同。
# WrapIndentIndented
self.__editor.setWrapIndentMode(QsciScintilla.WrapIndentIndented)
新行缩进与原始行相同,再缩进一个缩进级别。缩进级别由setTabWidth函数定义(请参阅有关缩进选项的章节)。
3.2 行尾选项
文件中的每一行都以EOL字符结尾(行尾字符)。在大多数文本编辑器中,此字符不可见。但是如果需要,你可以让它可见。不幸的是,对于Linux
,Windows
和Mac
,EOL角色并不相同:
- Windows :
\ r \ n
- Unix,Linux :
\ n
- Mac :
\ r
EOL模式
EOL 可以进行如下设置:
setEolMode(eol_mode)
对于不同的操作系统
# EolWindows
self.__editor.setEolMode(QsciScintilla.EolWindows)
---------------------------------------------------
# EolUnix
self.__editor.setEolMode(QsciScintilla.EolUnix)
---------------------------------------------------
# EolMac
self.__editor.setEolMode(QsciScintilla.EolMac)
EOL可见性
EOL 可见性用以下方法进行设置:
setEolVisibility(visibility)
参数:
# False
self.__editor.setEolVisibility(False):
# True
self.__editor.setEolVisibility(True):
3.3 缩进
缩进字符
方法
setIndentationsUseTabs(use_tabs)
确定缩进/取消是否使用TAB ‘\ t’ 角色或WHITESPACE ‘’ 字符。
# False 缩进使用空白字符。
self.__editor.setIndentationsUseTabs(False)
---------------------------------------
# True 缩进使用制表符。
self.__editor.setIndentationsUseTabs(True)
缩进尺寸
方法
setTabWidth(indentation_size)
选择要缩进的空格字符数。使用TAB
完成缩进时,此参数定义TAB
字符的宽度 - 表示为空格的倍数。
# 4个空格为一个缩进宽度
self.__editor.setTabWidth(4)
缩进指示
QScintilla可以显示虚线垂直线的方式来指示缩进。
setIndentationGuides(visible)
参数:
# False 无垂直参考线
self.__editor.setIndentationGuides(False)
# True 有垂直参考线
self.__editor.setIndentationGuides(True)
空格缩进
方法
setTabIndents(at_spaces)
当光标被空格包围时,会影响TAB键的行为。如果设置为False
,编辑器只需插入n个空格(或者 '\ t’每当按下TAB键时。但如果设置为True
,编辑器将第一个非空白字符推送到下一个缩进级别!
# False
self.__editor.setTabIndents(False)
# True
self.__editor.setTabIndents(True)
自动缩进
插入新行时,自动缩进将光标推送到与前一个相同的缩进级别。
setAutoIndent(autoindent_on)
参数
# False
self.__editor.setAutoIndent(False)
# True
self.__editor.setAutoIndent(True)
注意:词法分析器可以使用setAutoIndentStyle
方法修改此行为!
3.4 插入线(光标)
您的编辑器可以以不同的颜色和形状显示插入线(光标)。本章研究了这些选项。
插入光标前景色
“插入光标前景色”只不过是插入光标本身的颜色。您可以使用设置颜色
setCaretForegroundColor(color)
让我们将插入光标颜色设置为蓝色:
# QColor(…)
self.__editor.setCaretForegroundColor(QColor(“#ff0000ff”))
插入光标的可见性
这个标题 - 以及相应功能的名称 - 可能有点误导。这不是关于插入符本身,而是关于在插入符号下划线。功能
setCaretLineVisible(visible)
确定插入符号下的行是否应该获得背景颜色。
# False
self.__editor.setCaretLineVisible(False)
# True
self.__editor.setCaretLineVisible(True)
插入光标背景色
突出显示的行(参见上一段)默认为黄色。但是你可以轻松改变这种颜色:
setCaretLineBackgroundColor(color)
参数
# QColor(…)
self.__editor.setCaretLineBackgroundColor(QColor(“#1fff0000”))
插入光标宽度
设置插入符号的宽度(以像素为单位)。宽度等于0会使插入符不可见!
setCaretWidth(size)