我可以将多个 QPdfSearchModel 合并为一个来与我的 QListView 连接吗?

问题描述 投票:0回答:1

我想使用 QPdfSearchModel 用 pdf 中的所有搜索结果填充 QListView。问题是我正在寻找的字符串可以有或没有空格。例如。当我搜索“ABC DEF”时,QListView 应该显示“ABC DEF”和“ABCDEF”的所有结果。

在 QPdfSearchModel 中,您只能设置单个搜索词。因此,我想扩展这一功能以包含多个搜索词。

我创建了一个新类“CombinedListModel”来组合多个 QPDFSearchmodels 的结果。这部分有效,因为我能够看到 QListView 中所有搜索字符串的所有命中。但是,与 PdfViewer 的链接消失了,因为单击 QListView 中的项目不会执行任何操作。

import sys
from PySide6.QtCore import Qt, QModelIndex
from PySide6.QtWidgets import QApplication, QMainWindow, QListView, QVBoxLayout, QWidget, QLineEdit
from PySide6.QtPdf import QPdfDocument, QPdfSearchModel
from PySide6.QtPdfWidgets import QPdfView
from PySide6 import QtGui  

class CombinedListModel(QPdfSearchModel):
    def __init__(self, models, parent=None):
        super(CombinedListModel, self).__init__(parent)
        self.models = models

    def rowCount(self, parent=QModelIndex()):
        return sum(model.rowCount(QModelIndex()) for model in self.models)

    def data(self, index, role=Qt.DisplayRole):
        if not index.isValid():
            return None

        current_row = index.row()
        for model in self.models:
            if current_row < model.rowCount(QModelIndex()):
                return model.data(model.index(current_row), role)
            current_row -= model.rowCount(QModelIndex())

        return None


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("PDF Search Viewer")

        self.search_bar = QLineEdit(self)
        self.search_bar.textChanged.connect(self.on_search_text_changed)
        self.list_view = QListView(self)
        self.list_view.clicked.connect(self.on_list_view_clicked)

        layout = QVBoxLayout()
        layout.addWidget(self.search_bar)
        layout.addWidget(self.list_view)

        container = QWidget()
        container.setLayout(layout)
        self.setCentralWidget(container)

        self.pdf_document = QPdfDocument(self)
        self.pdf_document.load(r"C:\temp\OCR_highlighted.pdf")  # Path to your PDF file


        self.pdf_viewer = QPdfView(self)
        self.pdf_viewer.setDocument(self.pdf_document)
        self.pdf_viewer.setPageMode(QPdfView.PageMode.MultiPage)
        layout.addWidget(self.pdf_viewer)

        self.search_bar.setText("ABCDEF;ABC DEF")

    def on_search_text_changed(self, text):
        # create multiple search models
        search_terms = text.split(';')  # Split the search terms by semicolon
        self.search_models = [QPdfSearchModel(self) for _ in search_terms]
        for model, term in zip(self.search_models, search_terms):
            model.setDocument(self.pdf_document)
            model.setSearchString(term)
            print(f"Found: {len(sum([model.resultsOnPage(i) for i in range(self.pdf_document.pageCount())],[]))} times")

        combined_model = CombinedListModel(self.search_models)

        if False:
            self.list_view.setModel(self.search_models[(0)])
            self.pdf_viewer.setSearchModel(self.search_models[0])
        else:
            self.list_view.setModel(combined_model)
            self.pdf_viewer.setSearchModel(combined_model) # --> This does not work properly (links are gone)


    def on_list_view_clicked(self, index):
        self.pdf_viewer.setCurrentSearchResultIndex(index.row()) # --> This does not work properly with combined model (links are gone)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())
python pyqt pyqt6
1个回答
0
投票

QPdfView
类使用
resultAtIndex()
类的
resultsOnPage()
QPdfSearchModel
方法,但目前无法重写这些方法,如 Musicamante 所评论的。 (视图在渲染页面时调用它们。)因此,不可能同时渲染多个模型的搜索结果(
QPdfLink
对象)。

您最好的选择是,当单击搜索结果时,将搜索模型更改为相应的模型。 (先调用

setSearchModel()
,然后再调用
setCurrentSearchResultIndex()
。)

© www.soinside.com 2019 - 2024. All rights reserved.