QPlainTextEdit输入文本实时校验与格式化实现技术问询
Great question! Let's break this down step by step—your current while True loop approach will block Qt's event loop and freeze your application, so we need to use Qt's built-in signal-slot mechanism for continuous validation instead. Here's how to make it work:
1. 实现持续实时校验
Qt widgets like QPlainTextEdit emit a textChanged() signal every time the content is modified. We can connect this signal to our validation/formatting function to trigger it automatically whenever the user types, pastes, or edits text.
Forget the infinite loop—this is the proper event-driven way to handle continuous checks in Qt.
2. 文本校验与格式化(标记"print"为粗体彩色)
To format specific text (like highlighting "print"), we'll use QTextCharFormat to define the style (color, bold, etc.) and QTextCursor to apply this format to matching parts of the text. We also need a flag to prevent infinite recursion, since modifying the text will trigger textChanged() again.
Full Working Code Example
from PyQt5.QtWidgets import (QApplication, QMainWindow, QPlainTextEdit) from PyQt5.QtGui import QTextCharFormat, QColor from PyQt5.QtCore import Qt class EditorWindow(QMainWindow): def __init__(self): super().__init__() self.plainTextEdit = QPlainTextEdit(self) self.setCentralWidget(self.plainTextEdit) # Connect text change signal to our recognizer function self.plainTextEdit.textChanged.connect(self.recognizer) # Flag to prevent infinite recursion when updating text format self.updating_format = False def recognizer(self): # Skip if we're already applying formatting to avoid loops if self.updating_format: return self.updating_format = True cursor = self.plainTextEdit.textCursor() cursor.beginEditBlock() # Batch changes for better performance # Define the format for "print": bold, red text highlight_format = QTextCharFormat() highlight_format.setFontWeight(QTextCharFormat.Bold) highlight_format.setForeground(QColor(Qt.red)) # Reset existing formats first (optional but cleaner) default_format = QTextCharFormat() cursor.select(QTextCursor.Document) cursor.setCharFormat(default_format) cursor.clearSelection() # Search for all occurrences of "print" search_text = "print" document = self.plainTextEdit.document() cursor = document.find(search_text) while not cursor.isNull(): # Apply the highlight format to the matched text cursor.setCharFormat(highlight_format) # Continue searching from the end of the current match cursor = document.find(search_text, cursor) cursor.endEditBlock() self.updating_format = False if __name__ == "__main__": app = QApplication([]) window = EditorWindow() window.show() app.exec_()
Key Details:
- Signal-Slot Connection: The
textChanged()signal triggersrecognizer()every time the text changes—this is our "continuous validation" mechanism. - Formatting Guard: The
self.updating_formatflag stops the function from re-triggering itself when we apply formatting (since changing the text format emitstextChanged()again). - Batch Edits:
beginEditBlock()andendEditBlock()wrap our formatting changes into a single undo/redo step, which is better for user experience. - Resetting Formats: We first clear all existing formatting to avoid leftover styles as the user edits.
3. Customization Tips
- To add more keywords to highlight, just expand the search logic (e.g., loop through a list of words like
["print", "def", "class"]). - Adjust the
QTextCharFormatto change styles—you can set font size, background color, italics, etc. - For more complex syntax highlighting, consider subclassing
QSyntaxHighlighterinstead—it's designed specifically for this use case and more efficient for large documents.
内容的提问来源于stack exchange,提问作者Hunterx01

