直接在QMainWindow对QTextEdit查找关键词进行高亮显示,发现效果可以达到,但是当要检索的内容比较多的时候,会出现应用卡住的情况,使用体验很不友好。
于是想着放到子线程中来执行,结果发现子线程中无法查找到关键字,查找资料说不能在子线程中操作GUI控件,可以将查找单独封装一个类来执行,在子线程中调用,高亮显示在主线程中完成。
查找类:
class SearchWorker(QObject):
finished = pyqtSignal(list)
def find_text(self, document, keyword):
# 查找匹配项
matches = []
if keyword.strip():
cursor = QTextCursor(document)
cursor = document.find(keyword, cursor)
while not cursor.isNull():
matches.append(cursor)
cursor = document.find(keyword, cursor)
self.finished.emit(matches)
子线程:
class SearchThread(QThread):
def __init__(self, dialog):
super().__init__()
self.dialog = dialog
def run(self):
keyword = self.dialog.search_box.text()
document = self.dialog.detail_edit.document()
self.dialog.detail_edit.moveCursor(QTextCursor.Start)
self.dialog.search_worker.find_text(document, keyword)
主线程:
class MyDialog(QMainWindow):
def __init__(self, parent=None):
super(MyDialog, self).__init__(parent)
...
self.search_count = 0
self.search_text = ""
self.search_worker = SearchWorker(self)
self.search_thread = SearchThread(self)
self.search_worker.finished.connect(self.handleSearchResult)
def clearHighlight(self):
# 清除之前的高亮
white_format = QTextCharFormat()
white_format.setBackground(QColor("white"))
# 选择全部文本
self.detail_edit.selectAll()
# 应用QTextCharFormat对象,清除高亮
self.detail_edit.mergeCurrentCharFormat(white_format)
def handleSearchResult(self,matches):
self.search_count = len(matches)
self.clearHighlight()
# 设置下一个匹配项的高亮
yellow_format = QTextCharFormat()
yellow_format.setBackground(QColor("yellow"))
for match in matches:
match.mergeCharFormat(yellow_format)
cursor = QTextCursor(self.detail_edit.document())
for match in matches:
# 将光标定位到第一个匹配项上
cursor.setPosition(match.position())
self.detail_edit.setTextCursor(cursor)
break # 只需要定位到第一个匹配项即可