Я пытаюсь реализовать функцию fold_by_level
SublimeText3 в компоненте QScintilla, но я не очень хорошо знаю, как это сделать, до сих пор я придумал этот код:
import sys
import re
import math
from PyQt5.Qt import * # noqa
from PyQt5.Qsci import QsciScintilla
from PyQt5 import Qsci
from PyQt5.Qsci import QsciLexerCPP
class Foo(QsciScintilla):
def __init__(self, parent=None):
super().__init__(parent)
# http://www.scintilla.org/ScintillaDoc.html#Folding
self.setFolding(QsciScintilla.BoxedTreeFoldStyle)
# Indentation
self.setIndentationsUseTabs(False)
self.setIndentationWidth(4)
self.setBackspaceUnindents(True)
self.setIndentationGuides(True)
# Set the default font
self.font = QFont()
self.font.setFamily('Consolas')
self.font.setFixedPitch(True)
self.font.setPointSize(10)
self.setFont(self.font)
self.setMarginsFont(self.font)
# Margin 0 is used for line numbers
fontmetrics = QFontMetrics(self.font)
self.setMarginsFont(self.font)
self.setMarginWidth(0, fontmetrics.width("000") + 6)
self.setMarginLineNumbers(0, True)
self.setMarginsBackgroundColor(QColor("#cccccc"))
# Indentation
self.setIndentationsUseTabs(False)
self.setIndentationWidth(4)
self.setBackspaceUnindents(True)
lexer = QsciLexerCPP()
lexer.setFoldAtElse(True)
lexer.setFoldComments(True)
lexer.setFoldCompact(False)
lexer.setFoldPreprocessor(True)
self.setLexer(lexer)
QShortcut(QKeySequence("Ctrl+K, Ctrl+J"), self,
lambda level=-1: self.fold_by_level(level))
QShortcut(QKeySequence("Ctrl+K, Ctrl+1"), self,
lambda level=1: self.fold_by_level(level))
QShortcut(QKeySequence("Ctrl+K, Ctrl+2"), self,
lambda level=2: self.fold_by_level(level))
QShortcut(QKeySequence("Ctrl+K, Ctrl+3"), self,
lambda level=3: self.fold_by_level(level))
QShortcut(QKeySequence("Ctrl+K, Ctrl+4"), self,
lambda level=4: self.fold_by_level(level))
QShortcut(QKeySequence("Ctrl+K, Ctrl+5"), self,
lambda level=5: self.fold_by_level(level))
def fold_by_level(self, lvl):
if lvl < 0:
self.foldAll(True)
else:
for i in range(self.lines()):
level = self.SendScintilla(
QsciScintilla.SCI_GETFOLDLEVEL, i) & QsciScintilla.SC_FOLDLEVELNUMBERMASK
level -= 0x400
print(f"line={i+1}, level={level}")
if lvl == level:
self.foldLine(i)
def main():
app = QApplication(sys.argv)
ex = Foo()
ex.setText("""\
#include <iostream>
using namespace std;
void Function0() {
cout << "Function0";
}
void Function1() {
cout << "Function1";
}
void Function2() {
cout << "Function2";
}
void Function3() {
cout << "Function3";
}
int main(void) {
if (1) {
if (1) {
if (1) {
if (1) {
int yay;
}
}
}
}
if (1) {
if (1) {
if (1) {
if (1) {
int yay2;
}
}
}
}
return 0;
}\
""")
ex.resize(800, 600)
ex.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
Документы, за которыми я следовал: https://www.scintilla.org/ScintillaDoc.html#Folding и http://pyqt.sourceforge.net/Docs/QScintilla2/classQsciScintilla.html.
Как я уже сказал, функция fold_by_level
должна вести себя точно так же, как SublimeText, но я не уверен в деталях реализации функции ST. В любом случае, позвольте мне опубликовать несколько скриншотов после тестирования некоторых основных последовательностей на SublimeText, которые могли бы немного прояснить, чего я пытаюсь достичь здесь:
Sequence1: {ctrl+k, ctrl+5}, {ctrl+k, ctrl+j} {ctrl+k, ctrl+4}, {ctrl+k, ctrl+j} {ctrl+k, ctrl+3}, {ctrl+k, ctrl+j} {ctrl+k, ctrl+2}, {ctrl+k, ctrl+j} {ctrl+k, ctrl+1}, {ctrl+k, ctrl+j}
Sequence2: {ctrl+k, ctrl+5}, {ctrl+k, ctrl+4}, {ctrl+k, ctrl+3}, {ctrl+k, ctrl+2}, {ctrl+k, ctrl+1}
Я уверен, что есть больше внутренних деталей о поведении SublimeText, но если мой пример вел себя точно так же, как опубликовано на этих снимках после тестирования последовательностей, вы могли бы сказать, что эта функция стала довольно удобной для использования.