Pyside2-Linenumbers 에서 되는 잘못되었을 때 변경된 글꼴/사이즈

0

질문

나가이드 편집기를 들어에서 공식 웹사이트 Qt5 https://doc.qt.io/qt-5/qtwidgets-widgets-codeeditor-example.html. 그것은 C++로 작성된 그러나 나는 그것을 구현했에서 사용하는 파이썬 Pyside2.

예제 코드의 잘 작동으로,그러나 빠르게 액세스할 수 있습을 변경하는 글꼴 및 크기 QPlainTextEdit 일을 시작 지저분하다. 내가 하려고 했을 조정할 다른 분야의 많은 같은 사용 fontMetrics 을 결정을 높이는 등등.

여기에는 최소 예 문제를 재현

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_())

하나의 가장 큰 문제는 있을 것 최고률 오프셋에서는 일반 텍스트로 출구로 나는 할 수 없습을 동적으로 얻을 줄 번호 위젯입니다. 고 설정할 때 편집기 글꼴을의 숫자는되지 않습니다 같은 사이즈!!!!!!!!?

사람을 조절하는 방법을 알고 선 번호를 동일한 수평 수준으로 해당 텍스트와 그들이 동일한 크기의 동적 방법을 의미하는 경우 글꼴을 설정하는 다른 무언가들은 모두 자동으로 조정됩니다.

pyside2 python-3.x
2021-11-20 05:34:22
1

최고의 응답

1

문제는 사실에서 사용하고 있는 두 글꼴을 다른 목적을 위해:이 위젯 글꼴 및 문서에 글꼴입니다.

각 글꼴은 다른 측면이며,그 선형이 다를 수 있습 고려하는 경우,해당 글꼴을 기반으로 그리기를 조정합니다.

때문에 당신은 그림과 문서에 글꼴 하지만 위젯을 사용하는 글꼴 참고로,결과는 당신이 그리는 문제점:

  • 심지어 같은 포인트 크기,다른 글꼴은 그린 서로 다른 높이에서,특히 경우 텍스트의 정렬을 사각형은 정확하지 않다(또한 당신이 사용되는 일관성이 없는 맞춤로 Qt.AlignRight | Qt.AlignHCenter 이 항상 고려 오른쪽 정렬하고 기본값은 위로 정렬)
  • 당신이 사용하는 위젯 글꼴 메트릭을 텍스트를 설정하는 사각형의 높이와 다른 문서의 통계,그래서 당신은 제한을 높이의 그림이 있습니다.

다른 위젯과 달리,풍부한 텍스트 편집기에서는 Qt 두 글꼴 설정:

  • 위젯 글꼴
  • (기본값) 문서에 글꼴을 수정할 수 있습으로 QTextOption 에서 문서

이 문서에서 항상 상속에 위젯 글꼴(또는 응용 프로그램이 글꼴)에 대한 기본적으로 그리고 이것은 또한 때 일어날 글꼴을 설정한 위젯 at runtime,심지어 응용 프로그램에 대한(하지 않는 글꼴을 명시적으로 설정 한 위젯).

설정하는 편집기의 글꼴은 일반적으로 미세한 간단한 상황에 있지만,당신이 기억하는 글꼴을 전파하기 때문에,어린이 위젯을 상속 글꼴 too.

다른 한편으로,설정을 기본 글꼴을 위해 문서를 전파하지 않을 어린이들에게,그러나,위에 설명된 대로,재정의할 수 있습 응용 프로그램이 글꼴을 경우에는 변경되었을 수 있습니다.

가장 간단한 솔루션 당신의 경우에는 것,글꼴을 설정하기 위해 온라인 설문 조사를 진행하고 위젯을 대신의 문서입니다. 이 방법을 것임을 확신 LineNumberArea(는 편집기의 아동)또한 상속 같은 글꼴입니다. 이 방법으로 당신도 필요하지 않은 글꼴을 설정하의 화가로,그것은 항상 위젯을 사용 글꼴입니다.

하고 싶은 경우에 다른 글꼴을 사용하고 여전히 계속 올바른 정렬을 고려하는 기준 위치의 글꼴을 사용에 대한 문서 사용하는 참조 기준에 대한 위젯의 글꼴입니다. 그러기 위해서는,당신은 당신을 번역하는 블록에 위치의 차이가 ascent() 의 두 글꼴 메트릭.

2021-11-20 13:08:21

다른 언어로

이 페이지는 다른 언어로되어 있습니다

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................