import multiprocessing import os import tempfile import time from typing import Optional from PyQt6.QtCore import QRunnable, QThread, QThreadPool from PyQt6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLineEdit, QCheckBox from bigtext import BigText from logFileModel import LogFileModel import asyncio class FilterTask(QRunnable): aborted = False future : asyncio.Future def __init__(self, source_model: LogFileModel, filter_model: LogFileModel, query: str): super(FilterTask, self).__init__() self.source_model = source_model self.filter_model = filter_model self.query = query self.future = asyncio.Future() def run(self): #print("writing to tmp file", self.filter_model.get_file()) start = time.time() self.filter_model.truncate() with open(self.source_model.get_file(), "rb") as source: while l := source.readline(): line = l.decode("utf8", errors="ignore") #print(line) if line.find(self.query) >= 0: self.filter_model.write_line(line) if self.aborted or self.future.cancelled(): print("aborted") break print("filtering for %s took %s" % (self.query, time.time() - start) ) self.future.done() class FilterWidget(QWidget): future = None filter_model : LogFileModel filter_task :Optional[FilterTask] = None def __init__(self, source_model: LogFileModel): super(FilterWidget, self).__init__() self.source_model = source_model self.layout = QVBoxLayout(self) self.layout.setContentsMargins(0, 0, 0, 0) query_field = QLineEdit() query_field.textChanged.connect(self.query_changed) ignore_case = QCheckBox(self.tr("ignore case")) ignore_case.setChecked(True) is_regex = QCheckBox(self.tr("regex")) is_regex.setChecked(True) filter_bar = QWidget() filter_bar.layout = QHBoxLayout(filter_bar) filter_bar.layout.setContentsMargins(0, 0, 0, 0) filter_bar.layout.addWidget(query_field) filter_bar.layout.addWidget(ignore_case) filter_bar.layout.addWidget(is_regex) (_handle, self.tmpfilename) = tempfile.mkstemp() self.filter_model = LogFileModel(self.tmpfilename, self.source_model.settings) self.hits_view = BigText(self.filter_model) self.layout.addWidget(filter_bar) self.layout.addWidget(self.hits_view) def query_changed(self, query: str): if len(query) == 0: return print("start function") if self.filter_task: print("abort started ", time.time()) self.filter_task.aborted = True print("abort done ", time.time()) self.filter_task = FilterTask(self.source_model, self.filter_model, query) # QThreadPool takes ownership and deletes 'hello' automatically QThreadPool.globalInstance().start(self.filter_task)