Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a69f3f6a1 |
+42
-21
@@ -969,10 +969,11 @@ class ScrapeSearchWorker(QObject):
|
||||
results = Signal(list) # candidates with thumb_bytes added
|
||||
finished = Signal()
|
||||
|
||||
def __init__(self, system, query):
|
||||
def __init__(self, system, query, gen):
|
||||
super().__init__()
|
||||
self.system = system
|
||||
self.query = query
|
||||
self.gen = gen
|
||||
self._cancel = threading.Event()
|
||||
|
||||
def cancel(self):
|
||||
@@ -1003,11 +1004,12 @@ class ScrapeFetchWorker(QObject):
|
||||
result = Signal(dict) # {"meta": {...}, "cover": bytes|None}
|
||||
finished = Signal()
|
||||
|
||||
def __init__(self, system, rid, candidate):
|
||||
def __init__(self, system, rid, candidate, gen):
|
||||
super().__init__()
|
||||
self.system = system
|
||||
self.rid = rid
|
||||
self.candidate = candidate
|
||||
self.gen = gen
|
||||
self._cancel = threading.Event()
|
||||
|
||||
def cancel(self):
|
||||
@@ -1122,17 +1124,17 @@ class ScrapeDialog(QDialog):
|
||||
self.list.clear()
|
||||
self.candidates = []
|
||||
thread = QThread(self)
|
||||
worker = ScrapeSearchWorker(self.system, query)
|
||||
worker = ScrapeSearchWorker(self.system, query, gen)
|
||||
worker.moveToThread(thread)
|
||||
thread.started.connect(worker.run)
|
||||
worker.results.connect(lambda r, g=gen: self._on_results(r, g))
|
||||
worker.results.connect(self._on_results)
|
||||
worker.finished.connect(thread.quit)
|
||||
self._threads.append(thread)
|
||||
self._workers.append(worker)
|
||||
thread.start()
|
||||
|
||||
def _on_results(self, results, gen):
|
||||
if gen != self._search_gen:
|
||||
def _on_results(self, results):
|
||||
if getattr(self.sender(), "gen", None) != self._search_gen:
|
||||
return
|
||||
self.search_btn.setEnabled(True)
|
||||
self.candidates = results
|
||||
@@ -1172,17 +1174,17 @@ class ScrapeDialog(QDialog):
|
||||
self.search_btn.setEnabled(False)
|
||||
self.status.setText("Scraping…")
|
||||
thread = QThread(self)
|
||||
worker = ScrapeFetchWorker(self.system, self.rid, candidate)
|
||||
worker = ScrapeFetchWorker(self.system, self.rid, candidate, gen)
|
||||
worker.moveToThread(thread)
|
||||
thread.started.connect(worker.run)
|
||||
worker.result.connect(lambda p, g=gen: self._on_scraped(p, g))
|
||||
worker.result.connect(self._on_scraped)
|
||||
worker.finished.connect(thread.quit)
|
||||
self._threads.append(thread)
|
||||
self._workers.append(worker)
|
||||
thread.start()
|
||||
|
||||
def _on_scraped(self, payload, gen):
|
||||
if gen != self._search_gen:
|
||||
def _on_scraped(self, payload):
|
||||
if getattr(self.sender(), "gen", None) != self._search_gen:
|
||||
return
|
||||
meta = payload.get("meta") or {}
|
||||
cover = payload.get("cover")
|
||||
@@ -1198,7 +1200,15 @@ class ScrapeDialog(QDialog):
|
||||
self.search_btn.setEnabled(True)
|
||||
self.status.setText("Could not fetch anything for that selection.")
|
||||
|
||||
def closeEvent(self, event):
|
||||
def _shutdown_threads(self):
|
||||
"""Cancel workers and wait for their threads to fully finish.
|
||||
|
||||
Must run before the dialog is destroyed — QThread children abort the
|
||||
process with "QThread: Destroyed while thread is still running" if they
|
||||
are deleted while their worker thread is alive. ``done()`` covers
|
||||
accept()/reject() (including the accept() in ``_on_scraped``); the
|
||||
close event covers the window-manager close path.
|
||||
"""
|
||||
for w in self._workers:
|
||||
w.cancel()
|
||||
for t in self._threads:
|
||||
@@ -1207,8 +1217,15 @@ class ScrapeDialog(QDialog):
|
||||
t.wait()
|
||||
self._workers = []
|
||||
self._threads = []
|
||||
|
||||
def closeEvent(self, event):
|
||||
self._shutdown_threads()
|
||||
event.accept()
|
||||
|
||||
def done(self, result):
|
||||
self._shutdown_threads()
|
||||
super().done(result)
|
||||
|
||||
|
||||
class SettingsPage(QWidget):
|
||||
saved = Signal()
|
||||
@@ -4856,12 +4873,11 @@ class MainWindow(QMainWindow):
|
||||
thread = QThread(self)
|
||||
worker = LibraryWorker(self._ps1_dir, self._ps1_output_dir, self._nps_dir)
|
||||
worker.moveToThread(thread)
|
||||
thread._worker = worker
|
||||
thread.started.connect(worker.run)
|
||||
worker.result.connect(self._on_library_loaded)
|
||||
worker.finished.connect(thread.quit)
|
||||
worker.finished.connect(worker.deleteLater)
|
||||
thread.finished.connect(thread.deleteLater)
|
||||
thread.finished.connect(lambda t=thread, w=worker: self._forget_library_thread(t, w))
|
||||
thread.finished.connect(self._forget_library_thread)
|
||||
self._library_threads.append(thread)
|
||||
self._library_workers.append(worker)
|
||||
thread.start()
|
||||
@@ -4875,11 +4891,14 @@ class MainWindow(QMainWindow):
|
||||
self.store_page.set_library_items(self._library_cache)
|
||||
self.statusBar().showMessage("")
|
||||
|
||||
def _forget_library_thread(self, thread, worker):
|
||||
def _forget_library_thread(self):
|
||||
thread = self.sender()
|
||||
worker = getattr(thread, "_worker", None)
|
||||
if thread in self._library_threads:
|
||||
self._library_threads.remove(thread)
|
||||
if worker in self._library_workers:
|
||||
if worker is not None and worker in self._library_workers:
|
||||
self._library_workers.remove(worker)
|
||||
thread.deleteLater()
|
||||
|
||||
def _apply_library_filter(self):
|
||||
if not hasattr(self, "_library_cache"):
|
||||
@@ -5012,21 +5031,23 @@ class MainWindow(QMainWindow):
|
||||
thread = QThread(self)
|
||||
worker = MetadataWorker(title, gen, system, rid)
|
||||
worker.moveToThread(thread)
|
||||
thread._worker = worker
|
||||
thread.started.connect(worker.run)
|
||||
worker.result.connect(self._on_metadata)
|
||||
worker.finished.connect(worker.deleteLater)
|
||||
worker.finished.connect(thread.quit)
|
||||
thread.finished.connect(thread.deleteLater)
|
||||
thread.finished.connect(lambda t=thread, w=worker: self._forget_meta_thread(t, w))
|
||||
thread.finished.connect(self._forget_meta_thread)
|
||||
self._meta_threads.append(thread)
|
||||
self._meta_workers.append(worker)
|
||||
thread.start()
|
||||
|
||||
def _forget_meta_thread(self, thread, worker):
|
||||
def _forget_meta_thread(self):
|
||||
thread = self.sender()
|
||||
worker = getattr(thread, "_worker", None)
|
||||
if thread in self._meta_threads:
|
||||
self._meta_threads.remove(thread)
|
||||
if worker in self._meta_workers:
|
||||
if worker is not None and worker in self._meta_workers:
|
||||
self._meta_workers.remove(worker)
|
||||
thread.deleteLater()
|
||||
|
||||
def _on_metadata(self, gen, meta):
|
||||
if gen != self._meta_gen:
|
||||
|
||||
Reference in New Issue
Block a user