gpt4 book ai didi

python - 如何在 QScintilla 中使用自定义折叠图标?

转载 作者:太空狗 更新时间:2023-10-29 23:56:30 25 4
gpt4 key购买 nike

考虑这个片段:

import sys

from PyQt5.Qsci import QsciScintilla
from PyQt5.Qt import *

if __name__ == '__main__':
app = QApplication(sys.argv)
view = QsciScintilla()

# http://www.scintilla.org/ScintillaDoc.html#Folding
view.setFolding(QsciScintilla.BoxedTreeFoldStyle)
# view.setFolding(QsciScintilla.BoxedFoldStyle)
# view.setFolding(QsciScintilla.CircledFoldStyle)
# view.setFolding(QsciScintilla.CircledTreeFoldStyle)
# view.setFolding(QsciScintilla.NoFoldStyle)
# view.setFolding(QsciScintilla.PlainFoldStyle)

lines = [
(0, "def foo():"),
(1, " x = 10"),
(1, " y = 20"),
(1, " return x+y"),
(-1, ""),
(0, "def bar(x):"),
(1, " if x > 0:"),
(2, " print('this is')"),
(2, " print('branch1')"),
(1, " else:"),
(2, " print('and this')"),
(2, " print('is branch2')"),
(-1, ""),
(-1, ""),
(-1, ""),
(-1, "print('end')"),

]

view.setText("\n".join([b for a, b in lines]))
MASK = QsciScintilla.SC_FOLDLEVELNUMBERMASK

for i, tpl in enumerate(lines):
level, line = tpl
if level >= 0:
view.SendScintilla(view.SCI_SETFOLDLEVEL, i, level | QsciScintilla.SC_FOLDLEVELHEADERFLAG)
else:
view.SendScintilla(view.SCI_SETFOLDLEVEL, i, 0)

view.show()
app.exec_()

我想弄清楚是否可以将折叠图标更改为与 QScintilla 提供的图标不同的自定义图标,特别是我想要一个类似于 Sublime 的向下箭头:

enter image description here

通过查看 QSciScintilla foldstyle您可以看到没有任何相似之处。

其实不仅如此,我还想知道是否可以实现这种在鼠标位置进入/离开边缘区域时折叠图标逐渐淡出的微妙效果,看看:

enter image description here

这是一个非常好的功能,这样一来,您在编码时就不会被“始终可见”的折叠图标分心。

在此thread似乎有一个叫做 SC_MARK_ARROWDOWN 的东西,但不确定它是否可以用作折叠图标...无论如何,我仍然更喜欢我的自定义图片,因为我将使用 monokai 主题我希望图标看起来像 Sublime 的一样优雅。

下面你会发现我创建的 2 个 12x12 png 来表示深色和浅色箭头。

enter image description here enter image description here

最佳答案

缺少悬停标记突出显示的初步版本:

from PyQt5.Qsci import QsciScintilla
from PyQt5.Qt import *

def get_arrow(down, size, cmin, cmax):
from PIL import Image
from PIL.ImageQt import ImageQt
from math import atan2, cos, pi
pict = Image.new("RGBA", (size, size), tuple(cmin + [255]))
pixl = pict.load()
step = 3.25**2
for y in range(pict.size[1]):
for x in range(pict.size[0]):
xpos = x - pict.size[0] // 2 + 1
ypos = y - pict.size[1] // 2 + 1
retn = 1.5 * atan2(ypos, xpos) + (pi / 4, 0)[not down]
retn = ((abs(cos(retn))**2.5 + 3) * 2)**2 - xpos**2 - ypos**2
if (retn < 0):
retn = cmin
elif (retn >= step):
retn = cmax
else:
retn = [int((cmax[i] - cmin[i]) * retn / step + cmin[i])
for i in range(0, 3)]
pixl[x, y] = tuple(retn + [255])
return ImageQt(pict)

def color_to_sc(c):
return (c[0] & 0xFF) | ((c[1] & 0xFF) << 8) | ((c[2] & 0xFF) << 16)

def set_fold(prev, line, fold, full):
if (prev[0] >= 0):
fmax = max(fold, prev[1])
for iter in range(prev[0], line + 1):
view.SendScintilla(view.SCI_SETFOLDLEVEL, iter,
fmax | (0, view.SC_FOLDLEVELHEADERFLAG)[iter + 1 < full])

def line_empty(line):
return view.SendScintilla(view.SCI_GETLINEENDPOSITION, line) \
<= view.SendScintilla(view.SCI_GETLINEINDENTPOSITION, line)

