PySide6 文本编辑(QTextEdit)查找功能进阶 读取并记录上一次状态
文章目录
- PySide6 文本编辑(QTextEdit)查找功能进阶 读取并记录上一次状态
- 为什么写这篇文章?
- 参考
- 实现逻辑
- 完整代码
- 更多记事本功能
PySide6 文本编辑(QTextEdit)查找功能进阶 读取并记录上一次状态
为什么写这篇文章?
这篇文章是借鉴 win10
记事本 每次都可以读取上一次属性,使用PySide6
的实现!
参考
自定义查找对话框
查找功能大杂烩
匹配完整单词,区分大小写
更多
实现逻辑
通过读取和写入json
文件来存取和保存信息。
想法: Python
的字典读取与写入json
文件非常方便,所以就借用json
文件 而不是ini
文件
记录的信息:
- 行编辑里的查找文本 => 字符串(Str)类型
- 忽略大小写 复选框勾选状态 => 布尔(Bool)类型
- 循环 复选框勾选状态 => 布尔(Bool)类型
- 匹配完整单词 复选框勾选状态 => 布尔(Bool)类型
- 向上与向下 按钮的勾选状态 => 布尔(Bool)类型
读取注意: json
转为字典 json.load(file)
写入注意: 字典转为json
json.dumps(dictData)
关键代码:
def getStatWithFile(self) -> tuple[str,bool,bool,bool,bool,bool]:"""从文件获取状态 :return: 查找字符串,忽略大小写状态,循环状态,单词状态,上一个状态"""with open("cache/Dialog/findTextDialog/config.json","r",encoding="utf-8") as file:data = json.load(file)tupData = (data["findStr"],data["caseCheck"],data["cycleCheck"],data["wordCheck"],data["upBtn"],data["downBtn"])return tupDatadef setStat(self):"""设置状态"""findStr,caseStat,cycleStat,workStat,upStat,downBtn = self.getStatWithFile()self.findLineEdit.setText(findStr)self.caseSensitiveCheck.setChecked(caseStat)self.cycleCheck.setChecked(cycleStat)self.wordCheck.setChecked(workStat)self.upButton.setChecked(upStat)self.downButton.setChecked(downBtn)def saveStatusTofile(self):""" 保存状态到文件"""findStr = self.findLineEdit.text()caseStat = self.caseSensitiveCheck.isChecked()cycyleStat = self.cycleCheck.isChecked()wordStat = self.wordCheck.isChecked()upBtn = self.upButton.isChecked()downBtn = self.downButton.isChecked()data = {"findStr":findStr,"caseCheck":caseStat,"cycleCheck": cycyleStat,"wordCheck": wordStat,"upBtn": upBtn,"downBtn": downBtn}jsonData = json.dumps(data, ensure_ascii=False, indent=4)with open("cache/Dialog/findTextDialog/config.json","w",encoding="utf-8") as file:file.write(jsonData)
完整代码
注意
路径需要自行修改
自定义查找对话框findDialog.py
目前是取消按钮点击信号关联关闭窗口和 保存状态 俩个槽函数
取消了上一篇的设置默认状态。
# 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
import jsonclass 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.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_)self.setStat() #放到构造函数会一直读取def setEvnetBind(self):"""设置事件绑定"""# 查找下一个文本文档self.findNextButton.clicked.connect(self.setTextCursor)# 取消按钮触发关闭self.cancelButton.clicked.connect(self.close)self.cancelButton.clicked.connect(self.saveStatusTofile)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)def getStatWithFile(self) -> tuple[str,bool,bool,bool,bool,bool]:"""从文件获取状态 :return: 查找字符串,忽略大小写状态,循环状态,单词状态,上一个状态"""with open("cache/Dialog/findTextDialog/config.json","r",encoding="utf-8") as file:data = json.load(file)tupData = (data["findStr"],data["caseCheck"],data["cycleCheck"],data["wordCheck"],data["upBtn"],data["downBtn"])return tupDatadef setStat(self):"""设置状态"""findStr,caseStat,cycleStat,workStat,upStat,downBtn = self.getStatWithFile()self.findLineEdit.setText(findStr)self.caseSensitiveCheck.setChecked(caseStat)self.cycleCheck.setChecked(cycleStat)self.wordCheck.setChecked(workStat)self.upButton.setChecked(upStat)self.downButton.setChecked(downBtn)def saveStatusTofile(self):""" 保存状态到文件"""findStr = self.findLineEdit.text()caseStat = self.caseSensitiveCheck.isChecked()cycyleStat = self.cycleCheck.isChecked()wordStat = self.wordCheck.isChecked()upBtn = self.upButton.isChecked()downBtn = self.downButton.isChecked()data = {"findStr":findStr,"caseCheck":caseStat,"cycleCheck": cycyleStat,"wordCheck": wordStat,"upBtn": upBtn,"downBtn": downBtn}jsonData = json.dumps(data, ensure_ascii=False, indent=4)with open("cache/Dialog/findTextDialog/config.json","w",encoding="utf-8") as file:file.write(jsonData)
调用示例findDialog.py
# 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())
配置文件 config.json
{"findStr": "Apple","caseCheck": true,"cycleCheck": true,"wordCheck": true,"upBtn": true,"downBtn": false
}
更多记事本功能
欢迎来看看我的项目