在 QTextEdit 中滚动时 drawText 导致问题
drawText causing problems when scrolling in QTextEdit
我有一个自定义文本框,它在文本框的右上角显示字符数。
我通过继承 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)
我有一个自定义文本框,它在文本框的右上角显示字符数。 我通过继承 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)