lineNumberWidget.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. from PySide2.QtGui import *
  2. from PySide2.QtWidgets import QTextBrowser
  3. from PySide2.QtCore import Qt
  4. class LineNumberWidget(QTextBrowser):
  5. def __init__(self, widget):
  6. super().__init__()
  7. self.__initUi(widget)
  8. def __initUi(self, widget):
  9. self.__lineCount = widget.document().lineCount()
  10. self.__size = int(widget.font().pointSizeF())
  11. self.__styleInit()
  12. self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
  13. self.setTextInteractionFlags(Qt.NoTextInteraction)
  14. self.verticalScrollBar().setEnabled(False)
  15. widget.verticalScrollBar().valueChanged.connect(self.__changeLineWidgetScrollAsTargetedWidgetScrollChanged)
  16. self.__initLineCount()
  17. self.befor_hightlight_line = None
  18. def __changeLineWidgetScrollAsTargetedWidgetScrollChanged(self, v):
  19. self.verticalScrollBar().setValue(v)
  20. self.setWidthByStr()
  21. def __initLineCount(self):
  22. for n in range(1, self.__lineCount+1):
  23. self.append(str(n))
  24. def changeLineCount(self, n):
  25. max_one = max(self.__lineCount, n)
  26. diff = n-self.__lineCount
  27. if max_one == self.__lineCount:
  28. first_v = self.verticalScrollBar().value()
  29. for i in range(self.__lineCount, self.__lineCount + diff, -1):
  30. self.moveCursor(QTextCursor.End, QTextCursor.MoveAnchor)
  31. self.moveCursor(QTextCursor.StartOfLine, QTextCursor.MoveAnchor)
  32. self.moveCursor(QTextCursor.End, QTextCursor.KeepAnchor)
  33. self.textCursor().removeSelectedText()
  34. self.textCursor().deletePreviousChar()
  35. last_v = self.verticalScrollBar().value()
  36. if abs(first_v-last_v) != 2:
  37. self.verticalScrollBar().setValue(first_v)
  38. else:
  39. for i in range(self.__lineCount, self.__lineCount + diff, 1):
  40. self.append(str(i + 1))
  41. self.__lineCount = n
  42. def selectLine(self, line):
  43. position = self.document().findBlockByLineNumber(line-1).position()
  44. tc = self.textCursor()
  45. tc.setPosition(position, QTextCursor.MoveAnchor) # 直接跳转到start_pos
  46. tc.movePosition(QTextCursor.EndOfLine, QTextCursor.KeepAnchor)
  47. return tc
  48. def highlightLineNumber(self, line):
  49. if self.befor_hightlight_line:
  50. self.clearHighlightLineNumber(self.befor_hightlight_line)
  51. fmt = QTextCharFormat()
  52. fmt.setFontWeight(QFont.Bold)
  53. fmt.setForeground(QBrush(QColor(0,0,0)))
  54. tc = self.selectLine(line)
  55. tc.mergeCharFormat(fmt) # 格式化选中文本
  56. tc.clearSelection() # 取消选中
  57. self.befor_hightlight_line = line
  58. def clearHighlightLineNumber(self, line):
  59. tc = self.selectLine(line)
  60. tc.setCharFormat(QTextCharFormat())
  61. def setValue(self, v):
  62. self.verticalScrollBar().setValue(v)
  63. def setFontSize(self, s: float):
  64. self.__size = int(s)
  65. self.__styleInit()
  66. def setWidthByStr(self):
  67. withd = (len(str(self.__lineCount)) + 2) * self.__size*0.7
  68. self.setFixedWidth(withd)
  69. def line_count(self):
  70. return self.__lineCount
  71. def __styleInit(self):
  72. self.__style = f'''
  73. QTextBrowser
  74. {{
  75. background: transparent;
  76. border: none;
  77. color: #AAA;
  78. font: {self.__size}pt;
  79. }}
  80. '''
  81. self.setStyleSheet(self.__style)
  82. self.setWidthByStr()