Pozrel som sa na tento kód editor príklad z oficiálnych Qt5 webové stránky https://doc.qt.io/qt-5/qtwidgets-widgets-codeeditor-example.html. Je napísaný v C++, ale ja ho zaviedli v Pythone pomocou Pyside2.
Napríklad kód funguje tak, ako je, avšak, keď som sa pokúsiť zmeniť rodina písma a veľkosť QPlainTextEdit
veci sa začnú dostať chaotický. Snažil som sa meniť veľa rôznych oblastiach, ako pomocou fontMetrics
na určenie výšky atď.
Tu je minimálnym príklad na reprodukovanie problému
import sys
import signal
from PySide2.QtCore import Qt, QSize, QRect
from PySide2.QtGui import QPaintEvent, QPainter, QColor, QResizeEvent
from PySide2.QtWidgets import QWidget, QPlainTextEdit, QVBoxLayout
from PySide2 import QtCore
from PySide2.QtWidgets import QApplication
FONT_SIZE = 20
FONT_FAMILY = 'Source Code Pro'
class PlainTextEdit(QPlainTextEdit):
def __init__(self, parent=None):
super().__init__(parent)
self.init_settings_font()
def init_settings_font(self):
font = self.document().defaultFont()
font.setFamily(FONT_FAMILY)
font.setFixedPitch(True)
font.setPixelSize(FONT_SIZE)
self.document().setDefaultFont(font)
class LineNumberArea(QWidget):
TMP = dict()
def __init__(self, editor):
super().__init__(editor)
self._editor = editor
self._editor.blockCountChanged.connect(lambda new_count: self._update_margin())
self._editor.updateRequest.connect(lambda rect, dy: self._update_request(rect, dy))
self._update_margin()
def width(self) -> int:
# we use 1000 as a default size, so from 0-9999 this length will be applied
_max = max(1000, self._editor.blockCount())
digits = len(f'{_max}')
space = self._editor.fontMetrics().horizontalAdvance('0', -1) * (digits + 1) + 6
return QSize(space, 0).width()
def _update_line_geometry(self):
content_rect = self._editor.contentsRect()
self._update_geometry(content_rect)
def _update_geometry(self, content_rect: QRect):
self.setGeometry(
QRect(content_rect.left(), content_rect.top(), self.width(), content_rect.height())
)
def _update_margin(self):
self._editor.setViewportMargins(self.width(), 0, 0, 0)
def _update_request(self, rect: QRect, dy: int):
self._update(0, rect.y(), self.width(), rect.height(), self._editor.contentsRect())
if rect.contains(self._editor.viewport().rect()):
self._update_margin()
def _update(self, x: int, y: int, w: int, h: int, content_rect: QRect):
self.update(x, y, w, h)
self._update_geometry(content_rect)
# override
def resizeEvent(self, event: QResizeEvent) -> None:
self._update_line_geometry()
# override
def paintEvent(self, event: QPaintEvent):
painter = QPainter(self)
area_color = QColor('darkgrey')
# Clearing rect to update
painter.fillRect(event.rect(), area_color)
visible_block_num = self._editor.firstVisibleBlock().blockNumber()
block = self._editor.document().findBlockByNumber(visible_block_num)
top = self._editor.blockBoundingGeometry(block).translated(self._editor.contentOffset()).top()
bottom = top + self._editor.blockBoundingRect(block).height()
active_line_number = self._editor.textCursor().block().blockNumber() + 1
# font_size = storage.get_setting(Constants.Editor_font_size).value
font = self._editor.font()
while block.isValid() and top <= event.rect().bottom():
if block.isVisible() and bottom >= event.rect().top():
number_to_draw = visible_block_num + 1
if number_to_draw == active_line_number:
painter.setPen(QColor('black'))
else:
painter.setPen(QColor('white'))
font.setPixelSize(self._editor.document().defaultFont().pixelSize())
painter.setFont(font)
painter.drawText(
-5,
top,
self.width(),
self._editor.fontMetrics().height(),
int(Qt.AlignRight | Qt.AlignHCenter),
str(number_to_draw)
)
block = block.next()
top = bottom
bottom = top + self._editor.blockBoundingGeometry(block).height()
visible_block_num += 1
painter.end()
if __name__ == "__main__":
app = QApplication(sys.argv)
signal.signal(signal.SIGINT, signal.SIG_DFL)
window = QWidget()
layout = QVBoxLayout()
editor = PlainTextEdit()
line_num = LineNumberArea(editor)
layout.addWidget(editor)
window.setLayout(layout)
window.show()
sys.exit(app.exec_())
Jedným z najväčších problémov je, že sa zdá byť horný okraj kompenzované vo forme obyčajného textu východ, ktorý som schopný dynamicky dostať v linenumber widget. A keď nastavenie editora font na maliar čísla nebudú vypracované rovnakej veľkosti!?
Vie niekto ako nastaviť čísla riadkov, na rovnakej horizontálnej úrovni ako príslušný text a aj sa im byť rovnakej veľkosti v dynamickým spôsobom, to znamená, že ak písmo bude nastavený na niečo iné, všetky by mali byť nastavená automaticky.