def modify(position, modificationType, text, length, linesAdded,
line, foldLevelNow, foldLevelPrev, token, annotationLinesAdded):
full = view.SC_MOD_INSERTTEXT | view.SC_MOD_DELETETEXT
if (~modificationType & full == full):
return
prev = [-1, 0]
full = view.SendScintilla(view.SCI_GETLINECOUNT)
lbgn = view.SendScintilla(view.SCI_LINEFROMPOSITION, position)
lend = view.SendScintilla(view.SCI_LINEFROMPOSITION, position + length)
for iter in range(max(lbgn - 1, 0), -1, -1):
if ((iter == 0) or not line_empty(iter)):
lbgn = iter
break
for iter in range(min(lend + 1, full), full + 1):
if ((iter == full) or not line_empty(iter)):
lend = min(iter + 1, full)
break
for iter in range(lbgn, lend):
if (line_empty(iter)):
if (prev[0] == -1):
prev[0] = iter
else:
fold = view.SendScintilla(view.SCI_GETLINEINDENTATION, iter)
fold //= view.SendScintilla(view.SCI_GETTABWIDTH)
set_fold(prev, iter - 1, fold, full)
set_fold([iter, fold], iter, fold, full)
prev = [-1, fold]
set_fold(prev, lend - 1, 0, full)

def hover(position, xpos, ypos):
mask = view.SendScintilla(view.SCI_GETMARGINMASKN, 2)
mask = (mask | view.SC_MASK_FOLDERS, mask & ~view.SC_MASK_FOLDERS) \
[xpos > StandardMarginWidth]
view.SendScintilla(view.SCI_SETMARGINMASKN, 2, mask)

if __name__ == '__main__':
import sys
import textwrap

app = QApplication(sys.argv)
view = QsciScintilla()
view.SendScintilla(view.SCI_SETMULTIPLESELECTION, True)
view.SendScintilla(view.SCI_SETMULTIPASTE, 1)
view.SendScintilla(view.SCI_SETADDITIONALSELECTIONTYPING, True)
view.SendScintilla(view.SCI_SETINDENTATIONGUIDES, view.SC_IV_REAL);
view.SendScintilla(view.SCI_SETTABWIDTH, 4)

view.setFolding(view.BoxedFoldStyle)

StandardIconSize = 16
StandardMarginWidth = 20
StandardBackground = [64, 64, 64]
StandardForeground = [192, 192, 192] # [R, G, B]

view.SendScintilla(view.SCI_SETMARGINWIDTHN, 1, 0)
view.SendScintilla(view.SCI_SETMARGINWIDTHN, 2, StandardMarginWidth)

view.SendScintilla(view.SCI_STYLESETBACK, view.STYLE_LINENUMBER, color_to_sc(StandardBackground))
view.SendScintilla(view.SCI_SETFOLDMARGINHICOLOUR, True, color_to_sc(StandardBackground))
view.SendScintilla(view.SCI_SETFOLDMARGINCOLOUR, True, color_to_sc(StandardBackground))

view.SendScintilla(view.SCI_RGBAIMAGESETHEIGHT, StandardIconSize)
view.SendScintilla(view.SCI_RGBAIMAGESETWIDTH, StandardIconSize)
fldr = get_arrow(0, StandardIconSize, StandardBackground, StandardForeground)
open = get_arrow(1, StandardIconSize, StandardBackground, StandardForeground)
view.SendScintilla(view.SCI_MARKERDEFINERGBAIMAGE, view.SC_MARKNUM_FOLDER, fldr)
view.SendScintilla(view.SCI_MARKERDEFINERGBAIMAGE, view.SC_MARKNUM_FOLDEROPEN, open)

view.SendScintilla(view.SCI_SETMOUSEDWELLTIME, 50)
view.SCN_DWELLSTART.connect(hover)
view.SCN_DWELLEND.connect(hover)

view.SCN_MODIFIED.connect(modify)

NUM_CHUNKS = 1
chunk = textwrap.dedent("""\
def foo():
x = 10
y = 20
return x+y

def bar(x):
if x > 0:
print('this is')
print('branch1')
else:
print('and this')
print('is branch2')

print('end')
""")
view.setText("\n".join([chunk for i in range(NUM_CHUNKS)]))
view.show()
app.exec_()

关于python - 如何在 QScintilla 中使用自定义折叠图标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55745636/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com