x01.DiamondIDEhelloide[Python基础]

python

虽然一直在用 vscode,但自己写一个也不错。通过比较,选择 Spyder 来学习。代码: x01.DiamondIDE

1 Edit

1.1 hello DiamondIDE

使用 pip 安装所需模块 pyqt 等,自不待言。hello.py 代码如下:

from qtpy.QtWidgets import QApplication, QPlainTextEdit

app = QApplication(["x01.DiamondIDE"])

edit = QPlainTextEdit("hello DiamondIDE")

edit.show()

app.exec_()

终端输入: python3 hello.py 运行一下,OK!

1.2 添加测试

删除 hello.py, 添加 widgets/edit.py 如下:

# widgets/edit.py (c) 2021 by x01

from qtpy.QtWidgets import QPlainTextEdit, QApplication

class Edit(QPlainTextEdit):

def __init__(self, parent=None):

super().__init__(parent=parent)

def test_edit():

app = QApplication(["x01.DiamondIDE"])

edit = Edit()

edit.setPlainText("Hello IDE!")

edit.show()

app.exec()

if __name__ == "__main__":

test_edit()

添加 tests/test_edit.py 如下:

import os, sys 

RootDir = os.path.dirname(os.path.dirname(__file__))

sys.path.append(RootDir)

import widgets.edit as edit

def test_edit():

edit.test_edit()

先安装 pytest: python3 -m pip install -U pytest, 然后在终端运行测试: pytest, OK!

顺便添加 main.py,代码如下:

import os, sys 

CurrDir = os.path.dirname(__file__)

sys.path.append(CurrDir)

from widgets.edit import test_edit

def main():

test_edit()

if __name__ == "__main__":

main()

运行一下,OK!

注释 tests/test_edit.py 的 RootDir,添加 test.py 以在测试时统一添加路径,代码如下:

import os, sys 

RootDir = os.path.dirname(__file__)

sys.path.append(RootDir)

import pytest

if __name__ == "__main__":

pytest.main()

运行一下,OK!

1.3 切入点

在 Python 的 site-packages 目录下新建 mypath.pth 文件,添加 x01.DiamondIDE 所在路径,以便导入。

Spyder 太大,还是以 CodeEditor作为切入点。

widgets/edit.py 更改如下:

# widgets/edit.py (c) 2021 by x01

from qtpy.QtWidgets import QPlainTextEdit, QApplication, QWidget

from qtpy.QtCore import QSize

from PyQt5.QtGui import QColor, QPaintEvent, QPainter, QTextBlock, QTextFormat

from PyQt5.QtCore import QRect, Qt

from PyQt5.QtWidgets import QMainWindow, QTextEdit

class LineNumberArea(QWidget):

def __init__(self, editor=None):

super().__init__(editor)

self.editor = editor

self.left_padding = 3

self.right_padding = 6

# override

def sizeHint(self):

return QSize(self.editor.LineNumberAreaWidth(), 0)

def paintEvent(self, event):

self.editor.LineNumberAreaPaintEvent(event)

class CodeEditor(QPlainTextEdit):

def __init__(self, parent=None):

super().__init__(parent=parent)

self.line_number_area = LineNumberArea(self)

self.line_number_enabled = True

#event

self.blockCountChanged.connect(self.UpdateLineNumberAreaWidth)

self.updateRequest.connect(self.UpdateLineNumberArea)

self.cursorPositionChanged.connect(self.HighlightCurrentLine)

self.UpdateLineNumberAreaWidth(0)

self.HighlightCurrentLine()

def resizeEvent(self, event):

super().resizeEvent(event)

cr:QRect = self.contentsRect()

self.line_number_area.setGeometry(QRect(cr.left(), cr.top(), self.LineNumberAreaWidth(), cr.height()))

def LineNumberAreaWidth(self):

width = 0

if self.line_number_enabled:

digits = 1

count = max(1, self.blockCount())

while count >= 10:

count /= 10

digits += 1

fm = self.fontMetrics()

width = fm.width("9") * digits + self.line_number_area.left_padding + self.line_number_area.right_padding

return width

def LineNumberAreaPaintEvent(self, event:QPaintEvent):

if self.line_number_enabled:

painter = QPainter(self.line_number_area)

painter.fillRect(event.rect(), Qt.lightGray)

block:QTextBlock = self.firstVisibleBlock()

block_number = block.blockNumber()

top = round(self.blockBoundingGeometry(block).translated(self.contentOffset()).top())

bottom = top + round(self.blockBoundingRect(block).height())

while block.isValid() and top <= event.rect().bottom():

if block.isVisible() and bottom >= event.rect().top():

number = block_number + 1

painter.setPen(Qt.black)

painter.drawText(0, top, self.line_number_area.width() - self.line_number_area.right_padding,

self.fontMetrics().height(), Qt.AlignRight, str(number))

block = block.next()

top = bottom

bottom = top + round(self.blockBoundingRect(block).height())

block_number += 1

def UpdateLineNumberAreaWidth(self, new_block_count=None):

self.setViewportMargins(self.LineNumberAreaWidth(),0,0,0)

def UpdateLineNumberArea(self, rect, dy):

if self.line_number_enabled:

if dy:

self.line_number_area.scroll(0, dy)

else:

self.line_number_area.update(0, rect.y(), self.line_number_area.width(), rect.height())

if rect.contains(self.viewport().rect()):

self.UpdateLineNumberAreaWidth(0)

def HighlightCurrentLine(self):

extra = []

if not self.isReadOnly():

lineColor = QColor(Qt.yellow).lighter(160)

selection = QTextEdit.ExtraSelection()

selection.format.setBackground(lineColor)

selection.format.setProperty(QTextFormat.FullWidthSelection, True)

selection.cursor = self.textCursor()

selection.cursor.clearSelection()

extra.append(selection)

self.setExtraSelections(extra)

def test_edit():

app = QApplication(["x01.DiamondIDE"])

ed = CodeEditor()

ed.setPlainText("Hello IDE!")

ed.show()

app.exec_()

if __name__ == "__main__":

test_edit()

运行一下,OK!现在已经可以显示行号和高亮当前行了。

以上是 x01.DiamondIDEhelloide[Python基础] 的全部内容, 来源链接: utcz.com/z/530722.html

回到顶部