TG-PlatformPlus/show_editor.py

290 lines
12 KiB
Python
Raw Normal View History

2026-03-02 14:29:58 +08:00
#!/opt/homebrew/bin/python3
# -*- coding:utf-8 -*-
from PyQt6.QtCore import *
from PyQt6.Qsci import QsciLexerPython, QsciScintilla, QsciAPIs,QsciCommand
from PyQt6.QtWidgets import *
from PyQt6.QtGui import QFont, QColor, QKeySequence, QShortcut,QIcon
import keyword
from common import MarkdownViewer
import time
class highlight(QsciLexerPython):
def __init__(self, parent):
super().__init__(parent)
font = QFont()
font.setFamily('Courier')
font.setPointSize(12)
font.setFixedPitch(True)
self.setFont(font)
self.setColor(QColor(0, 0, 0))
self.setPaper(QColor(255, 255, 255))
self.setColor(QColor("#00FF00"), QsciLexerPython.ClassName)
self.setColor(QColor("#B0171F"), QsciLexerPython.Keyword)
self.setColor(QColor("#3CB371"), QsciLexerPython.Comment)
self.setColor(QColor("#FF00FF"), QsciLexerPython.Number)
self.setColor(QColor("#0000FF"), QsciLexerPython.DoubleQuotedString)
self.setColor(QColor("#0000FF"), QsciLexerPython.SingleQuotedString)
self.setColor(QColor("#288B22"), QsciLexerPython.TripleSingleQuotedString)
self.setColor(QColor("#288B22"), QsciLexerPython.TripleDoubleQuotedString)
self.setColor(QColor("#0000FF"), QsciLexerPython.FunctionMethodName)
self.setColor(QColor("#191970"), QsciLexerPython.Operator)
self.setColor(QColor("#000000"), QsciLexerPython.Identifier)
self.setColor(QColor("#3CB371"), QsciLexerPython.CommentBlock)
self.setColor(QColor("#0000FF"), QsciLexerPython.UnclosedString)
self.setColor(QColor("#FFFF00"), QsciLexerPython.HighlightedIdentifier)
self.setColor(QColor("#FF8000"), QsciLexerPython.Decorator)
self.setFont(QFont('Courier', 12, weight=QFont.Weight.Bold), 5)
self.setFont(QFont('Courier', 12, italic=True), QsciLexerPython.Comment)
class CommentCommand(QsciCommand):
def __init__(self, editor):
super().__init__(editor)
def execute(self):
editor = self.editor()
line_from, index_from, line_to, index_to = editor.getSelection()
# 如果没有选中文本,就注释当前行
if line_from < 0 or line_to < 0:
line_from, line_to = editor.getCursorPosition()
for line in range(line_from, line_to + 1):
text = editor.text(line)
if text.startswith('#'):
editor.setSelection(line, 0, line, 1)
editor.removeSelectedText()
else:
editor.insertAt('#', line, 0)
class CodeDialog(QDialog):
def __init__(self, title='指令脚本编辑'):
super().__init__()
self.mkviewer = MarkdownViewer()
font = QFont()
self.oldTime = 0
font.setFamily('Courier')
font.setPointSize(12)
font.setFixedPitch(True)
self.setFont(font)
self.editor = QsciScintilla()
self.editor.setFont(font)
# layout = QVBoxLayout()
# layout.addWidget(self.editor)
# 设置窗口标题和大小
self.setWindowTitle(title)
screen = QApplication.primaryScreen() # 获取主屏幕
screen_size = screen.size() # 获取屏幕大小
self.original_size = (1200, 900)
# 计算缩放比例
scale_x = screen_size.width() / 1920
scale_y = screen_size.height() / 1080
width = int(1200 * scale_x)
height = int(900 * scale_y)
self.setFixedWidth(width)
self.setFixedHeight(height)
self.helpType = "instruction"
# 创建自定义标题栏
self.title_bar = QFrame(self)
self.title_bar.setFixedHeight(30)
self.title_bar.setStyleSheet(" QWidget QPushButton {\
subcontrol-origin: content; /* 设置子部件的原点为content */\
color: rgb(255, 255, 255); \
border: none; /* 去掉按钮的边框 */\
}\
QWidget{\
background-color: qlineargradient(spread:pad, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(191, 205, 220, 255), stop:1 rgba(214, 227, 241, 255));\
}")
self.title_bar.mousePressEvent = self.toolbar_mousePressEvent
self.title_bar.mouseMoveEvent = self.toolbar_mouseMoveEvent
self.title_bar.mouseReleaseEvent = self.toolbar_mouseReleaseEvent
# 标题栏布局
title_layout = QHBoxLayout(self.title_bar)
title_layout.setContentsMargins(0, 0, 0, 0)
# 添加系统图标
icon_label = QLabel(self.title_bar)
icon_label.setPixmap(QIcon(':/resource/logo.ico').pixmap(20, 20)) # 设置图标尺寸
title_layout.addWidget(icon_label)
# 添加标题文本
title_label = QLabel(title, self.title_bar)
title_layout.addWidget(title_label)
title_layout.addStretch(1)
# 添加帮助按钮
help_button = QPushButton( self.title_bar)
help_button.setIcon(QIcon(":/resource/help.png"))
help_button.setToolTip("帮助")
help_button.clicked.connect(self.showHelp)
help_button.setFixedSize(50, 30) # 设置按钮宽度为50像素
title_layout.addWidget(help_button)
# 添加关闭按钮
close_button = QPushButton(self.title_bar)
close_button.setIcon(QIcon(":/resource/w_close.png"))
close_button.setFixedSize(50, 30)
close_button.clicked.connect(self.cancelClick)
title_layout.addWidget(close_button)
# 主窗口布局
main_layout = QVBoxLayout(self)
main_layout.addWidget(self.title_bar)
main_layout.addWidget(self.editor)
main_layout.setContentsMargins(1, 1, 1, 1)
main_layout.setSpacing(0)
rowlayout = QHBoxLayout()
btnOk = QPushButton("确认")
btnCancel = QPushButton("取消")
btnOk.clicked.connect(self.okClick )
btnCancel.clicked.connect(self.cancelClick )
rowlayout.addWidget(btnOk)
rowlayout.addWidget(btnCancel)
main_layout.addLayout(rowlayout)
self.editor.setUtf8(True)
self.editor.setMarginsFont(font)
self.editor.setMarginWidth(0, len(str(len(self.editor.text().split('\n')))) * 20)
self.editor.setMarginLineNumbers(0, True)
self.editor.setEdgeColumn(80)
self.editor.setEdgeColor(QColor(0, 0, 0))
self.setWindowFlags(Qt.WindowType.FramelessWindowHint|Qt.WindowType.WindowCloseButtonHint|Qt.WindowType.WindowContextHelpButtonHint)
self.editor.setBraceMatching(QsciScintilla.BraceMatch.StrictBraceMatch)
self.editor.setIndentationsUseTabs(False)
self.editor.setIndentationWidth(4)
self.editor.setTabIndents(True)
self.editor.setAutoIndent(True)
self.editor.setBackspaceUnindents(True)
self.editor.setTabWidth(4)
self.editor.setCaretLineVisible(True)
self.editor.setCaretLineBackgroundColor(QColor('#FFFFCD'))
self.editor.setIndentationGuides(True)
self.editor.setFolding(QsciScintilla.FoldStyle.PlainFoldStyle)
self.editor.setMarginWidth(2, 12)
self.editor.markerDefine(QsciScintilla.MarkerSymbol.Minus, QsciScintilla.SC_MARKNUM_FOLDEROPEN)
self.editor.markerDefine(QsciScintilla.MarkerSymbol.Plus, QsciScintilla.SC_MARKNUM_FOLDER)
self.editor.markerDefine(QsciScintilla.MarkerSymbol.Minus, QsciScintilla.SC_MARKNUM_FOLDEROPENMID)
self.editor.markerDefine(QsciScintilla.MarkerSymbol.Plus, QsciScintilla.SC_MARKNUM_FOLDEREND)
self.editor.setMarkerBackgroundColor(QColor("#FFFFFF"), QsciScintilla.SC_MARKNUM_FOLDEREND)
self.editor.setMarkerForegroundColor(QColor("#272727"), QsciScintilla.SC_MARKNUM_FOLDEREND)
self.editor.setMarkerBackgroundColor(QColor("#FFFFFF"), QsciScintilla.SC_MARKNUM_FOLDEROPENMID)
self.editor.setMarkerForegroundColor(QColor("#272727"), QsciScintilla.SC_MARKNUM_FOLDEROPENMID)
self.editor.setAutoCompletionSource(QsciScintilla.AutoCompletionSource.AcsAll)
self.editor.setAutoCompletionCaseSensitivity(True)
self.editor.setAutoCompletionReplaceWord(False)
self.editor.setAutoCompletionThreshold(1)
self.editor.setAutoCompletionUseSingle(QsciScintilla.AutoCompletionUseSingle.AcusExplicit)
self.lexer = highlight(self.editor)
self.editor.setLexer(self.lexer)
self.mod = False
self.context = ""
self.__api = QsciAPIs(self.lexer)
autocompletions = keyword.kwlist + ["abs", "all", "any", "basestring", "bool",
"callable", "chr", "classmethod", "cmp", "compile",
"complex", "delattr", "dict", "dir", "divmod",
"enumerate", "eval", "execfile", "exit", "file",
"filter", "float", "frozenset", "getattr", "globals",
"hasattr", "hex", "id", "int", "isinstance",
"issubclass", "iter", "len", "list", "locals", "map",
"max", "min", "object", "oct", "open", "ord", "pow",
"property", "range", "reduce", "repr", "reversed",
"round", "set", "setattr", "slice", "sorted",
"staticmethod", "str", "sum", "super", "tuple", "type",
"vars", "zip", 'print',
'log', 'send', 'start', 'finish']
for ac in autocompletions:
self.__api.add(ac)
self.__api.prepare()
self.editor.autoCompleteFromAll()
self.name = ''
self.editor.textChanged.connect(self.changed)
# 设置快捷键
self.comment_shortcut = QShortcut(QKeySequence('Ctrl+k'), self)
self.comment_shortcut.activated.connect(self.comment_code)
def toolbar_mousePressEvent(self, event):
if event.button() == Qt.MouseButton.LeftButton:
self.oldPos = event.globalPosition()
def toolbar_mouseMoveEvent(self, event):
if self.oldPos:
delta = event.globalPosition() - self.oldPos
new_pos = self.pos() + QPoint(delta.toPoint())
self.move(new_pos)
self.oldPos = event.globalPosition()
def toolbar_mouseReleaseEvent(self, event):
if event.button() == Qt.MouseButton.LeftButton:
self.oldPos = None
def showHelp(self):
if self.helpType == "instruction":
self.mkviewer.showMarkdown("help.md")
elif self.helpType == "task":
self.mkviewer.showMarkdown("help_task.md")
def comment_code(self):
line_from, index_from, line_to, index_to = self.editor.getSelection()
# 如果没有选中文本,就注释当前行
if line_from < 0 or line_to < 0:
line = self.editor.getCursorPosition()[0]
text = self.editor.text(line)
if text.startswith('#'):
self.editor.setSelection(line, 0, line, 1)
self.editor.removeSelectedText()
else:
self.editor.insertAt('#', line, 0)
else:
for line in range(line_from, line_to + 1):
text = self.editor.text(line)
if text.startswith('#'):
self.editor.setSelection(line, 0, line, 1)
self.editor.removeSelectedText()
else:
self.editor.insertAt('#', line, 0)
def okClick(self):
self.context = self.editor.text()
self.close()
def cancelClick(self):
self.context = ""
self.close()
def changed(self):
self.mod = True
self.editor.setMarginWidth(0, len(str(len(self.editor.text().split('\n')))) * 20)
def getValue(self):
return self.editor.text()
def closeEvent(self, event):
event.accept()
@pyqtSlot(str, result=str)
def showEditor(self,text):
self.editor.setText(text)
self.exec()
result = self.getValue() # 获取子窗口返回的值
self.editor.setText("")
# if result == "":
# return text
# else:
return result
def showEditDlg(self, text, htype="instruction"):
self.helpType = htype
self.editor.setText(text)
self.exec()
result = self.context # 获取子窗口返回的值
self.editor.setText("")
# if result == "":
# return text
# else:
return result