From e8e3b8187104ec70b3bf1fded798237ba092fa1f Mon Sep 17 00:00:00 2001 From: BasioMeusPuga Date: Fri, 16 Mar 2018 20:19:35 +0530 Subject: [PATCH] Put cache refilling on separate thread Lookout for memory leaks --- lector/threaded.py | 46 +++++++++++++++++++++++++++++++++++++++++++++- lector/widgets.py | 34 +++++++++++++++------------------- 2 files changed, 60 insertions(+), 20 deletions(-) diff --git a/lector/threaded.py b/lector/threaded.py index badde53..7bc1dfe 100644 --- a/lector/threaded.py +++ b/lector/threaded.py @@ -19,7 +19,7 @@ import os import pathlib from multiprocessing.dummy import Pool -from PyQt5 import QtCore +from PyQt5 import QtCore, QtGui from lector import sorter from lector import database @@ -119,3 +119,47 @@ class BackGroundBookSearch(QtCore.QThread): initiate_threads() print(len(self.valid_files), 'books found') + + +class BackGroundCacheRefill(QtCore.QThread): + def __init__(self, image_cache, remove_value, filetype, book, all_pages, parent=None): + super(BackGroundCacheRefill, self).__init__(parent) + + self.image_cache = image_cache + self.remove_value = remove_value + self.filetype = filetype + self.book = book + self.all_pages = all_pages + + def run(self): + def load_page(current_page): + image_pixmap = QtGui.QPixmap() + + if self.filetype in ('cbz', 'cbr'): + page_data = self.book.read(current_page) + image_pixmap.loadFromData(page_data) + elif self.filetype == 'pdf': + page_data = self.book.page(current_page) + page_qimage = page_data.renderToImage(350, 350) + image_pixmap.convertFromImage(page_qimage) + return image_pixmap + + remove_index = self.image_cache.index(self.remove_value) + + if remove_index == 1: + first_path = self.image_cache[0][0] + self.image_cache.pop(3) + previous_page = self.all_pages[self.all_pages.index(first_path) - 1] + refill_pixmap = load_page(previous_page) + self.image_cache.insert(0, (previous_page, refill_pixmap)) + + else: + self.image_cache[0] = self.image_cache[1] + self.image_cache.pop(1) + try: + last_page = self.image_cache[2][0] + next_page = self.all_pages[self.all_pages.index(last_page) + 1] + refill_pixmap = load_page(next_page) + self.image_cache.append((next_page, refill_pixmap)) + except (IndexError, TypeError): + self.image_cache.append(None) diff --git a/lector/widgets.py b/lector/widgets.py index ac3d616..5dc967e 100644 --- a/lector/widgets.py +++ b/lector/widgets.py @@ -31,8 +31,9 @@ import popplerqt5 from rarfile import rarfile from lector.models import BookmarkProxyModel -from lector.sorter import resize_image from lector.delegates import BookmarkDelegate +from lector.threaded import BackGroundCacheRefill +from lector.sorter import resize_image class Tab(QtWidgets.QWidget): @@ -137,6 +138,8 @@ class Tab(QtWidgets.QWidget): self.horzLayout.addWidget(self.contentView) self.horzLayout.addWidget(self.dockWidget) title = self.metadata['title'] + if self.are_we_doing_images_only: + title = os.path.basename(title) self.parent.addTab(self, title) # Hide mouse cursor timer @@ -480,6 +483,8 @@ class PliantQGraphicsView(QtWidgets.QGraphicsView): self.image_pixmap = None self.image_cache = [None for _ in range(4)] + self.thread = None + self.filepath = filepath self.filetype = os.path.splitext(self.filepath)[1][1:] @@ -538,25 +543,16 @@ class PliantQGraphicsView(QtWidgets.QGraphicsView): self.image_cache[i + 1] = None def refill_cache(remove_value): - remove_index = self.image_cache.index(remove_value) + # Do NOT put a parent in here or the mother of all + # memory leaks will result + self.thread = BackGroundCacheRefill( + self.image_cache, remove_value, + self.filetype, self.book, all_pages) + self.thread.finished.connect(overwrite_cache) + self.thread.start() - if remove_index == 1: - first_path = self.image_cache[0][0] - self.image_cache.pop(3) - previous_page = all_pages[all_pages.index(first_path) - 1] - refill_pixmap = load_page(previous_page) - self.image_cache.insert(0, (previous_page, refill_pixmap)) - - else: - self.image_cache[0] = self.image_cache[1] - self.image_cache.pop(1) - try: - last_page = self.image_cache[2][0] - next_page = all_pages[all_pages.index(last_page) + 1] - refill_pixmap = load_page(next_page) - self.image_cache.append((next_page, refill_pixmap)) - except (IndexError, TypeError): - self.image_cache.append(None) + def overwrite_cache(): + self.image_cache = self.thread.image_cache def check_cache(current_page): for i in self.image_cache: