PySide6 自定义文本查找对话框(QFindTextDialog)以及调用示例——重构版
PySide6 自定义文本查找对话框(QFindTextDialog)以及调用示例——重构版
实现功能一览
- 向上或向下查找
- 区分大小写
- 匹配完整单词
- 循环
- 向上或向下与其他的组合
实现了 上一版 没有实现的循环
参考
匹配完整单词
区分大小写
循环
代码示例
QFindTextDialog
# coding = utf-8from PySide6.QtWidgets import (QDialog,QLabel,QLineEdit,QCheckBox,QGroupBox,QRadioButton,QPushButton,QVBoxLayout,QHBoxLayout,QPlainTextEdit,QMessageBox)
from PySide6.QtCore import QRegularExpression
from PySide6.QtGui import QTextDocument,QTextCursor
class QFindTextDialog(QDialog):def __init__(self,plainTextEdit: QPlainTextEdit,parent=None):"""初始化"""self.plainTextEdit = plainTextEditsuper().__init__(parent)self.setupUi()self.setEvnetBind()def setupUi(self):self.setWindowTitle("查找")self.findLabel = QLabel("查找内容(&N)") # 需要设置伙伴关系self.findLineEdit = QLineEdit()self.findLabel.setBuddy(self.findLineEdit)# 全局布局 使用垂直布局gVboxLayout = QVBoxLayout(self)hboxLayout = QHBoxLayout()hboxLayout.addWidget(self.findLabel)hboxLayout.addWidget(self.findLineEdit)# 区分大小写 与循环self.caseSensitiveCheck = QCheckBox("区分大小写")self.cycleCheck = QCheckBox("循环")self.wordCheck = QCheckBox("匹配完整单词")vboxLayout = QVBoxLayout()vboxLayout.addWidget(self.caseSensitiveCheck)vboxLayout.addWidget(self.cycleCheck)vboxLayout.addWidget(self.wordCheck)# 方向 组合盒子 self.directGroupBox = QGroupBox()self.directGroupBox.setTitle("方向")self.upButton = QRadioButton("向上(&U)")self.downButton = QRadioButton("向下(&D)")directVLayout = QVBoxLayout(self.directGroupBox)directVLayout.addWidget(self.upButton)directVLayout.addWidget(self.downButton)# 默认向下self.downButton.setChecked(True)# 查找下一个与取消按钮self.findNextButton = QPushButton("查找下一个(F)")self.cancelButton = QPushButton("取消")vboxLayout_ = QVBoxLayout()vboxLayout_.addWidget(self.findNextButton)vboxLayout_.addWidget(self.cancelButton)# 添加部件与控件gVboxLayout.addLayout(hboxLayout)gVboxLayout.addLayout(vboxLayout)gVboxLayout.addWidget(self.directGroupBox)gVboxLayout.addLayout(vboxLayout_)def setEvnetBind(self):"""设置事件绑定"""# 查找下一个文本文档self.findNextButton.clicked.connect(self.setTextCursor)# 取消按钮触发关闭self.cancelButton.clicked.connect(self.close)def getRadioBtnStatus(self) -> tuple[bool,bool]:"""获取圆角按钮状体:return: 俩个按钮状态布尔值 的元组"""return (self.upButton.isChecked(),self.downButton.isChecked())def getCheckBoxStatus(self) -> tuple[bool,bool]:"""获取复选框的状态:return: 表示复选框状态的元组值"""return (self.caseSensitiveCheck.isChecked(),self.cycleCheck.isChecked(),self.wordCheck.isChecked)def getCycleCheckBoxStatus(self) -> bool:"""获取循环复选框状态:return: True|False"""return self.cycleCheck.isChecked()def getFindFlags(self):"""设置查找标签循环未实现后续添加完整单词"""# 上一个标签prevFlags = QTextDocument.FindFlag.FindBackward # 区分大小写标签caseFlags= QTextDocument.FindFlag.FindCaseSensitively# 匹配完整单词标签wordFlags = QTextDocument.FindFlag.FindWholeWords# 获取圆角按钮状态upBtnStat,downBtnStat = self.getRadioBtnStatus()# 获取复选框状态caseSensitiveStat,cycleStat,wordStat = self.getCheckBoxStatus()if upBtnStat:flags = prevFlagsif caseSensitiveStat and wordStat:flags = prevFlags | caseFlags | wordFlagselif caseSensitiveStat:flags = prevFlags | caseFlagselif wordStat:flags = prevFlags | wordFlagselif downBtnStat:flags = Noneif caseSensitiveStat and wordStat:flags = caseFlags | wordFlagselif caseSensitiveStat:flags = caseFlagselif wordStat:flags = wordFlagsreturn flagsdef setTextCursor(self):"""设置文本光标"""findStr = self.findLineEdit.text()exp = QRegularExpression(findStr)flags = self.getFindFlags()if flags:findRes = self.plainTextEdit.find(exp,flags)self.isResetCursor(findRes)else:findRes = self.plainTextEdit.find(exp)self.isResetCursor(findRes)def setNoFindMsgBox(self,findResult:bool):"""弹出找不到提示"""if findResult == False:findStr = self.findLineEdit.text()# 提示窗口msgBox = QMessageBox(self)msgBox.setWindowTitle("记事本") #查找窗口太小 时不会显示msgBox.setIcon(QMessageBox.Icon.Information)msgBox.setText(f'"{findStr}"')msgBox.exec()def isResetCursor(self,findResult:bool):"""重新设置光标"""cycleStatus = self.getCycleCheckBoxStatus()prevBtnStat,nextBtnStat = self.getRadioBtnStatus()# 如果勾选 按钮为向上 从最后开始查找# 如果勾选 按钮为向下 从开头开始查找if cycleStatus:if prevBtnStat and findResult == False:self.plainTextEdit.moveCursor(QTextCursor.MoveOperation.End)elif nextBtnStat and findResult == False:self.plainTextEdit.moveCursor(QTextCursor.MoveOperation.Start)else:if findResult == False:self.setNoFindMsgBox(findResult)
调用示例
# coding = utf-8from PySide6.QtWidgets import QWidget,QPushButton,QVBoxLayout,QPlainTextEdit,QApplication
from findDialog import QFindTextDialog
import sysclass TestNotePad(QWidget):def __init__(self):super().__init__()self.setupUi()self.setEventBind()def setupUi(self):"""设置用户界面"""self.setWindowTitle("测试查找对话框")# 全局使用垂直布局vboxLayout = QVBoxLayout(self)# 初始化 文本编辑器 按钮 self.plainTextEdit = QPlainTextEdit()self.findPushButton = QPushButton("查找下一个")# 将控件添加到垂直布局管理器中vboxLayout.addWidget(self.plainTextEdit)vboxLayout.addWidget(self.findPushButton)def setEventBind(self):"""设置事件绑定"""self.findPushButton.clicked.connect(self.getFindDialog)def getFindDialog(self):"""获取查找对话框"""findTextDialog = QFindTextDialog(self.plainTextEdit,self)findTextDialog.show()return findTextDialogif __name__ == "__main__":app = QApplication(sys.argv)testNotePad = TestNotePad()testNotePad.show()sys.exit(app.exec())