Edit添加行号实际上是一个控件重绘的过程。
需要在Edit中重绘一个矩形区域,然后把行号“画”在这个矩形区域上。
首先,需要定义一个行号栏类:
class NumberBar(QtGui.QWidget): def __init__(self, editor): QtGui.QWidget.__init__(self, editor) self.codeEditor = editor #get行号值 def getWidth(self): digits = 1 try: if ui.ui2isOpen: blockNumber = ui2.verticalScrollBar1.value() else: blockNumber = ui.verticalScrollBar1.value() except Exception, e: blockNumber = self.codeEditor.blockCount() Max = max(1, blockNumber) while (Max >= 10) : Max /= 10 digits += 1 space = 30 + self.codeEditor.fontMetrics().width('9') * digits return space #更新行号栏宽度 def updateWidth(self): width = self.getWidth() self.codeEditor.setViewportMargins(width, 0, 0, 0) #根据 updateRequest 信号 调整行号栏 def updateArea(self, rect, dy): if dy: self.scroll(0, dy) else: self.update(0, rect.y(), self.getWidth(), rect.height()) if (rect.contains(self.codeEditor.viewport().rect())): width = self.getWidth() self.codeEditor.setViewportMargins(width, 0, 0, 0) #绘制行号栏 def paintEvent(self, event): painter = QtGui.QPainter(self) rect = event.rect() painter.fillRect(rect, QtGui.QColor(243,243,243)) block = self.codeEditor.firstVisibleBlock() if ui.ui2isOpen: blockNumber = ui2.verticalScrollBar1.value() else: blockNumber = ui.verticalScrollBar1.value() top = int(self.codeEditor.blockBoundingGeometry(block).translated(self.codeEditor.contentOffset()).top()) bottom = top + int(self.codeEditor.blockBoundingRect(block).height()) while (block.isValid() and top <= rect.bottom()): if (block.isVisible() and bottom >= rect.top()): number = QtCore.QString.number(blockNumber + 1) painter.setPen(QtGui.QColor(59,153,181)) painter.drawText(0, top, self.codeEditor.lineNumberArea.width(), \ painter.fontMetrics().height(), \ QtCore.Qt.AlignVCenter|QtCore.Qt.AlignRight, number + ' ') block = block.next() top = bottom bottom = top + int(self.codeEditor.blockBoundingRect(block).height()) blockNumber += 1
然后重写Edit类:
在Edit类的__init__()函数中:
1、定义一个行号栏类NumberBar类的对象self.lineNumberArea,并且为信号添加以下事件:
self.connect(self, QtCore.SIGNAL('blockCountChanged(int)'),\ self.lineNumberArea.updateWidth) self.connect(self, QtCore.SIGNAL('updateRequest(const QRect &, int)'),\ self.lineNumberArea.updateArea)
2、然后调用self.lineNumberArea的updateWidth()函数:
self.lineNumberArea.updateWidth()
效果:
行万里路,不忘初心!