我正在寻找一种方法来实现上述内容。我创建了一个自定义 QTextEdit,它在下面的 QLabel 中显示字符数和允许的字符数。当我创建此类的实例时,一切都按预期工作,除了我尝试重新创建的 .setMaxLength 函数。下面是我的自定义 QTextEdit 类
class CustomTextEdit(QWidget):
def __init__(self, max_length=None, placeholder_text='', height=None, callback=None, *args, **kwargs):
super().__init__(*args, **kwargs)
self.max_length = max_length
self.text_edit = QTextEdit(self)
self.label = QLabel(self)
if height:
self.setFixedHeight(height)
if placeholder_text:
self.text_edit.setPlaceholderText(placeholder_text)
if callback:
self.text_edit.textChanged.connect(callback)
self.text_edit.textChanged.connect(self.update_char_count)
self.text_edit.setLineWrapMode(QTextEdit.LineWrapMode.WidgetWidth)
self.text_edit.setWordWrapMode(QTextOption.WrapMode.WordWrap)
layout = QVBoxLayout()
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(0)
layout.addWidget(self.text_edit, 1)
layout.addWidget(self.label, alignment=Qt.AlignmentFlag.AlignRight)
self.setLayout(layout)
self.update_char_count()
def update_char_count(self):
char_count = len(self.text_edit.toPlainText())
self.label.setText(f'{char_count}/{self.max_length if self.max_length is not None else "∞"}')
def keyPressEvent(self, event):
if self.max_length is not None:
# Allow special keys and deletion regardless of character count
if event.key() in (Qt.Key.Key_Backspace, Qt.Key.Key_Delete, Qt.Key.Key_Left, Qt.Key.Key_Right,
Qt.Key.Key_Up, Qt.Key.Key_Down, Qt.Key.Key_Control, Qt.Key.Key_Shift, Qt.Key.Key_Alt):
super().keyPressEvent(event)
return
# Check if current character count exceeds max_length
current_text = self.text_edit.toPlainText()
if len(current_text) >= self.max_length and event.text():
return # Ignore new character input if it exceeds max_length
super().keyPressEvent(event)
你的
keyPressEvent
函数中已经实现了一个非常接近
setMaxLength
行为的方案。然而,可以通过以下两种主要方式进行改进:
1. 使用信号来限制文本长度
与其在每次按键时检查文本长度,不如连接到
QTextEdit.textChanged
信号,并在文本长度超过限制时截断文本。这将提供更可靠的解决方案,即使文本以编程方式或通过粘贴操作更改:
class CustomTextEdit(QWidget):
def __init__(self, max_length=None, placeholder_text='', height=None, callback=None, *args, **kwargs):
# ... 其他初始化代码 ...
self.text_edit.textChanged.connect(self.limit_text_length)
def limit_text_length(self):
if self.max_length is not None:
text = self.text_edit.toPlainText()
if len(text) > self.max_length:
self.text_edit.setPlainText(text[:self.max_length])
# 可选:将光标移动到文本末尾
cursor = self.text_edit.textCursor()
cursor.movePosition(QTextCursor.End)
self.text_edit.setTextCursor(cursor)
self.update_char_count()
# ... 其他方法 ...
2. 使用
QPlainTextEdit
的 input mask
QLineEdit
的
setMaxLength
方法在内部使用输入掩码来限制文本长度。虽然
QTextEdit
没有直接等效的方法,但你可以使用
QPlainTextEdit
并设置一个输入掩码来达到类似的效果:
from PyQt6.QtWidgets import QPlainTextEdit
class CustomTextEdit(QWidget):
def __init__(self, max_length=None, placeholder_text='', height=None, callback=None, *args, **kwargs):
# ... 其他初始化代码 ...
self.text_edit = QPlainTextEdit(self)
if max_length is not None:
self.text_edit.setInputMask(f'X{max_length}')
# ... 其他初始化代码 ...
这种方法使用
X
字符作为占位符,最多允许
max_length
个字符。
选择哪种方法?
- 如果你需要一个简单的解决方案并且不需要支持富文本格式,则 input mask 方法更简单直接。
- 如果你需要支持富文本格式或者需要对文本长度限制进行更精细的控制,则 信号 方法更灵活。
希望这些改进对你有帮助!
标签:python,pyqt,pyqt6,qtextedit From: 78805505