Pyqt5 Satır Numarası Sorunu

from PyQt5.QtCore import QRect, QSize, Qt
from PyQt5.QtGui import QPainter
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QPlainTextEdit

class TextArea(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        
        self.editor = QPlainTextEdit(self)
        self.lineNumberArea = LineNumberArea(self.editor)
        self.editor.setViewportMargins(self.lineNumberAreaWidth(), 0, 0, 0)
        self.editor.textChanged.connect(self.updateLineNumberArea)
        
        layout = QVBoxLayout(self)
        layout.addWidget(self.editor)
        self.setLayout(layout)

    def lineNumberAreaWidth(self):
        digits = 4
        max_num = max(1, self.editor.blockCount())
        while max_num >= 10:
            max_num /= 10
            digits += 1
        space = 10 + self.editor.fontMetrics().horizontalAdvance('9') * digits  # Adding a fixed offset of 10
        return space

    def resizeEvent(self, event):
        super().resizeEvent(event)
        cr = self.editor.contentsRect()
        self.lineNumberArea.setGeometry(
            QRect(cr.left(), cr.top(), self.lineNumberAreaWidth(), cr.height())
        )

    def updateLineNumberArea(self):
        self.lineNumberArea.update()


class LineNumberArea(QWidget):
    def __init__(self, editor):
        super(LineNumberArea, self).__init__(editor)
        self.editor = editor

    def sizeHint(self):
        return QSize(self.editor.lineNumberAreaWidth(), 0)

    def paintEvent(self, event):
        self.lineNumberAreaPaintEvent(event)

    def lineNumberAreaPaintEvent(self, event):
        painter = QPainter(self)
        painter.fillRect(event.rect(), Qt.lightGray)

        block = self.editor.firstVisibleBlock()
        blockNumber = block.blockNumber()
        top = round(self.editor.blockBoundingGeometry(block).translated(self.editor.contentOffset()).top())
        bottom = top + round(self.editor.blockBoundingRect(block).height())

        # Adjust spacing
        left_margin = 5
        right_margin = 5

        while block.isValid() and top <= event.rect().bottom():
            if block.isVisible() and bottom >= event.rect().top():
                number = str(blockNumber + 1)
                painter.setPen(Qt.black)
                # Draw text with margins
                painter.drawText(left_margin, top, self.width() - left_margin - right_margin,
                                self.editor.fontMetrics().height(), Qt.AlignRight, number)

            block = block.next()
            top = bottom
            bottom = top + round(self.editor.blockBoundingRect(block).height())
            blockNumber += 1

Chatgtp ile böle bir element oluşturdum fakat text alanını aşşağı yukarı yaptığımda satır numaraları haraket etmiyor bu sorunu nasıl çözerim.

Merhaba, self.editor üzerinden QPlainTextEdit’ın kendi Scrollbar widgetine ulaşabilir ve bu scrollbar’ın her hareketinde updateLineNumberArea fonksiyonunun tetiklenmesini sağlayabilirsiniz.

ChatGPT sadece editor’deki textChanged durumuna göre tetiklenen bir self.updateLineNumberArea çağrı mekanizması yazmış. Sizin ekstradan, scrollbar hareketi için de bu fonksiyonun tetiklenmesi gerektiğini tanımlamanız lazım.

Yani, aşağıdaki ifadeyi

self.editor.verticalScrollBar().valueChanged.connect(self.updateLineNumberArea)

sizin paylaştığınız kodun 12. satırında yer alan self.editor.textChanged.connect(self.updateLineNumberArea) ifadesinin altına eklemelisiniz ki scrollbar’daki değer değiştiğinde self.updateLineNumberArea fonksiyonu tetiklensin.

2 Beğeni