python - 在 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_())
问题图片:
解决方案
这是一个演示如何使用标签在文本上打印字符数
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)
推荐阅读
- c - 错误编译后C编程的错误消息中的“标签”是什么?
- python - Python父子特定类结构
- java - 奖励后如何自动关闭奖励广告[Android-Studio]
- html - 为什么位置:相对;似乎改变了z-index?
- javascript - 下拉菜单不会在第二次点击时关闭
- c++ - 使用 AES 和 XTR-DH Crypto++ 加密音频文件
- sql-server - 在 SQL 函数中比较日期失败
- javascript - 如何使用`cid`在Node js中嵌入带有覆盖文本CSS的图像
- mysql - 由mysql中的主键和唯一键组成的复合键?
- php - 将默认文件名从数据库更改为其当前值