首页 > 解决方案 > 在 QTextEdit 中滚动时导致出现问题的 drawText

问题描述

我有一个自定义文本框,显示文本框右上角的字符数。我通过继承 QTextEdit 并覆盖绘制事件并使用 QPainter 绘制字符数来做到这一点。

问题是,当滚动绘画时,会出现扭曲并显示多个字符数。当使用滚动条而不是鼠标滚轮进行滚动时,可以更清楚地看到问题。

这是我的代码。

from PyQt5 import QtWidgets, QtCore, QtGui
import sys


class TextBox(QtWidgets.QTextEdit):

    def __init__(self, maxChar=1000, *args, **kwargs):
        super(TextBox, self).__init__(*args, **kwargs)

        self.charCount = 0
        self.maxChar = maxChar

        self.painter_font = self.font()
        self.painter_font.setFamily('')
        self.painter_font.setPointSize(5)

        self.textChanged.connect(self.changeCount)

    def changeCount(self):
        self.charCount = len(self.toPlainText())

    def keyPressEvent(self, event):

        if self.charCount < self.maxChar:
            super(TextBox, self).keyPressEvent(event)

        if self.charCount >= self.maxChar:
            if event.key() in [QtCore.Qt.Key_Backspace, QtCore.Qt.Key_Delete, QtCore.Qt.Key_Up,
                               QtCore.Qt.Key_Left, QtCore.Qt.Key_Right, QtCore.Qt.Key_Down]:
                super(TextBox, self).keyPressEvent(event)

            if event.key() & QtCore.Qt.Key_A and event.modifiers() & QtCore.Qt.ControlModifier:
                super(TextBox, self).keyPressEvent(event)

    def paintEvent(self, event):
        super(TextBox, self).paintEvent(event)

        painter = QtGui.QPainter(self.viewport())
        painter.setFont(self.painter_font)

        painter.setPen(QtGui.QColor(QtCore.Qt.red))
        count = f'{self.charCount}/{self.maxChar}'

        multiplier = 4
        if self.verticalScrollBar().isVisible():
            multiplier = 8

        painter.drawText(QtCore.QPoint(self.width() - (len(count) * multiplier + 30), self.height() - 10), count)  # This is to make sure that the count stays inside the textbox when the number increases. If you have a better way pls help.


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)

    win = TextBox()
    win.show()

    sys.exit(app.exec_())

问题图片:

在此处输入图像描述

标签: pythonpyqtpyqt5

解决方案


这是一个演示如何使用标签在文本上打印字符数

class TextBox(QtWidgets.QTextEdit):

    def __init__(self, maxChar=1000, *args, **kwargs):
        super(TextBox, self).__init__(*args, **kwargs)

        self.charCount = 0
        self.maxChar = maxChar

        self.textChanged.connect(self.changeCount)

        # add a label to self.
        self.label = QtWidgets.QLabel('', self)
        self.label.setFixedSize(150, 15)
        self.label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignBottom)
        font = self.font()
        font.setPointSize(8)
        self.label.setFont(font)
        palette = self.label.palette()
        palette.setColor(palette.WindowText, QtGui.QColor("red"))
        self.label.setPalette(palette)
        self.changeCount()

    # the label text is updated when character count is changed   
    def changeCount(self):
        self.charCount = len(self.toPlainText())
        self.label.setText(f'{self.charCount}/{self.maxChar}')

    # The position of the label needs to be updated manually when the size of the text box changes     
    def resizeEvent(self, event):
        super().resizeEvent(event)
        self.label.move(event.size().width()-self.label.width(), event.size().height()-self.label.height())

    def keyPressEvent(self, event):

        if self.charCount < self.maxChar:
            super(TextBox, self).keyPressEvent(event)

        if self.charCount >= self.maxChar:
            if event.key() in [QtCore.Qt.Key_Backspace, QtCore.Qt.Key_Delete, QtCore.Qt.Key_Up,
                               QtCore.Qt.Key_Left, QtCore.Qt.Key_Right, QtCore.Qt.Key_Down]:
                super(TextBox, self).keyPressEvent(event)

            if event.key() & QtCore.Qt.Key_A and event.modifiers() & QtCore.Qt.ControlModifier:
                super(TextBox, self).keyPressEvent(event)

推荐阅读