PyQt5 從零開始製作 PDF 閱讀器(二)

PyQt5 從零開始製作 PDF 閱讀器(二)

上一篇文章中,我們實現了 PDF 閱讀器的初始介面。這一次,新增了閱讀功能,可以實現基本的翻頁以及縮放等操作。不過,暫時只可以同時閱讀一本書。

下圖為效果圖:

PyQt5 從零開始製作 PDF 閱讀器(二)

下面我來介紹下,這次主要新增的功能:

選項卡

QTabWidget 可以允許我們在一個視窗顯示多個頁面。對於書庫的這個選項卡,頁面顯示為 self。table ,即初始介面

self。table(QTableWidget) -> self。tabwidget(QTabWidge)。

# Python高效程式設計# 初始化選項卡self。tabwidget = QTabWidget()# 新增書庫選項卡self。tabwidget。addTab(self。table, ‘書庫’)self。setCentralWidget(self。tabwidget)# 設定選項卡可以關閉self。tabwidget。setTabsClosable(True)# 點選選項卡叉號時,執行 removeTabab 操作self。tabwidget。tabCloseRequested[int]。connect(self。remove_tab)

新建選項卡:每次開始閱讀時,新建一個選項卡,名稱為檔名。

def read_book(self, fname): # self。close() # 記憶體有可能洩露 self。doc = fitz。open(fname) # metadata = doc。metadata title = fname。split(‘/’ or ‘\\’)[-1]。replace(‘。pdf’, ‘’)​ vbox = self。book_area(self。doc。loadPage(0)) self。book_add_tab(title, vbox)

其中,我們要求主選項卡,即書庫選項卡是不可以關閉的。

def remove_tab(self, index): if index: # 當前頁數 self。current_page = 0 self。tabwidget。removeTab(index) # 正在閱讀的書 self。read_list。pop(index)

閱讀介面的選項卡對應的頁面區域為 QScrollArea ,QScrollArea 支援滾輪操作。也就是說,如果我們縮放 PDF 頁面大小超過 QScrollArea 的大小,那麼就會自動出現滾輪,以便我們瀏覽頁面。其中,MyArea 類是對 QScrollArea 的過載,綁定了快捷鍵以支援翻頁以及縮放等操作。

Pixmap -> label -> area(MyArea) -> vbox(QVBoxLayout) -> tab(QWidget) -> self。tabwidget(QTabWidge)。

def book_add_tab(self, title, vbox): tab = QWidget() tab。setLayout(vbox) # tab 為頁面,title 為標籤名稱 self。tabwidget。addTab(tab, title) def book_area(self, page): label = self。page_pixmap(page) # area = QScrollArea() area = MyArea(self) area。init(self) area。setWidget(label)​ vbox = QVBoxLayout() vbox。addWidget(area) return vbox

下面我們來看看, MyArea 這個類該如何定義:

MyArea(QScrollArea)

這裡,我們定義了 init 方法,用來接受 Reader 主類 的 self 引數, 即透過 self。widget 呼叫 Reader 類的例項方法。

在 init_action 函式中,我們新建了四個 QShortCut 例項,分別支援快捷鍵實現縮小、放大、下一頁、上一頁的操作。

class MyArea(QScrollArea): def init(self, widget): self。widget = widget self。init_action()​ def init_action(self): zoom_minus = QShortcut(QKeySequence(“Ctrl+-”), self) zoom_minus。activated。connect(self。minus) zoom_plus = QShortcut(QKeySequence(“Ctrl+=”), self) zoom_plus。activated。connect(self。plus)​ switch_left = QShortcut(QKeySequence(Qt。Key_Left), self) switch_left。activated。connect(self。left) switch_right = QShortcut(QKeySequence(Qt。Key_Right), self) switch_right。activated。connect(self。right)​​ def plus(self): self。widget。zoom_book(plus=True)​ def minus(self): self。widget。zoom_book(plus=False)​ def right(self): self。widget。switch_page(right=True)​ def left(self): self。widget。switch_page(right=False)

下面,我們來介紹縮放與翻頁功能的具體實現:

縮放功能

self。size 用來儲存頁面大小,self。page 正是根據 self。size 來實現縮放功能。

def zoom_book(self, plus=True): a, b = self。size if plus: a += 0。4 b += 0。4 self。size = (a, b) self。set_page() elif not plus and a > 0: if a >= 1: a -= 0。4 b -= 0。4 self。size = (a, b) self。set_page()

Pixmap -> label -> area(MyArea) -> vbox(QVBoxLayout) -> tab(QWidget) -> self。tabwidget(QTabWidge)。

tab 獲取 tab 物件,layout 獲取 vbox 物件,widget 獲取 area 物件,直接更改 area 上 label 控制元件。

def set_page(self): # 載入頁面 page = self。doc。loadPage(self。current_page) # 獲取當前 Widget tab = self。tabwidget。currentWidget() # 獲取當前的 Layout layout = tab。layout() # 獲取 Layout 上的控制元件 widget = layout。itemAt(0)。widget() # 獲取已經繪製好的 label 物件 label = self。page_pixmap(page) # 將 widget 的內容更改為現在的 label 物件 widget。setWidget(label)

接著我們介紹如何實現翻頁功能

翻頁功能

這次,我們實現的 PDF 閱讀器只能同時閱讀一本書,所以翻頁功能只需由 self。current_page 控制就行。

self。doc。pageCount 為總頁數,當前頁數不能為負數或者大於總頁數。更改完 self。current_page 之後,就可以執行 self。set_page 操作,直接更改 area 上的 label 控制元件。

def set_current_page(self, right): if right and self。current_page < self。doc。pageCount - 1: self。current_page += 1​ elif not right and self。current_page > 0: self。current_page -= 1 ​def switch_page(self, right=True): self。set_current_page(right) self。set_page()

PyQt5 從零開始製作 PDF 閱讀器(二)

點選連結,獲取原始碼。