QGraphicsView for image browsing

This commit is contained in:
BasioMeusPuga
2017-11-16 23:25:03 +05:30
parent b1b27cf3b9
commit d70d61a84e
3 changed files with 133 additions and 51 deletions

View File

@@ -34,6 +34,8 @@
✓ Keep fontsize and margins consistent - Let page increase in length
✓ Fullscreening
✓ Remember open tabs
Special Keyboard shortcuts and view modes for QGraphicsView
Selectable background color for QGraphicsView
Record progress
Pagination
Set context menu for definitions and the like
@@ -286,11 +288,9 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
self.tabWidget.removeTab(tab_index)
def set_toc_position(self, event=None):
chapter_name = self.bookToolBar.tocBox.currentText()
current_tab = self.tabWidget.widget(self.tabWidget.currentIndex())
required_content = current_tab.metadata['content'][chapter_name]
# We're also updating the underlying model to have real-time
# We're updating the underlying model to have real-time
# updates on the read status
# Set a baseline model index in case the item gets deleted
@@ -314,14 +314,13 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
self.viewModel.setData(
model_index, current_tab.metadata['position'], QtCore.Qt.UserRole + 7)
# current_tab.contentView.verticalScrollBar().setValue(0)
current_tab.contentView.clear()
current_tab.contentView.setHtml(required_content)
current_tab.chapter_change()
def set_fullscreen(self):
current_tab = self.tabWidget.currentIndex()
current_tab_widget = self.tabWidget.widget(current_tab)
self.current_contentView = current_tab_widget.findChildren(QtWidgets.QTextBrowser)[0]
self.current_contentView = current_tab_widget.findChildren(
(QtWidgets.QTextBrowser, QtWidgets.QGraphicsView))[0]
self.current_contentView.setWindowFlags(QtCore.Qt.Window)
self.current_contentView.setWindowState(QtCore.Qt.WindowFullScreen)
@@ -458,16 +457,8 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
return
# Change contentView to match new settings
current_tab = self.tabWidget.currentIndex()
current_tab_widget = self.tabWidget.widget(current_tab)
current_contentView = current_tab_widget.findChildren(QtWidgets.QTextBrowser)[0]
# This allows for the scrollbar to always be at the edge of the screen
current_contentView.setViewportMargins(padding, 0, padding, 0)
current_contentView.setStyleSheet(
"QTextEdit {{font-family: {0}; font-size: {1}px; color: {2}; background-color: {3}}}".format(
font, font_size, foreground, background))
current_tab = self.tabWidget.widget(self.tabWidget.currentIndex())
current_tab.format_view(font, font_size, foreground, background, padding)
def reset_profile(self):
current_profile_index = self.bookToolBar.profileBox.currentIndex()

View File

@@ -93,7 +93,7 @@ class ParseCBZ:
page_name = 'Page ' + str(count)
image_path = os.path.join(extract_path, image_dir, i)
# contents[page_name] = image_path
contents[page_name] = "<img src='%s' align='middle'/>" % image_path
contents[page_name] = image_path
# contents[page_name] = "<img src='%s' align='middle'/>" % image_path
return contents, file_settings

View File

