Function:
1. Click the Open Find and Replace button to pop up the Find and Replace window. After selecting the string, the window will open and the value will be automatically searched.
2. All found results are highlighted.
3. Display the number of results found and the number currently found
4. Implement batch replacement
Rendering:
Code:
import re importsys from PyQt5.QtCore import QRegExp, Qt from PyQt5.QtGui import QTextCharFormat, QColor, QTextCursor, QPalette, QFont from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QLineEdit, QLabel, QWidget, QCheckBox, \ QStatusBar, QToolBar, QComboBox, QTextEdit class FindReplace(QMainWindow): def __init__(self, parent=None): super(FindReplace, self).__init__(parent) def setupUi(self, text_edit,find_text): # Set positioning and upper left corner coordinates self.setGeometry(1200, 200, 250, 300) self.setWindowTitle("Find/Replace") self.text_edit = text_edit self.find_replace_window_is_open = 1 self.find_count = 0 #Number of searches self.find_label = QLabel("Find:") self.find_edit = QComboBox() self.find_edit.setEditable(True) self.find_edit.activated.connect(self.find_text) self.find_edit.editTextChanged.connect(self.find_text_edit) self.replace_label = QLabel("Replace:") self.replace_edit = QLineEdit() self.find_cb_case_sensitive = QCheckBox() self.find_cb_case_sensitive.setChecked(True) #self.find_cb_case_sensitive.stateChanged.connect(self.restore_checkbox_clicked) self.find_label_case_sensitive = QLabel() self.find_label_case_sensitive.setText("Case-insensitive:") self.find_cb_case_sensitive = QCheckBox() self.find_cb_case_sensitive.setChecked(True) #self.find_cb_case_sensitive.stateChanged.connect(self.restore_checkbox_clicked) self.find_label_case_sensitive = QLabel() self.find_label_case_sensitive.setText("Highlight all:") self.find_button = QPushButton('Find') self.find_button.clicked.connect(self.find_text) self.replace_button = QPushButton('replace') self.replace_button.clicked.connect(self.replace_text) self.replace_all_button = QPushButton('Replace all') self.replace_all_button.clicked.connect(self.replace_text_all) self.find_StatusBar1 = QToolBar() #self.find_StatusBar1 = QStatusBar() self.find_StatusBar1.setLayoutDirection(Qt.LeftToRight) self.find_StatusBar1_Label = QLabel() self.find_StatusBar1_Label.setStyleSheet("QLabel { color: blue; }") self.find_StatusBar1_Label.setFont(QFont("Microsoft YaHei", 8, 0)) self.find_StatusBar1.addWidget(self.find_StatusBar1_Label) self.find_edit.addItem(find_text) layout = QVBoxLayout() layout.addWidget(self.find_label) layout.addWidget(self.find_edit) layout.addWidget(self.replace_label) layout.addWidget(self.replace_edit) layout.addWidget(self.find_button) layout.addWidget(self.replace_button) layout.addWidget(self.replace_all_button) layout.addWidget(self.find_StatusBar1) container = QWidget() container.setLayout(layout) self.setCentralWidget(container) def find_text_edit(self): self.position = self.text_edit.textCursor().position() text = self.text_edit.document().toPlainText() find_text = self.find_edit.currentText() text_edit_select = self.text_edit.textCursor().selectedText() if find_text == '': self.background_reset(text) return if text_edit_select: self.position = self.position - len(text_edit_select) self.find_and_highlight() if self.i > 0: self.find_and_select() def find_text(self): self.position = self.text_edit.textCursor().position() find_text = self.find_edit.currentText() text = self.text_edit.document().toPlainText() if find_text == '': self.background_reset(text) return self.find_and_highlight() if self.i > 0 : self.find_and_select() def find_and_select(self): text = self.text_edit.document().toPlainText() find_text = self.find_edit.currentText() re_search = QRegExp(find_text) matches = re.finditer(re_search.pattern(), text) length = len(find_text) format = QTextCharFormat() format.setBackground(QColor("yellow")) # Loop through documents j = 0 for match in matches: if j == 0: self.start_match = match j+=1 index = match.start() if index >= self.position: cursor = self.text_edit.textCursor() cursor.setPosition(index) cursor.movePosition(QTextCursor.Right, QTextCursor.KeepAnchor, length) #self.text_edit.setFocus() self.text_edit.setTextCursor(cursor) cursor = self.text_edit.textCursor() cursor.mergeCharFormat(format) # Change the background color of the text self.find_StatusBar1_Label.setText(str(self.i) + 'result, current ' + str(j) + 'result) break #Judge if it reaches the end, then display the first one if self.i > 0 and self.i == j: index = self.start_match.start() cursor = self.text_edit.textCursor() cursor.setPosition(index) cursor.movePosition(QTextCursor.Right, QTextCursor.KeepAnchor, length) # self.text_edit.setFocus() self.text_edit.setTextCursor(cursor) cursor = self.text_edit.textCursor() cursor.mergeCharFormat(format) # Change the background color of the text self.find_StatusBar1_Label.setText(str(self.i) + ' results, current 1') def find_and_highlight(self): text_edit_select = self.text_edit.textCursor().selectedText() text = self.text_edit.document().toPlainText() find_text = self.find_edit.currentText() re_search = QRegExp(find_text) matches = re.finditer(re_search.pattern(), text) length = len(find_text) #Set the background color to white self.background_reset(text) cursor = self.text_edit.textCursor() format = QTextCharFormat() format.setBackground(QColor("yellow")) self.i = 0 # Loop through the document to select and display the value for match in re.finditer(re.escape(find_text), text): self.i + = 1 start = match.start() end = match.end() cursor.setPosition(start) cursor.movePosition(QTextCursor.Right, QTextCursor.KeepAnchor, end - start) cursor.mergeCharFormat(format) self.find_edit.setStyleSheet("QComboBox { color: black; }") self.find_StatusBar1_Label.setText(str(self.i) + 'results') if self.i == 0: self.find_edit.setStyleSheet("QComboBox { color: red; }") self.find_StatusBar1_Label.setStyleSheet("QLabel { color: red; }") else: self.find_StatusBar1_Label.setStyleSheet("QLabel { color: blue; }") #Judge the first time you enter. If the textedit selected string is equal to the search string, move the cursor to the initialization - search string length to facilitate the search for the first time it is selected. if self.find_count == 0 and text_edit_select == find_text: self.position = self.position - len(find_text) self.find_count + = 1 def replace_text(self): text = self.text_edit.document().toPlainText() find_text = self.find_edit.currentText() replace_text = self.replace_edit.text() self.background_reset(text) if find_text: text = text.replace(find_text, replace_text) self.text_edit.setPlainText(text) def replace_text_all(self): text_edit_select = self.text_edit.textCursor().selectedText() text = self.text_edit.document().toPlainText() find_text = self.find_edit.currentText() replace_text = self.replace_edit.text() self.background_reset(text) if find_text == text_edit_select: text = text.replace(find_text, replace_text) self.text_edit.setPlainText(text) def background_reset(self,text): #Set the background color to white format = QTextCharFormat() format.setBackground(QColor("white")) cursor = self.text_edit.textCursor() cursor.setPosition(0) cursor.movePosition(QTextCursor.Right, QTextCursor.KeepAnchor, len(text)) cursor.mergeCharFormat(format) # Change the background color of the text def closeEvent(self, event): #Add here the action you want to perform when closing the window self.background_reset(self.text_edit.document().toPlainText()) self.find_replace_window_is_open = 0 #Set the background color to white text = self.text_edit.document().toPlainText() self.background_reset(text) print("Window closed") event.accept() class MainWindow(QMainWindow): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.setWindowTitle("Main Window") self.setGeometry(400, 100, 1100, 800) self.text_edit = QTextEdit() self.button = QPushButton("Open the find and replace window") self.button.clicked.connect(self.open_find_replace_window) layout = QVBoxLayout() layout.addWidget(self.text_edit) layout.addWidget(self.button) container = QWidget() container.setLayout(layout) self.setCentralWidget(container) def open_find_replace_window(self): find_text = self.text_edit.textCursor().selectedText() self.find_replace_window = FindReplace(self) self.find_replace_window.setupUi(self.text_edit,find_text) self.find_replace_window.show() if __name__ == "__main__": app = QApplication(sys.argv) main_window = MainWindow() main_window.show() sys.exit(app.exec_())