Python 实施";“查找全部”;在表格中显示匹配行并在单击表格单元格时跳转到行的算法

Python 实施";“查找全部”;在表格中显示匹配行并在单击表格单元格时跳转到行的算法,python,pyqt,pyside,Python,Pyqt,Pyside,我希望实现能够在QPlainTextEdit中搜索查询字符串并在表中显示所有匹配行的功能。选择表中的行应将光标移动到文档中的正确行 下面是一个查找所有匹配项并将其显示在表中的工作示例。如何获取明文编辑保存的字符串中的选定行号?我可以改为使用匹配.capturedEnd()和匹配.capturedStart()来显示匹配,但是行号比字符索引匹配更直观 MWE(为了好玩,很长的示例文本) 要将光标移动到指定位置,必须使用下面的using命令。 通过,您可以构造和使用将光标(包括实际插入符号位置)“应

我希望实现能够在
QPlainTextEdit
中搜索查询字符串并在表中显示所有匹配行的功能。选择表中的行应将光标移动到文档中的正确行

下面是一个查找所有匹配项并将其显示在表中的工作示例。如何获取明文编辑保存的字符串中的选定行号?我可以改为使用
匹配.capturedEnd()
匹配.capturedStart()
来显示匹配,但是行号比字符索引匹配更直观

MWE(为了好玩,很长的示例文本)
要将光标移动到指定位置,必须使用下面的using命令。
通过,您可以构造和使用将光标(包括实际插入符号位置)“应用”到纯文本

    def goToLine(self, line):
        block = self.fileViewer.document().findBlockByLineNumber(line)
        self.fileViewer.setTextCursor(qtg.QTextCursor(block))
        self.fileViewer.setFocus()
由于您将使用QTextDocument和QTextCursor,我建议您避免逐行搜索,因为QTextDocument已经通过以下方式提供了更兼容和可扩展的界面:

虽然使用QTextCursor接口有点困难,但它有很多好处。例如,您可以将匹配的游标(包括对找到的文本的选择)设置为项目数据,并将该游标设置为纯文本;结果是,不仅可以获得正确的位置,还可以自动选择匹配的文本:

    def findAll(self):
            # ...
            itemNumber = qtw.QTableWidgetItem()
            itemNumber.setData(qtc.Qt.DisplayRole, block.firstLineNumber())
            # since the cursor is being reused for the search, you must
            # construct a *new* instance based on it
            itemNumber.setData(qtc.Qt.UserRole, qtg.QTextCursor(cursor))
            # ...

    def goToLine(self, item):
        index = self.tableResults.model().index(item.row(), 0)
        cursor = index.data(qtc.Qt.UserRole)
        self.fileViewer.setTextCursor(cursor)
        self.fileViewer.setFocus()
def findAll(自身):
# ...
itemNumber=qtw.QTableWidgetItem()
itemNumber.setData(qtc.Qt.DisplayRole,block.firstLineNumber())
#由于光标将被重新用于搜索,因此必须
#基于它构造一个*新*实例
setData(qtc.Qt.UserRole、qtg.QTextCursor(cursor))
# ...
def goToLine(自身,项目):
index=self.tableResults.model().index(item.row(),0)
游标=index.data(qtc.Qt.UserRole)
self.fileViewer.setTextCursor(游标)
self.fileViewer.setFocus()

注意:您应该使用
self.tableResults.setEditTriggers(self.tableResults.NoEditTriggers)
来避免表中的项目编辑

什么是“到达所选行”?我的意思是将fileViewer中的光标移动到找到匹配项的行号。太好了,谢谢!我现在会选择更快的解决方案,但最终会尝试使用建议的游标界面!
class MainWindow(qtw.QWidget):
    def __init__(self):
        # ...
        self.tableResults.itemClicked.connect(self.goToLine)

    def findAll(self):
        self.tableResults.setRowCount(0)
        query = qtc.QRegularExpression(self.lineEditQuery.text())
        doc = self.fileViewer.document()
        cursor = qtg.QTextCursor(doc)
        rowCounter = 0
        while True:
            cursor = doc.find(query, cursor)
            if cursor.isNull():
                break
            self.tableResults.insertRow(rowCounter)
            block = cursor.block()
            itemNumber = qtw.QTableWidgetItem()
            # set the data as integer, not as string; you cannot do that using
            # QTableWidgetItem constructor
            itemNumber.setData(qtc.Qt.DisplayRole, block.firstLineNumber())
            itemLine = qtw.QTableWidgetItem(block.text())
            self.tableResults.setItem(rowCounter, 0, itemNumber)
            self.tableResults.setItem(rowCounter, 1, itemLine)
            rowCounter += 1
        self.tableResults.resizeColumnsToContents()

    def goToLine(self, item):
        line = self.tableResults.model().index(item.row(), 0).data()
        block = self.fileViewer.document().findBlockByLineNumber(line)
        self.fileViewer.setTextCursor(qtg.QTextCursor(block))
        self.fileViewer.setFocus()
    def findAll(self):
            # ...
            itemNumber = qtw.QTableWidgetItem()
            itemNumber.setData(qtc.Qt.DisplayRole, block.firstLineNumber())
            # since the cursor is being reused for the search, you must
            # construct a *new* instance based on it
            itemNumber.setData(qtc.Qt.UserRole, qtg.QTextCursor(cursor))
            # ...

    def goToLine(self, item):
        index = self.tableResults.model().index(item.row(), 0)
        cursor = index.data(qtc.Qt.UserRole)
        self.fileViewer.setTextCursor(cursor)
        self.fileViewer.setFocus()