@@ -274,28 +274,14 @@ class Tab(QtWidgets.QWidget):
# Take hint from a position function argument to open the book
# at a specific page
# The content display widget is currently a QTextBrowser
super(Tab, self).__init__(parent)
self.parent = parent
self.metadata = metadata # Save progress data into this dictionary
self.gridLayout = QtWidgets.QGridLayout(self)
self.gridLayout.setObjectName("gridLayout")
self.contentView = PliantQTextBrowser(self.window())
self.contentView.setFrameShape(QtWidgets.QFrame.NoFrame)
self.contentView.setObjectName("contentView")
self.contentView.verticalScrollBar().setSingleStep(7)
self.contentView.setHorizontalScrollBarPolicy(
QtCore.Qt.ScrollBarAlwaysOff)
self.scroll_past_end_tries = 0
title = self.metadata['title']
position = self.metadata['position']
relative_path_root = self.metadata['temp_dir']
relative_paths = []
for i in os.walk(relative_path_root):
relative_paths.append(os.path.join(relative_path_root, i[0]))
# TODO
# Chapter position and vertical scrollbar position
@@ -307,13 +293,42 @@ class Tab(QtWidgets.QWidget):
chapter_name = list(self.metadata['content'])[current_chapter - 1]
chapter_content = self.metadata['content'][chapter_name]
# The content display widget is, by default a QTextBrowser
# In case the incoming data is only images
# such as in the case of comic book files,
# we want a QGraphicsView widget doing all the heavy lifting
# instead of a QTextBrowser
self.are_we_doing_images_only = self.metadata['images_only']
if self.are_we_doing_images_only: # Boolean
self.contentView = PliantQGraphicsView(self.window())
self.contentView.loadImage(chapter_content)
self.setStyleSheet("background-color: black;")
else:
self.contentView = PliantQTextBrowser(self.window())
relative_path_root = self.metadata['temp_dir']
relative_paths = []
for i in os.walk(relative_path_root):
relative_paths.append(os.path.join(relative_path_root, i[0]))
self.contentView.setSearchPaths(relative_paths)
self.contentView.setOpenLinks(False) # Change this when HTML navigation works
self.contentView.setHtml(chapter_content)
# The following are common to both the text browser and
# the graphics view
self.contentView.setFrameShape(QtWidgets.QFrame.NoFrame)
self.contentView.setObjectName("contentView")
self.contentView.verticalScrollBar().setSingleStep(7)
self.contentView.setHorizontalScrollBarPolicy(
QtCore.Qt.ScrollBarAlwaysOff)
self.generate_keyboard_shortcuts()
self.gridLayout.addWidget(self.contentView, 0, 0, 1, 1)
title = self.metadata['title']
self.parent.addTab(self, title)
def generate_position(self):
@@ -352,40 +367,116 @@ class Tab(QtWidgets.QWidget):
# self.exit_all.activated.connect(self.sneaky_exit)
def exit_fullscreen(self):
self.window().show()
self.contentView.setWindowFlags(QtCore.Qt.Widget)
self.contentView.setWindowState(QtCore.Qt.WindowNoState)
self.contentView.show()
self.window().show()
def chapter_change(self):
chapter_name = self.window().bookToolBar.tocBox.currentText()
required_content = self.metadata['content'][chapter_name]
if self.are_we_doing_images_only:
self.contentView.loadImage(required_content)
else:
self.contentView.clear()
self.contentView.setHtml(required_content)
def format_view(self, font, font_size, foreground, background, padding):
self.contentView.setViewportMargins(padding, 0, padding, 0)
if self.are_we_doing_images_only:
self.contentView.setBackgroundBrush(
QtGui.QBrush(QtCore.Qt.black, QtCore.Qt.SolidPattern))
else:
self.contentView.setStyleSheet(
"QTextEdit {{font-family: {0}; font-size: {1}px; color: {2}; background-color: {3}}}".format(
font, font_size, foreground, background))
def sneaky_change(self):
direction = -1
if self.sender().objectName() == 'nextChapter':
direction = 1
self.contentView.change_chapter(direction, True)
self.contentView.common_functions.change_chapter(
direction, True)
def sneaky_exit(self):
self.contentView.hide()
self.window().closeEvent()
class PliantQGraphicsView(QtWidgets.QGraphicsView):
def __init__(self, main_window, parent=None):
super(PliantQGraphicsView, self).__init__(parent)
self.main_window = main_window
self.image_pixmap = None
self.ignore_wheel_event = False
self.ignore_wheel_event_number = 0
self.common_functions = PliantWidgetsCommonFunctions(self, self.main_window)
def loadImage(self, image_path):
self.image_pixmap = QtGui.QPixmap()
self.image_pixmap.load(image_path)
self.resizeEvent()
def resizeEvent(self, event=None):
if not self.image_pixmap:
return
profile_index = self.main_window.bookToolBar.profileBox.currentIndex()
current_profile = self.main_window.bookToolBar.profileBox.itemData(
profile_index, QtCore.Qt.UserRole)
padding = current_profile['padding']
available_width = self.viewport().width() - 2 * padding
if self.image_pixmap.width() > available_width:
image_pixmap = self.image_pixmap.scaledToWidth(
available_width, QtCore.Qt.SmoothTransformation)
else:
image_pixmap = self.image_pixmap
graphics_scene = QtWidgets.QGraphicsScene()
graphics_scene.addPixmap(image_pixmap)
self.setScene(graphics_scene)
self.show()
def wheelEvent(self, event):
self.common_functions.wheelEvent(event, True)
class PliantQTextBrowser(QtWidgets.QTextBrowser):
def __init__(self, main_window, parent=None):
super(PliantQTextBrowser, self).__init__(parent)
self.main_window = main_window
self.ignore_wheel_event = False
self.ignore_wheel_event_number = 0
self.common_functions = PliantWidgetsCommonFunctions(self, self.main_window)
def wheelEvent(self, event):
if self.ignore_wheel_event:
self.common_functions.wheelEvent(event, False)
class PliantWidgetsCommonFunctions():
def __init__(self, parent_widget, main_window):
self.pw = parent_widget
self.main_window = main_window
def wheelEvent(self, event, are_we_doing_images_only):
if self.pw.ignore_wheel_event:
# Ignore first n wheel events after a chapter change
self.ignore_wheel_event_number += 1
if self.ignore_wheel_event_number > 20:
self.ignore_wheel_event = False
self.ignore_wheel_event_number = 0
self.pw.ignore_wheel_event_number += 1
if self.pw.ignore_wheel_event_number > 20:
self.pw.ignore_wheel_event = False
self.pw.ignore_wheel_event_number = 0
return
QtWidgets.QTextBrowser.wheelEvent(self, event)
if are_we_doing_images_only:
QtWidgets.QGraphicsView.wheelEvent(self.pw, event)
else:
QtWidgets.QTextBrowser.wheelEvent(self.pw, event)
# Since this is a delta on a mouse move event, it cannot ever be 0
vertical_pdelta = event.pixelDelta().y()
@@ -396,19 +487,19 @@ class PliantQTextBrowser(QtWidgets.QTextBrowser):
if abs(vertical_pdelta) > 100: # Adjust sensitivity here
# Implies that no scrollbar movement is possible
if self.verticalScrollBar().value() == self.verticalScrollBar().maximum() == 0:
if self.pw.verticalScrollBar().value() == self.pw.verticalScrollBar().maximum() == 0:
if moving_up:
self.change_chapter(-1)
else:
self.change_chapter(1)
# Implies that the scrollbar is at the bottom
elif self.verticalScrollBar().value() == self.verticalScrollBar().maximum():
elif self.pw.verticalScrollBar().value() == self.pw.verticalScrollBar().maximum():
if not moving_up:
self.change_chapter(1)
# Implies scrollbar is at the top
elif self.verticalScrollBar().value() == 0:
elif self.pw.verticalScrollBar().value() == 0:
if moving_up:
self.change_chapter(-1)
@@ -422,12 +513,12 @@ class PliantQTextBrowser(QtWidgets.QTextBrowser):
# Set page position depending on if the chapter number is increasing or decreasing
if direction == 1 or was_button_pressed:
self.verticalScrollBar().setValue(0)
self.pw.verticalScrollBar().setValue(0)
else:
self.verticalScrollBar().setValue(
self.verticalScrollBar().maximum())
self.pw.verticalScrollBar().setValue(
self.pw.verticalScrollBar().maximum())
self.ignore_wheel_event = True
self.pw.ignore_wheel_event = True
class LibraryDelegate(QtWidgets.QStyledItemDelegate):